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