Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / dmx / examples / xinput.c
CommitLineData
a09e091a
JB
1/*
2 * Copyright 2001,2002 Red Hat Inc., Durham, North Carolina.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28/*
29 * Authors:
30 * Rickard E. (Rik) Faith <faith@redhat.com>
31 *
32 */
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <X11/Xlib.h>
38#include <X11/XKBlib.h>
39#include <X11/extensions/XInput.h>
40#include <X11/extensions/XKB.h>
41#include <X11/extensions/XKBstr.h>
42#include <X11/extensions/dmxext.h>
43#include <sys/time.h>
44
45static const char *
46core(DMXInputAttributes * iinf)
47{
48 if (iinf->isCore)
49 return "core";
50 else if (iinf->sendsCore)
51 return "extension (sends core events)";
52 else
53 return "extension";
54}
55
56static void
57printdmxinfo(Display * display, int id)
58{
59 int event_base;
60 int error_base;
61 int major_version, minor_version, patch_version;
62 DMXInputAttributes iinf;
63 Display *backend;
64 char *backendname = NULL;
65
66 if (!DMXQueryExtension(display, &event_base, &error_base))
67 return;
68 if (!DMXQueryVersion(display, &major_version, &minor_version,
69 &patch_version))
70 return;
71 if (major_version == 1 && minor_version == 0)
72 return; /* too old */
73 if (!DMXGetInputAttributes(display, id, &iinf))
74 return;
75
76 printf(" DMX Information: ");
77 if (iinf.detached)
78 printf("detached ");
79 else
80 printf("active ");
81 switch (iinf.inputType) {
82 case DMXLocalInputType:
83 printf("local, %s", core(&iinf));
84 break;
85 case DMXConsoleInputType:
86 printf("console %s, %s", iinf.name, core(&iinf));
87 break;
88 case DMXBackendInputType:
89 if (iinf.physicalId >= 0) {
90 if ((backend = XOpenDisplay(iinf.name))) {
91 XExtensionVersion *ext = XGetExtensionVersion(backend, INAME);
92
93 if (ext && ext != (XExtensionVersion *) NoSuchExtension) {
94 int count, i;
95 XDeviceInfo *devInfo = XListInputDevices(backend, &count);
96
97 if (devInfo) {
98 for (i = 0; i < count; i++) {
99 if ((unsigned) iinf.physicalId == devInfo[i].id
100 && devInfo[i].name) {
101 backendname = strdup(devInfo[i].name);
102 break;
103 }
104 }
105 XFreeDeviceList(devInfo);
106 }
107 }
108 XCloseDisplay(backend);
109 }
110 }
111 printf("backend o%d/%s", iinf.physicalScreen, iinf.name);
112 if (iinf.physicalId >= 0)
113 printf("/id%d", iinf.physicalId);
114 if (backendname) {
115 printf("=%s", backendname);
116 free(backendname);
117 }
118 printf(" %s", core(&iinf));
119 break;
120 }
121 printf("\n");
122}
123
124int
125main(int argc, char **argv)
126{
127 Display *display = NULL;
128 int device = -1;
129 int newmouse = -1;
130 int newkbd = -1;
131 int count;
132 int i, j;
133 XDeviceInfo *devInfo;
134 XExtensionVersion *ext;
135
136 if (argc == 2 || argc == 3 || argc == 4 || argc == 5) {
137 if (!(display = XOpenDisplay(argv[1]))) {
138 printf("Cannot open display %s\n", argv[1]);
139 return -1;
140 }
141 if (argc >= 3)
142 device = strtol(argv[2], NULL, 0);
143 if (argc >= 4)
144 newmouse = strtol(argv[3], NULL, 0);
145 if (argc >= 5)
146 newkbd = strtol(argv[4], NULL, 0);
147 }
148 else {
149 printf("Usage: %s display [device] [newmouse] [newkbd]\n", argv[0]);
150 return -1;
151 }
152
153 if (!display && !(display = XOpenDisplay(NULL))) {
154 printf("Cannot open default display\n");
155 return -1;
156 }
157
158 ext = XGetExtensionVersion(display, INAME);
159 if (!ext || ext == (XExtensionVersion *) NoSuchExtension) {
160 printf("No XInputExtension\n");
161 return -1;
162 }
163 printf("%s version %d.%d\n", INAME, ext->major_version, ext->minor_version);
164
165 if (!(devInfo = XListInputDevices(display, &count)) || !count) {
166 printf("Cannot list devices\n");
167 return -1;
168 }
169
170 for (i = 0; i < count; i++) {
171 XAnyClassPtr any;
172 const char *kind = "Unknown";
173 int has_key = 0;
174
175 switch (devInfo[i].use) {
176 case IsXPointer:
177 kind = "XPointer";
178 break;
179 case IsXKeyboard:
180 kind = "XKeyboard";
181 break;
182 case IsXExtensionDevice:
183 kind = "XExtensionDevice";
184 break;
185 }
186 printf("%2lu %-20.20s %-16.16s",
187 (long unsigned) devInfo[i].id,
188 devInfo[i].name ? devInfo[i].name : "", kind);
189
190 for (j = 0, any = devInfo[i].inputclassinfo;
191 j < devInfo[i].num_classes;
192 any = (XAnyClassPtr) ((char *) any + any->length), j++) {
193 const char *class = "unk";
194
195 switch (any->class) {
196 case KeyClass:
197 class = "key";
198 ++has_key;
199 break;
200 case ButtonClass:
201 class = "btn";
202 break;
203 case ValuatorClass:
204 class = "val";
205 break;
206 case FeedbackClass:
207 class = "fdb";
208 break;
209 case ProximityClass:
210 class = "prx";
211 break;
212 case FocusClass:
213 class = "foc";
214 break;
215 case OtherClass:
216 class = "oth";
217 break;
218 }
219 printf(" %s", class);
220 }
221 printf("\n");
222 printdmxinfo(display, i);
223
224 if (has_key) {
225 XkbDescPtr xkb;
226
227 if ((xkb = XkbGetKeyboard(display,
228 XkbAllComponentsMask, devInfo[i].id))) {
229 printf(" Xkb Information:\n");
230 printf(" Device id = %d\n", xkb->device_spec);
231 printf(" Min keycode = 0x%02x\n", xkb->min_key_code);
232 printf(" Max keycode = 0x%02x\n", xkb->max_key_code);
233#define PRINTNAME(x) \
234 printf(" %s = %s\n", \
235 #x, xkb->names->x ? XGetAtomName(display, xkb->names->x) : "")
236 PRINTNAME(keycodes);
237 PRINTNAME(geometry);
238 PRINTNAME(symbols);
239 PRINTNAME(types);
240 PRINTNAME(compat);
241 }
242 }
243 }
244
245 if (newmouse >= 0) {
246 XDevice *dev;
247
248 printf("Trying to make device %d core mouse\n", newmouse);
249 dev = XOpenDevice(display, devInfo[newmouse].id);
250 printf("Status = %d\n", XChangePointerDevice(display, dev, 0, 1));
251 return 0;
252 }
253
254 if (newkbd >= 0) {
255 XDevice *dev;
256
257 printf("Trying to make device %d core keyboard\n", newkbd);
258 dev = XOpenDevice(display, devInfo[newkbd].id);
259 printf("Status = %d\n", XChangeKeyboardDevice(display, dev));
260 return 0;
261 }
262
263 if (device >= 0) {
264#define MAX_EVENTS 100
265 int cnt = 0;
266 XDevice *dev;
267 XEventClass event_list[MAX_EVENTS];
268 int event_type[MAX_EVENTS];
269 const char *names[MAX_EVENTS];
270 int total = 0;
271
272#define ADD(type) \
273 if (cnt >= MAX_EVENTS) abort(); \
274 names[cnt] = #type; \
275 type(dev, event_type[cnt], event_list[cnt]); \
276 if (event_type[cnt]) ++cnt
277
278 dev = XOpenDevice(display, devInfo[device].id);
279 ADD(DeviceKeyPress);
280 ADD(DeviceKeyRelease);
281 ADD(DeviceButtonPress);
282 ADD(DeviceButtonRelease);
283 ADD(DeviceMotionNotify);
284 ADD(DeviceFocusIn);
285 ADD(DeviceFocusOut);
286 ADD(ProximityIn);
287 ADD(ProximityOut);
288 ADD(DeviceStateNotify);
289 ADD(DeviceMappingNotify);
290 ADD(ChangeDeviceNotify);
291
292 for (i = 0; i < cnt; i++) {
293 printf("Waiting for %s events of type %d (%lu) on 0x%08lx\n",
294 names[i],
295 event_type[i], (unsigned long) event_list[i],
296 (long unsigned) DefaultRootWindow(display));
297 }
298 XSelectExtensionEvent(display, DefaultRootWindow(display),
299 event_list, cnt);
300
301 for (;;) {
302 XEvent event;
303
304 XNextEvent(display, &event);
305 for (i = 0; i < cnt; i++) {
306 XDeviceMotionEvent *e = (XDeviceMotionEvent *) &event;
307 XDeviceButtonEvent *b = (XDeviceButtonEvent *) &event;
308
309 if (event.type == event_type[i]) {
310 printf("%s id=%lu (%d @ %d,%d; s=0x%04x, d=%d, t=%lu)"
311 " axes_count=%d first=%d %d %d %d %d %d %d\n",
312 names[i],
313 (long unsigned) e->deviceid,
314 e->type,
315 e->x, e->y,
316 e->device_state,
317 b->button,
318 (long unsigned) b->time,
319 e->axes_count,
320 e->first_axis,
321 e->axis_data[0],
322 e->axis_data[1],
323 e->axis_data[2],
324 e->axis_data[3], e->axis_data[4], e->axis_data[5]);
325 }
326 }
327 ++total;
328#if 0
329 /* Used to check motion history for
330 * extension devices. */
331 if (!(total % 10)) {
332 XDeviceTimeCoord *tc;
333 int n, m, a;
334 struct timeval tv;
335 unsigned long ms;
336
337 gettimeofday(&tv, NULL);
338 ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
339 tc = XGetDeviceMotionEvents(display, dev, ms - 1000, ms,
340 &n, &m, &a);
341 printf("Got %d events of mode %s with %d axes\n",
342 n, m == Absolute ? "Absolute" : "Relative", a);
343 for (i = 0; i < n && i < 10; i++) {
344 printf(" %d: %lu %d %d\n",
345 i, tc[i].time, tc[i].data[0], tc[i].data[1]);
346 }
347 XFreeDeviceMotionEvents(tc);
348 }
349#endif
350 }
351 }
352
353 XCloseDisplay(display);
354 return 0;
355}