27 #include <spnav.h> |
27 #include <spnav.h> |
28 |
28 |
29 // from proto_x11.c (spacenavd) |
29 // from proto_x11.c (spacenavd) |
30 static Atom xa_event_motion, xa_event_bpress, xa_event_brelease, xa_event_cmd; |
30 static Atom xa_event_motion, xa_event_bpress, xa_event_brelease, xa_event_cmd; |
31 static float x11_sens = 1.0; |
31 static float x11_sens = 1.0; |
32 |
|
33 /* X11 error handler */ |
|
34 static int xerr(Display *dpy, XErrorEvent *err) { |
|
35 char buf[512]; |
|
36 |
|
37 fprintf(stderr, "xerr(%p, %p)\n", (void*) dpy, (void*) err); |
|
38 if (err->error_code == BadWindow) { |
|
39 fprintf(stderr, "BadWindow\n"); |
|
40 } else { |
|
41 XGetErrorText(dpy, err->error_code, buf, sizeof buf); |
|
42 fprintf(stderr, "Caught unexpected X error: %s\n", buf); |
|
43 } |
|
44 return 0; |
|
45 } |
|
46 |
|
47 /* X11 I/O error handler |
|
48 * This function must not return or xlib will abort. |
|
49 */ |
|
50 static int xioerr(Display *display) { |
|
51 fprintf(stderr, "Lost the X server!\n"); |
|
52 return 0; |
|
53 } |
|
54 |
32 |
55 /** |
33 /** |
56 * This function is based on proto_x11.c (spacenavd) written by: |
34 * This function is based on proto_x11.c (spacenavd) written by: |
57 * Copyright (C) 2007-2019 John Tsiombikas <nuclear@member.fsf.org> |
35 * Copyright (C) 2007-2019 John Tsiombikas <nuclear@member.fsf.org> |
58 * and published under GNU GPLv3+ |
36 * and published under GNU GPLv3+ |
107 } |
85 } |
108 |
86 |
109 static void spacenav_hack_translate_events(Window win) { |
87 static void spacenav_hack_translate_events(Window win) { |
110 spnav_event event; |
88 spnav_event event; |
111 Display* dpy = XOpenDisplay(0); |
89 Display* dpy = XOpenDisplay(0); |
112 XSetErrorHandler(xerr); |
|
113 XSetIOErrorHandler(xioerr); |
|
114 fprintf(stderr, "Error handlers were set\n"); |
|
115 |
|
116 /* |
|
117 xa_event_motion = XInternAtom(dpy, "MotionEvent", False); |
|
118 xa_event_bpress = XInternAtom(dpy, "ButtonPressEvent", False); |
|
119 xa_event_brelease = XInternAtom(dpy, "ButtonReleaseEvent", False); |
|
120 xa_event_cmd = XInternAtom(dpy, "CommandEvent", False); |
|
121 */ |
|
122 |
|
123 fprintf(stderr, "spnav-lib-hack: xa_event_motion = %ld\n", xa_event_motion); |
|
124 fprintf(stderr, "spnav-lib-hack: xa_event_bpress = %ld\n", xa_event_bpress); |
|
125 fprintf(stderr, "spnav-lib-hack: xa_event_brelease = %ld\n", xa_event_brelease); |
|
126 fprintf(stderr, "spnav-lib-hack: xa_event_cmd = %ld\n", xa_event_cmd); |
|
127 |
90 |
128 while (1) { |
91 while (1) { |
129 if (spnav_wait_event(&event)) { |
92 if (spnav_wait_event(&event)) { |
130 fprintf(stderr, "spnav-lib-hack: got event: PID=%d dpy=%p win=%lx\n", getpid(), dpy, win); |
|
131 //XLockDisplay(dpy); |
|
132 send_xevent(&event, dpy, win); |
93 send_xevent(&event, dpy, win); |
133 //XUnlockDisplay(dpy); |
|
134 } |
94 } |
135 } |
95 } |
|
96 // FIXME: this process never ends and must be killed manually |
136 } |
97 } |
137 |
98 |
138 int spnav_x11_open(Display* dpy, Window win) { |
99 int spnav_x11_open(Display* dpy, Window win) { |
139 int result = spnav_open(); |
100 int result = spnav_open(); |
140 fprintf(stderr, "spnav-lib-hack: instead of spnav_x11_open(%p, 0x%lx) calling spnav_open() = %d\n", dpy, win, result); |
101 fprintf(stderr, "spnav-lib-hack: instead of spnav_x11_open(%p, 0x%lx) calling spnav_open() = %d\n", dpy, win, result); |
145 xa_event_cmd = XInternAtom(dpy, "CommandEvent", False); |
106 xa_event_cmd = XInternAtom(dpy, "CommandEvent", False); |
146 |
107 |
147 if (result == 0) { |
108 if (result == 0) { |
148 pid_t pid = fork(); |
109 pid_t pid = fork(); |
149 fprintf(stderr, "spnav-lib-hack: fork() = %d; PID=%d\n", pid, getpid()); |
110 fprintf(stderr, "spnav-lib-hack: fork() = %d; PID=%d\n", pid, getpid()); |
150 if (pid == -1) return 1; |
111 if (pid == -1) return 1; // error |
151 if (pid == 0) spacenav_hack_translate_events(win); |
112 if (pid == 0) spacenav_hack_translate_events(win); // child |
|
113 else; // parent |
152 } |
114 } |
153 |
115 |
154 return result; |
116 return result; |
155 } |
117 } |
156 |
118 |
196 event->button.press = xmsg_type == xa_event_bpress ? 1 : 0; |
158 event->button.press = xmsg_type == xa_event_bpress ? 1 : 0; |
197 event->button.bnum = xev->xclient.data.s[2]; |
159 event->button.bnum = xev->xclient.data.s[2]; |
198 } |
160 } |
199 return event->type; |
161 return event->type; |
200 |
162 |
|
163 // real_spnav_x11_event() is not working (see comment above): |
|
164 |
201 /* |
165 /* |
202 static int (*real_spnav_x11_event)(const XEvent*, spnav_event*) = NULL; |
166 static int (*real_spnav_x11_event)(const XEvent*, spnav_event*) = NULL; |
203 if (!real_spnav_x11_event) real_spnav_x11_event = dlsym(RTLD_NEXT, "spnav_x11_event"); |
167 if (!real_spnav_x11_event) real_spnav_x11_event = dlsym(RTLD_NEXT, "spnav_x11_event"); |
204 int result = real_spnav_x11_event(xev, event); |
168 int result = real_spnav_x11_event(xev, event); |
205 if (result == SPNAV_EVENT_MOTION || result == SPNAV_EVENT_BUTTON) fprintf(stderr, "spnav-lib-hack: spnav_x11_event() = %d\n", result); |
169 if (result == SPNAV_EVENT_MOTION || result == SPNAV_EVENT_BUTTON) fprintf(stderr, "spnav-lib-hack: spnav_x11_event() = %d\n", result); |
216 fprintf(stderr, "spnav-lib-hack: spnav_x11_open() = %d\n", result); |
180 fprintf(stderr, "spnav-lib-hack: spnav_x11_open() = %d\n", result); |
217 return result; |
181 return result; |
218 } |
182 } |
219 */ |
183 */ |
220 |
184 |
221 |
|
222 /* |
|
223 int spnav_open() { |
|
224 return -1; |
|
225 } |
|
226 */ |
|
227 |
|
228 /* |
185 /* |
229 int spnav_open() { |
186 int spnav_open() { |
230 static int (*real_spnav_open)() = NULL; |
187 static int (*real_spnav_open)() = NULL; |
231 if (!real_spnav_open) real_spnav_open = dlsym(RTLD_NEXT, "spnav_open"); |
188 if (!real_spnav_open) real_spnav_open = dlsym(RTLD_NEXT, "spnav_open"); |
232 int result = real_spnav_open(); |
189 int result = real_spnav_open(); |