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