Created
January 23, 2013 13:13
-
-
Save akovalenko/4605420 to your computer and use it in GitHub Desktop.
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.
This file contains 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
/* (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: */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment