XExtInt.c revision f1ee322d
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 * Input Extension library internal functions. 50 * 51 */ 52 53#if HAVE_CONFIG_H 54#include <config.h> 55#endif 56 57#include <stdio.h> 58#include <stdint.h> 59#include <X11/extensions/XI.h> 60#include <X11/extensions/XI2.h> 61#include <X11/extensions/XIproto.h> 62#include <X11/extensions/XI2proto.h> 63#include <X11/Xlibint.h> 64#include <X11/extensions/XInput.h> 65#include <X11/extensions/XInput2.h> 66#include <X11/extensions/extutil.h> 67#include <X11/extensions/geproto.h> 68#include <X11/extensions/ge.h> 69#include <X11/extensions/Xge.h> 70#include "XIint.h" 71 72#define ENQUEUE_EVENT True 73#define DONT_ENQUEUE False 74#define FP1616toDBL(x) ((x) * 1.0 / (1 << 16)) 75 76int copy_classes(XIDeviceInfo *to, xXIAnyInfo* from, int *nclasses); 77int size_classes(xXIAnyInfo* from, int nclasses); 78 79static XExtensionInfo *xinput_info; 80static const char *xinput_extension_name = INAME; 81 82static int XInputClose( 83 Display * /* dpy */, 84 XExtCodes * /* codes */ 85); 86 87static char *XInputError( 88 Display * /* dpy */, 89 int /* code */, 90 XExtCodes * /* codes */, 91 char * /* buf */, 92 int /* n */ 93); 94 95static Bool XInputWireToEvent( 96 Display * /* dpy */, 97 XEvent * /* re */, 98 xEvent * /* event */ 99); 100static Bool XInputWireToCookie( 101 Display* /* display */, 102 XGenericEventCookie* /* re */, 103 xEvent* /* event */ 104); 105 106static Bool XInputCopyCookie( 107 Display* /* display */, 108 XGenericEventCookie* /* in */, 109 XGenericEventCookie* /* out */ 110); 111 112static int 113wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* out); 114static int 115wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie); 116static int 117wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie); 118static int 119wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie); 120static int 121wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie); 122static int 123wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie); 124static int 125wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in, 126 XGenericEventCookie *cookie); 127static int 128wireToBarrierEvent(xXIBarrierEvent *in, 129 XGenericEventCookie *cookie); 130 131static /* const */ XEvent emptyevent; 132 133typedef Status (*core_event_to_wire)(Display*, XEvent*, xEvent*); 134 135static /* const */ XExtensionHooks xinput_extension_hooks = { 136 NULL, /* create_gc */ 137 NULL, /* copy_gc */ 138 NULL, /* flush_gc */ 139 NULL, /* free_gc */ 140 NULL, /* create_font */ 141 NULL, /* free_font */ 142 XInputClose, /* close_display */ 143 XInputWireToEvent, /* wire_to_event */ 144 (core_event_to_wire)_XiEventToWire, /* event_to_wire */ 145 NULL, /* error */ 146 XInputError, /* error_string */ 147}; 148 149static const char *XInputErrorList[] = { 150 "BadDevice, invalid or uninitialized input device", /* BadDevice */ 151 "BadEvent, invalid event type", /* BadEvent */ 152 "BadMode, invalid mode parameter", /* BadMode */ 153 "DeviceBusy, device is busy", /* DeviceBusy */ 154 "BadClass, invalid event class", /* BadClass */ 155}; 156 157/* Get the version supported by the server to know which number of 158* events are support. Otherwise, a wrong number of events may smash 159* the Xlib-internal event processing vector. 160* 161* Since the extension hasn't been initialized yet, we need to 162* manually get the opcode, then the version. 163*/ 164static int 165_XiFindEventsSupported(Display *dpy) 166{ 167 XExtCodes codes; 168 XExtensionVersion *extversion = NULL; 169 int nevents = 0; 170 171 if (!XQueryExtension(dpy, INAME, &codes.major_opcode, 172 &codes.first_event, &codes.first_error)) 173 goto out; 174 175 LockDisplay(dpy); 176 extversion = _XiGetExtensionVersionRequest(dpy, INAME, codes.major_opcode); 177 UnlockDisplay(dpy); 178 SyncHandle(); 179 180 if (!extversion || !extversion->present) 181 goto out; 182 183 if (extversion->major_version >= 2) 184 nevents = IEVENTS; /* number is fixed, XI2 adds GenericEvents only */ 185 else if (extversion->major_version <= 0) 186 { 187 printf("XInput_find_display: invalid extension version %d.%d\n", 188 extversion->major_version, extversion->minor_version); 189 goto out; 190 } 191 else 192 { 193 switch(extversion->minor_version) 194 { 195 case XI_Add_DeviceProperties_Minor: 196 nevents = XI_DevicePropertyNotify + 1; 197 break; 198 case XI_Add_DevicePresenceNotify_Minor: 199 nevents = XI_DevicePresenceNotify + 1; 200 break; 201 default: 202 nevents = XI_DeviceButtonstateNotify + 1; 203 break; 204 } 205 } 206 207out: 208 if (extversion) 209 XFree(extversion); 210 return nevents; 211} 212 213 214_X_HIDDEN 215XExtDisplayInfo *XInput_find_display (Display *dpy) 216{ 217 XExtDisplayInfo *dpyinfo; 218 if (!xinput_info) { if (!(xinput_info = XextCreateExtension())) return NULL; } 219 if (!(dpyinfo = XextFindDisplay (xinput_info, dpy))) 220 { 221 int nevents = _XiFindEventsSupported(dpy); 222 223 dpyinfo = XextAddDisplay (xinput_info, dpy, 224 xinput_extension_name, 225 &xinput_extension_hooks, 226 nevents, NULL); 227 if (dpyinfo->codes) /* NULL if XI doesn't exist on the server */ 228 { 229 XESetWireToEventCookie(dpy, dpyinfo->codes->major_opcode, XInputWireToCookie); 230 XESetCopyEventCookie(dpy, dpyinfo->codes->major_opcode, XInputCopyCookie); 231 } 232 } 233 return dpyinfo; 234} 235 236static XEXT_GENERATE_ERROR_STRING(XInputError, xinput_extension_name, 237 IERRORS, XInputErrorList) 238/******************************************************************* 239* 240* Input extension versions. 241* 242*/ 243static XExtensionVersion versions[] = { {XI_Absent, 0, 0}, 244{XI_Present, XI_Initial_Release_Major, XI_Initial_Release_Minor}, 245{XI_Present, XI_Add_XDeviceBell_Major, XI_Add_XDeviceBell_Minor}, 246{XI_Present, XI_Add_XSetDeviceValuators_Major, 247 XI_Add_XSetDeviceValuators_Minor}, 248{XI_Present, XI_Add_XChangeDeviceControl_Major, 249 XI_Add_XChangeDeviceControl_Minor}, 250{XI_Present, XI_Add_DevicePresenceNotify_Major, 251 XI_Add_DevicePresenceNotify_Minor}, 252{XI_Present, XI_Add_DeviceProperties_Major, 253 XI_Add_DeviceProperties_Minor}, 254{XI_Present, 2, 0}, 255{XI_Present, 2, 1}, 256{XI_Present, 2, 2} 257}; 258 259/*********************************************************************** 260 * 261 * Return errors reported by this extension. 262 * 263 */ 264 265void 266_xibaddevice( 267 Display *dpy, 268 int *error) 269{ 270 XExtDisplayInfo *info = XInput_find_display(dpy); 271 272 *error = info->codes->first_error + XI_BadDevice; 273} 274 275void 276_xibadclass( 277 Display *dpy, 278 int *error) 279{ 280 XExtDisplayInfo *info = XInput_find_display(dpy); 281 282 *error = info->codes->first_error + XI_BadClass; 283} 284 285void 286_xibadevent( 287 Display *dpy, 288 int *error) 289{ 290 XExtDisplayInfo *info = XInput_find_display(dpy); 291 292 *error = info->codes->first_error + XI_BadEvent; 293} 294 295void 296_xibadmode( 297 Display *dpy, 298 int *error) 299{ 300 XExtDisplayInfo *info = XInput_find_display(dpy); 301 302 *error = info->codes->first_error + XI_BadMode; 303} 304 305void 306_xidevicebusy( 307 Display *dpy, 308 int *error) 309{ 310 XExtDisplayInfo *info = XInput_find_display(dpy); 311 312 *error = info->codes->first_error + XI_DeviceBusy; 313} 314 315static int XInputCheckExtension(Display *dpy, XExtDisplayInfo *info) 316{ 317 XextCheckExtension (dpy, info, xinput_extension_name, 0); 318 return 1; 319} 320 321/***************************************************************** 322 * Compare version numbers between info and the built-in version table. 323 * Returns 324 * -1 if info's version is less than version_index's version, 325 * 0 if equal (or DontCheck), 326 * 1 if info's version is greater than version_index's version. 327 * Returns -2 on initialization errors which shouldn't happen if you call it 328 * correctly. 329 */ 330_X_HIDDEN int 331_XiCheckVersion(XExtDisplayInfo *info, 332 int version_index) 333{ 334 XExtensionVersion *ext; 335 336 if (versions[version_index].major_version == Dont_Check) 337 return 0; 338 339 if (!info->data) 340 return -2; 341 342 ext = ((XInputData *) info->data)->vers; 343 if (!ext) 344 return -2; 345 346 if (ext->major_version == versions[version_index].major_version && 347 ext->minor_version == versions[version_index].minor_version) 348 return 0; 349 350 if (ext->major_version < versions[version_index].major_version || 351 (ext->major_version == versions[version_index].major_version && 352 ext->minor_version < versions[version_index].minor_version)) 353 return -1; 354 else 355 return 1; 356} 357 358/*********************************************************************** 359 * 360 * Check to see if the input extension is installed in the server. 361 * Also check to see if the version is >= the requested version. 362 * 363 */ 364 365_X_HIDDEN int 366_XiCheckExtInit( 367 register Display *dpy, 368 register int version_index, 369 XExtDisplayInfo *info) 370{ 371 if (!XInputCheckExtension(dpy, info)) { 372 UnlockDisplay(dpy); 373 return (-1); 374 } 375 376 if (info->data == NULL) { 377 info->data = (XPointer) Xmalloc(sizeof(XInputData)); 378 if (!info->data) { 379 UnlockDisplay(dpy); 380 return (-1); 381 } 382 ((XInputData *) info->data)->vers = 383 _XiGetExtensionVersion(dpy, "XInputExtension", info); 384 } 385 386 if (_XiCheckVersion(info, version_index) < 0) { 387 UnlockDisplay(dpy); 388 return -1; 389 } 390 391 return (0); 392} 393 394/*********************************************************************** 395 * 396 * Close display routine. 397 * 398 */ 399 400static int 401XInputClose( 402 Display *dpy, 403 XExtCodes *codes) 404{ 405 XExtDisplayInfo *info = XInput_find_display(dpy); 406 407 if (info->data != NULL) { 408 XFree((char *)((XInputData *) info->data)->vers); 409 XFree((char *)info->data); 410 } 411 412 if (!XextRemoveDisplay(xinput_info, dpy)) 413 return 0; 414 415 if (xinput_info->ndisplays == 0) { 416 XextDestroyExtension(xinput_info); 417 xinput_info = NULL; 418 } 419 420 return 1; 421} 422 423static int 424Ones(Mask mask) 425{ 426 register Mask y; 427 428 y = (mask >> 1) & 033333333333; 429 y = mask - y - ((y >> 1) & 033333333333); 430 return (((y + (y >> 3)) & 030707070707) % 077); 431} 432 433static int count_bits(unsigned char* ptr, int len) 434{ 435 int bits = 0; 436 unsigned int i; 437 unsigned char x; 438 439 for (i = 0; i < len; i++) 440 { 441 x = ptr[i]; 442 while(x > 0) 443 { 444 bits += (x & 0x1); 445 x >>= 1; 446 } 447 } 448 return bits; 449} 450 451int 452_XiGetDevicePresenceNotifyEvent(Display * dpy) 453{ 454 XExtDisplayInfo *info = XInput_find_display(dpy); 455 456 return info->codes->first_event + XI_DevicePresenceNotify; 457} 458 459/*********************************************************************** 460 * 461 * Handle Input extension events. 462 * Reformat a wire event into an XEvent structure of the right type. 463 * 464 */ 465 466static Bool 467XInputWireToEvent( 468 Display *dpy, 469 XEvent *re, 470 xEvent *event) 471{ 472 unsigned int type, reltype; 473 XExtDisplayInfo *info = XInput_find_display(dpy); 474 XEvent *save = (XEvent *) info->data; 475 476 type = event->u.u.type & 0x7f; 477 reltype = (type - info->codes->first_event); 478 479 if (type == GenericEvent || 480 (reltype != XI_DeviceValuator && 481 reltype != XI_DeviceKeystateNotify && 482 reltype != XI_DeviceButtonstateNotify)) { 483 *save = emptyevent; 484 save->type = type; 485 ((XAnyEvent *) save)->serial = _XSetLastRequestRead(dpy, 486 (xGenericReply *) 487 event); 488 ((XAnyEvent *) save)->send_event = ((event->u.u.type & 0x80) != 0); 489 ((XAnyEvent *) save)->display = dpy; 490 } 491 492 /* Process traditional events */ 493 if (type != GenericEvent) 494 { 495 switch (reltype) { 496 case XI_DeviceMotionNotify: 497 { 498 register XDeviceMotionEvent *ev = (XDeviceMotionEvent *) save; 499 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 500 501 ev->root = ev2->root; 502 ev->window = ev2->event; 503 ev->subwindow = ev2->child; 504 ev->time = ev2->time; 505 ev->x_root = ev2->root_x; 506 ev->y_root = ev2->root_y; 507 ev->x = ev2->event_x; 508 ev->y = ev2->event_y; 509 ev->state = ev2->state; 510 ev->same_screen = ev2->same_screen; 511 ev->is_hint = ev2->detail; 512 ev->deviceid = ev2->deviceid & DEVICE_BITS; 513 return (DONT_ENQUEUE); 514 } 515 break; 516 case XI_DeviceKeyPress: 517 case XI_DeviceKeyRelease: 518 { 519 register XDeviceKeyEvent *ev = (XDeviceKeyEvent *) save; 520 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 521 522 ev->root = ev2->root; 523 ev->window = ev2->event; 524 ev->subwindow = ev2->child; 525 ev->time = ev2->time; 526 ev->x_root = ev2->root_x; 527 ev->y_root = ev2->root_y; 528 ev->x = ev2->event_x; 529 ev->y = ev2->event_y; 530 ev->state = ev2->state; 531 ev->same_screen = ev2->same_screen; 532 ev->keycode = ev2->detail; 533 ev->deviceid = ev2->deviceid & DEVICE_BITS; 534 if (ev2->deviceid & MORE_EVENTS) 535 return (DONT_ENQUEUE); 536 else { 537 *re = *save; 538 return (ENQUEUE_EVENT); 539 } 540 } 541 break; 542 case XI_DeviceButtonPress: 543 case XI_DeviceButtonRelease: 544 { 545 register XDeviceButtonEvent *ev = (XDeviceButtonEvent *) save; 546 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 547 548 ev->root = ev2->root; 549 ev->window = ev2->event; 550 ev->subwindow = ev2->child; 551 ev->time = ev2->time; 552 ev->x_root = ev2->root_x; 553 ev->y_root = ev2->root_y; 554 ev->x = ev2->event_x; 555 ev->y = ev2->event_y; 556 ev->state = ev2->state; 557 ev->same_screen = ev2->same_screen; 558 ev->button = ev2->detail; 559 ev->deviceid = ev2->deviceid & DEVICE_BITS; 560 if (ev2->deviceid & MORE_EVENTS) 561 return (DONT_ENQUEUE); 562 else { 563 *re = *save; 564 return (ENQUEUE_EVENT); 565 } 566 } 567 break; 568 case XI_ProximityIn: 569 case XI_ProximityOut: 570 { 571 register XProximityNotifyEvent *ev = (XProximityNotifyEvent *) save; 572 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 573 574 ev->root = ev2->root; 575 ev->window = ev2->event; 576 ev->subwindow = ev2->child; 577 ev->time = ev2->time; 578 ev->x_root = ev2->root_x; 579 ev->y_root = ev2->root_y; 580 ev->x = ev2->event_x; 581 ev->y = ev2->event_y; 582 ev->state = ev2->state; 583 ev->same_screen = ev2->same_screen; 584 ev->deviceid = ev2->deviceid & DEVICE_BITS; 585 if (ev2->deviceid & MORE_EVENTS) 586 return (DONT_ENQUEUE); 587 else { 588 *re = *save; 589 return (ENQUEUE_EVENT); 590 } 591 } 592 break; 593 case XI_DeviceValuator: 594 { 595 deviceValuator *xev = (deviceValuator *) event; 596 int save_type = save->type - info->codes->first_event; 597 int i; 598 599 if (save_type == XI_DeviceKeyPress || save_type == XI_DeviceKeyRelease) { 600 XDeviceKeyEvent *kev = (XDeviceKeyEvent *) save; 601 602 kev->device_state = xev->device_state; 603 kev->axes_count = xev->num_valuators; 604 kev->first_axis = xev->first_valuator; 605 i = xev->num_valuators; 606 if (i > 6) 607 i = 6; 608 switch (i) { 609 case 6: 610 kev->axis_data[5] = xev->valuator5; 611 case 5: 612 kev->axis_data[4] = xev->valuator4; 613 case 4: 614 kev->axis_data[3] = xev->valuator3; 615 case 3: 616 kev->axis_data[2] = xev->valuator2; 617 case 2: 618 kev->axis_data[1] = xev->valuator1; 619 case 1: 620 kev->axis_data[0] = xev->valuator0; 621 } 622 } else if (save_type == XI_DeviceButtonPress || 623 save_type == XI_DeviceButtonRelease) { 624 XDeviceButtonEvent *bev = (XDeviceButtonEvent *) save; 625 626 bev->device_state = xev->device_state; 627 bev->axes_count = xev->num_valuators; 628 bev->first_axis = xev->first_valuator; 629 i = xev->num_valuators; 630 if (i > 6) 631 i = 6; 632 switch (i) { 633 case 6: 634 bev->axis_data[5] = xev->valuator5; 635 case 5: 636 bev->axis_data[4] = xev->valuator4; 637 case 4: 638 bev->axis_data[3] = xev->valuator3; 639 case 3: 640 bev->axis_data[2] = xev->valuator2; 641 case 2: 642 bev->axis_data[1] = xev->valuator1; 643 case 1: 644 bev->axis_data[0] = xev->valuator0; 645 } 646 } else if (save_type == XI_DeviceMotionNotify) { 647 XDeviceMotionEvent *mev = (XDeviceMotionEvent *) save; 648 649 mev->device_state = xev->device_state; 650 mev->axes_count = xev->num_valuators; 651 mev->first_axis = xev->first_valuator; 652 i = xev->num_valuators; 653 if (i > 6) 654 i = 6; 655 switch (i) { 656 case 6: 657 mev->axis_data[5] = xev->valuator5; 658 case 5: 659 mev->axis_data[4] = xev->valuator4; 660 case 4: 661 mev->axis_data[3] = xev->valuator3; 662 case 3: 663 mev->axis_data[2] = xev->valuator2; 664 case 2: 665 mev->axis_data[1] = xev->valuator1; 666 case 1: 667 mev->axis_data[0] = xev->valuator0; 668 } 669 } else if (save_type == XI_ProximityIn || save_type == XI_ProximityOut) { 670 XProximityNotifyEvent *pev = (XProximityNotifyEvent *) save; 671 672 pev->device_state = xev->device_state; 673 pev->axes_count = xev->num_valuators; 674 pev->first_axis = xev->first_valuator; 675 i = xev->num_valuators; 676 if (i > 6) 677 i = 6; 678 switch (i) { 679 case 6: 680 pev->axis_data[5] = xev->valuator5; 681 case 5: 682 pev->axis_data[4] = xev->valuator4; 683 case 4: 684 pev->axis_data[3] = xev->valuator3; 685 case 3: 686 pev->axis_data[2] = xev->valuator2; 687 case 2: 688 pev->axis_data[1] = xev->valuator1; 689 case 1: 690 pev->axis_data[0] = xev->valuator0; 691 } 692 } else if (save_type == XI_DeviceStateNotify) { 693 int j; 694 XDeviceStateNotifyEvent *sev = (XDeviceStateNotifyEvent *) save; 695 XInputClass *any = (XInputClass *) & sev->data[0]; 696 XValuatorStatus *v; 697 698 for (i = 0; i < sev->num_classes; i++) 699 if (any->class != ValuatorClass) 700 any = (XInputClass *) ((char *)any + any->length); 701 v = (XValuatorStatus *) any; 702 i = v->num_valuators; 703 j = xev->num_valuators; 704 if (j > 3) 705 j = 3; 706 switch (j) { 707 case 3: 708 v->valuators[i + 2] = xev->valuator2; 709 case 2: 710 v->valuators[i + 1] = xev->valuator1; 711 case 1: 712 v->valuators[i + 0] = xev->valuator0; 713 } 714 v->num_valuators += j; 715 716 } 717 *re = *save; 718 return (ENQUEUE_EVENT); 719 } 720 break; 721 case XI_DeviceFocusIn: 722 case XI_DeviceFocusOut: 723 { 724 register XDeviceFocusChangeEvent *ev = (XDeviceFocusChangeEvent *) re; 725 deviceFocus *fev = (deviceFocus *) event; 726 727 *ev = *((XDeviceFocusChangeEvent *) save); 728 ev->window = fev->window; 729 ev->time = fev->time; 730 ev->mode = fev->mode; 731 ev->detail = fev->detail; 732 ev->deviceid = fev->deviceid & DEVICE_BITS; 733 return (ENQUEUE_EVENT); 734 } 735 break; 736 case XI_DeviceStateNotify: 737 { 738 int j; 739 XDeviceStateNotifyEvent *stev = (XDeviceStateNotifyEvent *) save; 740 deviceStateNotify *sev = (deviceStateNotify *) event; 741 char *data; 742 743 stev->window = None; 744 stev->deviceid = sev->deviceid & DEVICE_BITS; 745 stev->time = sev->time; 746 stev->num_classes = Ones((Mask) sev->classes_reported & InputClassBits); 747 data = (char *)&stev->data[0]; 748 if (sev->classes_reported & (1 << KeyClass)) { 749 register XKeyStatus *kstev = (XKeyStatus *) data; 750 751 kstev->class = KeyClass; 752 kstev->length = sizeof(XKeyStatus); 753 kstev->num_keys = sev->num_keys; 754 memcpy((char *)&kstev->keys[0], (char *)&sev->keys[0], 4); 755 data += sizeof(XKeyStatus); 756 } 757 if (sev->classes_reported & (1 << ButtonClass)) { 758 register XButtonStatus *bev = (XButtonStatus *) data; 759 760 bev->class = ButtonClass; 761 bev->length = sizeof(XButtonStatus); 762 bev->num_buttons = sev->num_buttons; 763 memcpy((char *)bev->buttons, (char *)sev->buttons, 4); 764 data += sizeof(XButtonStatus); 765 } 766 if (sev->classes_reported & (1 << ValuatorClass)) { 767 register XValuatorStatus *vev = (XValuatorStatus *) data; 768 769 vev->class = ValuatorClass; 770 vev->length = sizeof(XValuatorStatus); 771 vev->num_valuators = sev->num_valuators; 772 vev->mode = sev->classes_reported >> ModeBitsShift; 773 j = sev->num_valuators; 774 if (j > 3) 775 j = 3; 776 switch (j) { 777 case 3: 778 vev->valuators[2] = sev->valuator2; 779 case 2: 780 vev->valuators[1] = sev->valuator1; 781 case 1: 782 vev->valuators[0] = sev->valuator0; 783 } 784 data += sizeof(XValuatorStatus); 785 } 786 if (sev->deviceid & MORE_EVENTS) 787 return (DONT_ENQUEUE); 788 else { 789 *re = *save; 790 return (ENQUEUE_EVENT); 791 } 792 } 793 break; 794 case XI_DeviceKeystateNotify: 795 { 796 int i; 797 XInputClass *anyclass; 798 register XKeyStatus *kv; 799 deviceKeyStateNotify *ksev = (deviceKeyStateNotify *) event; 800 XDeviceStateNotifyEvent *kstev = (XDeviceStateNotifyEvent *) save; 801 802 anyclass = (XInputClass *) & kstev->data[0]; 803 for (i = 0; i < kstev->num_classes; i++) 804 if (anyclass->class == KeyClass) 805 break; 806 else 807 anyclass = (XInputClass *) ((char *)anyclass + 808 anyclass->length); 809 810 kv = (XKeyStatus *) anyclass; 811 kv->num_keys = 256; 812 memcpy((char *)&kv->keys[4], (char *)ksev->keys, 28); 813 if (ksev->deviceid & MORE_EVENTS) 814 return (DONT_ENQUEUE); 815 else { 816 *re = *save; 817 return (ENQUEUE_EVENT); 818 } 819 } 820 break; 821 case XI_DeviceButtonstateNotify: 822 { 823 int i; 824 XInputClass *anyclass; 825 register XButtonStatus *bv; 826 deviceButtonStateNotify *bsev = (deviceButtonStateNotify *) event; 827 XDeviceStateNotifyEvent *bstev = (XDeviceStateNotifyEvent *) save; 828 829 anyclass = (XInputClass *) & bstev->data[0]; 830 for (i = 0; i < bstev->num_classes; i++) 831 if (anyclass->class == ButtonClass) 832 break; 833 else 834 anyclass = (XInputClass *) ((char *)anyclass + 835 anyclass->length); 836 837 bv = (XButtonStatus *) anyclass; 838 bv->num_buttons = 256; 839 memcpy((char *)&bv->buttons[4], (char *)bsev->buttons, 28); 840 if (bsev->deviceid & MORE_EVENTS) 841 return (DONT_ENQUEUE); 842 else { 843 *re = *save; 844 return (ENQUEUE_EVENT); 845 } 846 } 847 break; 848 case XI_DeviceMappingNotify: 849 { 850 register XDeviceMappingEvent *ev = (XDeviceMappingEvent *) re; 851 deviceMappingNotify *ev2 = (deviceMappingNotify *) event; 852 853 *ev = *((XDeviceMappingEvent *) save); 854 ev->window = 0; 855 ev->first_keycode = ev2->firstKeyCode; 856 ev->request = ev2->request; 857 ev->count = ev2->count; 858 ev->time = ev2->time; 859 ev->deviceid = ev2->deviceid & DEVICE_BITS; 860 return (ENQUEUE_EVENT); 861 } 862 break; 863 case XI_ChangeDeviceNotify: 864 { 865 register XChangeDeviceNotifyEvent *ev = (XChangeDeviceNotifyEvent *) re; 866 changeDeviceNotify *ev2 = (changeDeviceNotify *) event; 867 868 *ev = *((XChangeDeviceNotifyEvent *) save); 869 ev->window = 0; 870 ev->request = ev2->request; 871 ev->time = ev2->time; 872 ev->deviceid = ev2->deviceid & DEVICE_BITS; 873 return (ENQUEUE_EVENT); 874 } 875 break; 876 877 case XI_DevicePresenceNotify: 878 { 879 XDevicePresenceNotifyEvent *ev = (XDevicePresenceNotifyEvent *) re; 880 devicePresenceNotify *ev2 = (devicePresenceNotify *) event; 881 882 *ev = *(XDevicePresenceNotifyEvent *) save; 883 ev->window = 0; 884 ev->time = ev2->time; 885 ev->devchange = ev2->devchange; 886 ev->deviceid = ev2->deviceid; 887 ev->control = ev2->control; 888 return (ENQUEUE_EVENT); 889 } 890 break; 891 case XI_DevicePropertyNotify: 892 { 893 XDevicePropertyNotifyEvent* ev = (XDevicePropertyNotifyEvent*)re; 894 devicePropertyNotify *ev2 = (devicePropertyNotify*)event; 895 896 *ev = *(XDevicePropertyNotifyEvent*)save; 897 ev->time = ev2->time; 898 ev->deviceid = ev2->deviceid; 899 ev->atom = ev2->atom; 900 ev->state = ev2->state; 901 return ENQUEUE_EVENT; 902 } 903 break; 904 default: 905 printf("XInputWireToEvent: UNKNOWN WIRE EVENT! type=%d\n", type); 906 break; 907 } 908 } 909 return (DONT_ENQUEUE); 910} 911 912static void xge_copy_to_cookie(xGenericEvent* ev, 913 XGenericEventCookie *cookie) 914{ 915 cookie->type = ev->type; 916 cookie->evtype = ev->evtype; 917 cookie->extension = ev->extension; 918} 919 920static Bool 921XInputWireToCookie( 922 Display *dpy, 923 XGenericEventCookie *cookie, 924 xEvent *event) 925{ 926 XExtDisplayInfo *info = XInput_find_display(dpy); 927 XEvent *save = (XEvent *) info->data; 928 xGenericEvent* ge = (xGenericEvent*)event; 929 930 if (ge->extension != info->codes->major_opcode) 931 { 932 printf("XInputWireToCookie: wrong extension opcode %d\n", 933 ge->extension); 934 return DONT_ENQUEUE; 935 } 936 937 *save = emptyevent; 938 save->type = event->u.u.type; 939 ((XAnyEvent*)save)->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 940 ((XAnyEvent*)save)->send_event = ((event->u.u.type & 0x80) != 0); 941 ((XAnyEvent*)save)->display = dpy; 942 943 xge_copy_to_cookie((xGenericEvent*)event, (XGenericEventCookie*)save); 944 switch(ge->evtype) 945 { 946 case XI_Motion: 947 case XI_ButtonPress: 948 case XI_ButtonRelease: 949 case XI_KeyPress: 950 case XI_KeyRelease: 951 case XI_TouchBegin: 952 case XI_TouchUpdate: 953 case XI_TouchEnd: 954 *cookie = *(XGenericEventCookie*)save; 955 if (!wireToDeviceEvent((xXIDeviceEvent*)event, cookie)) 956 { 957 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 958 ge->evtype); 959 break; 960 } 961 return ENQUEUE_EVENT; 962 case XI_DeviceChanged: 963 *cookie = *(XGenericEventCookie*)save; 964 if (!wireToDeviceChangedEvent((xXIDeviceChangedEvent*)event, cookie)) 965 { 966 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 967 ge->evtype); 968 break; 969 } 970 return ENQUEUE_EVENT; 971 case XI_HierarchyChanged: 972 *cookie = *(XGenericEventCookie*)save; 973 if (!wireToHierarchyChangedEvent((xXIHierarchyEvent*)event, cookie)) 974 { 975 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 976 ge->evtype); 977 break; 978 } 979 return ENQUEUE_EVENT; 980 case XI_TouchOwnership: 981 *cookie = *(XGenericEventCookie*)save; 982 if (!wireToTouchOwnershipEvent((xXITouchOwnershipEvent*)event, 983 cookie)) 984 { 985 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 986 ge->evtype); 987 break; 988 } 989 return ENQUEUE_EVENT; 990 991 case XI_RawKeyPress: 992 case XI_RawKeyRelease: 993 case XI_RawButtonPress: 994 case XI_RawButtonRelease: 995 case XI_RawMotion: 996 case XI_RawTouchBegin: 997 case XI_RawTouchUpdate: 998 case XI_RawTouchEnd: 999 *cookie = *(XGenericEventCookie*)save; 1000 if (!wireToRawEvent(info, (xXIRawEvent*)event, cookie)) 1001 { 1002 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 1003 ge->evtype); 1004 break; 1005 } 1006 return ENQUEUE_EVENT; 1007 case XI_Enter: 1008 case XI_Leave: 1009 case XI_FocusIn: 1010 case XI_FocusOut: 1011 *cookie = *(XGenericEventCookie*)save; 1012 if (!wireToEnterLeave((xXIEnterEvent*)event, cookie)) 1013 { 1014 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 1015 ge->evtype); 1016 break; 1017 } 1018 return ENQUEUE_EVENT; 1019 case XI_PropertyEvent: 1020 *cookie = *(XGenericEventCookie*)save; 1021 if (!wireToPropertyEvent((xXIPropertyEvent*)event, cookie)) 1022 { 1023 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 1024 ge->evtype); 1025 break; 1026 } 1027 return ENQUEUE_EVENT; 1028 case XI_BarrierHit: 1029 case XI_BarrierLeave: 1030 *cookie = *(XGenericEventCookie*)save; 1031 if (!wireToBarrierEvent((xXIBarrierEvent*)event, cookie)) 1032 { 1033 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 1034 ge->evtype); 1035 break; 1036 } 1037 return ENQUEUE_EVENT; 1038 default: 1039 printf("XInputWireToCookie: Unknown generic event. type %d\n", ge->evtype); 1040 1041 } 1042 return DONT_ENQUEUE; 1043} 1044 1045/** 1046 * Calculate length in bytes needed for the device event with the given 1047 * button mask length, valuator mask length + valuator mask. All parameters 1048 * in bytes. 1049 */ 1050static inline int 1051sizeDeviceEvent(int buttons_len, int valuators_len, 1052 unsigned char *valuators_mask) 1053{ 1054 int len; 1055 1056 len = sizeof(XIDeviceEvent); 1057 len += sizeof(XIButtonState) + buttons_len; 1058 len += sizeof(XIValuatorState) + valuators_len; 1059 len += count_bits(valuators_mask, valuators_len) * sizeof(double); 1060 len += sizeof(XIModifierState) + sizeof(XIGroupState); 1061 1062 return len; 1063} 1064 1065/* Return the size with added padding so next element would be 1066 double-aligned unless the architecture is known to allow unaligned 1067 data accesses. Not doing this can cause a bus error on 1068 MIPS N32. */ 1069static int 1070pad_to_double(int size) 1071{ 1072#if !defined(__i386__) && !defined(__sh__) 1073 if (size % sizeof(double) != 0) 1074 size += sizeof(double) - size % sizeof(double); 1075#endif 1076 return size; 1077} 1078 1079/** 1080 * Set structure and atoms to size in bytes of XIButtonClassInfo, its 1081 * button state mask and labels array. 1082 */ 1083static void 1084sizeXIButtonClassType(int num_buttons, int* structure, int* state, int* atoms) 1085{ 1086 int size; 1087 int labels; 1088 1089 *structure = pad_to_double(sizeof(XIButtonClassInfo)); 1090 size = ((((num_buttons + 7)/8) + 3)/4); 1091 1092 /* Force mask alignment with longs to avoid unaligned 1093 * access when accessing the atoms. */ 1094 *state = pad_to_double(size * 4); 1095 labels = num_buttons * sizeof(Atom); 1096 1097 /* Force mask alignment with longs to avoid 1098 * unaligned access when accessing the atoms. */ 1099 labels += ((((num_buttons + 7)/8) + 3)/4) * sizeof(Atom); 1100 *atoms = pad_to_double(labels); 1101} 1102 1103/** 1104 * Set structure and keycodes to size in bytes of XIKeyClassInfo and 1105 * its keycodes array. 1106 */ 1107static void 1108sizeXIKeyClassType(int num_keycodes, int* structure, int* keycodes) 1109{ 1110 *structure = pad_to_double(sizeof(XIKeyClassInfo)); 1111 *keycodes = pad_to_double(num_keycodes * sizeof(int)); 1112} 1113 1114/** 1115 * Return the size in bytes required to store the matching class type 1116 * num_elements is num_buttons for XIButtonClass or num_keycodes for 1117 * XIKeyClass. 1118 * 1119 * Also used from copy_classes in XIQueryDevice.c 1120 */ 1121static int 1122sizeDeviceClassType(int type, int num_elements) 1123{ 1124 int l = 0; 1125 int extra1 = 0; 1126 int extra2 = 0; 1127 switch(type) 1128 { 1129 case XIButtonClass: 1130 sizeXIButtonClassType(num_elements, &l, &extra1, &extra2); 1131 l += extra1 + extra2; 1132 break; 1133 case XIKeyClass: 1134 sizeXIKeyClassType(num_elements, &l, &extra1); 1135 l += extra1; 1136 break; 1137 case XIValuatorClass: 1138 l = pad_to_double(sizeof(XIValuatorClassInfo)); 1139 break; 1140 case XIScrollClass: 1141 l = pad_to_double(sizeof(XIScrollClassInfo)); 1142 break; 1143 case XITouchClass: 1144 l = pad_to_double(sizeof(XITouchClassInfo)); 1145 break; 1146 default: 1147 printf("sizeDeviceClassType: unknown type %d\n", type); 1148 break; 1149 } 1150 return l; 1151} 1152 1153static Bool 1154copyHierarchyEvent(XGenericEventCookie *cookie_in, 1155 XGenericEventCookie *cookie_out) 1156{ 1157 XIHierarchyEvent *in, *out; 1158 void *ptr; 1159 1160 in = cookie_in->data; 1161 1162 ptr = cookie_out->data = malloc(sizeof(XIHierarchyEvent) + 1163 in->num_info * sizeof(XIHierarchyInfo)); 1164 if (!ptr) 1165 return False; 1166 1167 out = next_block(&ptr, sizeof(XIHierarchyEvent)); 1168 *out = *in; 1169 out->info = next_block(&ptr, in->num_info * sizeof(XIHierarchyInfo)); 1170 memcpy(out->info, in->info, in->num_info * sizeof(XIHierarchyInfo)); 1171 1172 return True; 1173} 1174 1175static Bool 1176copyDeviceChangedEvent(XGenericEventCookie *in_cookie, 1177 XGenericEventCookie *out_cookie) 1178{ 1179 int len, i; 1180 XIDeviceChangedEvent *in, *out; 1181 XIAnyClassInfo *any; 1182 void *ptr; 1183 1184 in = in_cookie->data; 1185 1186 len = sizeof(XIDeviceChangedEvent); 1187 len += in->num_classes * sizeof(XIAnyClassInfo*); 1188 1189 for (i = 0; i < in->num_classes; i++) 1190 { 1191 any = in->classes[i]; 1192 switch(any->type) 1193 { 1194 case XIButtonClass: 1195 len += sizeDeviceClassType(XIButtonClass, 1196 ((XIButtonClassInfo*)any)->num_buttons); 1197 break; 1198 case XIKeyClass: 1199 len += sizeDeviceClassType(XIKeyClass, 1200 ((XIKeyClassInfo*)any)->num_keycodes); 1201 break; 1202 case XIValuatorClass: 1203 len += sizeDeviceClassType(XIValuatorClass, 0); 1204 break; 1205 case XIScrollClass: 1206 len += sizeDeviceClassType(XIScrollClass, 0); 1207 break; 1208 default: 1209 printf("copyDeviceChangedEvent: unknown type %d\n", 1210 any->type); 1211 break; 1212 } 1213 1214 } 1215 1216 ptr = out_cookie->data = malloc(len); 1217 if (!ptr) 1218 return False; 1219 out = next_block(&ptr, sizeof(XIDeviceChangedEvent)); 1220 *out = *in; 1221 1222 out->classes = next_block(&ptr, 1223 out->num_classes * sizeof(XIAnyClassInfo*)); 1224 1225 for (i = 0; i < in->num_classes; i++) 1226 { 1227 any = in->classes[i]; 1228 1229 switch(any->type) 1230 { 1231 case XIButtonClass: 1232 { 1233 int struct_size; 1234 int state_size; 1235 int labels_size; 1236 XIButtonClassInfo *bin, *bout; 1237 bin = (XIButtonClassInfo*)any; 1238 sizeXIButtonClassType(bin->num_buttons, &struct_size, 1239 &state_size, &labels_size); 1240 bout = next_block(&ptr, struct_size); 1241 1242 *bout = *bin; 1243 bout->state.mask = next_block(&ptr, state_size); 1244 memcpy(bout->state.mask, bin->state.mask, 1245 bout->state.mask_len); 1246 1247 bout->labels = next_block(&ptr, labels_size); 1248 memcpy(bout->labels, bin->labels, bout->num_buttons * sizeof(Atom)); 1249 out->classes[i] = (XIAnyClassInfo*)bout; 1250 break; 1251 } 1252 case XIKeyClass: 1253 { 1254 XIKeyClassInfo *kin, *kout; 1255 int struct_size; 1256 int keycodes_size; 1257 kin = (XIKeyClassInfo*)any; 1258 sizeXIKeyClassType(kin->num_keycodes, &struct_size, 1259 &keycodes_size); 1260 1261 kout = next_block(&ptr, struct_size); 1262 *kout = *kin; 1263 kout->keycodes = next_block(&ptr, keycodes_size); 1264 memcpy(kout->keycodes, kin->keycodes, kout->num_keycodes * sizeof(int)); 1265 out->classes[i] = (XIAnyClassInfo*)kout; 1266 break; 1267 } 1268 case XIValuatorClass: 1269 { 1270 XIValuatorClassInfo *vin, *vout; 1271 vin = (XIValuatorClassInfo*)any; 1272 vout = next_block(&ptr, 1273 sizeDeviceClassType(XIValuatorClass, 0)); 1274 *vout = *vin; 1275 out->classes[i] = (XIAnyClassInfo*)vout; 1276 break; 1277 } 1278 case XIScrollClass: 1279 { 1280 XIScrollClassInfo *sin, *sout; 1281 sin = (XIScrollClassInfo*)any; 1282 sout = next_block(&ptr, 1283 sizeDeviceClassType(XIScrollClass, 0)); 1284 *sout = *sin; 1285 out->classes[i] = (XIAnyClassInfo*)sout; 1286 break; 1287 } 1288 } 1289 } 1290 1291 return True; 1292} 1293 1294static Bool 1295copyDeviceEvent(XGenericEventCookie *cookie_in, 1296 XGenericEventCookie *cookie_out) 1297{ 1298 int len; 1299 XIDeviceEvent *in, *out; 1300 int bits; /* valuator bits */ 1301 void *ptr; 1302 1303 in = cookie_in->data; 1304 bits = count_bits(in->valuators.mask, in->valuators.mask_len); 1305 1306 len = sizeDeviceEvent(in->buttons.mask_len, in->valuators.mask_len, 1307 in->valuators.mask); 1308 1309 ptr = cookie_out->data = malloc(len); 1310 if (!ptr) 1311 return False; 1312 1313 out = next_block(&ptr, sizeof(XIDeviceEvent)); 1314 *out = *in; 1315 1316 out->buttons.mask = next_block(&ptr, in->buttons.mask_len); 1317 memcpy(out->buttons.mask, in->buttons.mask, 1318 out->buttons.mask_len); 1319 out->valuators.mask = next_block(&ptr, in->valuators.mask_len); 1320 memcpy(out->valuators.mask, in->valuators.mask, 1321 out->valuators.mask_len); 1322 out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1323 memcpy(out->valuators.values, in->valuators.values, 1324 bits * sizeof(double)); 1325 1326 return True; 1327} 1328 1329static Bool 1330copyEnterEvent(XGenericEventCookie *cookie_in, 1331 XGenericEventCookie *cookie_out) 1332{ 1333 int len; 1334 XIEnterEvent *in, *out; 1335 void *ptr; 1336 1337 in = cookie_in->data; 1338 1339 len = sizeof(XIEnterEvent) + in->buttons.mask_len; 1340 1341 ptr = cookie_out->data = malloc(len); 1342 if (!ptr) 1343 return False; 1344 1345 out = next_block(&ptr, sizeof(XIEnterEvent)); 1346 *out = *in; 1347 1348 out->buttons.mask = next_block(&ptr, in->buttons.mask_len); 1349 memcpy(out->buttons.mask, in->buttons.mask, out->buttons.mask_len); 1350 1351 return True; 1352} 1353 1354static Bool 1355copyPropertyEvent(XGenericEventCookie *cookie_in, 1356 XGenericEventCookie *cookie_out) 1357{ 1358 XIPropertyEvent *in, *out; 1359 1360 in = cookie_in->data; 1361 1362 out = cookie_out->data = malloc(sizeof(XIPropertyEvent)); 1363 if (!out) 1364 return False; 1365 1366 *out = *in; 1367 return True; 1368} 1369 1370static Bool 1371copyTouchOwnershipEvent(XGenericEventCookie *cookie_in, 1372 XGenericEventCookie *cookie_out) 1373{ 1374 XITouchOwnershipEvent *in, *out; 1375 1376 in = cookie_in->data; 1377 1378 out = cookie_out->data = malloc(sizeof(XITouchOwnershipEvent)); 1379 if (!out) 1380 return False; 1381 1382 *out = *in; 1383 return True; 1384} 1385 1386static Bool 1387copyRawEvent(XGenericEventCookie *cookie_in, 1388 XGenericEventCookie *cookie_out) 1389{ 1390 XIRawEvent *in, *out; 1391 void *ptr; 1392 int len; 1393 int bits; 1394 1395 in = cookie_in->data; 1396 1397 bits = count_bits(in->valuators.mask, in->valuators.mask_len); 1398 len = sizeof(XIRawEvent) + in->valuators.mask_len; 1399 len += bits * sizeof(double) * 2; 1400 1401 ptr = cookie_out->data = malloc(len); 1402 if (!ptr) 1403 return False; 1404 1405 out = next_block(&ptr, sizeof(XIRawEvent)); 1406 *out = *in; 1407 out->valuators.mask = next_block(&ptr, out->valuators.mask_len); 1408 memcpy(out->valuators.mask, in->valuators.mask, out->valuators.mask_len); 1409 1410 out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1411 memcpy(out->valuators.values, in->valuators.values, bits * sizeof(double)); 1412 1413 out->raw_values = next_block(&ptr, bits * sizeof(double)); 1414 memcpy(out->raw_values, in->raw_values, bits * sizeof(double)); 1415 1416 return True; 1417} 1418 1419static Bool 1420copyBarrierEvent(XGenericEventCookie *in_cookie, 1421 XGenericEventCookie *out_cookie) 1422{ 1423 XIBarrierEvent *in, *out; 1424 1425 in = in_cookie->data; 1426 1427 out = out_cookie->data = calloc(1, sizeof(XIBarrierEvent)); 1428 if (!out) 1429 return False; 1430 *out = *in; 1431 1432 return True; 1433} 1434 1435static Bool 1436XInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 1437{ 1438 int ret = True; 1439 1440 XExtDisplayInfo *info = XInput_find_display(dpy); 1441 1442 if (in->extension != info->codes->major_opcode) 1443 { 1444 printf("XInputCopyCookie: wrong extension opcode %d\n", 1445 in->extension); 1446 return False; 1447 } 1448 1449 *out = *in; 1450 out->data = NULL; 1451 out->cookie = 0; 1452 1453 switch(in->evtype) { 1454 case XI_Motion: 1455 case XI_ButtonPress: 1456 case XI_ButtonRelease: 1457 case XI_KeyPress: 1458 case XI_KeyRelease: 1459 case XI_TouchBegin: 1460 case XI_TouchUpdate: 1461 case XI_TouchEnd: 1462 ret = copyDeviceEvent(in, out); 1463 break; 1464 case XI_DeviceChanged: 1465 ret = copyDeviceChangedEvent(in, out); 1466 break; 1467 case XI_HierarchyChanged: 1468 ret = copyHierarchyEvent(in, out); 1469 break; 1470 case XI_Enter: 1471 case XI_Leave: 1472 case XI_FocusIn: 1473 case XI_FocusOut: 1474 ret = copyEnterEvent(in, out); 1475 break; 1476 case XI_PropertyEvent: 1477 ret = copyPropertyEvent(in, out); 1478 break; 1479 case XI_TouchOwnership: 1480 ret = copyTouchOwnershipEvent(in, out); 1481 break; 1482 case XI_RawKeyPress: 1483 case XI_RawKeyRelease: 1484 case XI_RawButtonPress: 1485 case XI_RawButtonRelease: 1486 case XI_RawMotion: 1487 case XI_RawTouchBegin: 1488 case XI_RawTouchUpdate: 1489 case XI_RawTouchEnd: 1490 ret = copyRawEvent(in, out); 1491 break; 1492 case XI_BarrierHit: 1493 case XI_BarrierLeave: 1494 ret = copyBarrierEvent(in, out); 1495 break; 1496 default: 1497 printf("XInputCopyCookie: unknown evtype %d\n", in->evtype); 1498 ret = False; 1499 } 1500 1501 if (!ret) 1502 printf("XInputCopyCookie: Failed to copy evtype %d", in->evtype); 1503 return ret; 1504} 1505 1506static int 1507wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* cookie) 1508{ 1509 int len, i; 1510 unsigned char *ptr; 1511 void *ptr_lib; 1512 FP3232 *values; 1513 XIDeviceEvent *out; 1514 1515 ptr = (unsigned char*)&in[1] + in->buttons_len * 4; 1516 1517 len = sizeDeviceEvent(in->buttons_len * 4, in->valuators_len * 4, ptr); 1518 1519 cookie->data = ptr_lib = malloc(len); 1520 1521 out = next_block(&ptr_lib, sizeof(XIDeviceEvent)); 1522 out->display = cookie->display; 1523 out->type = in->type; 1524 out->extension = in->extension; 1525 out->evtype = in->evtype; 1526 out->send_event = ((in->type & 0x80) != 0); 1527 out->time = in->time; 1528 out->deviceid = in->deviceid; 1529 out->sourceid = in->sourceid; 1530 out->detail = in->detail; 1531 out->root = in->root; 1532 out->event = in->event; 1533 out->child = in->child; 1534 out->root_x = FP1616toDBL(in->root_x); 1535 out->root_y = FP1616toDBL(in->root_y); 1536 out->event_x = FP1616toDBL(in->event_x); 1537 out->event_y = FP1616toDBL(in->event_y); 1538 out->flags = in->flags; 1539 out->mods.base = in->mods.base_mods; 1540 out->mods.locked = in->mods.locked_mods; 1541 out->mods.latched = in->mods.latched_mods; 1542 out->mods.effective = in->mods.effective_mods; 1543 out->group.base = in->group.base_group; 1544 out->group.locked = in->group.locked_group; 1545 out->group.latched = in->group.latched_group; 1546 out->group.effective = in->group.effective_group; 1547 out->buttons.mask_len = in->buttons_len * 4; 1548 out->valuators.mask_len = in->valuators_len * 4; 1549 1550 out->buttons.mask = next_block(&ptr_lib, out->buttons.mask_len); 1551 1552 /* buttons */ 1553 ptr = (unsigned char*)&in[1]; 1554 memcpy(out->buttons.mask, ptr, out->buttons.mask_len); 1555 ptr += in->buttons_len * 4; 1556 1557 /* valuators */ 1558 out->valuators.mask = next_block(&ptr_lib, out->valuators.mask_len); 1559 memcpy(out->valuators.mask, ptr, out->valuators.mask_len); 1560 ptr += in->valuators_len * 4; 1561 1562 len = count_bits(out->valuators.mask, out->valuators.mask_len); 1563 out->valuators.values = next_block(&ptr_lib, len * sizeof(double)); 1564 1565 values = (FP3232*)ptr; 1566 for (i = 0; i < len; i++, values++) 1567 { 1568 out->valuators.values[i] = values->integral; 1569 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 1570 } 1571 1572 1573 return 1; 1574} 1575 1576_X_HIDDEN int 1577size_classes(xXIAnyInfo* from, int nclasses) 1578{ 1579 int len, i; 1580 xXIAnyInfo *any_wire; 1581 char *ptr_wire; 1582 1583 /* len for to->classes */ 1584 len = pad_to_double(nclasses * sizeof(XIAnyClassInfo*)); 1585 ptr_wire = (char*)from; 1586 for (i = 0; i < nclasses; i++) 1587 { 1588 int l = 0; 1589 any_wire = (xXIAnyInfo*)ptr_wire; 1590 switch(any_wire->type) 1591 { 1592 case XIButtonClass: 1593 l = sizeDeviceClassType(XIButtonClass, 1594 ((xXIButtonInfo*)any_wire)->num_buttons); 1595 break; 1596 case XIKeyClass: 1597 l = sizeDeviceClassType(XIKeyClass, 1598 ((xXIKeyInfo*)any_wire)->num_keycodes); 1599 break; 1600 case XIValuatorClass: 1601 l = sizeDeviceClassType(XIValuatorClass, 0); 1602 break; 1603 case XIScrollClass: 1604 l = sizeDeviceClassType(XIScrollClass, 0); 1605 break; 1606 case XITouchClass: 1607 l = sizeDeviceClassType(XITouchClass, 0); 1608 break; 1609 } 1610 1611 len += l; 1612 ptr_wire += any_wire->length * 4; 1613 } 1614 1615 return len; 1616} 1617 1618/* Copy classes from any into to->classes and return the number of bytes 1619 * copied. Memory layout of to->classes is 1620 * [clsptr][clsptr][clsptr][classinfo][classinfo]... 1621 * |________|___________^ 1622 * |______________________^ 1623 */ 1624_X_HIDDEN int 1625copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) 1626{ 1627 XIAnyClassInfo *any_lib; 1628 xXIAnyInfo *any_wire; 1629 void *ptr_lib; 1630 char *ptr_wire; 1631 int i, len; 1632 int cls_idx = 0; 1633 1634 if (!to->classes) 1635 return -1; 1636 1637 ptr_wire = (char*)from; 1638 ptr_lib = to->classes; 1639 to->classes = next_block(&ptr_lib, 1640 pad_to_double((*nclasses) * sizeof(XIAnyClassInfo*))); 1641 memset(to->classes, 0, (*nclasses) * sizeof(XIAnyClassInfo*)); 1642 len = 0; /* count wire length */ 1643 1644 for (i = 0; i < *nclasses; i++) 1645 { 1646 any_lib = (XIAnyClassInfo*)ptr_lib; 1647 any_wire = (xXIAnyInfo*)ptr_wire; 1648 1649 switch(any_wire->type) 1650 { 1651 case XIButtonClass: 1652 { 1653 XIButtonClassInfo *cls_lib; 1654 xXIButtonInfo *cls_wire; 1655 uint32_t *atoms; 1656 int j; 1657 int struct_size; 1658 int state_size; 1659 int labels_size; 1660 int wire_mask_size; 1661 1662 cls_wire = (xXIButtonInfo*)any_wire; 1663 sizeXIButtonClassType(cls_wire->num_buttons, 1664 &struct_size, &state_size, 1665 &labels_size); 1666 cls_lib = next_block(&ptr_lib, struct_size); 1667 wire_mask_size = ((cls_wire->num_buttons + 7)/8 + 3)/4 * 4; 1668 1669 cls_lib->type = cls_wire->type; 1670 cls_lib->sourceid = cls_wire->sourceid; 1671 cls_lib->num_buttons = cls_wire->num_buttons; 1672 cls_lib->state.mask_len = state_size; 1673 cls_lib->state.mask = next_block(&ptr_lib, state_size); 1674 memcpy(cls_lib->state.mask, &cls_wire[1], 1675 wire_mask_size); 1676 if (state_size != wire_mask_size) 1677 memset(&cls_lib->state.mask[wire_mask_size], 0, 1678 state_size - wire_mask_size); 1679 1680 cls_lib->labels = next_block(&ptr_lib, labels_size); 1681 1682 atoms =(uint32_t*)((char*)&cls_wire[1] + wire_mask_size); 1683 for (j = 0; j < cls_lib->num_buttons; j++) 1684 cls_lib->labels[j] = *atoms++; 1685 1686 to->classes[cls_idx++] = any_lib; 1687 break; 1688 } 1689 case XIKeyClass: 1690 { 1691 XIKeyClassInfo *cls_lib; 1692 xXIKeyInfo *cls_wire; 1693 int struct_size; 1694 int keycodes_size; 1695 1696 cls_wire = (xXIKeyInfo*)any_wire; 1697 sizeXIKeyClassType(cls_wire->num_keycodes, 1698 &struct_size, &keycodes_size); 1699 cls_lib = next_block(&ptr_lib, struct_size); 1700 1701 cls_lib->type = cls_wire->type; 1702 cls_lib->sourceid = cls_wire->sourceid; 1703 cls_lib->num_keycodes = cls_wire->num_keycodes; 1704 cls_lib->keycodes = next_block(&ptr_lib, keycodes_size); 1705 memcpy(cls_lib->keycodes, &cls_wire[1], 1706 cls_lib->num_keycodes); 1707 1708 to->classes[cls_idx++] = any_lib; 1709 break; 1710 } 1711 case XIValuatorClass: 1712 { 1713 XIValuatorClassInfo *cls_lib; 1714 xXIValuatorInfo *cls_wire; 1715 1716 cls_lib = 1717 next_block(&ptr_lib, 1718 sizeDeviceClassType(XIValuatorClass, 0)); 1719 cls_wire = (xXIValuatorInfo*)any_wire; 1720 1721 cls_lib->type = cls_wire->type; 1722 cls_lib->sourceid = cls_wire->sourceid; 1723 cls_lib->number = cls_wire->number; 1724 cls_lib->label = cls_wire->label; 1725 cls_lib->resolution = cls_wire->resolution; 1726 cls_lib->min = cls_wire->min.integral; 1727 cls_lib->max = cls_wire->max.integral; 1728 cls_lib->value = cls_wire->value.integral; 1729 /* FIXME: fractional parts */ 1730 cls_lib->mode = cls_wire->mode; 1731 1732 to->classes[cls_idx++] = any_lib; 1733 } 1734 break; 1735 case XIScrollClass: 1736 { 1737 XIScrollClassInfo *cls_lib; 1738 xXIScrollInfo *cls_wire; 1739 1740 cls_lib = 1741 next_block(&ptr_lib, 1742 sizeDeviceClassType(XIScrollClass, 0)); 1743 cls_wire = (xXIScrollInfo*)any_wire; 1744 1745 cls_lib->type = cls_wire->type; 1746 cls_lib->sourceid = cls_wire->sourceid; 1747 cls_lib->number = cls_wire->number; 1748 cls_lib->scroll_type= cls_wire->scroll_type; 1749 cls_lib->flags = cls_wire->flags; 1750 cls_lib->increment = cls_wire->increment.integral; 1751 cls_lib->increment += (unsigned int)cls_wire->increment.frac/(double)(1ULL << 32); 1752 1753 to->classes[cls_idx++] = any_lib; 1754 } 1755 break; 1756 case XITouchClass: 1757 { 1758 XITouchClassInfo *cls_lib; 1759 xXITouchInfo *cls_wire; 1760 1761 cls_wire = (xXITouchInfo*)any_wire; 1762 cls_lib = next_block(&ptr_lib, sizeof(XITouchClassInfo)); 1763 1764 cls_lib->type = cls_wire->type; 1765 cls_lib->sourceid = cls_wire->sourceid; 1766 cls_lib->mode = cls_wire->mode; 1767 cls_lib->num_touches = cls_wire->num_touches; 1768 1769 to->classes[cls_idx++] = any_lib; 1770 } 1771 break; 1772 } 1773 len += any_wire->length * 4; 1774 ptr_wire += any_wire->length * 4; 1775 } 1776 1777 /* we may have skipped unknown classes, reset nclasses */ 1778 *nclasses = cls_idx; 1779 return len; 1780} 1781 1782 1783static int 1784wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie) 1785{ 1786 XIDeviceChangedEvent *out; 1787 XIDeviceInfo info; 1788 int len; 1789 int nclasses = in->num_classes; 1790 1791 len = size_classes((xXIAnyInfo*)&in[1], in->num_classes); 1792 1793 cookie->data = out = malloc(sizeof(XIDeviceChangedEvent) + len); 1794 1795 out->type = in->type; 1796 out->display = cookie->display; 1797 out->extension = in->extension; 1798 out->evtype = in->evtype; 1799 out->send_event = ((in->type & 0x80) != 0); 1800 out->time = in->time; 1801 out->deviceid = in->deviceid; 1802 out->sourceid = in->sourceid; 1803 out->reason = in->reason; 1804 1805 out->classes = (XIAnyClassInfo**)&out[1]; 1806 1807 info.classes = out->classes; 1808 1809 copy_classes(&info, (xXIAnyInfo*)&in[1], &nclasses); 1810 out->num_classes = nclasses; 1811 1812 return 1; 1813} 1814 1815static int 1816wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie) 1817{ 1818 int i; 1819 XIHierarchyInfo *info_out; 1820 xXIHierarchyInfo *info_in; 1821 XIHierarchyEvent *out; 1822 1823 cookie->data = out = malloc(sizeof(XIHierarchyEvent) + in->num_info * sizeof(XIHierarchyInfo));; 1824 1825 out->info = (XIHierarchyInfo*)&out[1]; 1826 out->display = cookie->display; 1827 out->type = in->type; 1828 out->extension = in->extension; 1829 out->evtype = in->evtype; 1830 out->send_event = ((in->type & 0x80) != 0); 1831 out->time = in->time; 1832 out->flags = in->flags; 1833 out->num_info = in->num_info; 1834 1835 info_out = out->info; 1836 info_in = (xXIHierarchyInfo*)&in[1]; 1837 1838 for (i = 0; i < out->num_info; i++, info_out++, info_in++) 1839 { 1840 info_out->deviceid = info_in->deviceid; 1841 info_out->attachment = info_in->attachment; 1842 info_out->use = info_in->use; 1843 info_out->enabled = info_in->enabled; 1844 info_out->flags = info_in->flags; 1845 } 1846 1847 return 1; 1848} 1849 1850static int 1851wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie) 1852{ 1853 int len, i, bits; 1854 FP3232 *values; 1855 XIRawEvent *out; 1856 void *ptr; 1857 1858 len = sizeof(XIRawEvent) + in->valuators_len * 4; 1859 bits = count_bits((unsigned char*)&in[1], in->valuators_len * 4); 1860 len += bits * sizeof(double) * 2; /* raw + normal */ 1861 1862 cookie->data = ptr = calloc(1, len); 1863 if (!ptr) 1864 return 0; 1865 1866 out = next_block(&ptr, sizeof(XIRawEvent)); 1867 out->type = in->type; 1868 out->display = cookie->display; 1869 out->extension = in->extension; 1870 out->evtype = in->evtype; 1871 out->send_event = ((in->type & 0x80) != 0); 1872 out->time = in->time; 1873 out->detail = in->detail; 1874 out->deviceid = in->deviceid; 1875 out->flags = in->flags; 1876 1877 /* https://bugs.freedesktop.org/show_bug.cgi?id=34240 */ 1878 if (_XiCheckVersion(info, XInput_2_2) >= 0) 1879 out->sourceid = in->sourceid; 1880 else 1881 out->sourceid = 0; 1882 1883 out->valuators.mask_len = in->valuators_len * 4; 1884 out->valuators.mask = next_block(&ptr, out->valuators.mask_len); 1885 memcpy(out->valuators.mask, &in[1], out->valuators.mask_len); 1886 1887 out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1888 out->raw_values = next_block(&ptr, bits * sizeof(double)); 1889 1890 values = (FP3232*)(((char*)&in[1]) + in->valuators_len * 4); 1891 for (i = 0; i < bits; i++) 1892 { 1893 out->valuators.values[i] = values->integral; 1894 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 1895 out->raw_values[i] = (values + bits)->integral; 1896 out->raw_values[i] += ((double)(values + bits)->frac / (1 << 16) / (1 << 16)); 1897 values++; 1898 } 1899 1900 return 1; 1901} 1902 1903/* Memory layout of XIEnterEvents: 1904 [event][modifiers][group][button] 1905 */ 1906static int 1907wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie) 1908{ 1909 int len; 1910 XIEnterEvent *out; 1911 1912 len = sizeof(XIEnterEvent) + in->buttons_len * 4; 1913 1914 cookie->data = out = malloc(len); 1915 out->buttons.mask = (unsigned char*)&out[1]; 1916 1917 out->type = in->type; 1918 out->display = cookie->display; 1919 out->extension = in->extension; 1920 out->evtype = in->evtype; 1921 out->send_event = ((in->type & 0x80) != 0); 1922 out->time = in->time; 1923 out->detail = in->detail; 1924 out->deviceid = in->deviceid; 1925 out->root = in->root; 1926 out->event = in->event; 1927 out->child = in->child; 1928 out->sourceid = in->sourceid; 1929 out->root_x = FP1616toDBL(in->root_x); 1930 out->root_y = FP1616toDBL(in->root_y); 1931 out->event_x = FP1616toDBL(in->event_x); 1932 out->event_y = FP1616toDBL(in->event_y); 1933 out->mode = in->mode; 1934 out->focus = in->focus; 1935 out->same_screen = in->same_screen; 1936 1937 out->mods.base = in->mods.base_mods; 1938 out->mods.locked = in->mods.locked_mods; 1939 out->mods.latched = in->mods.latched_mods; 1940 out->mods.effective = in->mods.effective_mods; 1941 out->group.base = in->group.base_group; 1942 out->group.locked = in->group.locked_group; 1943 out->group.latched = in->group.latched_group; 1944 out->group.effective = in->group.effective_group; 1945 1946 out->buttons.mask_len = in->buttons_len * 4; 1947 memcpy(out->buttons.mask, &in[1], out->buttons.mask_len); 1948 1949 return 1; 1950} 1951 1952static int 1953wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie) 1954{ 1955 XIPropertyEvent *out = malloc(sizeof(XIPropertyEvent)); 1956 1957 cookie->data = out; 1958 1959 out->type = in->type; 1960 out->extension = in->extension; 1961 out->evtype = in->evtype; 1962 out->send_event = ((in->type & 0x80) != 0); 1963 out->time = in->time; 1964 out->property = in->property; 1965 out->what = in->what; 1966 out->deviceid = in->deviceid; 1967 1968 return 1; 1969} 1970 1971static int 1972wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in, 1973 XGenericEventCookie *cookie) 1974{ 1975 XITouchOwnershipEvent *out = malloc(sizeof(XITouchOwnershipEvent)); 1976 1977 cookie->data = out; 1978 1979 out->type = in->type; 1980 out->display = cookie->display; 1981 out->extension = in->extension; 1982 out->evtype = in->evtype; 1983 out->send_event = ((in->type & 0x80) != 0); 1984 out->time = in->time; 1985 out->deviceid = in->deviceid; 1986 out->sourceid = in->sourceid; 1987 out->touchid = in->touchid; 1988 out->root = in->root; 1989 out->event = in->event; 1990 out->child = in->child; 1991 out->flags = in->flags; 1992 1993 return 1; 1994} 1995 1996#define FP3232_TO_DOUBLE(x) ((double) (x).integral + (x).frac / (1ULL << 32)) 1997 1998static int 1999wireToBarrierEvent(xXIBarrierEvent *in, XGenericEventCookie *cookie) 2000{ 2001 XIBarrierEvent *out = malloc(sizeof(XIBarrierEvent)); 2002 2003 cookie->data = out; 2004 2005 out->display = cookie->display; 2006 out->type = in->type; 2007 out->extension = in->extension; 2008 out->evtype = in->evtype; 2009 out->send_event = ((in->type & 0x80) != 0); 2010 out->time = in->time; 2011 out->deviceid = in->deviceid; 2012 out->sourceid = in->sourceid; 2013 out->event = in->event; 2014 out->root = in->root; 2015 out->root_x = FP1616toDBL(in->root_x); 2016 out->root_y = FP1616toDBL(in->root_y); 2017 out->dx = FP3232_TO_DOUBLE (in->dx); 2018 out->dy = FP3232_TO_DOUBLE (in->dy); 2019 out->dtime = in->dtime; 2020 out->flags = in->flags; 2021 out->barrier = in->barrier; 2022 out->eventid = in->eventid; 2023 2024 return 1; 2025} 2026