Last active
April 23, 2018 00:04
-
-
Save Earnestly/c546558f7e6918a62cdeec97a5fc8fcf to your computer and use it in GitHub Desktop.
Mouse pointer centering for X11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PREFIX = /usr/local | |
bindir = /bin | |
LDLIBS := $(shell pkg-config --libs-only-l x11 xi) | |
all: mouse-spring | |
install: | |
install -Dm0755 mouse-spring $(DESTDIR)$(PREFIX)$(bindir)/mouse-spring |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <err.h> | |
#include <X11/Xlib.h> | |
#include <X11/extensions/XInput2.h> | |
int | |
main(void) | |
{ | |
Window window; | |
Display *display; | |
int screen; | |
int xi_opcode; | |
int error; | |
int event; | |
unsigned int width; | |
unsigned int height; | |
int fd; | |
fd_set fdset; | |
struct timeval tv; | |
XIEventMask mask[2]; | |
XIEventMask *m; | |
display = XOpenDisplay(NULL); | |
window = DefaultRootWindow(display); | |
screen = DefaultScreen(display); | |
if(!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) | |
err(1, "XINPUT not available\n"); | |
m = &mask[0]; | |
m->deviceid = XIAllDevices; | |
m->mask_len = XIMaskLen(XI_LASTEVENT); | |
m->mask = calloc(m->mask_len, sizeof(unsigned char)); | |
XISetMask(m->mask, XI_Motion); | |
XISelectEvents(display, window, &mask[0], 1); | |
XSync(display, False); | |
free(mask[0].mask); | |
fd = ConnectionNumber(display); | |
width = DisplayWidth(display, screen); | |
height = DisplayHeight(display, screen); | |
for(;;){ | |
FD_ZERO(&fdset); | |
FD_SET(fd, &fdset); | |
/* The goal here is to allow for some slop in the movement rather than | |
* pinning the pointer. By using a timeout for the event window we can | |
* allow the pointer to move before forcing it back to the centre. | |
*/ | |
tv.tv_usec = 20000; | |
if(select(fd + 1, &fdset, NULL, NULL, &tv) == 0){ | |
XWarpPointer(display, None, window, 0, 0, 0, 0, width/2, height/2); | |
} | |
XEvent event; | |
XGenericEventCookie *cookie = (XGenericEventCookie*)&event.xcookie; | |
XNextEvent(display, (XEvent*)&event); | |
#if 0 | |
if(XGetEventData(display, cookie) && cookie->type == GenericEvent && cookie->extension == xi_opcode){ | |
XIDeviceEvent *device = cookie->data; | |
printf("%.0f %.0f\n", device->root_x, device->root_y); | |
} | |
#endif | |
XFreeEventData(display, cookie); | |
} | |
XDestroyWindow(display, window); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment