public
Created

Watch-xi2 looks for X Window System events that occur when input device hierarchy changes in any way (e.g. when a keyboard or a mouse is connected or disconnected). It may take a single parameter: a shell command to run on the hierarchy change events.

  • Download Gist
watch-xi2.c
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
/* (c) Copyright 2010 Anton Kovalenko <anton@sw4me.com>.
LICENSE:Do what you want with this software, but don't blame me.
 
Compile it with gcc -lX11 -lXi.
*/
#define WATCH_XI2_TIMESTAMP "Time-stamp: <2010-08-14 19:39:55 anton>"
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
 
#define EPIC_FAILF(format,...) \
do { \
fprintf(stderr,format "\n",__VA_ARGS__); \
exit(1); \
} while (0)
 
#define EPIC_FAIL(string) EPIC_FAILF("%s",string)
 
 
void usage()
{
EPIC_FAIL("\nwatch-xi2 [" WATCH_XI2_TIMESTAMP "]\n\n"
"Watch-xi2 looks for X Window System events that occur when \n"
"input device hierarchy changes in any way (e.g. when keyboard or\n"
"mouse is connected or disconnected).\n\n"
"It may take a single parameter: a shell command to run on the hierarchy\n"
"change events:\n\n"
" watch-xi2 'xmodmap .my-xmodmap'\n\n"
"If no parameter is given, watch-xi2 just prints a line to stdout\n"
"instead of running anything.");
}
 
 
int main(int argc, char *argv[])
{
Display *dpy;
int major=2, minor=0, xi_opcode, event, error;
XIEventMask interesting;
Window root;
 
if (argc != 1 && argc != 2 ||
argc == 2 && argv[1][0]=='-')
usage();
dpy = XOpenDisplay(NULL);
if (!dpy)
EPIC_FAIL("Can't open display");
if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error))
EPIC_FAIL("X Input extension not available.");
if (XIQueryVersion(dpy,&major,&minor)!=Success)
EPIC_FAIL("XInput2 not supperted");
root = DefaultRootWindow(dpy);
interesting.deviceid = XIAllDevices;
interesting.mask_len = XIMaskLen(XI_HierarchyChanged);
interesting.mask = calloc(interesting.mask_len, sizeof(char));
if (!interesting.mask)
EPIC_FAIL("Out of memory");
XISetMask(interesting.mask, XI_HierarchyChanged);
XISelectEvents(dpy,root,&interesting,1);
XSync(dpy,False);
while (1) {
XEvent xevent;
XGenericEventCookie *cookie = (XGenericEventCookie*)&xevent.xcookie;
 
XNextEvent(dpy,&xevent);
if (XGetEventData(dpy,cookie) &&
(cookie->type == GenericEvent) &&
(cookie->extension == xi_opcode)) {
if (argc<2) {
puts("Something happened: please do something useful."); }
else {
printf("Running shell command %s...\n",argv[1]);
system(argv[1]); }
fflush(stdout);}}}
 
/* Local Variables: */
/* compile-command: "make LDFLAGS='-lX11 -lXi' CFLAGS='-O2' watch-xi2" */
/* End: */

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.