list.c revision 0309d3b3
1b1297603Smrg/* 2b1297603Smrg * Copyright 1996 by Frederic Lepied, France. <Frederic.Lepied@sugix.frmug.org> 3b1297603Smrg * 4b1297603Smrg * Permission to use, copy, modify, distribute, and sell this software and its 5b1297603Smrg * documentation for any purpose is hereby granted without fee, provided that 6b1297603Smrg * the above copyright notice appear in all copies and that both that 7b1297603Smrg * copyright notice and this permission notice appear in supporting 85b944e2aSmrg * documentation, and that the name of the authors not be used in 9b1297603Smrg * advertising or publicity pertaining to distribution of the software without 105b944e2aSmrg * specific, written prior permission. The authors make no 11b1297603Smrg * representations about the suitability of this software for any purpose. It 12b1297603Smrg * is provided "as is" without express or implied warranty. 13b1297603Smrg * 145b944e2aSmrg * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15b1297603Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 165b944e2aSmrg * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17b1297603Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18b1297603Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19b1297603Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20b1297603Smrg * PERFORMANCE OF THIS SOFTWARE. 21b1297603Smrg * 22b1297603Smrg */ 23b1297603Smrg 24b1297603Smrg#include "xinput.h" 25b1297603Smrg#include <string.h> 260309d3b3Smrg 270309d3b3Smrgenum print_format { 280309d3b3Smrg FORMAT_NONE, 290309d3b3Smrg FORMAT_SHORT, 300309d3b3Smrg FORMAT_LONG, 310309d3b3Smrg FORMAT_NAME, 320309d3b3Smrg FORMAT_ID, 330309d3b3Smrg}; 340309d3b3Smrg 35b1297603Smrg 36b1297603Smrgstatic void 370309d3b3Smrgprint_info(Display* dpy, XDeviceInfo *info, enum print_format format) 38b1297603Smrg{ 39b1297603Smrg int i,j; 40b1297603Smrg XAnyClassPtr any; 41b1297603Smrg XKeyInfoPtr k; 42b1297603Smrg XButtonInfoPtr b; 43b1297603Smrg XValuatorInfoPtr v; 44b1297603Smrg XAxisInfoPtr a; 45b1297603Smrg 460309d3b3Smrg if (format == FORMAT_NAME) 470309d3b3Smrg { 480309d3b3Smrg printf("%s\n", info->name); 490309d3b3Smrg return; 500309d3b3Smrg } else if (format == FORMAT_ID) 510309d3b3Smrg { 520309d3b3Smrg printf("%ld\n", info->id); 530309d3b3Smrg return; 540309d3b3Smrg } 550309d3b3Smrg 56b1297603Smrg printf("\"%s\"\tid=%ld\t[", info->name, info->id); 57b1297603Smrg 58b1297603Smrg switch (info->use) { 59b1297603Smrg case IsXPointer: 60b1297603Smrg printf("XPointer"); 61b1297603Smrg break; 62b1297603Smrg case IsXKeyboard: 63b1297603Smrg printf("XKeyboard"); 64b1297603Smrg break; 65b1297603Smrg case IsXExtensionDevice: 66b1297603Smrg printf("XExtensionDevice"); 67b1297603Smrg break; 68b1297603Smrg case IsXExtensionKeyboard: 69b1297603Smrg printf("XExtensionKeyboard"); 70b1297603Smrg break; 71b1297603Smrg case IsXExtensionPointer: 72b1297603Smrg printf("XExtensionPointer"); 73b1297603Smrg break; 74b1297603Smrg default: 75b1297603Smrg printf("Unknown class"); 76b1297603Smrg break; 77b1297603Smrg } 78b1297603Smrg printf("]\n"); 79b1297603Smrg 800309d3b3Smrg if (format == FORMAT_SHORT) 81b1297603Smrg return; 82b1297603Smrg 83d3263506Smrg if(info->type != None) 84d3263506Smrg printf("\tType is %s\n", XGetAtomName(dpy, info->type)); 85d3263506Smrg 86b1297603Smrg if (info->num_classes > 0) { 87b1297603Smrg any = (XAnyClassPtr) (info->inputclassinfo); 88b1297603Smrg for (i=0; i<info->num_classes; i++) { 89b1297603Smrg switch (any->class) { 90b1297603Smrg case KeyClass: 91b1297603Smrg k = (XKeyInfoPtr) any; 92b1297603Smrg printf("\tNum_keys is %d\n", k->num_keys); 93b1297603Smrg printf("\tMin_keycode is %d\n", k->min_keycode); 94b1297603Smrg printf("\tMax_keycode is %d\n", k->max_keycode); 95b1297603Smrg break; 96b1297603Smrg 97b1297603Smrg case ButtonClass: 98b1297603Smrg b = (XButtonInfoPtr) any; 99b1297603Smrg printf("\tNum_buttons is %d\n", b->num_buttons); 100b1297603Smrg break; 101b1297603Smrg 102b1297603Smrg case ValuatorClass: 103b1297603Smrg v = (XValuatorInfoPtr) any; 104b1297603Smrg a = (XAxisInfoPtr) ((char *) v + 105b1297603Smrg sizeof (XValuatorInfo)); 106b1297603Smrg printf("\tNum_axes is %d\n", v->num_axes); 107b1297603Smrg printf("\tMode is %s\n", (v->mode == Absolute) ? "Absolute" : "Relative"); 108b1297603Smrg printf("\tMotion_buffer is %ld\n", v->motion_buffer); 109b1297603Smrg for (j=0; j<v->num_axes; j++, a++) { 110b1297603Smrg printf("\tAxis %d :\n", j); 111b1297603Smrg printf("\t\tMin_value is %d\n", a->min_value); 112b1297603Smrg printf("\t\tMax_value is %d\n", a->max_value); 113b1297603Smrg printf ("\t\tResolution is %d\n", a->resolution); 114b1297603Smrg } 115b1297603Smrg break; 116b1297603Smrg default: 117b1297603Smrg printf ("unknown class\n"); 118b1297603Smrg } 119b1297603Smrg any = (XAnyClassPtr) ((char *) any + any->length); 120b1297603Smrg } 121b1297603Smrg } 122b1297603Smrg} 123b1297603Smrg 12453719b08Smrgstatic int list_xi1(Display *display, 1250309d3b3Smrg enum print_format format) 126b1297603Smrg{ 127b1297603Smrg XDeviceInfo *info; 128b1297603Smrg int loop; 12953719b08Smrg int num_devices; 130b1297603Smrg 13153719b08Smrg info = XListInputDevices(display, &num_devices); 13253719b08Smrg for(loop=0; loop<num_devices; loop++) { 1330309d3b3Smrg print_info(display, info+loop, format); 13453719b08Smrg } 13553719b08Smrg return EXIT_SUCCESS; 13653719b08Smrg} 137b1297603Smrg 13853719b08Smrg#ifdef HAVE_XI2 13953719b08Smrg/* also used from test_xi2.c */ 14053719b08Smrgvoid 14153719b08Smrgprint_classes_xi2(Display* display, XIAnyClassInfo **classes, 14253719b08Smrg int num_classes) 14353719b08Smrg{ 14453719b08Smrg int i, j; 1455b944e2aSmrg 14653719b08Smrg printf("\tReporting %d classes:\n", num_classes); 14753719b08Smrg for (i = 0; i < num_classes; i++) 14853719b08Smrg { 1490309d3b3Smrg printf("\t\tClass originated from: %d. Type: ", classes[i]->sourceid); 15053719b08Smrg switch(classes[i]->type) 1515b944e2aSmrg { 15253719b08Smrg case XIButtonClass: 15353719b08Smrg { 15453719b08Smrg XIButtonClassInfo *b = (XIButtonClassInfo*)classes[i]; 15553719b08Smrg char *name; 1560309d3b3Smrg printf("XIButtonClass\n"); 15753719b08Smrg printf("\t\tButtons supported: %d\n", b->num_buttons); 15853719b08Smrg printf("\t\tButton labels:"); 15953719b08Smrg for (j = 0; j < b->num_buttons; j++) 16053719b08Smrg { 16153719b08Smrg name = (b->labels[j]) ? XGetAtomName(display, b->labels[j]) : NULL; 1620309d3b3Smrg if (name) 1630309d3b3Smrg printf(" \"%s\"", name); 1640309d3b3Smrg else 1650309d3b3Smrg printf(" None"); 16653719b08Smrg XFree(name); 16753719b08Smrg } 16853719b08Smrg printf("\n"); 16953719b08Smrg printf("\t\tButton state:"); 17053719b08Smrg for (j = 0; j < b->state.mask_len * 8; j++) 17153719b08Smrg if (XIMaskIsSet(b->state.mask, j)) 17253719b08Smrg printf(" %d", j); 17353719b08Smrg printf("\n"); 17453719b08Smrg 17553719b08Smrg } 17653719b08Smrg break; 17753719b08Smrg case XIKeyClass: 17853719b08Smrg { 17953719b08Smrg XIKeyClassInfo *k = (XIKeyClassInfo*)classes[i]; 1800309d3b3Smrg printf("XIKeyClass\n"); 18153719b08Smrg printf("\t\tKeycodes supported: %d\n", k->num_keycodes); 18253719b08Smrg } 18353719b08Smrg break; 18453719b08Smrg case XIValuatorClass: 18553719b08Smrg { 18653719b08Smrg XIValuatorClassInfo *v = (XIValuatorClassInfo*)classes[i]; 18753719b08Smrg char *name = v->label ? XGetAtomName(display, v->label) : NULL; 18853719b08Smrg 1890309d3b3Smrg /* Bug in X servers 1.7..1.8.1, mode was | OutOfProximity */ 19054e0bb33Smrg v->mode &= DeviceMode; 19154e0bb33Smrg 1920309d3b3Smrg printf("XIValuatorClass\n"); 19353719b08Smrg printf("\t\tDetail for Valuator %d:\n", v->number); 19453719b08Smrg printf("\t\t Label: %s\n", (name) ? name : "None"); 19553719b08Smrg printf("\t\t Range: %f - %f\n", v->min, v->max); 19653719b08Smrg printf("\t\t Resolution: %d units/m\n", v->resolution); 19753719b08Smrg printf("\t\t Mode: %s\n", v->mode == Absolute ? "absolute" : 19853719b08Smrg "relative"); 19953719b08Smrg if (v->mode == Absolute) 20053719b08Smrg printf("\t\t Current value: %f\n", v->value); 20153719b08Smrg XFree(name); 20253719b08Smrg } 20353719b08Smrg break; 2040309d3b3Smrg#if HAVE_XI21 2050309d3b3Smrg case XIScrollClass: 2060309d3b3Smrg { 2070309d3b3Smrg XIScrollClassInfo *s = (XIScrollClassInfo*)classes[i]; 2080309d3b3Smrg 2090309d3b3Smrg printf("XIScrollClass\n"); 2100309d3b3Smrg printf("\t\tScroll info for Valuator %d\n", s->number); 2110309d3b3Smrg printf("\t\t type: %d (%s)\n", s->scroll_type, 2120309d3b3Smrg (s->scroll_type == XIScrollTypeHorizontal) ? "horizontal" : 2130309d3b3Smrg (s->scroll_type == XIScrollTypeVertical) ? "vertical" : "unknown"); 2140309d3b3Smrg printf("\t\t increment: %f\n", s->increment); 2150309d3b3Smrg printf("\t\t flags: 0x%x", s->flags); 2160309d3b3Smrg if (s->flags) { 2170309d3b3Smrg printf(" ("); 2180309d3b3Smrg if (s->flags & XIScrollFlagNoEmulation) 2190309d3b3Smrg printf(" no-emulation "); 2200309d3b3Smrg if (s->flags & XIScrollFlagPreferred) 2210309d3b3Smrg printf(" preferred "); 2220309d3b3Smrg printf(")"); 2230309d3b3Smrg } 2240309d3b3Smrg printf("\n"); 2250309d3b3Smrg } 2260309d3b3Smrg break; 2270309d3b3Smrg#endif 2280309d3b3Smrg#if HAVE_XI22 2290309d3b3Smrg case XITouchClass: 2300309d3b3Smrg { 2310309d3b3Smrg XITouchClassInfo *t = (XITouchClassInfo*)classes[i]; 2320309d3b3Smrg 2330309d3b3Smrg printf("XITouchClass\n"); 2340309d3b3Smrg printf("\t\tTouch mode: %s\n", 2350309d3b3Smrg (t->mode == XIDirectTouch) ? "direct" : "dependent"); 2360309d3b3Smrg printf("\t\tMax number of touches: %d\n", t->num_touches); 2370309d3b3Smrg } 2380309d3b3Smrg#endif 2395b944e2aSmrg } 24053719b08Smrg } 2415b944e2aSmrg 24253719b08Smrg printf("\n"); 24353719b08Smrg} 2445b944e2aSmrg 24553719b08Smrgstatic void 2460309d3b3Smrgprint_info_xi2(Display* display, XIDeviceInfo *dev, enum print_format format) 24753719b08Smrg{ 2480309d3b3Smrg if (format == FORMAT_NAME) 2490309d3b3Smrg { 2500309d3b3Smrg printf("%s\n", dev->name); 2510309d3b3Smrg return; 2520309d3b3Smrg } else if (format == FORMAT_ID) 2530309d3b3Smrg { 2540309d3b3Smrg printf("%d\n", dev->deviceid); 2550309d3b3Smrg return; 2560309d3b3Smrg } 2570309d3b3Smrg 25853719b08Smrg printf("%-40s\tid=%d\t[", dev->name, dev->deviceid); 25953719b08Smrg switch(dev->use) 26053719b08Smrg { 26153719b08Smrg case XIMasterPointer: 26253719b08Smrg printf("master pointer (%d)]\n", dev->attachment); 26353719b08Smrg break; 26453719b08Smrg case XIMasterKeyboard: 26553719b08Smrg printf("master keyboard (%d)]\n", dev->attachment); 26653719b08Smrg break; 26753719b08Smrg case XISlavePointer: 26853719b08Smrg printf("slave pointer (%d)]\n", dev->attachment); 26953719b08Smrg break; 27053719b08Smrg case XISlaveKeyboard: 27153719b08Smrg printf("slave keyboard (%d)]\n", dev->attachment); 27253719b08Smrg break; 27353719b08Smrg case XIFloatingSlave: 27453719b08Smrg printf("floating slave]\n"); 27553719b08Smrg break; 27653719b08Smrg } 27753719b08Smrg 2780309d3b3Smrg if (format == FORMAT_SHORT) 27953719b08Smrg return; 28053719b08Smrg 28153719b08Smrg if (!dev->enabled) 28253719b08Smrg printf("\tThis device is disabled\n"); 28353719b08Smrg 28453719b08Smrg print_classes_xi2(display, dev->classes, dev->num_classes); 28553719b08Smrg} 28653719b08Smrg 28753719b08Smrg 28853719b08Smrgstatic int 28953719b08Smrglist_xi2(Display *display, 2900309d3b3Smrg enum print_format format) 29153719b08Smrg{ 29253719b08Smrg int ndevices; 29353719b08Smrg int i, j; 29453719b08Smrg XIDeviceInfo *info, *dev; 29553719b08Smrg 29653719b08Smrg info = XIQueryDevice(display, XIAllDevices, &ndevices); 29753719b08Smrg 29853719b08Smrg for(i = 0; i < ndevices; i++) 29953719b08Smrg { 30053719b08Smrg dev = &info[i]; 30153719b08Smrg if (dev->use == XIMasterPointer || dev->use == XIMasterKeyboard) 30253719b08Smrg { 3030309d3b3Smrg if (format == FORMAT_SHORT || format == FORMAT_LONG) 3040309d3b3Smrg { 3050309d3b3Smrg if (dev->use == XIMasterPointer) 3060309d3b3Smrg printf("⎡ "); 3070309d3b3Smrg else 3080309d3b3Smrg printf("⎣ "); 3090309d3b3Smrg } 31053719b08Smrg 3110309d3b3Smrg print_info_xi2(display, dev, format); 31253719b08Smrg for (j = 0; j < ndevices; j++) 3135b944e2aSmrg { 31453719b08Smrg XIDeviceInfo* sd = &info[j]; 31553719b08Smrg 31653719b08Smrg if ((sd->use == XISlavePointer || sd->use == XISlaveKeyboard) && 31753719b08Smrg (sd->attachment == dev->deviceid)) 3185b944e2aSmrg { 3190309d3b3Smrg if (format == FORMAT_SHORT || format == FORMAT_LONG) 3200309d3b3Smrg printf("%s ↳ ", dev->use == XIMasterPointer ? "⎜" : " "); 3210309d3b3Smrg print_info_xi2(display, sd, format); 3225b944e2aSmrg } 3235b944e2aSmrg } 32453719b08Smrg } 32553719b08Smrg } 32653719b08Smrg 32753719b08Smrg for (i = 0; i < ndevices; i++) 32853719b08Smrg { 32953719b08Smrg dev = &info[i]; 33053719b08Smrg if (dev->use == XIFloatingSlave) 33153719b08Smrg { 33253719b08Smrg printf("∼ "); 3330309d3b3Smrg print_info_xi2(display, dev, format); 33453719b08Smrg } 33553719b08Smrg } 33653719b08Smrg 33753719b08Smrg 33853719b08Smrg XIFreeDeviceInfo(info); 33953719b08Smrg return EXIT_SUCCESS; 34053719b08Smrg} 3415b944e2aSmrg#endif 342b1297603Smrg 34353719b08Smrgint 34453719b08Smrglist(Display *display, 34553719b08Smrg int argc, 34653719b08Smrg char *argv[], 34753719b08Smrg char *name, 34853719b08Smrg char *desc) 34953719b08Smrg{ 3500309d3b3Smrg enum print_format format = FORMAT_NONE; 3510309d3b3Smrg int arg_dev = 1; 3520309d3b3Smrg 3530309d3b3Smrg if (argc >= 1) 3540309d3b3Smrg { 3550309d3b3Smrg if (strcmp(argv[0], "--short") == 0) 3560309d3b3Smrg format = FORMAT_SHORT; 3570309d3b3Smrg else if (strcmp(argv[0], "--long") == 0) 3580309d3b3Smrg format = FORMAT_LONG; 3590309d3b3Smrg else if (strcmp(argv[0], "--name-only") == 0) 3600309d3b3Smrg format = FORMAT_NAME; 3610309d3b3Smrg else if (strcmp(argv[0], "--id-only") == 0) 3620309d3b3Smrg format = FORMAT_ID; 3630309d3b3Smrg else 3640309d3b3Smrg arg_dev--; 3650309d3b3Smrg } 366b1297603Smrg 36753719b08Smrg if (argc > arg_dev) 36853719b08Smrg { 3690309d3b3Smrg if (format == FORMAT_NONE) 3700309d3b3Smrg format = FORMAT_LONG; 37153719b08Smrg#ifdef HAVE_XI2 37253719b08Smrg if (xinput_version(display) == XI_2_Major) 37353719b08Smrg { 37453719b08Smrg XIDeviceInfo *info = xi2_find_device_info(display, argv[arg_dev]); 37553719b08Smrg 37653719b08Smrg if (!info) { 37753719b08Smrg fprintf(stderr, "unable to find device %s\n", argv[arg_dev]); 37853719b08Smrg return EXIT_FAILURE; 37953719b08Smrg } else { 3800309d3b3Smrg print_info_xi2(display, info, format); 38153719b08Smrg return EXIT_SUCCESS; 38253719b08Smrg } 38353719b08Smrg } else 38453719b08Smrg#endif 38553719b08Smrg { 38653719b08Smrg XDeviceInfo *info = find_device_info(display, argv[arg_dev], False); 38753719b08Smrg 38853719b08Smrg if (!info) { 38953719b08Smrg fprintf(stderr, "unable to find device %s\n", argv[arg_dev]); 39053719b08Smrg return EXIT_FAILURE; 39153719b08Smrg } else { 3920309d3b3Smrg print_info(display, info, format); 39353719b08Smrg return EXIT_SUCCESS; 39453719b08Smrg } 39553719b08Smrg } 39653719b08Smrg } else { 3970309d3b3Smrg if (format == FORMAT_NONE) 3980309d3b3Smrg format = FORMAT_SHORT; 39953719b08Smrg#ifdef HAVE_XI2 40053719b08Smrg if (xinput_version(display) == XI_2_Major) 4010309d3b3Smrg return list_xi2(display, format); 40253719b08Smrg#endif 4030309d3b3Smrg return list_xi1(display, format); 404b1297603Smrg } 405b1297603Smrg} 406b1297603Smrg 407b1297603Smrg/* end of list.c */ 408