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