Git init
[framework/uifw/xorg/app/xinput.git] / src / list.c
1 /*
2  * Copyright 1996 by Frederic Lepied, France. <Frederic.Lepied@sugix.frmug.org>
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is  hereby granted without fee, provided that
6  * the  above copyright   notice appear  in   all  copies and  that both  that
7  * copyright  notice   and   this  permission   notice  appear  in  supporting
8  * documentation, and that   the  name of  the authors  not  be  used  in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific,  written      prior  permission.     The authors  make  no
11  * representations about the suitability of this software for any purpose.  It
12  * is provided "as is" without express or implied warranty.
13  *
14  * THE AUTHORS DISCLAIM ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
16  * EVENT  SHALL THE AUTHORS  BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
19  * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  *
22  */
23
24 #include "xinput.h"
25 #include <string.h>
26 #include <X11/extensions/XIproto.h> /* for XI_Device***ChangedNotify */
27
28 static void
29 print_info(Display* dpy, XDeviceInfo    *info, Bool shortformat)
30 {
31     int                 i,j;
32     XAnyClassPtr        any;
33     XKeyInfoPtr         k;
34     XButtonInfoPtr      b;
35     XValuatorInfoPtr    v;
36     XAxisInfoPtr        a;
37
38     printf("\"%s\"\tid=%ld\t[", info->name, info->id);
39
40     switch (info->use) {
41     case IsXPointer:
42        printf("XPointer");
43        break;
44     case IsXKeyboard:
45        printf("XKeyboard");
46        break;
47     case IsXExtensionDevice:
48        printf("XExtensionDevice");
49        break;
50     case IsXExtensionKeyboard:
51        printf("XExtensionKeyboard");
52        break;
53     case IsXExtensionPointer:
54        printf("XExtensionPointer");
55        break;
56     default:
57        printf("Unknown class");
58        break;
59     }
60     printf("]\n");
61
62     if (shortformat)
63         return;
64
65     if(info->type != None)
66         printf("\tType is %s\n", XGetAtomName(dpy, info->type));
67
68     if (info->num_classes > 0) {
69         any = (XAnyClassPtr) (info->inputclassinfo);
70         for (i=0; i<info->num_classes; i++) {
71             switch (any->class) {
72             case KeyClass:
73                 k = (XKeyInfoPtr) any;
74                 printf("\tNum_keys is %d\n", k->num_keys);
75                 printf("\tMin_keycode is %d\n", k->min_keycode);
76                 printf("\tMax_keycode is %d\n", k->max_keycode);
77                 break;
78
79             case ButtonClass:
80                 b = (XButtonInfoPtr) any;
81                 printf("\tNum_buttons is %d\n", b->num_buttons);
82                 break;
83
84             case ValuatorClass:
85                 v = (XValuatorInfoPtr) any;
86                 a = (XAxisInfoPtr) ((char *) v +
87                                     sizeof (XValuatorInfo));
88                 printf("\tNum_axes is %d\n", v->num_axes);
89                 printf("\tMode is %s\n", (v->mode == Absolute) ? "Absolute" : "Relative");
90                 printf("\tMotion_buffer is %ld\n", v->motion_buffer);
91                 for (j=0; j<v->num_axes; j++, a++) {
92                     printf("\tAxis %d :\n", j);
93                     printf("\t\tMin_value is %d\n", a->min_value);
94                     printf("\t\tMax_value is %d\n", a->max_value);
95                     printf ("\t\tResolution is %d\n", a->resolution);
96                 }
97                 break;
98             default:
99                 printf ("unknown class\n");
100             }
101             any = (XAnyClassPtr) ((char *) any + any->length);
102         }
103     }
104 }
105
106 static int list_xi1(Display     *display,
107                     int         shortformat)
108 {
109     XDeviceInfo         *info;
110     int                 loop;
111     int                 num_devices;
112
113     info = XListInputDevices(display, &num_devices);
114     for(loop=0; loop<num_devices; loop++) {
115         print_info(display, info+loop, shortformat);
116     }
117     return EXIT_SUCCESS;
118 }
119
120 #ifdef HAVE_XI2
121 /* also used from test_xi2.c */
122 void
123 print_classes_xi2(Display* display, XIAnyClassInfo **classes,
124                   int num_classes)
125 {
126     int i, j;
127
128     printf("\tReporting %d classes:\n", num_classes);
129     for (i = 0; i < num_classes; i++)
130     {
131         printf("\t\tClass originated from: %d\n", classes[i]->sourceid);
132         switch(classes[i]->type)
133         {
134             case XIButtonClass:
135                 {
136                     XIButtonClassInfo *b = (XIButtonClassInfo*)classes[i];
137                     char *name;
138                     printf("\t\tButtons supported: %d\n", b->num_buttons);
139                     printf("\t\tButton labels:");
140                     for (j = 0; j < b->num_buttons; j++)
141                     {
142                         name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL;
143                         printf(" %s", (name) ? name : "None");
144                         XFree(name);
145                     }
146                     printf("\n");
147                     printf("\t\tButton state:");
148                     for (j = 0; j < b->state.mask_len * 8; j++)
149                         if (XIMaskIsSet(b->state.mask, j))
150                             printf(" %d", j);
151                     printf("\n");
152
153                 }
154                 break;
155             case XIKeyClass:
156                 {
157                     XIKeyClassInfo *k = (XIKeyClassInfo*)classes[i];
158                     printf("\t\tKeycodes supported: %d\n", k->num_keycodes);
159                 }
160                 break;
161             case XIValuatorClass:
162                 {
163                     XIValuatorClassInfo *v = (XIValuatorClassInfo*)classes[i];
164                     char *name = v->label ?  XGetAtomName(display, v->label) : NULL;
165
166                     /* XXX: Bug in X servers 1.7..1.8.1, mode was |
167                        OutOfProximity. Remove this once 1.9 is out. */
168                     v->mode &= DeviceMode;
169
170                     printf("\t\tDetail for Valuator %d:\n", v->number);
171                     printf("\t\t  Label: %s\n",  (name) ? name : "None");
172                     printf("\t\t  Range: %f - %f\n", v->min, v->max);
173                     printf("\t\t  Resolution: %d units/m\n", v->resolution);
174                     printf("\t\t  Mode: %s\n", v->mode == Absolute ? "absolute" :
175                             "relative");
176                     if (v->mode == Absolute)
177                         printf("\t\t  Current value: %f\n", v->value);
178                     XFree(name);
179                 }
180                 break;
181         }
182     }
183
184     printf("\n");
185 }
186
187 static void
188 print_info_xi2(Display* display, XIDeviceInfo *dev, Bool shortformat)
189 {
190     printf("%-40s\tid=%d\t[", dev->name, dev->deviceid);
191     switch(dev->use)
192     {
193         case XIMasterPointer:
194             printf("master pointer  (%d)]\n", dev->attachment);
195             break;
196         case XIMasterKeyboard:
197             printf("master keyboard (%d)]\n", dev->attachment);
198             break;
199         case XISlavePointer:
200             printf("slave  pointer  (%d)]\n", dev->attachment);
201             break;
202         case XISlaveKeyboard:
203             printf("slave  keyboard (%d)]\n", dev->attachment);
204             break;
205         case XIFloatingSlave:
206             printf("floating slave]\n");
207             break;
208     }
209
210     if (shortformat)
211         return;
212
213     if (!dev->enabled)
214         printf("\tThis device is disabled\n");
215
216     print_classes_xi2(display, dev->classes, dev->num_classes);
217 }
218
219
220 static int
221 list_xi2(Display *display,
222          int     shortformat)
223 {
224     int major = XI_2_Major,
225         minor = XI_2_Minor;
226     int ndevices;
227     int i, j;
228     XIDeviceInfo *info, *dev;
229
230     if (XIQueryVersion(display, &major, &minor) != Success ||
231         (major * 1000 + minor) < (XI_2_Major * 1000 + XI_2_Minor))
232     {
233         fprintf(stderr, "XI2 not supported.\n");
234         return EXIT_FAILURE;
235     }
236
237     info = XIQueryDevice(display, XIAllDevices, &ndevices);
238
239     for(i = 0; i < ndevices; i++)
240     {
241         dev = &info[i];
242         if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
243         {
244             if (dev->use == XIMasterPointer)
245                 printf("⎡ ");
246             else
247                 printf("⎣ ");
248
249             print_info_xi2(display, dev, shortformat);
250             for (j = 0; j < ndevices; j++)
251             {
252                 XIDeviceInfo* sd = &info[j];
253
254                 if ((sd->use == XISlavePointer || sd->use == XISlaveKeyboard) &&
255                      (sd->attachment == dev->deviceid))
256                 {
257                     printf("%s   ↳ ", dev->use == XIMasterPointer ? "⎜" : " ");
258                     print_info_xi2(display, sd, shortformat);
259                 }
260             }
261         }
262     }
263
264     for (i = 0; i < ndevices; i++)
265     {
266         dev = &info[i];
267         if (dev->use == XIFloatingSlave)
268         {
269             printf("∼ ");
270             print_info_xi2(display, dev, shortformat);
271         }
272     }
273
274
275     XIFreeDeviceInfo(info);
276     return EXIT_SUCCESS;
277 }
278 #endif
279
280 int
281 list(Display    *display,
282      int        argc,
283      char       *argv[],
284      char       *name,
285      char       *desc)
286 {
287     int shortformat = (argc >= 1 && strcmp(argv[0], "--short") == 0);
288     int longformat = (argc >= 1 && strcmp(argv[0], "--long") == 0);
289     int arg_dev = shortformat || longformat;
290
291     if (argc > arg_dev)
292     {
293 #ifdef HAVE_XI2
294         if (xinput_version(display) == XI_2_Major)
295         {
296             XIDeviceInfo *info = xi2_find_device_info(display, argv[arg_dev]);
297
298             if (!info) {
299                 fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
300                 return EXIT_FAILURE;
301             } else {
302                 print_info_xi2(display, info, shortformat);
303                 return EXIT_SUCCESS;
304             }
305         } else
306 #endif
307         {
308             XDeviceInfo *info = find_device_info(display, argv[arg_dev], False);
309
310             if (!info) {
311                 fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
312                 return EXIT_FAILURE;
313             } else {
314                 print_info(display, info, shortformat);
315                 return EXIT_SUCCESS;
316             }
317         }
318     } else {
319 #ifdef HAVE_XI2
320         if (xinput_version(display) == XI_2_Major)
321             return list_xi2(display, !longformat);
322 #endif
323         return list_xi1(display, !longformat);
324     }
325 }
326
327 /* end of list.c */