XExtInt.c revision 37eb1ca1
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->type = in->type; 1351 out->extension = in->extension; 1352 out->evtype = in->evtype; 1353 out->send_event = ((in->type & 0x80) != 0); 1354 out->time = in->time; 1355 out->deviceid = in->deviceid; 1356 out->sourceid = in->sourceid; 1357 out->detail = in->detail; 1358 out->root = in->root; 1359 out->event = in->event; 1360 out->child = in->child; 1361 out->root_x = FP1616toDBL(in->root_x); 1362 out->root_y = FP1616toDBL(in->root_y); 1363 out->event_x = FP1616toDBL(in->event_x); 1364 out->event_y = FP1616toDBL(in->event_y); 1365 out->flags = in->flags; 1366 out->mods.base = in->mods.base_mods; 1367 out->mods.locked = in->mods.locked_mods; 1368 out->mods.latched = in->mods.latched_mods; 1369 out->mods.effective = in->mods.effective_mods; 1370 out->group.base = in->group.base_group; 1371 out->group.locked = in->group.locked_group; 1372 out->group.latched = in->group.latched_group; 1373 out->group.effective = in->group.effective_group; 1374 out->buttons.mask_len = in->buttons_len * 4; 1375 out->valuators.mask_len = in->valuators_len * 4; 1376 1377 out->buttons.mask = next_block(&ptr_lib, out->buttons.mask_len); 1378 1379 /* buttons */ 1380 ptr = (unsigned char*)&in[1]; 1381 memcpy(out->buttons.mask, ptr, out->buttons.mask_len); 1382 ptr += in->buttons_len * 4; 1383 1384 /* valuators */ 1385 out->valuators.mask = next_block(&ptr_lib, out->valuators.mask_len); 1386 memcpy(out->valuators.mask, ptr, out->valuators.mask_len); 1387 ptr += in->valuators_len * 4; 1388 1389 len = count_bits(out->valuators.mask, out->valuators.mask_len); 1390 out->valuators.values = next_block(&ptr_lib, len * sizeof(double)); 1391 1392 values = (FP3232*)ptr; 1393 for (i = 0; i < len; i++, values++) 1394 { 1395 out->valuators.values[i] = values->integral; 1396 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 1397 } 1398 1399 1400 return 1; 1401} 1402 1403_X_HIDDEN int 1404size_classes(xXIAnyInfo* from, int nclasses) 1405{ 1406 int len, i; 1407 xXIAnyInfo *any_wire; 1408 char *ptr_wire; 1409 1410 len = nclasses * sizeof(XIAnyClassInfo*); /* len for to->classes */ 1411 ptr_wire = (char*)from; 1412 for (i = 0; i < nclasses; i++) 1413 { 1414 int l = 0; 1415 any_wire = (xXIAnyInfo*)ptr_wire; 1416 switch(any_wire->type) 1417 { 1418 case XIButtonClass: 1419 l = sizeDeviceClassType(XIButtonClass, 1420 ((xXIButtonInfo*)any_wire)->num_buttons); 1421 break; 1422 case XIKeyClass: 1423 l = sizeDeviceClassType(XIKeyClass, 1424 ((xXIKeyInfo*)any_wire)->num_keycodes); 1425 break; 1426 case XIValuatorClass: 1427 l = sizeDeviceClassType(XIValuatorClass, 0); 1428 break; 1429 } 1430 1431 len += l; 1432 ptr_wire += any_wire->length * 4; 1433 } 1434 1435 return len; 1436} 1437 1438/* Copy classes from any into to->classes and return the number of bytes 1439 * copied. Memory layout of to->classes is 1440 * [clsptr][clsptr][clsptr][classinfo][classinfo]... 1441 * |________|___________^ 1442 * |______________________^ 1443 */ 1444_X_HIDDEN int 1445copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int nclasses) 1446{ 1447 XIAnyClassInfo *any_lib; 1448 xXIAnyInfo *any_wire; 1449 void *ptr_lib; 1450 char *ptr_wire; 1451 int i, len; 1452 1453 if (!to->classes) 1454 return -1; 1455 1456 ptr_wire = (char*)from; 1457 ptr_lib = to->classes; 1458 to->classes = next_block(&ptr_lib, nclasses * sizeof(XIAnyClassInfo*)); 1459 len = 0; /* count wire length */ 1460 1461 for (i = 0; i < nclasses; i++) 1462 { 1463 any_lib = (XIAnyClassInfo*)ptr_lib; 1464 any_wire = (xXIAnyInfo*)ptr_wire; 1465 1466 to->classes[i] = any_lib; 1467 any_lib->type = any_wire->type; 1468 any_lib->sourceid = any_wire->sourceid; 1469 switch(any_wire->type) 1470 { 1471 case XIButtonClass: 1472 { 1473 XIButtonClassInfo *cls_lib; 1474 xXIButtonInfo *cls_wire; 1475 uint32_t *atoms; 1476 int j; 1477 1478 cls_lib = next_block(&ptr_lib, sizeof(XIButtonClassInfo)); 1479 cls_wire = (xXIButtonInfo*)any_wire; 1480 1481 cls_lib->num_buttons = cls_wire->num_buttons; 1482 cls_lib->state.mask_len = ((((cls_wire->num_buttons + 7)/8) + 3)/4) * 4; 1483 cls_lib->state.mask = next_block(&ptr_lib, cls_lib->state.mask_len); 1484 memcpy(cls_lib->state.mask, &cls_wire[1], 1485 cls_lib->state.mask_len); 1486 1487 cls_lib->labels = next_block(&ptr_lib, cls_lib->num_buttons * sizeof(Atom)); 1488 atoms =(uint32_t*)((char*)&cls_wire[1] + cls_lib->state.mask_len); 1489 for (j = 0; j < cls_lib->num_buttons; j++) 1490 cls_lib->labels[j] = *atoms++; 1491 1492 break; 1493 } 1494 case XIKeyClass: 1495 { 1496 XIKeyClassInfo *cls_lib; 1497 xXIKeyInfo *cls_wire; 1498 1499 cls_lib = next_block(&ptr_lib, sizeof(XIKeyClassInfo)); 1500 cls_wire = (xXIKeyInfo*)any_wire; 1501 1502 cls_lib->num_keycodes = cls_wire->num_keycodes; 1503 cls_lib->keycodes = next_block(&ptr_lib, 1504 cls_lib->num_keycodes * sizeof(int)); 1505 memcpy(cls_lib->keycodes, &cls_wire[1], 1506 cls_lib->num_keycodes); 1507 1508 break; 1509 } 1510 case XIValuatorClass: 1511 { 1512 XIValuatorClassInfo *cls_lib; 1513 xXIValuatorInfo *cls_wire; 1514 1515 cls_lib = next_block(&ptr_lib, sizeof(XIValuatorClassInfo)); 1516 cls_wire = (xXIValuatorInfo*)any_wire; 1517 1518 cls_lib->number = cls_wire->number; 1519 cls_lib->label = cls_wire->label; 1520 cls_lib->resolution = cls_wire->resolution; 1521 cls_lib->min = cls_wire->min.integral; 1522 cls_lib->max = cls_wire->max.integral; 1523 cls_lib->value = cls_wire->value.integral; 1524 /* FIXME: fractional parts */ 1525 cls_lib->mode = cls_wire->mode; 1526 1527 } 1528 break; 1529 } 1530 len += any_wire->length * 4; 1531 ptr_wire += any_wire->length * 4; 1532 } 1533 return len; 1534} 1535 1536 1537static int 1538wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie) 1539{ 1540 XIDeviceChangedEvent *out; 1541 XIDeviceInfo info; 1542 int len; 1543 1544 len = size_classes((xXIAnyInfo*)&in[1], in->num_classes); 1545 1546 cookie->data = out = malloc(sizeof(XIDeviceChangedEvent) + len); 1547 1548 out->type = in->type; 1549 out->extension = in->extension; 1550 out->evtype = in->evtype; 1551 out->send_event = ((in->type & 0x80) != 0); 1552 out->time = in->time; 1553 out->deviceid = in->deviceid; 1554 out->sourceid = in->sourceid; 1555 out->reason = in->reason; 1556 out->num_classes = in->num_classes; 1557 1558 out->classes = (XIAnyClassInfo**)&out[1]; 1559 1560 info.classes = out->classes; 1561 1562 copy_classes(&info, (xXIAnyInfo*)&in[1], in->num_classes); 1563 1564 return 1; 1565} 1566 1567static int 1568wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie) 1569{ 1570 int i; 1571 XIHierarchyInfo *info_out; 1572 xXIHierarchyInfo *info_in; 1573 XIHierarchyEvent *out; 1574 1575 cookie->data = out = malloc(sizeof(XIHierarchyEvent) + in->num_info * sizeof(XIHierarchyInfo));; 1576 1577 out->info = (XIHierarchyInfo*)&out[1]; 1578 out->type = in->type; 1579 out->extension = in->extension; 1580 out->evtype = in->evtype; 1581 out->send_event = ((in->type & 0x80) != 0); 1582 out->time = in->time; 1583 out->flags = in->flags; 1584 out->num_info = in->num_info; 1585 1586 info_out = out->info; 1587 info_in = (xXIHierarchyInfo*)&in[1]; 1588 1589 for (i = 0; i < out->num_info; i++, info_out++, info_in++) 1590 { 1591 info_out->deviceid = info_in->deviceid; 1592 info_out->attachment = info_in->attachment; 1593 info_out->use = info_in->use; 1594 info_out->enabled = info_in->enabled; 1595 info_out->flags = info_in->flags; 1596 } 1597 1598 return 1; 1599} 1600 1601static int 1602wireToRawEvent(xXIRawEvent *in, XGenericEventCookie *cookie) 1603{ 1604 int len, i, bits; 1605 FP3232 *values; 1606 XIRawEvent *out; 1607 void *ptr; 1608 1609 1610 len = sizeof(XIRawEvent) + in->valuators_len * 4; 1611 bits = count_bits((unsigned char*)&in[1], in->valuators_len * 4); 1612 len += bits * sizeof(double) * 2; /* raw + normal */ 1613 1614 cookie->data = ptr = calloc(1, len); 1615 if (!ptr) 1616 return 0; 1617 1618 out = next_block(&ptr, sizeof(XIRawEvent)); 1619 out->type = in->type; 1620 out->extension = in->extension; 1621 out->evtype = in->evtype; 1622 out->send_event = ((in->type & 0x80) != 0); 1623 out->time = in->time; 1624 out->detail = in->detail; 1625 out->deviceid = in->deviceid; 1626 out->flags = in->flags; 1627 1628 out->valuators.mask_len = in->valuators_len * 4; 1629 out->valuators.mask = next_block(&ptr, out->valuators.mask_len); 1630 memcpy(out->valuators.mask, &in[1], out->valuators.mask_len); 1631 1632 out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1633 out->raw_values = next_block(&ptr, bits * sizeof(double)); 1634 1635 values = (FP3232*)(((char*)&in[1]) + in->valuators_len * 4); 1636 for (i = 0; i < bits; i++) 1637 { 1638 out->valuators.values[i] = values->integral; 1639 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 1640 out->raw_values[i] = (values + bits)->integral; 1641 out->raw_values[i] += ((double)(values + bits)->frac / (1 << 16) / (1 << 16)); 1642 values++; 1643 } 1644 1645 return 1; 1646} 1647 1648/* Memory layout of XIEnterEvents: 1649 [event][modifiers][group][button] 1650 */ 1651static int 1652wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie) 1653{ 1654 int len; 1655 XIEnterEvent *out; 1656 1657 len = sizeof(XIEnterEvent) + in->buttons_len * 4; 1658 1659 cookie->data = out = malloc(len); 1660 out->buttons.mask = (unsigned char*)&out[1]; 1661 1662 out->type = in->type; 1663 out->extension = in->extension; 1664 out->evtype = in->evtype; 1665 out->send_event = ((in->type & 0x80) != 0); 1666 out->time = in->time; 1667 out->detail = in->detail; 1668 out->deviceid = in->deviceid; 1669 out->root = in->root; 1670 out->event = in->event; 1671 out->child = in->child; 1672 out->sourceid = in->sourceid; 1673 out->root_x = FP1616toDBL(in->root_x); 1674 out->root_y = FP1616toDBL(in->root_y); 1675 out->event_x = FP1616toDBL(in->event_x); 1676 out->event_y = FP1616toDBL(in->event_y); 1677 out->mode = in->mode; 1678 out->focus = in->focus; 1679 out->same_screen = in->same_screen; 1680 1681 out->mods.base = in->mods.base_mods; 1682 out->mods.locked = in->mods.locked_mods; 1683 out->mods.latched = in->mods.latched_mods; 1684 out->mods.effective = in->mods.effective_mods; 1685 out->group.base = in->group.base_group; 1686 out->group.locked = in->group.locked_group; 1687 out->group.latched = in->group.latched_group; 1688 out->group.effective = in->group.effective_group; 1689 1690 out->buttons.mask_len = in->buttons_len * 4; 1691 memcpy(out->buttons.mask, &in[1], out->buttons.mask_len); 1692 1693 return 1; 1694} 1695 1696static int 1697wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie) 1698{ 1699 XIPropertyEvent *out = malloc(sizeof(XIPropertyEvent)); 1700 1701 cookie->data = out; 1702 1703 out->type = in->type; 1704 out->extension = in->extension; 1705 out->evtype = in->evtype; 1706 out->send_event = ((in->type & 0x80) != 0); 1707 out->time = in->time; 1708 out->property = in->property; 1709 out->what = in->what; 1710 out->deviceid = in->deviceid; 1711 1712 return 1; 1713} 1714