/* * xchord -- run dwim on button 1 + 3 * * This is a simple program that runs dwim whenever the right * mouse button is pressed while the left mouse button is held. * * It does *not* block the button events. That means that both * clicks will be registered by other programs. This may be a * problem in programs that open a context menu on button 3. * * On NetBSD, xchord should be compiled with the following flags: * * CFLAGS = -I/usr/X11R7/include * LDFLAGS = -L/usr/X11R7/lib -Wl,-R/usr/X11R7/lib -lXi * * xchord is written by John Ankarström . */ #include #include #include #include #include #include #include Display *dpy; Window rwin; int main(int argc, char *argv[]) { int p; unsigned char mask[(XI_LASTEVENT+7)/8]; XEvent ev; XGenericEventCookie *cookie; XIEventMask evmasks[1]; XIRawEvent *rev; dpy = XOpenDisplay(NULL); if(!dpy){ fprintf(stderr, "could not open display"); return 1; } rwin = DefaultRootWindow(dpy); /* select events */ memset(mask, 0, sizeof(mask)); XISetMask(mask, XI_RawButtonPress); XISetMask(mask, XI_RawButtonRelease); evmasks[0].deviceid = XIAllMasterDevices; evmasks[0].mask_len = sizeof(mask); evmasks[0].mask = mask; XISelectEvents(dpy, rwin, evmasks, 1); XFlush(dpy); cookie = &ev.xcookie; p = 0; /* watch for events */ for(;;){ XNextEvent(dpy, &ev); XPutBackEvent(dpy, &ev); if(!XCheckTypedEvent(dpy, GenericEvent, &ev)) continue; if(cookie->type != GenericEvent || !XGetEventData(dpy, cookie)) continue; rev = (XIRawEvent*)cookie->data; switch(cookie->evtype){ case XI_RawButtonPress: /* 1 pressed (first step) */ if(rev->detail == 1) p = 1; /* 1 + 3 pressed (second step) */ if(p > 0 && rev->detail == 3) p = 2; break; case XI_RawButtonRelease: /* 1 pressed + 3 pressed + 3 released (third step) */ if(p == 2 && rev->detail == 3){ p = 3; system("dwim -o"); } /* 1 released (reset) */ if((p == 1 || p == 3) && rev->detail == 1) p = 0; break; } XFreeEventData(dpy, cookie); } }