list.c revision 5b944e2a
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(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->num_classes > 0) {
69	any = (XAnyClassPtr) (info->inputclassinfo);
70	for (i=0; i<info->num_classes; i++) {
71	    switch (any->class) {
72	    case KeyClass:
73		k = (XKeyInfoPtr) any;
74		printf("\tNum_keys is %d\n", k->num_keys);
75		printf("\tMin_keycode is %d\n", k->min_keycode);
76		printf("\tMax_keycode is %d\n", k->max_keycode);
77		break;
78
79	    case ButtonClass:
80		b = (XButtonInfoPtr) any;
81		printf("\tNum_buttons is %d\n", b->num_buttons);
82		break;
83
84	    case ValuatorClass:
85		v = (XValuatorInfoPtr) any;
86		a = (XAxisInfoPtr) ((char *) v +
87				    sizeof (XValuatorInfo));
88		printf("\tNum_axes is %d\n", v->num_axes);
89		printf("\tMode is %s\n", (v->mode == Absolute) ? "Absolute" : "Relative");
90		printf("\tMotion_buffer is %ld\n", v->motion_buffer);
91		for (j=0; j<v->num_axes; j++, a++) {
92		    printf("\tAxis %d :\n", j);
93		    printf("\t\tMin_value is %d\n", a->min_value);
94		    printf("\t\tMax_value is %d\n", a->max_value);
95		    printf ("\t\tResolution is %d\n", a->resolution);
96		}
97		break;
98#if HAVE_XI2
99            case AttachClass:
100                att = (XAttachInfoPtr)any;
101                printf("\tAttached to %d\n", att->attached);
102                break;
103#endif
104	    default:
105		printf ("unknown class\n");
106	    }
107	    any = (XAnyClassPtr) ((char *) any + any->length);
108	}
109    }
110}
111
112int
113list(Display	*display,
114     int	argc,
115     char	*argv[],
116     char	*name,
117     char	*desc)
118{
119    XDeviceInfo		*info;
120    int			loop;
121    int                 shortformat = False;
122    int                 daemon = False;
123
124    shortformat = (argc == 1 && strcmp(argv[0], "--short") == 0);
125    daemon = (argc == 1 && strcmp(argv[0], "--loop") == 0);
126
127    if (argc == 0 || shortformat || daemon) {
128	int		num_devices;
129        XEvent  ev;
130
131#if HAVE_XI2
132        if (daemon)
133        {
134            XiSelectEvent(display, DefaultRootWindow(display), NULL,
135                          XI_DeviceHierarchyChangedMask |
136                          XI_DeviceClassesChangedMask);
137        }
138#endif
139
140        do {
141            info = XListInputDevices(display, &num_devices);
142            for(loop=0; loop<num_devices; loop++) {
143                print_info(info+loop, shortformat);
144            }
145
146#if HAVE_XI2
147            /* just wait for the next generic event to come along */
148            while (daemon && !XNextEvent(display, &ev))
149            {
150                if (ev.type == GenericEvent)
151                {
152                    XGenericEvent* gev = (XGenericEvent*)&ev;
153                    /* we just assume that extension is IReqCode, pretty save
154                       since we don't register for other events. */
155                    if (gev->evtype == XI_DeviceHierarchyChangedNotify)
156                    {
157                        printf("Hierarchy change.\n");
158                    } else if (gev->evtype == XI_DeviceClassesChangedNotify)
159                    {
160                        printf("Device classes changed.\n");
161                        free(((XDeviceClassesChangedEvent*)&ev)->inputclassinfo);
162                    }
163                    break;
164                }
165            }
166#endif
167        } while(daemon);
168    } else {
169	int	ret = EXIT_SUCCESS;
170
171	for(loop=0; loop<argc; loop++) {
172	    info = find_device_info(display, argv[loop], False);
173
174	    if (!info) {
175		fprintf(stderr, "unable to find device %s\n", argv[loop]);
176		ret = EXIT_FAILURE;
177	    } else {
178		print_info(info, shortformat);
179	    }
180	}
181	return ret;
182    }
183    return EXIT_SUCCESS;
184}
185
186/* end of list.c */
187