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