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