- 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
+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 }