XListDev.c revision c43cc173
1/* $Xorg: XListDev.c,v 1.5 2001/02/09 02:03:51 xorgcvs Exp $ */
2
3/************************************************************
4
5Copyright 1989, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings
25in this Software without prior written authorization from The Open Group.
26
27Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
28
29			All Rights Reserved
30
31Permission to use, copy, modify, and distribute this software and its
32documentation for any purpose and without fee is hereby granted,
33provided that the above copyright notice appear in all copies and that
34both that copyright notice and this permission notice appear in
35supporting documentation, and that the name of Hewlett-Packard not be
36used in advertising or publicity pertaining to distribution of the
37software without specific, written prior permission.
38
39HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45SOFTWARE.
46
47********************************************************/
48/* $XFree86: xc/lib/Xi/XListDev.c,v 3.4 2001/12/14 19:55:19 dawes Exp $ */
49
50/***********************************************************************
51 *
52 * XListInputDevices - Request the server to return a list of
53 *			 available input devices.
54 *
55 */
56
57#define NEED_REPLIES
58#define NEED_EVENTS
59#include <X11/extensions/XI.h>
60#include <X11/extensions/XIproto.h>
61#include <X11/Xlibint.h>
62#include <X11/extensions/XInput.h>
63#include <X11/extensions/extutil.h>
64#include "XIint.h"
65
66XDeviceInfo *
67XListInputDevices(dpy, ndevices)
68    register Display *dpy;
69    int *ndevices;
70{
71    int size;
72    xListInputDevicesReq *req;
73    xListInputDevicesReply rep;
74    xDeviceInfo *list, *slist = NULL;
75    XDeviceInfo *sclist = NULL;
76    XDeviceInfo *clist = NULL;
77    xAnyClassPtr any, sav_any;
78    XAnyClassPtr Any;
79    char *nptr, *Nptr;
80    register int i, j, k;
81    register long rlen;
82    XExtDisplayInfo *info = XInput_find_display(dpy);
83
84    LockDisplay(dpy);
85    if (_XiCheckExtInit(dpy, XInput_Initial_Release, info) == -1)
86	return ((XDeviceInfo *) NULL);
87
88    GetReq(ListInputDevices, req);
89    req->reqType = info->codes->major_opcode;
90    req->ReqType = X_ListInputDevices;
91
92    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
93	UnlockDisplay(dpy);
94	SyncHandle();
95	return (XDeviceInfo *) NULL;
96    }
97
98    if ((*ndevices = rep.ndevices)) {	/* at least 1 input device */
99	size = *ndevices * sizeof(XDeviceInfo);
100	rlen = rep.length << 2;	/* multiply length by 4    */
101	list = (xDeviceInfo *) Xmalloc(rlen);
102	slist = list;
103	if (!slist) {
104	    _XEatData(dpy, (unsigned long)rlen);
105	    UnlockDisplay(dpy);
106	    SyncHandle();
107	    return (XDeviceInfo *) NULL;
108	}
109	_XRead(dpy, (char *)list, rlen);
110
111	any = (xAnyClassPtr) ((char *)list + (*ndevices * sizeof(xDeviceInfo)));
112	sav_any = any;
113	for (i = 0; i < *ndevices; i++, list++) {
114	    for (j = 0; j < (int)list->num_classes; j++) {
115		switch (any->class) {
116		case KeyClass:
117		    size += sizeof(XKeyInfo);
118		    break;
119		case ButtonClass:
120		    size += sizeof(XButtonInfo);
121		    break;
122		case ValuatorClass:
123		{
124		    xValuatorInfoPtr v;
125
126		    v = (xValuatorInfoPtr) any;
127		    size += sizeof(XValuatorInfo) +
128			(v->num_axes * sizeof(XAxisInfo));
129		    break;
130		}
131		default:
132		    break;
133		}
134		any = (xAnyClassPtr) ((char *)any + any->length);
135	    }
136	}
137
138	for (i = 0, nptr = (char *)any; i < *ndevices; i++) {
139	    size += *nptr + 1;
140	    nptr += (*nptr + 1);
141	}
142
143	clist = (XDeviceInfoPtr) Xmalloc(size);
144	if (!clist) {
145	    XFree((char *)slist);
146	    UnlockDisplay(dpy);
147	    SyncHandle();
148	    return (XDeviceInfo *) NULL;
149	}
150	sclist = clist;
151	Any = (XAnyClassPtr) ((char *)clist +
152			      (*ndevices * sizeof(XDeviceInfo)));
153	list = slist;
154	any = sav_any;
155	for (i = 0; i < *ndevices; i++, list++, clist++) {
156	    clist->type = list->type;
157	    clist->id = list->id;
158	    clist->use = list->use;
159	    clist->num_classes = list->num_classes;
160	    clist->inputclassinfo = Any;
161	    for (j = 0; j < (int)list->num_classes; j++) {
162		switch (any->class) {
163		case KeyClass:
164		{
165		    XKeyInfoPtr K = (XKeyInfoPtr) Any;
166		    xKeyInfoPtr k = (xKeyInfoPtr) any;
167
168		    K->class = KeyClass;
169		    K->length = sizeof(XKeyInfo);
170		    K->min_keycode = k->min_keycode;
171		    K->max_keycode = k->max_keycode;
172		    K->num_keys = k->num_keys;
173		    break;
174		}
175		case ButtonClass:
176		{
177		    XButtonInfoPtr B = (XButtonInfoPtr) Any;
178		    xButtonInfoPtr b = (xButtonInfoPtr) any;
179
180		    B->class = ButtonClass;
181		    B->length = sizeof(XButtonInfo);
182		    B->num_buttons = b->num_buttons;
183		    break;
184		}
185		case ValuatorClass:
186		{
187		    XValuatorInfoPtr V = (XValuatorInfoPtr) Any;
188		    xValuatorInfoPtr v = (xValuatorInfoPtr) any;
189		    XAxisInfoPtr A;
190		    xAxisInfoPtr a;
191
192		    V->class = ValuatorClass;
193		    V->length = sizeof(XValuatorInfo) +
194			(v->num_axes * sizeof(XAxisInfo));
195		    V->num_axes = v->num_axes;
196		    V->motion_buffer = v->motion_buffer_size;
197		    V->mode = v->mode;
198		    A = (XAxisInfoPtr) ((char *)V + sizeof(XValuatorInfo));
199		    V->axes = A;
200		    a = (xAxisInfoPtr) ((char *)any + sizeof(xValuatorInfo));
201		    for (k = 0; k < (int)v->num_axes; k++, a++, A++) {
202			A->min_value = a->min_value;
203			A->max_value = a->max_value;
204			A->resolution = a->resolution;
205		    }
206		    break;
207		}
208		default:
209		    break;
210		}
211		any = (xAnyClassPtr) ((char *)any + any->length);
212		Any = (XAnyClassPtr) ((char *)Any + Any->length);
213	    }
214	}
215
216	clist = sclist;
217	nptr = (char *)any;
218	Nptr = (char *)Any;
219	for (i = 0; i < *ndevices; i++, clist++) {
220	    clist->name = (char *)Nptr;
221	    memcpy(Nptr, nptr + 1, *nptr);
222	    Nptr += (*nptr);
223	    *Nptr++ = '\0';
224	    nptr += (*nptr + 1);
225	}
226    }
227
228    XFree((char *)slist);
229    UnlockDisplay(dpy);
230    SyncHandle();
231    return (sclist);
232}
233
234/***********************************************************************
235 *
236 * Free the list of input devices.
237 *
238 */
239
240void
241XFreeDeviceList(list)
242    XDeviceInfo *list;
243{
244    if (list != NULL) {
245	XFree((char *)list);
246    }
247}
248