list.c revision d3263506
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#include <X11/extensions/XIproto.h> /* for XI_Device***ChangedNotify */
27
28static void
29print_info(Display* dpy, XDeviceInfo	*info, Bool shortformat)
30{
31    int			i,j;
32    XAnyClassPtr	any;
33    XKeyInfoPtr		k;
34    XButtonInfoPtr	b;
35    XValuatorInfoPtr	v;
36    XAxisInfoPtr	a;
37#if HAVE_XI2
38    XAttachInfoPtr      att;
39#endif
40
41    printf("\"%s\"\tid=%ld\t[", info->name, info->id);
42
43    switch (info->use) {
44    case IsXPointer:
45       printf("XPointer");
46       break;
47    case IsXKeyboard:
48       printf("XKeyboard");
49       break;
50    case IsXExtensionDevice:
51       printf("XExtensionDevice");
52       break;
53    case IsXExtensionKeyboard:
54       printf("XExtensionKeyboard");
55       break;
56    case IsXExtensionPointer:
57       printf("XExtensionPointer");
58       break;
59    default:
60       printf("Unknown class");
61       break;
62    }
63    printf("]\n");
64
65    if (shortformat)
66        return;
67
68    if(info->type != None)
69	printf("\tType is %s\n", XGetAtomName(dpy, info->type));
70
71    if (info->num_classes > 0) {
72	any = (XAnyClassPtr) (info->inputclassinfo);
73	for (i=0; i<info->num_classes; i++) {
74	    switch (any->class) {
75	    case KeyClass:
76		k = (XKeyInfoPtr) any;
77		printf("\tNum_keys is %d\n", k->num_keys);
78		printf("\tMin_keycode is %d\n", k->min_keycode);
79		printf("\tMax_keycode is %d\n", k->max_keycode);
80		break;
81
82	    case ButtonClass:
83		b = (XButtonInfoPtr) any;
84		printf("\tNum_buttons is %d\n", b->num_buttons);
85		break;
86
87	    case ValuatorClass:
88		v = (XValuatorInfoPtr) any;
89		a = (XAxisInfoPtr) ((char *) v +
90				    sizeof (XValuatorInfo));
91		printf("\tNum_axes is %d\n", v->num_axes);
92		printf("\tMode is %s\n", (v->mode == Absolute) ? "Absolute" : "Relative");
93		printf("\tMotion_buffer is %ld\n", v->motion_buffer);
94		for (j=0; j<v->num_axes; j++, a++) {
95		    printf("\tAxis %d :\n", j);
96		    printf("\t\tMin_value is %d\n", a->min_value);
97		    printf("\t\tMax_value is %d\n", a->max_value);
98		    printf ("\t\tResolution is %d\n", a->resolution);
99		}
100		break;
101#if HAVE_XI2
102            case AttachClass:
103                att = (XAttachInfoPtr)any;
104                printf("\tAttached to %d\n", att->attached);
105                break;
106#endif
107	    default:
108		printf ("unknown class\n");
109	    }
110	    any = (XAnyClassPtr) ((char *) any + any->length);
111	}
112    }
113}
114
115int
116list(Display	*display,
117     int	argc,
118     char	*argv[],
119     char	*name,
120     char	*desc)
121{
122    XDeviceInfo		*info;
123    int			loop;
124    int                 shortformat = False;
125    int                 daemon = False;
126
127    shortformat = (argc == 1 && strcmp(argv[0], "--short") == 0);
128    daemon = (argc == 1 && strcmp(argv[0], "--loop") == 0);
129
130    if (argc == 0 || shortformat || daemon) {
131	int		num_devices;
132        XEvent  ev;
133
134#if HAVE_XI2
135        if (daemon)
136        {
137            XiSelectEvent(display, DefaultRootWindow(display), NULL,
138                          XI_DeviceHierarchyChangedMask |
139                          XI_DeviceClassesChangedMask);
140        }
141#endif
142
143        do {
144            info = XListInputDevices(display, &num_devices);
145            for(loop=0; loop<num_devices; loop++) {
146                print_info(display, info+loop, shortformat);
147            }
148
149#if HAVE_XI2
150            /* just wait for the next generic event to come along */
151            while (daemon && !XNextEvent(display, &ev))
152            {
153                if (ev.type == GenericEvent)
154                {
155                    XGenericEvent* gev = (XGenericEvent*)&ev;
156                    /* we just assume that extension is IReqCode, pretty save
157                       since we don't register for other events. */
158                    if (gev->evtype == XI_DeviceHierarchyChangedNotify)
159                    {
160                        printf("Hierarchy change.\n");
161                    } else if (gev->evtype == XI_DeviceClassesChangedNotify)
162                    {
163                        printf("Device classes changed.\n");
164                        free(((XDeviceClassesChangedEvent*)&ev)->inputclassinfo);
165                    }
166                    break;
167                }
168            }
169#endif
170        } while(daemon);
171    } else {
172	int	ret = EXIT_SUCCESS;
173
174	for(loop=0; loop<argc; loop++) {
175	    info = find_device_info(display, argv[loop], False);
176
177	    if (!info) {
178		fprintf(stderr, "unable to find device %s\n", argv[loop]);
179		ret = EXIT_FAILURE;
180	    } else {
181		print_info(display, info, shortformat);
182	    }
183	}
184	return ret;
185    }
186    return EXIT_SUCCESS;
187}
188
189/* end of list.c */
190