]> diplodocus.org Git - xorg-xinput/blob - src/list.c
b3bf87382a1065e53d9ba5d97548499e92fa5d60
[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 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\n", classes[i]->sourceid);
150 switch(classes[i]->type)
151 {
152 case XIButtonClass:
153 {
154 XIButtonClassInfo *b = (XIButtonClassInfo*)classes[i];
155 char *name;
156 printf("\t\tButtons supported: %d\n", b->num_buttons);
157 printf("\t\tButton labels:");
158 for (j = 0; j < b->num_buttons; j++)
159 {
160 name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL;
161 printf(" %s", (name) ? name : "None");
162 XFree(name);
163 }
164 printf("\n");
165 printf("\t\tButton state:");
166 for (j = 0; j < b->state.mask_len * 8; j++)
167 if (XIMaskIsSet(b->state.mask, j))
168 printf(" %d", j);
169 printf("\n");
170
171 }
172 break;
173 case XIKeyClass:
174 {
175 XIKeyClassInfo *k = (XIKeyClassInfo*)classes[i];
176 printf("\t\tKeycodes supported: %d\n", k->num_keycodes);
177 }
178 break;
179 case XIValuatorClass:
180 {
181 XIValuatorClassInfo *v = (XIValuatorClassInfo*)classes[i];
182 char *name = v->label ? XGetAtomName(display, v->label) : NULL;
183
184 /* XXX: Bug in X servers 1.7..1.8.1, mode was |
185 OutOfProximity. Remove this once 1.9 is out. */
186 v->mode &= DeviceMode;
187
188 printf("\t\tDetail for Valuator %d:\n", v->number);
189 printf("\t\t Label: %s\n", (name) ? name : "None");
190 printf("\t\t Range: %f - %f\n", v->min, v->max);
191 printf("\t\t Resolution: %d units/m\n", v->resolution);
192 printf("\t\t Mode: %s\n", v->mode == Absolute ? "absolute" :
193 "relative");
194 if (v->mode == Absolute)
195 printf("\t\t Current value: %f\n", v->value);
196 XFree(name);
197 }
198 break;
199 }
200 }
201
202 printf("\n");
203 }
204
205 static void
206 print_info_xi2(Display* display, XIDeviceInfo *dev, enum print_format format)
207 {
208 if (format == FORMAT_NAME)
209 {
210 printf("%s\n", dev->name);
211 return;
212 } else if (format == FORMAT_ID)
213 {
214 printf("%d\n", dev->deviceid);
215 return;
216 }
217
218 printf("%-40s\tid=%d\t[", dev->name, dev->deviceid);
219 switch(dev->use)
220 {
221 case XIMasterPointer:
222 printf("master pointer (%d)]\n", dev->attachment);
223 break;
224 case XIMasterKeyboard:
225 printf("master keyboard (%d)]\n", dev->attachment);
226 break;
227 case XISlavePointer:
228 printf("slave pointer (%d)]\n", dev->attachment);
229 break;
230 case XISlaveKeyboard:
231 printf("slave keyboard (%d)]\n", dev->attachment);
232 break;
233 case XIFloatingSlave:
234 printf("floating slave]\n");
235 break;
236 }
237
238 if (format == FORMAT_SHORT)
239 return;
240
241 if (!dev->enabled)
242 printf("\tThis device is disabled\n");
243
244 print_classes_xi2(display, dev->classes, dev->num_classes);
245 }
246
247
248 static int
249 list_xi2(Display *display,
250 enum print_format format)
251 {
252 int major = XI_2_Major,
253 minor = XI_2_Minor;
254 int ndevices;
255 int i, j;
256 XIDeviceInfo *info, *dev;
257
258 if (XIQueryVersion(display, &major, &minor) != Success ||
259 (major * 1000 + minor) < (XI_2_Major * 1000 + XI_2_Minor))
260 {
261 fprintf(stderr, "XI2 not supported.\n");
262 return EXIT_FAILURE;
263 }
264
265 info = XIQueryDevice(display, XIAllDevices, &ndevices);
266
267 for(i = 0; i < ndevices; i++)
268 {
269 dev = &info[i];
270 if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard)
271 {
272 if (format == FORMAT_SHORT || format == FORMAT_LONG)
273 {
274 if (dev->use == XIMasterPointer)
275 printf("⎡ ");
276 else
277 printf("⎣ ");
278 }
279
280 print_info_xi2(display, dev, format);
281 for (j = 0; j < ndevices; j++)
282 {
283 XIDeviceInfo* sd = &info[j];
284
285 if ((sd->use == XISlavePointer || sd->use == XISlaveKeyboard) &&
286 (sd->attachment == dev->deviceid))
287 {
288 if (format == FORMAT_SHORT || format == FORMAT_LONG)
289 printf("%s ↳ ", dev->use == XIMasterPointer ? "⎜" : " ");
290 print_info_xi2(display, sd, format);
291 }
292 }
293 }
294 }
295
296 for (i = 0; i < ndevices; i++)
297 {
298 dev = &info[i];
299 if (dev->use == XIFloatingSlave)
300 {
301 printf("∼ ");
302 print_info_xi2(display, dev, format);
303 }
304 }
305
306
307 XIFreeDeviceInfo(info);
308 return EXIT_SUCCESS;
309 }
310 #endif
311
312 int
313 list(Display *display,
314 int argc,
315 char *argv[],
316 char *name,
317 char *desc)
318 {
319 enum print_format format = FORMAT_NONE;
320 int arg_dev = 1;
321
322 if (argc >= 1)
323 {
324 if (strcmp(argv[0], "--short") == 0)
325 format = FORMAT_SHORT;
326 else if (strcmp(argv[0], "--long") == 0)
327 format = FORMAT_LONG;
328 else if (strcmp(argv[0], "--name-only") == 0)
329 format = FORMAT_NAME;
330 else if (strcmp(argv[0], "--id-only") == 0)
331 format = FORMAT_ID;
332 else
333 arg_dev--;
334 }
335
336 if (argc > arg_dev)
337 {
338 if (format == FORMAT_NONE)
339 format = FORMAT_LONG;
340 #ifdef HAVE_XI2
341 if (xinput_version(display) == XI_2_Major)
342 {
343 XIDeviceInfo *info = xi2_find_device_info(display, argv[arg_dev]);
344
345 if (!info) {
346 fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
347 return EXIT_FAILURE;
348 } else {
349 print_info_xi2(display, info, format);
350 return EXIT_SUCCESS;
351 }
352 } else
353 #endif
354 {
355 XDeviceInfo *info = find_device_info(display, argv[arg_dev], False);
356
357 if (!info) {
358 fprintf(stderr, "unable to find device %s\n", argv[arg_dev]);
359 return EXIT_FAILURE;
360 } else {
361 print_info(display, info, format);
362 return EXIT_SUCCESS;
363 }
364 }
365 } else {
366 if (format == FORMAT_NONE)
367 format = FORMAT_SHORT;
368 #ifdef HAVE_XI2
369 if (xinput_version(display) == XI_2_Major)
370 return list_xi2(display, format);
371 #endif
372 return list_xi1(display, format);
373 }
374 }
375
376 /* end of list.c */