1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include <X11/Xlib.h>
5 #include <X11/extensions/XTest.h>
6 
main(void)7 int main(void)
8 {
9     Display *dpy;
10     int scr;
11     XEvent xev;
12     Window root;
13 
14     dpy = XOpenDisplay(NULL);
15     if (dpy == NULL) {
16 	exit(1);
17     }
18     scr = DefaultScreen(dpy);
19     root = DefaultRootWindow(dpy);
20 
21     printf("Welcome to Carl Worth's test of grab passing.\n"
22 	   "Click Button1 to get a grab and try to pass it through with XTest.\n"
23 	   "Click any other button to get a grab and pass it through with XAllowEvents.\n\n");
24 
25     XGrabButton(dpy, AnyButton, AnyModifier, root,
26 		True, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
27 		GrabModeSync, GrabModeAsync, None, None);
28     while (1) {
29 	XNextEvent(dpy, &xev);
30 	switch (xev.type) {
31 	case ButtonPress: {
32 	    printf("Got a grab\n");
33 	    if (xev.xbutton.button != 1) {
34 		printf("Passing button through with XAllowEvents\n");
35 		XAllowEvents(dpy, ReplayPointer, CurrentTime);
36 	    } else {
37 		printf("Attempting to pass button through with XTest\n");
38 
39 		XGrabServer(dpy);
40 		XAllowEvents(dpy, AsyncPointer, CurrentTime);
41 		XUngrabPointer(dpy, CurrentTime);
42 		XUngrabButton(dpy, AnyButton, AnyModifier, root);
43 
44 		XTestFakeButtonEvent(dpy, xev.xbutton.button, False, CurrentTime);
45 		XTestFakeButtonEvent(dpy, xev.xbutton.button, True, CurrentTime);
46 
47 		XGrabButton(dpy, AnyButton, AnyModifier, root,
48 			    True, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
49 			    GrabModeSync, GrabModeAsync, None, None);
50 
51 		XSync(dpy, False);
52 		XUngrabServer(dpy);
53 	    }
54 	    break;
55 	}
56 	}
57     }
58 
59     return 0;
60 }
61