Skip to content

Instantly share code, notes, and snippets.

@Earnestly
Last active April 23, 2018 00:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Earnestly/c546558f7e6918a62cdeec97a5fc8fcf to your computer and use it in GitHub Desktop.
Save Earnestly/c546558f7e6918a62cdeec97a5fc8fcf to your computer and use it in GitHub Desktop.
Mouse pointer centering for X11
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
#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