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