/* xkeygrab -- grab keyboard and mouse, writing typed lines to stdout * Copyright (C) 2008 Neale Pickett * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include "obj.h" int main(int argc, char *argv[]) { Display *display = NULL; if (argc != 1) { (void)fprintf(stderr, "Usage: %s\n", argv[0]); return 64; /* EX_USAGE */ } try { Window root; char obuf[4096]; int obuflen = 0; struct pollfd fds[2]; if (! (display = XOpenDisplay(NULL))) raise("cannot open display"); root = DefaultRootWindow(display); fds[0].fd = STDOUT_FILENO; fds[0].events = 0; fds[1].fd = ConnectionNumber(display); fds[1].events = POLLIN; while (1) { int tograb = 3; int ret; if (tograb) { if ((tograb & 1) && (GrabSuccess == XGrabKeyboard(display, root, True, GrabModeAsync, GrabModeAsync, CurrentTime))) { tograb |= 1; } if ((tograb & 2) && (GrabSuccess == XGrabPointer(display, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime))) { tograb |= 2; } } ret = poll(fds, 2, (tograb?100:-1)); if (fds[0].revents & POLLERR) { break; } if (fds[1].revents & POLLIN) { XEvent event; (void)XNextEvent(display, &event); if (KeyPress == event.type) { char buf[32]; KeySym ksym; int i; if (obuflen == sizeof(obuf)) continue; i = XLookupString(&event.xkey, buf, sizeof(buf), &ksym, NULL); switch (ksym) { case XK_Return: if (obuflen) { (void)write(STDOUT_FILENO, obuf, obuflen); (void)write(STDOUT_FILENO, "\n", 1); obuflen = 0; } break; case XK_BackSpace: if (obuflen) obuflen -= 1; break; default: if (1 == i) { switch (buf[0]) { case '\025': obuflen = 0; break; case ' ' ... '~': obuf[obuflen++] = buf[0]; break; } } break; } if (obuflen == sizeof(obuf)) { (void)write(STDOUT_FILENO, obuf, obuflen); obuflen = 0; } } } } } while (0); if (display) { (void)XUngrabKeyboard(display, CurrentTime); (void)XUngrabPointer(display, CurrentTime); (void)XCloseDisplay(display); } except { (void)fprintf(stderr, "Error: %s\n", exception); return 69; /* EX_UNAVAILABLE */ } return 0; }