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