diff options
author | John Ankarstrom <john@ankarstrom.se> | 2021-07-01 18:40:44 +0200 |
---|---|---|
committer | John Ankarstrom <john@ankarstrom.se> | 2021-07-01 18:40:44 +0200 |
commit | 83923c1471d2d75c2872a5498258573ecfa05013 (patch) | |
tree | 14580b59c47e2806631f2b8f29ee686ce19764d5 | |
parent | cf19637336ad36f6e58519c2696742c079e6bbf8 (diff) | |
download | dwim-83923c1471d2d75c2872a5498258573ecfa05013.tar.gz |
Add xchord utility
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | xchord.c | 92 |
2 files changed, 98 insertions, 1 deletions
@@ -1,4 +1,9 @@ BINDIR ?= /usr/local/bin +CFLAGS = -I/usr/X11R7/include +LDFLAGS = -L/usr/X11R7/lib -Wl,-R/usr/X11R7/lib -lXi + +xchord: xchord.c install: - ln -s $(PWD)/dwim $(BINDIR)/dwim + ln -sf $(PWD)/dwim $(BINDIR)/dwim + install xchord /usr/local/bin diff --git a/xchord.c b/xchord.c new file mode 100644 index 0000000..3ceef51 --- /dev/null +++ b/xchord.c @@ -0,0 +1,92 @@ +/* + * 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 <john (at) ankarstrom.se>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <X11/extensions/XInput2.h> +#include <X11/Xlib.h> + +#define die(s, ...) do { \ + fprintf(stderr, "%s: ", argv[0]); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + exit(s); \ +} while (0) + +Display *dpy; +Window rwin; + +int +main(int argc, char *argv[]) +{ + int p1; + unsigned char mask[(XI_LASTEVENT+7)/8]; + XEvent ev; + XGenericEventCookie *cookie; + XIEvent *xiev; + XIEventMask evmasks[1]; + XIRawEvent *rev; + + dpy = XOpenDisplay(NULL); + if (!dpy) die(1, "could not open display"); + 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; + p1 = 0; + + /* watch for events */ + for (;;) { + if (!XCheckTypedEvent(dpy, GenericEvent, &ev)) + continue; + if (cookie->type != GenericEvent || !XGetEventData(dpy, cookie)) + continue; + + xiev = (XIEvent*)cookie->data; + rev = (XIRawEvent*)xiev; + + switch (cookie->evtype) { + case XI_RawButtonPress: + /* button 1 pressed */ + if (rev->detail == 1) p1 = 1; + /* button 1 + 3 pressed */ + if (p1 && rev->detail == 3) system("dwim"); + break; + case XI_RawButtonRelease: + /* button 1 released */ + if (rev->detail == 1) p1 = 0; + break; + } + + XFreeEventData(dpy, cookie); + } +} |