Kodi Community Forum

Full Version: X11 Mouse Warping
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am trying to develop a tool that will warp around the mouse when Linux receives various inputs to replicate an absolute pointing device. The approach I am taking is to determine the exact x,y coordinates where I want the mouse and then I am warping it as follows...

Code:
Display *dpy = XOpenDisplay(NULL);
Window root_window = DefaultRootWindow(dpy);
XWarpPointer(dpy, None, root_window, 0, 0, 0, 0, 100, 100);
XFlush(dpy);

The above code will move the mouse to 100,100 as expected while in windowed mode. The problem is that while in full screen mode the mouse warps are relative and not absolute. So basically the mouse pointer moves 100 right and 100 down instead of moving to 100,100. Again this works as expected while in windowed mode but full screen is messing up (or I am). Does anybody have any idea what I should try in order to get this working?
Are you doing this on XBMC?
Sorry for not giving the full background story. I'll explain a little more. I want to have an absolute pointing device such as the Wii remote to navigate the menus in xbmc. The existing methods of doing this in Linux involve using old userspace drivers that perform poorly in that they give very inaccurate pointing and they are poorly made. The more modern approach is to use the hid-wiimote kernel module and to create a userspace tool to interact with the driver using the libxwiimote.so library. There is no way of doing this yet as nobody has made any userspace mouse emulation that uses the IR of the wiimote and user absolute, not relative, pointing. I decided to take a shot at it.

The method I am taking is using the data that I poll from the wiimote to determine and exact X,Y coordinate to warp the mouse to. I can call this code in a loop where I continuously poll the wiimote and warp the pointer. I dont have everything working yet as I am not the most experienced in this area but it is a challenge that I am up for in my spare time. When I call the above mentioned code in c I can get the mouse to warp to a set of absolute coordinates as long as xbmc is in windowed mode. Also using something like xterm works as it is windowed too.

The problem is when I put xbmc in full screen. The same code starts warping the mouse relative to its current position and not from the top left of the xbmc window. I am trying to figure out if full screen in xbmc is just a windowed mode that takes up the entire screen and that is positioned perfectly to hide the window decoration or is it something else all together? I'm fighting the warping and having a hard time getting it to go to absolute coordinates when in full screen so I am trying to figure out more about the way full screen works or I am looking for any hints that might help me figure out the path forward. The end goal is to use my wiimote with the kernel driver and the user space application I am creating to provide a way to accurately control xbmc.
The current code of XBMC still uses SDL. SDL actually opens 3 windows: one for gl drawing, one for windowed size, and one for full screen mode which sets override redirect flag. The gl window is reparented when changing windowed/fullscreen mode.
It is likely that you don't get the window handle of the full screen window.

You can check out this version which has already dropped SDL and makes use of XWarpPointer: https://github.com/FernetMenta/xbmc/blob...temX11.cpp
Thanks for the feedback. I tried using all top level windows as well as the re-parented child window for GL and I still have the same issue. Mouse warping is always relative not absolute while in full screen. The current work around I am using is setting XBMC to windowed mode and setting the windowed mode width and height to that of the screen resolution in advancedsettings.xml. Not the most robust solution, but it keeps me moving forward. I can work with this for now but I wish I knew why I cant do an absolute warp in fullscreen.

I noticed that other programs such as ZSNES do the same thing. Windowed mode will do absolute warping and the same code in full screen only does relative. I bet it is SDL based too. Probably something to do with the way SDL functions.
SDL sets the override redirect flag on the fullscreen window. This shouldn't be done when running inside a window manager.
Thanks. I've learned quite alot about X11 and SDL in the last few days. During my learning I also learned about the uinput subsystem in Linux and how to create a virtual device node and register absolute mouse pointing events with a custom device node. I basically do...

Code:
open("/dev/uinput", O_WRONLY | O_NONBLOCK);
.
.
ioctl(fd, UI_SET_EVBIT, EV_ABS);
ioctl(fd, UI_SET_ABSBIT, ABS_X);
ioctl(fd, UI_SET_ABSBIT, ABS_Y);
.
.
struct input_event event;
memset(&event, 0, sizeof(event));

event.type = EV_ABS;
event.code = ABS_X;
event.value = (some x int);
write(fd, &event, sizeof(event));

event.type = EV_ABS;
event.code = ABS_Y;
event.value = (some y int);
write(fd, &event, sizeof(event));

event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(fd, &event, sizeof(event));

This gives the absolute pointing I desire as well as giving me the ability to send clicks, button presses, joystick input, and force feedback as long as I register a few more events on my custom device node. Using the mouse warping through x was the first thing I thought of, but at this point i am convinced that uinput is the way to go for a Linux only solution. I appreciate all of the help though.