Tizen 2.0 Release
[framework/uifw/xorg/util/x11-xserver-utils.git] / xinput / 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
27 enum print_format {
28     FORMAT_NONE,
29     FORMAT_SHORT,
30     FORMAT_LONG,
31     FORMAT_NAME,
32     FORMAT_ID,
33 };
34
35
36 static void
37 print_info(Display* dpy, XDeviceInfo    *info, enum print_format format)
38 {
39     int                 i,j;
40     XAnyClassPtr        any;
41     XKeyInfoPtr         k;
42     XButtonInfoPtr      b;
43     XValuatorInfoPtr    v;
44     XAxisInfoPtr        a;
45
46     if (format == FORMAT_NAME)
47     {
48         printf("%s\n", info->name);
49         return;
50     } else if (format == FORMAT_ID)
51     {
52         printf("%ld\n", info->id);
53         return;
54     }
55
56     printf("\"%s\"\tid=%ld\t[", info->name, info->id);
57
58     switch (info->use) {
59     case IsXPointer:
60        printf("XPointer");
61        break;
62     case IsXKeyboard:
63        printf("XKeyboard");
64        break;
65     case IsXExtensionDevice:
66        printf("XExtensionDevice");
67        break;
68     case IsXExtensionKeyboard:
69        printf("XExtensionKeyboard");
70        break;
71     case IsXExtensionPointer:
72        printf("XExtensionPointer");
73        break;
74     default:
75        printf("Unknown class");
76        break;
77     }
78     printf("]\n");
79
80     if (format == FORMAT_SHORT)
81         return;
82
83     if(info->type != None)
84         printf("\tType is %s\n", XGetAtomName(dpy, info->type));
85
86     if (info->num_classes > 0) {
87         any = (XAnyClassPtr) (info->inputclassinfo);
88         for (i=0; i<info->num_classes; i++) {
89             switch (any->class) {
90             case KeyClass:
91                 k = (XKeyInfoPtr) any;
92                 printf("\tNum_keys is %d\n", k->num_keys);
93                 printf("\tMin_keycode is %d\n", k->min_keycode);
94                 printf("\tMax_keycode is %d\n", k->max_keycode);
95                 break;
96
97             case ButtonClass:
98                 b = (XButtonInfoPtr) any;
99                 printf("\tNum_buttons is %d\n", b->num_buttons);
100                 break;
101
102             case ValuatorClass:
103                 v = (XValuatorInfoPtr) any;
104                 a = (XAxisInfoPtr) ((char *) v +
105                                     sizeof (XValuatorInfo));
106                 printf("\tNum_axes is %d\n", v->num_axes);
107                 printf("\tMode is %s\n", (v->mode == Absolute) ? "Absolute" : "Relative");
108                 printf("\tMotion_buffer is %ld\n", v->motion_buffer);
109                 for (j=0; j<v->num_axes; j++, a++) {
110                     printf("\tAxis %d :\n", j);
111                     printf("\t\tMin_value is %d\n", a->min_value);
112                     printf("\t\tMax_value is %d\n", a->max_value);
113                     printf ("\t\tResolution is %d\n", a->resolution);
114                 }
115                 break;
116             default:
117                 printf ("unknown class\n");
118             }
119             any = (XAnyClassPtr) ((char *) any + any->length);
120         }
121     }
122 }
123
124 static int list_xi1(Display     *display,
125                     enum print_format format)
126 {
127     XDeviceInfo         *info;
128     int                 loop;
129     int                 num_devices;
130
131     info = XListInputDevices(display, &num_devices);
132     for(loop=0; loop<num_devices; loop++) {
133         print_info(display, info+loop, format);
134     }
135     return EXIT_SUCCESS;
136 }
137
138 #ifdef HAVE_XI2
139 /* also used from test_xi2.c */
140 void
141 print_classes_xi2(Display* display, XIAnyClassInfo **classes,
142                   int num_classes)
143 {
144     int i, j;
145
146     printf("\tReporting %d classes:\n", num_classes);
147     for (i = 0; i < num_classes; i++)
148     {
149         printf("\t\tClass originated from: %d. Type: ", classes[i]->sourceid);
150         switch(classes[i]->type)
151         {
152             case XIButtonClass:
153                 {
154                     XIButtonClassInfo *b = (XIButtonClassInfo*)classes[i];
155                     char *name;
156                     printf("XIButtonClass\n");
157                     printf("\t\tButtons supported: %d\n", b->num_buttons);
158                     printf("\t\tButton labels:");
159                     for (j = 0; j < b->num_buttons; j++)
160                     {
161                         name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL;
162                         if (name)
163                             printf(" \"%s\"", name);
164                         else
165                             printf(" None");
166                         XFree(name);
167                     }
168                     printf("\n");
169                     printf("\t\tButton state:");
170                     for (j = 0; j < b->state.mask_len * 8; j++)
171                         if (XIMaskIsSet(b->state.mask, j))
172                             printf(" %d", j);
173                     printf("\n");
174
175                 }
176                 break;
177             case XIKeyClass:
178                 {
179                     XIKeyClassInfo *k = (XIKeyClassInfo*)classes[i];
180                     printf("XIKeyClass\n");
181                     printf("\t\tKeycodes supported: %d\n", k->num_keycodes);
182                 }
183                 break;
184             case XIValuatorClass:
185                 {
186                     XIValuatorClassInfo *v = (XIValuatorClassInfo*)classes[i];
187                     char *name = v->label ?  XGetAtomName(display, v->label) : NULL;
188
189                     /* Bug in X servers 1.7..1.8.1, mode was | OutOfProximity */
190                     v->mode &= DeviceMode;
191
192                     printf("XIValuatorClass\n");
193                     printf("\t\tDetail for Valuator %d:\n", v->number);
194                     printf("\t\t  Label: %s\n",  (name) ? name : "None");
195                     printf("\t\t  Range: %f - %f\n", v->min, v->max);
196                     printf("\t\t  Resolution: %d units/m\n", v->resolution);
197                     printf("\t\t  Mode: %s\n", v->mode == Absolute ? "absolute" :
198                             "relative");
199                     if (v->mode == Absolute)
200                         printf("\t\t  Current value: %f\n", v->value);
201                     XFree(name);
202                 }
203                 break;
204 #if HAVE_XI21
205             case XIScrollClass:
206                 {
207                     XIScrollClassInfo *s = (XIScrollClassInfo*)classes[i];
208
209                     printf("XIScrollClass\n");
210                     printf("\t\tScroll info for Valuator %d\n", s->number);
211                     printf("\t\t  type: %d (%s)\n", s->scroll_type,
212                            (s->scroll_type == XIScrollTypeHorizontal) ? "horizontal" :
213                               (s->scroll_type == XIScrollTypeVertical) ? "vertical" : "unknown");
214                     printf("\t\t  increment: %f\n", s->increment);
215                     printf("\t\t  flags: 0x%x", s->flags);
216                     if (s->flags) {
217                         printf(" (");
218                         if (s->flags & XIScrollFlagNoEmulation)
219                             printf(" no-emulation ");
220                         if (s->flags & XIScrollFlagPreferred)
221                             printf(" preferred ");
222                         printf(")");
223                     }
224                     printf("\n");
225                 }
226                 break;
227 #endif
228 #if HAVE_XI22
229             case XITouchClass:
230                 {
231                     XITouchClassInfo *t = (XITouchClassInfo*)classes[i];
232
233                     printf("XITouchClass\n");
234                     printf("\t\tTouch mode: %s\n",
235                            (t->mode == XIDirectTouch) ? "direct" : "dependent");
236                     printf("\t\tMax number of touches: %d\n", t->num_touches);
237                 }
238 #endif
239         }
240     }
241
242     printf("\n");
243 }
244
245 static void
246 print_info_xi2(Display* display, XIDeviceInfo *dev, enum print_format format)
247 {
248     if (format == FORMAT_NAME)
249     {
250         printf("%s\n", dev->name);
251         return;
252     } else if (format == FORMAT_ID)
253     {
254         printf("%d\n", dev->deviceid);
255         return;
256     }
257
258     printf("%-40s\tid=%d\t[", dev->name, dev->deviceid);
259     switch(dev->use)
260     {
261         case XIMasterPointer:
262             printf("master pointer  (%d)]\n", dev->attachment);
263             break;
264         case XIMasterKeyboard:
265             printf("master keyboard (%d)]\n", dev->attachment);
266             break;
267         case XISlavePointer:
268             printf("slave  pointer  (%d)]\n", dev->attachment);
269             break;
270         case XISlaveKeyboard:
271             printf("slave  keyboard (%d)]\n", dev->attachment);
272             break;
273         case XIFloatingSlave:
274             printf("floating slave]\n");
275             break;
276     }
277
278     if (format == FORMAT_SHORT)
279         return;
280
281     if (!dev->enabled)
282         printf("\tThis device is disabled\n");
283
284     print_classes_xi2(display, dev->classes, dev->num_classes);
285 }
286
287
288 static int
289 list_xi2(Display *display,
290          enum print_format format)
291 {
292     int ndevices;
293     int i, j;
294     XIDeviceInfo *info, *dev;
295
296     info = XIQueryDevice(display, XIAllDevices, &ndevices);
297
298     for(i = 0; i < ndevices; i++)
299     {
300         dev = &info[i];
301         if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
302         {
303             if (format == FORMAT_SHORT || format == FORMAT_LONG)
304             {
305                 if (dev->use == XIMasterPointer)
306                     printf("⎡ ");
307                 else
308                     printf("⎣ ");
309             }
310
311             print_info_xi2(display, dev, format);
312             for (j = 0; j < ndevices; j++)
313             {
314                 XIDeviceInfo* sd = &info[j];
315
316                 if ((sd->use == XISlavePointer || sd->use == XISlaveKeyboard) &&
317                      (sd->attachment == dev->deviceid))
318                 {
319                     if (format == FORMAT_SHORT || format == FORMAT_LONG)
320                         printf("%s   ↳ ", dev->use == XIMasterPointer ? "⎜" : " ");
321                     print_info_xi2(display, sd, format);
322                 }
323             }
324         }
325     }
326
327     for (i = 0; i < ndevices; i++)
328     {
329         dev = &info[i];
330         if (dev->use == XIFloatingSlave)
331         {
332             printf("∼ ");
333             print_info_xi2(display, dev, format);
334         }
335     }
336
337
338     XIFreeDeviceInfo(info);
339     return EXIT_SUCCESS;
340 }
341 #endif
342
343 int
344 list(Display    *display,
345      int        argc,
346      char       *argv[],
347      char       *name,
348      char       *desc)
349 {
350     enum print_format format = FORMAT_NONE;
351     int arg_dev = 1;
352
353     if (argc >= 1)
354     {
355         if (strcmp(argv[0], "--short") == 0)
356             format = FORMAT_SHORT;
357         else if (strcmp(argv[0], "--long") == 0)
358             format = FORMAT_LONG;
359         else if (strcmp(argv[0], "--name-only") == 0)
360             format = FORMAT_NAME;
361         else if (strcmp(argv[0], "--id-only") == 0)
362             format = FORMAT_ID;
363         else
364             arg_dev--;
365     }
366
367     if (argc > arg_dev)
368     {
369         if (format == FORMAT_NONE)
370             format = FORMAT_LONG;
371 #ifdef HAVE_XI2
372         if (xinput_version(display) == XI_2_Major)
373         {
374             XIDeviceInfo *info = xi2_find_device_info(display, argv[arg_dev]);
375
376             if (!info) {
377                 fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
378                 return EXIT_FAILURE;
379             } else {
380                 print_info_xi2(display, info, format);
381                 return EXIT_SUCCESS;
382             }
383         } else
384 #endif
385         {
386             XDeviceInfo *info = find_device_info(display, argv[arg_dev], False);
387
388             if (!info) {
389                 fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
390                 return EXIT_FAILURE;
391             } else {
392                 print_info(display, info, format);
393                 return EXIT_SUCCESS;
394             }
395         }
396     } else {
397         if (format == FORMAT_NONE)
398             format = FORMAT_SHORT;
399 #ifdef HAVE_XI2
400         if (xinput_version(display) == XI_2_Major)
401             return list_xi2(display, format);
402 #endif
403         return list_xi1(display, format);
404     }
405 }
406
407 /* end of list.c */