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