xss

Screensaver utilities for the X Windowing System
git clone https://git.woozle.org/neale/xss.git

commit
ebea23e
parent
92bb54a
author
Neale Pickett
date
2012-03-01 17:40:12 -0700 MST
fix xkeygrab latency bug, finally
1 files changed,  +132, -100
M xkeygrab.c
+132, -100
  1@@ -1,10 +1,11 @@
  2-/* xkeygrab -- grab keyboard and mouse, writing typed lines to stdout
  3- * Copyright (C) 2008  Neale Pickett <neale@woozle.org>
  4+/*
  5+ * xkeygrab -- grab keyboard and mouse, writing typed lines to stdout
  6+ * Copyright (C) 2008 Neale Pickett <neale@woozle.org> 
  7  *
  8- * This program is free software: you can redistribute it and/or modify
  9- * it under the terms of the GNU General Public License as published by
 10- * the Free Software Foundation, either version 3 of the License, or (at
 11- * your option) any later version.
 12+ * This program is free software:  you can redistribute it and/or
 13+ * modify it under the terms of the GNU General Public License as
 14+ * published by the Free Software Foundation, either version 3 of the
 15+ * License, or (at your option) any later version.
 16  *
 17  * This program is distributed in the hope that it will be useful, but
 18  * WITHOUT ANY WARRANTY; without even the implied warranty of
 19@@ -12,7 +13,7 @@
 20  * General Public License for more details.
 21  *
 22  * You should have received a copy of the GNU General Public License
 23- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 24+ * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 25  */
 26 
 27 #include <stdio.h>
 28@@ -28,104 +29,135 @@
 29 int
 30 main(int argc, char *argv[])
 31 {
 32-  Display *display = NULL;
 33-
 34-  if (argc != 1) {
 35-    (void)fprintf(stderr, "Usage: %s\n", argv[0]);
 36-    return 64;                  /* EX_USAGE */
 37-  }
 38-
 39-  try {
 40-    Window        root;
 41-    char          obuf[4096];
 42-    int           obuflen = 0;
 43-    struct pollfd fds[2];
 44-
 45-    if (! (display = XOpenDisplay(NULL))) raise("cannot open display");
 46-    root = DefaultRootWindow(display);
 47-
 48-    fds[0].fd = STDOUT_FILENO;
 49-    fds[0].events = 0;
 50-    fds[1].fd = ConnectionNumber(display);
 51-    fds[1].events = POLLIN;
 52-    while (1) {
 53-      int tograb = 3;
 54-      int ret;
 55-
 56-      if (tograb) {
 57-        if ((tograb & 1) && (GrabSuccess == XGrabKeyboard(display, root,
 58-                                                          True,
 59-                                                          GrabModeAsync, GrabModeAsync,
 60-                                                          CurrentTime))) {
 61-          tograb |= 1;
 62-        }
 63-        if ((tograb & 2) && (GrabSuccess == XGrabPointer(display, root,
 64-                                                         False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
 65-                                                         GrabModeAsync, GrabModeAsync,
 66-                                                         None, None, CurrentTime))) {
 67-          tograb |= 2;
 68+    Display        *display = NULL;
 69+
 70+    if (argc != 1) {
 71+        (void) fprintf(stderr, "Usage: %s\n", argv[0]);
 72+        return 64;              /* EX_USAGE */
 73+    }
 74+
 75+    try {
 76+        Window          root;
 77+        char            obuf[4096];
 78+        int             obuflen = 0;
 79+        struct pollfd   fds[2];
 80+
 81+        if (!(display = XOpenDisplay(NULL)))
 82+            raise("cannot open display");
 83+        root = DefaultRootWindow(display);
 84+
 85+        if (getenv("NOROOT")) {
 86+            int             screen = DefaultScreen(display);
 87+
 88+            XSetWindowAttributes wa;
 89+
 90+            zero(wa);
 91+
 92+            wa.override_redirect = 1;
 93+            wa.background_pixel = BlackPixel(display, screen);
 94+            root = XCreateWindow(display, root,
 95+                                 0, 0,
 96+                                 50, 50, 0,
 97+                                 CopyFromParent, CopyFromParent,
 98+                                 CopyFromParent, CWBackPixel, &wa);
 99+            XMapWindow(display, root);
100         }
101-      }
102-
103-      ret = poll(fds, 2, (tograb?100:-1));
104-
105-      if (fds[0].revents & POLLERR) {
106-        break;
107-      }
108-      if (fds[1].revents & POLLIN) {
109-        XEvent event;
110-
111-        (void)XNextEvent(display, &event);
112-        if (KeyPress == event.type) {
113-          char   buf[32];
114-          KeySym ksym;
115-          int    i;
116-
117-          if (obuflen == sizeof(obuf)) continue;
118-          i = XLookupString(&event.xkey, buf, sizeof(buf), &ksym, NULL);
119-          switch (ksym) {
120-            case XK_Return:
121-              if (obuflen) {
122-                (void)write(STDOUT_FILENO, obuf, obuflen);
123-                (void)write(STDOUT_FILENO, "\n", 1);
124-                obuflen = 0;
125-              }
126-              break;
127-            case XK_BackSpace:
128-              if (obuflen) obuflen -= 1;
129-              break;
130-            default:
131-              if (1 == i) {
132-                switch (buf[0]) {
133-                  case '\025':
134-                    obuflen = 0;
135-                    break;
136-                  case ' ' ... '~':
137-                    obuf[obuflen++] = buf[0];
138-                  break;
139+
140+
141+        fds[0].fd = STDOUT_FILENO;
142+        fds[0].events = 0;
143+        fds[1].fd = ConnectionNumber(display);
144+        fds[1].events = POLLIN;
145+        while (1) {
146+            int             tograb = 3;
147+            int             ret;
148+
149+            if (tograb) {
150+                if ((tograb & 1)
151+                    && (GrabSuccess ==
152+                        XGrabKeyboard(display, root, True, GrabModeAsync,
153+                                      GrabModeAsync, CurrentTime))) {
154+                    tograb |= 1;
155+                }
156+                if ((tograb & 2)
157+                    && (GrabSuccess ==
158+                        XGrabPointer(display, root, False,
159+                                     ButtonPressMask | ButtonReleaseMask |
160+                                     PointerMotionMask, GrabModeAsync,
161+                                     GrabModeAsync, None, None,
162+                                     CurrentTime))) {
163+                    tograb |= 2;
164                 }
165-              }
166-              break;
167-          }
168-          if (obuflen == sizeof(obuf)) {
169-            (void)write(STDOUT_FILENO, obuf, obuflen);
170-            obuflen = 0;
171-          }
172+            }
173+
174+            ret = poll(fds, 2, (tograb ? 100 : -1));
175+            if (-1 == ret)
176+                break;
177+
178+            if (fds[0].revents & POLLERR) {
179+                break;
180+            }
181+            if (fds[1].revents & POLLIN) {
182+                XEvent          event;
183+
184+                do {
185+                    (void) XNextEvent(display, &event);
186+                    if (KeyPress == event.type) {
187+                        char            buf[32];
188+                        KeySym          ksym;
189+                        int             i;
190+
191+                        if (obuflen == sizeof(obuf))
192+                            continue;
193+                        i = XLookupString(&event.xkey, buf, sizeof(buf),
194+                                          &ksym, NULL);
195+                        switch (ksym) {
196+                            case XK_Return:
197+                                if (obuflen) {
198+                                    (void) write(STDOUT_FILENO, obuf,
199+                                                 obuflen);
200+                                    (void) write(STDOUT_FILENO, "\n", 1);
201+                                    obuflen = 0;
202+                                }
203+                                break;
204+                            case XK_BackSpace:
205+                                if (obuflen)
206+                                    obuflen -= 1;
207+                                break;
208+                            default:
209+                                if (1 == i) {
210+                                    switch (buf[0]) {
211+                                        case '\025':
212+                                            obuflen = 0;
213+                                            break;
214+                                        case ' ' ... '~':
215+                                            obuf[obuflen++] = buf[0];
216+                                            break;
217+                                    }
218+                                }
219+                                break;
220+                        }
221+                        if (obuflen == sizeof(obuf)) {
222+                            (void) write(STDOUT_FILENO, obuf, obuflen);
223+                            obuflen = 0;
224+                        }
225+                    }
226+                } while (XPending(display));
227+            }
228         }
229-      }
230     }
231-  } while (0);
232+    while (0);
233 
234-  if (display) {
235-    (void)XUngrabKeyboard(display, CurrentTime);
236-    (void)XUngrabPointer(display, CurrentTime);
237-    (void)XCloseDisplay(display);
238-  }
239+    if (display) {
240+        (void) XUngrabKeyboard(display, CurrentTime);
241+        (void) XUngrabPointer(display, CurrentTime);
242+        (void) XCloseDisplay(display);
243+    }
244 
245-  except {
246-    (void)fprintf(stderr, "Error: %s\n", exception);
247-    return 69;                  /* EX_UNAVAILABLE */
248-  }
249+    except {
250+        (void) fprintf(stderr, "Error: %s\n", exception);
251+        return 69;              /* EX_UNAVAILABLE */
252+    }
253 
254-  return 0;
255+    return 0;
256 }