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 * XExtToWire.c - reformat an XEvent into a wire event. 50 */ 51 52#ifdef HAVE_CONFIG_H 53#include <config.h> 54#endif 55 56#include <X11/extensions/XIproto.h> 57#include <X11/Xlibint.h> 58#include <X11/extensions/XInput.h> 59#include <X11/extensions/extutil.h> 60#include <X11/extensions/Xge.h> 61#include <X11/extensions/geproto.h> 62#include "XIint.h" 63 64_X_HIDDEN Status 65_XiEventToWire( 66 register Display *dpy, /* pointer to display structure */ 67 register XEvent *re, /* pointer to client event */ 68 register xEvent **event, /* wire protocol event */ 69 register int *count) 70{ 71 XExtDisplayInfo *info = XInput_find_display(dpy); 72 int i; 73 74 if ((re->type & 0x7f) != GenericEvent) { 75 switch ((re->type & 0x7f) - info->codes->first_event) { 76 case XI_DeviceKeyPress: 77 case XI_DeviceKeyRelease: 78 { 79 register XDeviceKeyEvent *ev = (XDeviceKeyEvent *) re; 80 register deviceKeyButtonPointer *kev; 81 register deviceValuator *vev; 82 83 *count = 2; 84 kev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent)); 85 if (!kev) 86 return (_XUnknownNativeEvent(dpy, re, *event)); 87 *event = (xEvent *) kev; 88 89 kev->type = ev->type; 90 kev->root = ev->root; 91 kev->event = ev->window; 92 kev->child = ev->subwindow; 93 kev->time = ev->time; 94 kev->event_x = ev->x; 95 kev->event_y = ev->y; 96 kev->root_x = ev->x_root; 97 kev->root_y = ev->y_root; 98 kev->state = ev->state; 99 kev->same_screen = ev->same_screen; 100 kev->detail = ev->keycode; 101 kev->deviceid = ev->deviceid | MORE_EVENTS; 102 103 vev = (deviceValuator *)++ kev; 104 vev->type = info->codes->first_event + XI_DeviceValuator; 105 vev->deviceid = ev->deviceid; 106 vev->device_state = ev->device_state; 107 vev->first_valuator = ev->first_axis; 108 vev->num_valuators = ev->axes_count; 109 i = vev->num_valuators; 110 if (i > 6) 111 i = 6; 112 switch (i) { 113 case 6: 114 vev->valuator5 = ev->axis_data[5]; 115 case 5: 116 vev->valuator4 = ev->axis_data[4]; 117 case 4: 118 vev->valuator3 = ev->axis_data[3]; 119 case 3: 120 vev->valuator2 = ev->axis_data[2]; 121 case 2: 122 vev->valuator1 = ev->axis_data[1]; 123 case 1: 124 vev->valuator0 = ev->axis_data[0]; 125 } 126 break; 127 } 128 case XI_ProximityIn: 129 case XI_ProximityOut: 130 { 131 register XProximityNotifyEvent *ev = (XProximityNotifyEvent *) re; 132 register deviceKeyButtonPointer *pev; 133 register deviceValuator *vev; 134 135 *count = 2; 136 pev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent)); 137 if (!pev) 138 return (_XUnknownNativeEvent(dpy, re, *event)); 139 *event = (xEvent *) pev; 140 141 pev->type = ev->type; 142 pev->root = ev->root; 143 pev->event = ev->window; 144 pev->child = ev->subwindow; 145 pev->time = ev->time; 146 pev->event_x = ev->x; 147 pev->event_y = ev->y; 148 pev->root_x = ev->x_root; 149 pev->root_y = ev->y_root; 150 pev->state = ev->state; 151 pev->same_screen = ev->same_screen; 152 pev->deviceid = ev->deviceid | MORE_EVENTS; 153 154 vev = (deviceValuator *)++ pev; 155 vev->type = info->codes->first_event + XI_DeviceValuator; 156 vev->deviceid = ev->deviceid; 157 vev->device_state = ev->device_state; 158 vev->first_valuator = ev->first_axis; 159 vev->num_valuators = ev->axes_count; 160 161 i = vev->num_valuators; 162 if (i > 6) 163 i = 6; 164 switch (i) { 165 case 6: 166 vev->valuator5 = ev->axis_data[5]; 167 case 5: 168 vev->valuator4 = ev->axis_data[4]; 169 case 4: 170 vev->valuator3 = ev->axis_data[3]; 171 case 3: 172 vev->valuator2 = ev->axis_data[2]; 173 case 2: 174 vev->valuator1 = ev->axis_data[1]; 175 case 1: 176 vev->valuator0 = ev->axis_data[0]; 177 } 178 break; 179 } 180 case XI_DeviceButtonPress: 181 case XI_DeviceButtonRelease: 182 { 183 register XDeviceButtonEvent *ev = (XDeviceButtonEvent *) re; 184 register deviceKeyButtonPointer *bev; 185 register deviceValuator *vev; 186 187 *count = 2; 188 bev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent)); 189 if (!bev) 190 return (_XUnknownNativeEvent(dpy, re, *event)); 191 *event = (xEvent *) bev; 192 193 bev->type = ev->type; 194 bev->root = ev->root; 195 bev->event = ev->window; 196 bev->child = ev->subwindow; 197 bev->time = ev->time; 198 bev->event_x = ev->x; 199 bev->event_y = ev->y; 200 bev->root_x = ev->x_root; 201 bev->root_y = ev->y_root; 202 bev->state = ev->state; 203 bev->same_screen = ev->same_screen; 204 bev->detail = ev->button; 205 bev->deviceid = ev->deviceid | MORE_EVENTS; 206 207 vev = (deviceValuator *)++ bev; 208 vev->type = info->codes->first_event + XI_DeviceValuator; 209 vev->deviceid = ev->deviceid; 210 vev->device_state = ev->device_state; 211 vev->first_valuator = ev->first_axis; 212 vev->num_valuators = ev->axes_count; 213 214 i = vev->num_valuators; 215 if (i > 6) 216 i = 6; 217 switch (i) { 218 case 6: 219 vev->valuator5 = ev->axis_data[5]; 220 case 5: 221 vev->valuator4 = ev->axis_data[4]; 222 case 4: 223 vev->valuator3 = ev->axis_data[3]; 224 case 3: 225 vev->valuator2 = ev->axis_data[2]; 226 case 2: 227 vev->valuator1 = ev->axis_data[1]; 228 case 1: 229 vev->valuator0 = ev->axis_data[0]; 230 } 231 break; 232 } 233 case XI_DeviceMotionNotify: 234 { 235 register XDeviceMotionEvent *ev = (XDeviceMotionEvent *) re; 236 register deviceKeyButtonPointer *mev; 237 register deviceValuator *vev; 238 239 *count = 2; 240 mev = (deviceKeyButtonPointer *) Xmalloc(*count * sizeof(xEvent)); 241 if (!mev) 242 return (_XUnknownNativeEvent(dpy, re, *event)); 243 *event = (xEvent *) mev; 244 245 mev->type = ev->type; 246 mev->root = ev->root; 247 mev->event = ev->window; 248 mev->child = ev->subwindow; 249 mev->time = ev->time; 250 mev->event_x = ev->x; 251 mev->event_y = ev->y; 252 mev->root_x = ev->x_root; 253 mev->root_y = ev->y_root; 254 mev->state = ev->state; 255 mev->same_screen = ev->same_screen; 256 mev->detail = ev->is_hint; 257 mev->deviceid = ev->deviceid | MORE_EVENTS; 258 259 vev = (deviceValuator *)++ mev; 260 vev->type = info->codes->first_event + XI_DeviceValuator; 261 vev->deviceid = ev->deviceid; 262 vev->device_state = ev->device_state; 263 vev->first_valuator = ev->first_axis; 264 vev->num_valuators = ev->axes_count; 265 266 i = vev->num_valuators; 267 if (i > 6) 268 i = 6; 269 switch (i) { 270 case 6: 271 vev->valuator5 = ev->axis_data[5]; 272 case 5: 273 vev->valuator4 = ev->axis_data[4]; 274 case 4: 275 vev->valuator3 = ev->axis_data[3]; 276 case 3: 277 vev->valuator2 = ev->axis_data[2]; 278 case 2: 279 vev->valuator1 = ev->axis_data[1]; 280 case 1: 281 vev->valuator0 = ev->axis_data[0]; 282 } 283 break; 284 } 285 case XI_DeviceFocusIn: 286 case XI_DeviceFocusOut: 287 { 288 register XDeviceFocusChangeEvent *ev = (XDeviceFocusChangeEvent *) re; 289 register deviceFocus *fev; 290 291 *count = 1; 292 fev = (deviceFocus *) Xmalloc(*count * sizeof(xEvent)); 293 if (!fev) 294 return (_XUnknownNativeEvent(dpy, re, *event)); 295 *event = (xEvent *) fev; 296 297 fev->type = ev->type; 298 fev->window = ev->window; 299 fev->mode = ev->mode; 300 fev->detail = ev->detail; 301 fev->time = ev->time; 302 fev->deviceid = ev->deviceid; 303 break; 304 } 305 case XI_DeviceMappingNotify: 306 { 307 register XDeviceMappingEvent *ev = (XDeviceMappingEvent *) re; 308 register deviceMappingNotify *mev; 309 310 *count = 1; 311 mev = (deviceMappingNotify *) Xmalloc(*count * sizeof(xEvent)); 312 if (!mev) 313 return (_XUnknownNativeEvent(dpy, re, *event)); 314 *event = (xEvent *) mev; 315 316 mev->type = ev->type; 317 mev->firstKeyCode = ev->first_keycode; 318 mev->request = ev->request; 319 mev->count = ev->count; 320 mev->time = ev->time; 321 mev->deviceid = ev->deviceid; 322 break; 323 } 324 case XI_DeviceStateNotify: 325 { 326 register XDeviceStateNotifyEvent *ev = (XDeviceStateNotifyEvent *) re; 327 register deviceStateNotify *sev; 328 register xEvent *tev; 329 XInputClass *any = (XInputClass *) & ev->data[0]; 330 unsigned char *sav_id; 331 332 *count = 1; 333 334 for (i = 0; i < ev->num_classes; i++) { 335 if (any->class == KeyClass) { 336 XKeyStatus *k = (XKeyStatus *) any; 337 338 if (k->num_keys > 32) 339 (*count)++; 340 } else if (any->class == ButtonClass) { 341 XButtonStatus *b = (XButtonStatus *) any; 342 343 if (b->num_buttons > 32) 344 (*count)++; 345 } else if (any->class == ValuatorClass) { 346 XValuatorStatus *v = (XValuatorStatus *) any; 347 348 if (v->num_valuators > 3) 349 (*count)++; 350 } 351 any = (XInputClass *) ((char *)any + any->length); 352 } 353 354 sev = (deviceStateNotify *) Xmalloc(*count * sizeof(xEvent)); 355 if (!sev) 356 return (_XUnknownNativeEvent(dpy, re, *event)); 357 *event = (xEvent *) sev; 358 tev = (xEvent *) (sev + 1); 359 360 sev->type = ev->type; 361 sev->deviceid = ev->deviceid; 362 sav_id = &(sev->deviceid); 363 sev->time = ev->time; 364 sev->classes_reported = 0; 365 366 any = (XInputClass *) & ev->data[0]; 367 for (i = 0; i < ev->num_classes; i++) { 368 if (any->class == KeyClass) { 369 XKeyStatus *k = (XKeyStatus *) any; 370 register deviceKeyStateNotify *kev; 371 372 sev->classes_reported |= (1 << KeyClass); 373 sev->num_keys = k->num_keys; 374 memcpy((char *)(sev->keys), (char *)(k->keys), 4); 375 if (k->num_keys > 32) { 376 kev = (deviceKeyStateNotify *) tev++; 377 kev->type = info->codes->first_event + 378 XI_DeviceKeystateNotify; 379 kev->deviceid = ev->deviceid; 380 *sav_id |= MORE_EVENTS; 381 sav_id = &(kev->deviceid); 382 memcpy((char *)(kev->keys), (char *)(&k->keys[4]), 28); 383 } 384 } else if (any->class == ButtonClass) { 385 XButtonStatus *b = (XButtonStatus *) any; 386 register deviceButtonStateNotify *bev; 387 388 sev->classes_reported |= (1 << ButtonClass); 389 sev->num_buttons = b->num_buttons; 390 memcpy((char *)(sev->buttons), (char *)(b->buttons), 4); 391 if (b->num_buttons > 32) { 392 bev = (deviceButtonStateNotify *) tev++; 393 bev->type = info->codes->first_event + 394 XI_DeviceButtonstateNotify; 395 bev->deviceid = ev->deviceid; 396 *sav_id |= MORE_EVENTS; 397 sav_id = &(bev->deviceid); 398 memcpy((char *)(bev->buttons), (char *)(&b->buttons[4]), 399 28); 400 } 401 } else if (any->class == ValuatorClass) { 402 XValuatorStatus *val = (XValuatorStatus *) any; 403 register deviceValuator *vev; 404 405 sev->classes_reported |= (1 << ValuatorClass); 406 sev->num_valuators = val->num_valuators < 3 ? 407 val->num_valuators : 3; 408 switch (sev->num_valuators) { 409 case 3: 410 sev->valuator2 = val->valuators[2]; 411 case 2: 412 sev->valuator1 = val->valuators[1]; 413 case 1: 414 sev->valuator0 = val->valuators[0]; 415 } 416 if (val->num_valuators > 3) { 417 vev = (deviceValuator *) tev++; 418 vev->type = info->codes->first_event + XI_DeviceValuator; 419 vev->deviceid = ev->deviceid; 420 vev->first_valuator = 3; 421 vev->num_valuators = val->num_valuators - 3; 422 *sav_id |= MORE_EVENTS; 423 sav_id = &(vev->deviceid); 424 i = val->num_valuators; 425 if (i > 6) 426 i = 6; 427 switch (i) { 428 case 6: 429 vev->valuator2 = val->valuators[5]; 430 case 5: 431 vev->valuator1 = val->valuators[4]; 432 case 4: 433 vev->valuator0 = val->valuators[3]; 434 } 435 } 436 } 437 any = (XInputClass *) ((char *)any + any->length); 438 } 439 break; 440 } 441 case XI_ChangeDeviceNotify: 442 { 443 register XChangeDeviceNotifyEvent *ev = (XChangeDeviceNotifyEvent *) re; 444 register changeDeviceNotify *cev; 445 446 *count = 1; 447 cev = (changeDeviceNotify *) Xmalloc(*count * sizeof(xEvent)); 448 if (!cev) 449 return (_XUnknownNativeEvent(dpy, re, *event)); 450 *event = (xEvent *) cev; 451 452 cev->type = ev->type; 453 cev->request = ev->request; 454 cev->time = ev->time; 455 cev->deviceid = ev->deviceid; 456 break; 457 } 458 default: 459 return (_XUnknownNativeEvent(dpy, re, *event)); 460 } /* switch */ 461 } else /* if type != GenericEvent */ 462 { 463#if 0 464 switch (((XGenericEvent*)re)->evtype) 465 { 466 case XI_HierarchyChangedNotify: 467 { 468 XDeviceHierarchyChangedEvent *ev = 469 (XDeviceHierarchyChangedEvent*)re; 470 XIDeviceHierarchyEvent *dhcev; 471 *count = 1; 472 dhcev = (XIDeviceHierarchyEvent *)Xmalloc(*count * sizeof(xEvent)); 473 if (!dhcev) 474 return (_XUnknownNativeEvent(dpy, re, *event)); 475 476 *event = (xEvent *) dhcev; 477 dhcev->type = ev->type; 478 dhcev->time = ev->time; 479 break; 480 } 481 default: 482 return (_XUnknownNativeEvent(dpy, re, *event)); 483 } 484#endif 485 } 486 return (1); 487} 488