1 /************************************************************
3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of Hewlett-Packard not be
34 used in advertising or publicity pertaining to distribution of the
35 software without specific, written prior permission.
37 HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39 HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45 ********************************************************/
47 /***********************************************************************
49 * Input Extension library internal functions.
59 #include <X11/extensions/XI.h>
60 #include <X11/extensions/XI2.h>
61 #include <X11/extensions/XIproto.h>
62 #include <X11/extensions/XI2proto.h>
63 #include <X11/Xlibint.h>
64 #include <X11/extensions/XInput.h>
65 #include <X11/extensions/XInput2.h>
66 #include <X11/extensions/extutil.h>
67 #include <X11/extensions/geproto.h>
68 #include <X11/extensions/ge.h>
69 #include <X11/extensions/Xge.h>
72 #define ENQUEUE_EVENT True
73 #define DONT_ENQUEUE False
74 #define FP1616toDBL(x) ((x) * 1.0 / (1 << 16))
76 int copy_classes(XIDeviceInfo *to, xXIAnyInfo* from, int *nclasses);
77 int size_classes(xXIAnyInfo* from, int nclasses);
79 static XExtensionInfo *xinput_info;
80 static const char *xinput_extension_name = INAME;
82 static int XInputClose(
84 XExtCodes * /* codes */
87 static char *XInputError(
90 XExtCodes * /* codes */,
95 static Bool XInputWireToEvent(
100 static Bool XInputWireToCookie(
101 Display* /* display */,
102 XGenericEventCookie* /* re */,
106 static Bool XInputCopyCookie(
107 Display* /* display */,
108 XGenericEventCookie* /* in */,
109 XGenericEventCookie* /* out */
113 wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* out);
115 wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie);
117 wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie);
119 wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie);
121 wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie);
123 wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie);
125 wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in,
126 XGenericEventCookie *cookie);
128 wireToBarrierEvent(xXIBarrierEvent *in,
129 XGenericEventCookie *cookie);
131 static /* const */ XEvent emptyevent;
133 typedef Status (*core_event_to_wire)(Display*, XEvent*, xEvent*);
135 static /* const */ XExtensionHooks xinput_extension_hooks = {
136 NULL, /* create_gc */
140 NULL, /* create_font */
141 NULL, /* free_font */
142 XInputClose, /* close_display */
143 XInputWireToEvent, /* wire_to_event */
144 (core_event_to_wire)_XiEventToWire, /* event_to_wire */
146 XInputError, /* error_string */
149 static const char *XInputErrorList[] = {
150 "BadDevice, invalid or uninitialized input device", /* BadDevice */
151 "BadEvent, invalid event type", /* BadEvent */
152 "BadMode, invalid mode parameter", /* BadMode */
153 "DeviceBusy, device is busy", /* DeviceBusy */
154 "BadClass, invalid event class", /* BadClass */
157 /* Get the version supported by the server to know which number of
158 * events are support. Otherwise, a wrong number of events may smash
159 * the Xlib-internal event processing vector.
161 * Since the extension hasn't been initialized yet, we need to
162 * manually get the opcode, then the version.
165 _XiFindEventsSupported(Display *dpy)
168 XExtensionVersion *extversion = NULL;
171 if (!XQueryExtension(dpy, INAME, &codes.major_opcode,
172 &codes.first_event, &codes.first_error))
176 extversion = _XiGetExtensionVersionRequest(dpy, INAME, codes.major_opcode);
180 if (!extversion || !extversion->present)
183 if (extversion->major_version >= 2)
184 nevents = IEVENTS; /* number is fixed, XI2 adds GenericEvents only */
185 else if (extversion->major_version <= 0)
187 printf("XInput_find_display: invalid extension version %d.%d\n",
188 extversion->major_version, extversion->minor_version);
193 switch(extversion->minor_version)
195 case XI_Add_DeviceProperties_Minor:
196 nevents = XI_DevicePropertyNotify + 1;
198 case XI_Add_DevicePresenceNotify_Minor:
199 nevents = XI_DevicePresenceNotify + 1;
202 nevents = XI_DeviceButtonstateNotify + 1;
215 XExtDisplayInfo *XInput_find_display (Display *dpy)
217 XExtDisplayInfo *dpyinfo;
218 if (!xinput_info) { if (!(xinput_info = XextCreateExtension())) return NULL; }
219 if (!(dpyinfo = XextFindDisplay (xinput_info, dpy)))
221 int nevents = _XiFindEventsSupported(dpy);
223 dpyinfo = XextAddDisplay (xinput_info, dpy,
224 xinput_extension_name,
225 &xinput_extension_hooks,
227 if (dpyinfo->codes) /* NULL if XI doesn't exist on the server */
229 XESetWireToEventCookie(dpy, dpyinfo->codes->major_opcode, XInputWireToCookie);
230 XESetCopyEventCookie(dpy, dpyinfo->codes->major_opcode, XInputCopyCookie);
236 static XEXT_GENERATE_ERROR_STRING(XInputError, xinput_extension_name,
237 IERRORS, XInputErrorList)
238 /*******************************************************************
240 * Input extension versions.
243 static XExtensionVersion versions[] = { {XI_Absent, 0, 0},
244 {XI_Present, XI_Initial_Release_Major, XI_Initial_Release_Minor},
245 {XI_Present, XI_Add_XDeviceBell_Major, XI_Add_XDeviceBell_Minor},
246 {XI_Present, XI_Add_XSetDeviceValuators_Major,
247 XI_Add_XSetDeviceValuators_Minor},
248 {XI_Present, XI_Add_XChangeDeviceControl_Major,
249 XI_Add_XChangeDeviceControl_Minor},
250 {XI_Present, XI_Add_DevicePresenceNotify_Major,
251 XI_Add_DevicePresenceNotify_Minor},
252 {XI_Present, XI_Add_DeviceProperties_Major,
253 XI_Add_DeviceProperties_Minor},
259 /***********************************************************************
261 * Return errors reported by this extension.
270 XExtDisplayInfo *info = XInput_find_display(dpy);
272 *error = info->codes->first_error + XI_BadDevice;
280 XExtDisplayInfo *info = XInput_find_display(dpy);
282 *error = info->codes->first_error + XI_BadClass;
290 XExtDisplayInfo *info = XInput_find_display(dpy);
292 *error = info->codes->first_error + XI_BadEvent;
300 XExtDisplayInfo *info = XInput_find_display(dpy);
302 *error = info->codes->first_error + XI_BadMode;
310 XExtDisplayInfo *info = XInput_find_display(dpy);
312 *error = info->codes->first_error + XI_DeviceBusy;
315 static int XInputCheckExtension(Display *dpy, XExtDisplayInfo *info)
317 XextCheckExtension (dpy, info, xinput_extension_name, 0);
321 /*****************************************************************
322 * Compare version numbers between info and the built-in version table.
324 * -1 if info's version is less than version_index's version,
325 * 0 if equal (or DontCheck),
326 * 1 if info's version is greater than version_index's version.
327 * Returns -2 on initialization errors which shouldn't happen if you call it
331 _XiCheckVersion(XExtDisplayInfo *info,
334 XExtensionVersion *ext;
336 if (versions[version_index].major_version == Dont_Check)
342 ext = ((XInputData *) info->data)->vers;
346 if (ext->major_version == versions[version_index].major_version &&
347 ext->minor_version == versions[version_index].minor_version)
350 if (ext->major_version < versions[version_index].major_version ||
351 (ext->major_version == versions[version_index].major_version &&
352 ext->minor_version < versions[version_index].minor_version))
358 /***********************************************************************
360 * Check to see if the input extension is installed in the server.
361 * Also check to see if the version is >= the requested version.
367 register Display *dpy,
368 register int version_index,
369 XExtDisplayInfo *info)
371 if (!XInputCheckExtension(dpy, info)) {
376 if (info->data == NULL) {
377 info->data = (XPointer) Xmalloc(sizeof(XInputData));
382 ((XInputData *) info->data)->vers =
383 _XiGetExtensionVersion(dpy, "XInputExtension", info);
386 if (_XiCheckVersion(info, version_index) < 0) {
394 /***********************************************************************
396 * Close display routine.
405 XExtDisplayInfo *info = XInput_find_display(dpy);
407 if (info->data != NULL) {
408 XFree((char *)((XInputData *) info->data)->vers);
409 XFree((char *)info->data);
412 if (!XextRemoveDisplay(xinput_info, dpy))
415 if (xinput_info->ndisplays == 0) {
416 XextDestroyExtension(xinput_info);
428 y = (mask >> 1) & 033333333333;
429 y = mask - y - ((y >> 1) & 033333333333);
430 return (((y + (y >> 3)) & 030707070707) % 077);
433 static int count_bits(unsigned char* ptr, int len)
439 for (i = 0; i < len; i++)
452 _XiGetDevicePresenceNotifyEvent(Display * dpy)
454 XExtDisplayInfo *info = XInput_find_display(dpy);
456 return info->codes->first_event + XI_DevicePresenceNotify;
459 /***********************************************************************
461 * Handle Input extension events.
462 * Reformat a wire event into an XEvent structure of the right type.
472 unsigned int type, reltype;
473 XExtDisplayInfo *info = XInput_find_display(dpy);
474 XEvent *save = (XEvent *) info->data;
476 type = event->u.u.type & 0x7f;
477 reltype = (type - info->codes->first_event);
479 if (type == GenericEvent ||
480 (reltype != XI_DeviceValuator &&
481 reltype != XI_DeviceKeystateNotify &&
482 reltype != XI_DeviceButtonstateNotify)) {
485 ((XAnyEvent *) save)->serial = _XSetLastRequestRead(dpy,
488 ((XAnyEvent *) save)->send_event = ((event->u.u.type & 0x80) != 0);
489 ((XAnyEvent *) save)->display = dpy;
492 /* Process traditional events */
493 if (type != GenericEvent)
496 case XI_DeviceMotionNotify:
498 register XDeviceMotionEvent *ev = (XDeviceMotionEvent *) save;
499 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
501 ev->root = ev2->root;
502 ev->window = ev2->event;
503 ev->subwindow = ev2->child;
504 ev->time = ev2->time;
505 ev->x_root = ev2->root_x;
506 ev->y_root = ev2->root_y;
507 ev->x = ev2->event_x;
508 ev->y = ev2->event_y;
509 ev->state = ev2->state;
510 ev->same_screen = ev2->same_screen;
511 ev->is_hint = ev2->detail;
512 ev->deviceid = ev2->deviceid & DEVICE_BITS;
513 return (DONT_ENQUEUE);
516 case XI_DeviceKeyPress:
517 case XI_DeviceKeyRelease:
519 register XDeviceKeyEvent *ev = (XDeviceKeyEvent *) save;
520 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
522 ev->root = ev2->root;
523 ev->window = ev2->event;
524 ev->subwindow = ev2->child;
525 ev->time = ev2->time;
526 ev->x_root = ev2->root_x;
527 ev->y_root = ev2->root_y;
528 ev->x = ev2->event_x;
529 ev->y = ev2->event_y;
530 ev->state = ev2->state;
531 ev->same_screen = ev2->same_screen;
532 ev->keycode = ev2->detail;
533 ev->deviceid = ev2->deviceid & DEVICE_BITS;
534 if (ev2->deviceid & MORE_EVENTS)
535 return (DONT_ENQUEUE);
538 return (ENQUEUE_EVENT);
542 case XI_DeviceButtonPress:
543 case XI_DeviceButtonRelease:
545 register XDeviceButtonEvent *ev = (XDeviceButtonEvent *) save;
546 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
548 ev->root = ev2->root;
549 ev->window = ev2->event;
550 ev->subwindow = ev2->child;
551 ev->time = ev2->time;
552 ev->x_root = ev2->root_x;
553 ev->y_root = ev2->root_y;
554 ev->x = ev2->event_x;
555 ev->y = ev2->event_y;
556 ev->state = ev2->state;
557 ev->same_screen = ev2->same_screen;
558 ev->button = ev2->detail;
559 ev->deviceid = ev2->deviceid & DEVICE_BITS;
560 if (ev2->deviceid & MORE_EVENTS)
561 return (DONT_ENQUEUE);
564 return (ENQUEUE_EVENT);
569 case XI_ProximityOut:
571 register XProximityNotifyEvent *ev = (XProximityNotifyEvent *) save;
572 deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event;
574 ev->root = ev2->root;
575 ev->window = ev2->event;
576 ev->subwindow = ev2->child;
577 ev->time = ev2->time;
578 ev->x_root = ev2->root_x;
579 ev->y_root = ev2->root_y;
580 ev->x = ev2->event_x;
581 ev->y = ev2->event_y;
582 ev->state = ev2->state;
583 ev->same_screen = ev2->same_screen;
584 ev->deviceid = ev2->deviceid & DEVICE_BITS;
585 if (ev2->deviceid & MORE_EVENTS)
586 return (DONT_ENQUEUE);
589 return (ENQUEUE_EVENT);
593 case XI_DeviceValuator:
595 deviceValuator *xev = (deviceValuator *) event;
596 int save_type = save->type - info->codes->first_event;
599 if (save_type == XI_DeviceKeyPress || save_type == XI_DeviceKeyRelease) {
600 XDeviceKeyEvent *kev = (XDeviceKeyEvent *) save;
602 kev->device_state = xev->device_state;
603 kev->axes_count = xev->num_valuators;
604 kev->first_axis = xev->first_valuator;
605 i = xev->num_valuators;
610 kev->axis_data[5] = xev->valuator5;
612 kev->axis_data[4] = xev->valuator4;
614 kev->axis_data[3] = xev->valuator3;
616 kev->axis_data[2] = xev->valuator2;
618 kev->axis_data[1] = xev->valuator1;
620 kev->axis_data[0] = xev->valuator0;
622 } else if (save_type == XI_DeviceButtonPress ||
623 save_type == XI_DeviceButtonRelease) {
624 XDeviceButtonEvent *bev = (XDeviceButtonEvent *) save;
626 bev->device_state = xev->device_state;
627 bev->axes_count = xev->num_valuators;
628 bev->first_axis = xev->first_valuator;
629 i = xev->num_valuators;
634 bev->axis_data[5] = xev->valuator5;
636 bev->axis_data[4] = xev->valuator4;
638 bev->axis_data[3] = xev->valuator3;
640 bev->axis_data[2] = xev->valuator2;
642 bev->axis_data[1] = xev->valuator1;
644 bev->axis_data[0] = xev->valuator0;
646 } else if (save_type == XI_DeviceMotionNotify) {
647 XDeviceMotionEvent *mev = (XDeviceMotionEvent *) save;
649 mev->device_state = xev->device_state;
650 mev->axes_count = xev->num_valuators;
651 mev->first_axis = xev->first_valuator;
652 i = xev->num_valuators;
657 mev->axis_data[5] = xev->valuator5;
659 mev->axis_data[4] = xev->valuator4;
661 mev->axis_data[3] = xev->valuator3;
663 mev->axis_data[2] = xev->valuator2;
665 mev->axis_data[1] = xev->valuator1;
667 mev->axis_data[0] = xev->valuator0;
669 } else if (save_type == XI_ProximityIn || save_type == XI_ProximityOut) {
670 XProximityNotifyEvent *pev = (XProximityNotifyEvent *) save;
672 pev->device_state = xev->device_state;
673 pev->axes_count = xev->num_valuators;
674 pev->first_axis = xev->first_valuator;
675 i = xev->num_valuators;
680 pev->axis_data[5] = xev->valuator5;
682 pev->axis_data[4] = xev->valuator4;
684 pev->axis_data[3] = xev->valuator3;
686 pev->axis_data[2] = xev->valuator2;
688 pev->axis_data[1] = xev->valuator1;
690 pev->axis_data[0] = xev->valuator0;
692 } else if (save_type == XI_DeviceStateNotify) {
694 XDeviceStateNotifyEvent *sev = (XDeviceStateNotifyEvent *) save;
695 XInputClass *any = (XInputClass *) & sev->data[0];
698 for (i = 0; i < sev->num_classes; i++)
699 if (any->class != ValuatorClass)
700 any = (XInputClass *) ((char *)any + any->length);
701 v = (XValuatorStatus *) any;
702 i = v->num_valuators;
703 j = xev->num_valuators;
708 v->valuators[i + 2] = xev->valuator2;
710 v->valuators[i + 1] = xev->valuator1;
712 v->valuators[i + 0] = xev->valuator0;
714 v->num_valuators += j;
718 return (ENQUEUE_EVENT);
721 case XI_DeviceFocusIn:
722 case XI_DeviceFocusOut:
724 register XDeviceFocusChangeEvent *ev = (XDeviceFocusChangeEvent *) re;
725 deviceFocus *fev = (deviceFocus *) event;
727 *ev = *((XDeviceFocusChangeEvent *) save);
728 ev->window = fev->window;
729 ev->time = fev->time;
730 ev->mode = fev->mode;
731 ev->detail = fev->detail;
732 ev->deviceid = fev->deviceid & DEVICE_BITS;
733 return (ENQUEUE_EVENT);
736 case XI_DeviceStateNotify:
739 XDeviceStateNotifyEvent *stev = (XDeviceStateNotifyEvent *) save;
740 deviceStateNotify *sev = (deviceStateNotify *) event;
744 stev->deviceid = sev->deviceid & DEVICE_BITS;
745 stev->time = sev->time;
746 stev->num_classes = Ones((Mask) sev->classes_reported & InputClassBits);
747 data = (char *)&stev->data[0];
748 if (sev->classes_reported & (1 << KeyClass)) {
749 register XKeyStatus *kstev = (XKeyStatus *) data;
751 kstev->class = KeyClass;
752 kstev->length = sizeof(XKeyStatus);
753 kstev->num_keys = sev->num_keys;
754 memcpy((char *)&kstev->keys[0], (char *)&sev->keys[0], 4);
755 data += sizeof(XKeyStatus);
757 if (sev->classes_reported & (1 << ButtonClass)) {
758 register XButtonStatus *bev = (XButtonStatus *) data;
760 bev->class = ButtonClass;
761 bev->length = sizeof(XButtonStatus);
762 bev->num_buttons = sev->num_buttons;
763 memcpy((char *)bev->buttons, (char *)sev->buttons, 4);
764 data += sizeof(XButtonStatus);
766 if (sev->classes_reported & (1 << ValuatorClass)) {
767 register XValuatorStatus *vev = (XValuatorStatus *) data;
769 vev->class = ValuatorClass;
770 vev->length = sizeof(XValuatorStatus);
771 vev->num_valuators = sev->num_valuators;
772 vev->mode = sev->classes_reported >> ModeBitsShift;
773 j = sev->num_valuators;
778 vev->valuators[2] = sev->valuator2;
780 vev->valuators[1] = sev->valuator1;
782 vev->valuators[0] = sev->valuator0;
784 data += sizeof(XValuatorStatus);
786 if (sev->deviceid & MORE_EVENTS)
787 return (DONT_ENQUEUE);
790 return (ENQUEUE_EVENT);
794 case XI_DeviceKeystateNotify:
797 XInputClass *anyclass;
798 register XKeyStatus *kv;
799 deviceKeyStateNotify *ksev = (deviceKeyStateNotify *) event;
800 XDeviceStateNotifyEvent *kstev = (XDeviceStateNotifyEvent *) save;
802 anyclass = (XInputClass *) & kstev->data[0];
803 for (i = 0; i < kstev->num_classes; i++)
804 if (anyclass->class == KeyClass)
807 anyclass = (XInputClass *) ((char *)anyclass +
810 kv = (XKeyStatus *) anyclass;
812 memcpy((char *)&kv->keys[4], (char *)ksev->keys, 28);
813 if (ksev->deviceid & MORE_EVENTS)
814 return (DONT_ENQUEUE);
817 return (ENQUEUE_EVENT);
821 case XI_DeviceButtonstateNotify:
824 XInputClass *anyclass;
825 register XButtonStatus *bv;
826 deviceButtonStateNotify *bsev = (deviceButtonStateNotify *) event;
827 XDeviceStateNotifyEvent *bstev = (XDeviceStateNotifyEvent *) save;
829 anyclass = (XInputClass *) & bstev->data[0];
830 for (i = 0; i < bstev->num_classes; i++)
831 if (anyclass->class == ButtonClass)
834 anyclass = (XInputClass *) ((char *)anyclass +
837 bv = (XButtonStatus *) anyclass;
838 bv->num_buttons = 256;
839 memcpy((char *)&bv->buttons[4], (char *)bsev->buttons, 28);
840 if (bsev->deviceid & MORE_EVENTS)
841 return (DONT_ENQUEUE);
844 return (ENQUEUE_EVENT);
848 case XI_DeviceMappingNotify:
850 register XDeviceMappingEvent *ev = (XDeviceMappingEvent *) re;
851 deviceMappingNotify *ev2 = (deviceMappingNotify *) event;
853 *ev = *((XDeviceMappingEvent *) save);
855 ev->first_keycode = ev2->firstKeyCode;
856 ev->request = ev2->request;
857 ev->count = ev2->count;
858 ev->time = ev2->time;
859 ev->deviceid = ev2->deviceid & DEVICE_BITS;
860 return (ENQUEUE_EVENT);
863 case XI_ChangeDeviceNotify:
865 register XChangeDeviceNotifyEvent *ev = (XChangeDeviceNotifyEvent *) re;
866 changeDeviceNotify *ev2 = (changeDeviceNotify *) event;
868 *ev = *((XChangeDeviceNotifyEvent *) save);
870 ev->request = ev2->request;
871 ev->time = ev2->time;
872 ev->deviceid = ev2->deviceid & DEVICE_BITS;
873 return (ENQUEUE_EVENT);
877 case XI_DevicePresenceNotify:
879 XDevicePresenceNotifyEvent *ev = (XDevicePresenceNotifyEvent *) re;
880 devicePresenceNotify *ev2 = (devicePresenceNotify *) event;
882 *ev = *(XDevicePresenceNotifyEvent *) save;
884 ev->time = ev2->time;
885 ev->devchange = ev2->devchange;
886 ev->deviceid = ev2->deviceid;
887 ev->control = ev2->control;
888 return (ENQUEUE_EVENT);
891 case XI_DevicePropertyNotify:
893 XDevicePropertyNotifyEvent* ev = (XDevicePropertyNotifyEvent*)re;
894 devicePropertyNotify *ev2 = (devicePropertyNotify*)event;
896 *ev = *(XDevicePropertyNotifyEvent*)save;
897 ev->time = ev2->time;
898 ev->deviceid = ev2->deviceid;
899 ev->atom = ev2->atom;
900 ev->state = ev2->state;
901 return ENQUEUE_EVENT;
905 printf("XInputWireToEvent: UNKNOWN WIRE EVENT! type=%d\n", type);
909 return (DONT_ENQUEUE);
912 static void xge_copy_to_cookie(xGenericEvent* ev,
913 XGenericEventCookie *cookie)
915 cookie->type = ev->type;
916 cookie->evtype = ev->evtype;
917 cookie->extension = ev->extension;
923 XGenericEventCookie *cookie,
926 XExtDisplayInfo *info = XInput_find_display(dpy);
927 XEvent *save = (XEvent *) info->data;
928 xGenericEvent* ge = (xGenericEvent*)event;
930 if (ge->extension != info->codes->major_opcode)
932 printf("XInputWireToCookie: wrong extension opcode %d\n",
938 save->type = event->u.u.type;
939 ((XAnyEvent*)save)->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
940 ((XAnyEvent*)save)->send_event = ((event->u.u.type & 0x80) != 0);
941 ((XAnyEvent*)save)->display = dpy;
943 xge_copy_to_cookie((xGenericEvent*)event, (XGenericEventCookie*)save);
948 case XI_ButtonRelease:
954 *cookie = *(XGenericEventCookie*)save;
955 if (!wireToDeviceEvent((xXIDeviceEvent*)event, cookie))
957 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
961 return ENQUEUE_EVENT;
962 case XI_DeviceChanged:
963 *cookie = *(XGenericEventCookie*)save;
964 if (!wireToDeviceChangedEvent((xXIDeviceChangedEvent*)event, cookie))
966 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
970 return ENQUEUE_EVENT;
971 case XI_HierarchyChanged:
972 *cookie = *(XGenericEventCookie*)save;
973 if (!wireToHierarchyChangedEvent((xXIHierarchyEvent*)event, cookie))
975 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
979 return ENQUEUE_EVENT;
980 case XI_TouchOwnership:
981 *cookie = *(XGenericEventCookie*)save;
982 if (!wireToTouchOwnershipEvent((xXITouchOwnershipEvent*)event,
985 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
989 return ENQUEUE_EVENT;
992 case XI_RawKeyRelease:
993 case XI_RawButtonPress:
994 case XI_RawButtonRelease:
996 case XI_RawTouchBegin:
997 case XI_RawTouchUpdate:
999 *cookie = *(XGenericEventCookie*)save;
1000 if (!wireToRawEvent(info, (xXIRawEvent*)event, cookie))
1002 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1006 return ENQUEUE_EVENT;
1011 *cookie = *(XGenericEventCookie*)save;
1012 if (!wireToEnterLeave((xXIEnterEvent*)event, cookie))
1014 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1018 return ENQUEUE_EVENT;
1019 case XI_PropertyEvent:
1020 *cookie = *(XGenericEventCookie*)save;
1021 if (!wireToPropertyEvent((xXIPropertyEvent*)event, cookie))
1023 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1027 return ENQUEUE_EVENT;
1029 case XI_BarrierLeave:
1030 *cookie = *(XGenericEventCookie*)save;
1031 if (!wireToBarrierEvent((xXIBarrierEvent*)event, cookie))
1033 printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n",
1037 return ENQUEUE_EVENT;
1039 printf("XInputWireToCookie: Unknown generic event. type %d\n", ge->evtype);
1042 return DONT_ENQUEUE;
1046 * Calculate length in bytes needed for the device event with the given
1047 * button mask length, valuator mask length + valuator mask. All parameters
1051 sizeDeviceEvent(int buttons_len, int valuators_len,
1052 unsigned char *valuators_mask)
1056 len = sizeof(XIDeviceEvent);
1057 len += sizeof(XIButtonState) + buttons_len;
1058 len += sizeof(XIValuatorState) + valuators_len;
1059 len += count_bits(valuators_mask, valuators_len) * sizeof(double);
1060 len += sizeof(XIModifierState) + sizeof(XIGroupState);
1065 /* Return the size with added padding so next element would be
1066 double-aligned unless the architecture is known to allow unaligned
1067 data accesses. Not doing this can cause a bus error on
1070 pad_to_double(int size)
1072 #if !defined(__i386__) && !defined(__sh__)
1073 if (size % sizeof(double) != 0)
1074 size += sizeof(double) - size % sizeof(double);
1080 * Set structure and atoms to size in bytes of XIButtonClassInfo, its
1081 * button state mask and labels array.
1084 sizeXIButtonClassType(int num_buttons, int* structure, int* state, int* atoms)
1089 *structure = pad_to_double(sizeof(XIButtonClassInfo));
1090 size = ((((num_buttons + 7)/8) + 3)/4);
1092 /* Force mask alignment with longs to avoid unaligned
1093 * access when accessing the atoms. */
1094 *state = pad_to_double(size * 4);
1095 labels = num_buttons * sizeof(Atom);
1097 /* Force mask alignment with longs to avoid
1098 * unaligned access when accessing the atoms. */
1099 labels += ((((num_buttons + 7)/8) + 3)/4) * sizeof(Atom);
1100 *atoms = pad_to_double(labels);
1104 * Set structure and keycodes to size in bytes of XIKeyClassInfo and
1105 * its keycodes array.
1108 sizeXIKeyClassType(int num_keycodes, int* structure, int* keycodes)
1110 *structure = pad_to_double(sizeof(XIKeyClassInfo));
1111 *keycodes = pad_to_double(num_keycodes * sizeof(int));
1115 * Return the size in bytes required to store the matching class type
1116 * num_elements is num_buttons for XIButtonClass or num_keycodes for
1119 * Also used from copy_classes in XIQueryDevice.c
1122 sizeDeviceClassType(int type, int num_elements)
1130 sizeXIButtonClassType(num_elements, &l, &extra1, &extra2);
1131 l += extra1 + extra2;
1134 sizeXIKeyClassType(num_elements, &l, &extra1);
1137 case XIValuatorClass:
1138 l = pad_to_double(sizeof(XIValuatorClassInfo));
1141 l = pad_to_double(sizeof(XIScrollClassInfo));
1144 l = pad_to_double(sizeof(XITouchClassInfo));
1147 printf("sizeDeviceClassType: unknown type %d\n", type);
1154 copyHierarchyEvent(XGenericEventCookie *cookie_in,
1155 XGenericEventCookie *cookie_out)
1157 XIHierarchyEvent *in, *out;
1160 in = cookie_in->data;
1162 ptr = cookie_out->data = malloc(sizeof(XIHierarchyEvent) +
1163 in->num_info * sizeof(XIHierarchyInfo));
1167 out = next_block(&ptr, sizeof(XIHierarchyEvent));
1169 out->info = next_block(&ptr, in->num_info * sizeof(XIHierarchyInfo));
1170 memcpy(out->info, in->info, in->num_info * sizeof(XIHierarchyInfo));
1176 copyDeviceChangedEvent(XGenericEventCookie *in_cookie,
1177 XGenericEventCookie *out_cookie)
1180 XIDeviceChangedEvent *in, *out;
1181 XIAnyClassInfo *any;
1184 in = in_cookie->data;
1186 len = sizeof(XIDeviceChangedEvent);
1187 len += in->num_classes * sizeof(XIAnyClassInfo*);
1189 for (i = 0; i < in->num_classes; i++)
1191 any = in->classes[i];
1195 len += sizeDeviceClassType(XIButtonClass,
1196 ((XIButtonClassInfo*)any)->num_buttons);
1199 len += sizeDeviceClassType(XIKeyClass,
1200 ((XIKeyClassInfo*)any)->num_keycodes);
1202 case XIValuatorClass:
1203 len += sizeDeviceClassType(XIValuatorClass, 0);
1206 len += sizeDeviceClassType(XIScrollClass, 0);
1209 printf("copyDeviceChangedEvent: unknown type %d\n",
1216 ptr = out_cookie->data = malloc(len);
1219 out = next_block(&ptr, sizeof(XIDeviceChangedEvent));
1222 out->classes = next_block(&ptr,
1223 out->num_classes * sizeof(XIAnyClassInfo*));
1225 for (i = 0; i < in->num_classes; i++)
1227 any = in->classes[i];
1236 XIButtonClassInfo *bin, *bout;
1237 bin = (XIButtonClassInfo*)any;
1238 sizeXIButtonClassType(bin->num_buttons, &struct_size,
1239 &state_size, &labels_size);
1240 bout = next_block(&ptr, struct_size);
1243 bout->state.mask = next_block(&ptr, state_size);
1244 memcpy(bout->state.mask, bin->state.mask,
1245 bout->state.mask_len);
1247 bout->labels = next_block(&ptr, labels_size);
1248 memcpy(bout->labels, bin->labels, bout->num_buttons * sizeof(Atom));
1249 out->classes[i] = (XIAnyClassInfo*)bout;
1254 XIKeyClassInfo *kin, *kout;
1257 kin = (XIKeyClassInfo*)any;
1258 sizeXIKeyClassType(kin->num_keycodes, &struct_size,
1261 kout = next_block(&ptr, struct_size);
1263 kout->keycodes = next_block(&ptr, keycodes_size);
1264 memcpy(kout->keycodes, kin->keycodes, kout->num_keycodes * sizeof(int));
1265 out->classes[i] = (XIAnyClassInfo*)kout;
1268 case XIValuatorClass:
1270 XIValuatorClassInfo *vin, *vout;
1271 vin = (XIValuatorClassInfo*)any;
1272 vout = next_block(&ptr,
1273 sizeDeviceClassType(XIValuatorClass, 0));
1275 out->classes[i] = (XIAnyClassInfo*)vout;
1280 XIScrollClassInfo *sin, *sout;
1281 sin = (XIScrollClassInfo*)any;
1282 sout = next_block(&ptr,
1283 sizeDeviceClassType(XIScrollClass, 0));
1285 out->classes[i] = (XIAnyClassInfo*)sout;
1295 copyDeviceEvent(XGenericEventCookie *cookie_in,
1296 XGenericEventCookie *cookie_out)
1299 XIDeviceEvent *in, *out;
1300 int bits; /* valuator bits */
1303 in = cookie_in->data;
1304 bits = count_bits(in->valuators.mask, in->valuators.mask_len);
1306 len = sizeDeviceEvent(in->buttons.mask_len, in->valuators.mask_len,
1307 in->valuators.mask);
1309 ptr = cookie_out->data = malloc(len);
1313 out = next_block(&ptr, sizeof(XIDeviceEvent));
1316 out->buttons.mask = next_block(&ptr, in->buttons.mask_len);
1317 memcpy(out->buttons.mask, in->buttons.mask,
1318 out->buttons.mask_len);
1319 out->valuators.mask = next_block(&ptr, in->valuators.mask_len);
1320 memcpy(out->valuators.mask, in->valuators.mask,
1321 out->valuators.mask_len);
1322 out->valuators.values = next_block(&ptr, bits * sizeof(double));
1323 memcpy(out->valuators.values, in->valuators.values,
1324 bits * sizeof(double));
1330 copyEnterEvent(XGenericEventCookie *cookie_in,
1331 XGenericEventCookie *cookie_out)
1334 XIEnterEvent *in, *out;
1337 in = cookie_in->data;
1339 len = sizeof(XIEnterEvent) + in->buttons.mask_len;
1341 ptr = cookie_out->data = malloc(len);
1345 out = next_block(&ptr, sizeof(XIEnterEvent));
1348 out->buttons.mask = next_block(&ptr, in->buttons.mask_len);
1349 memcpy(out->buttons.mask, in->buttons.mask, out->buttons.mask_len);
1355 copyPropertyEvent(XGenericEventCookie *cookie_in,
1356 XGenericEventCookie *cookie_out)
1358 XIPropertyEvent *in, *out;
1360 in = cookie_in->data;
1362 out = cookie_out->data = malloc(sizeof(XIPropertyEvent));
1371 copyTouchOwnershipEvent(XGenericEventCookie *cookie_in,
1372 XGenericEventCookie *cookie_out)
1374 XITouchOwnershipEvent *in, *out;
1376 in = cookie_in->data;
1378 out = cookie_out->data = malloc(sizeof(XITouchOwnershipEvent));
1387 copyRawEvent(XGenericEventCookie *cookie_in,
1388 XGenericEventCookie *cookie_out)
1390 XIRawEvent *in, *out;
1395 in = cookie_in->data;
1397 bits = count_bits(in->valuators.mask, in->valuators.mask_len);
1398 len = sizeof(XIRawEvent) + in->valuators.mask_len;
1399 len += bits * sizeof(double) * 2;
1401 ptr = cookie_out->data = malloc(len);
1405 out = next_block(&ptr, sizeof(XIRawEvent));
1407 out->valuators.mask = next_block(&ptr, out->valuators.mask_len);
1408 memcpy(out->valuators.mask, in->valuators.mask, out->valuators.mask_len);
1410 out->valuators.values = next_block(&ptr, bits * sizeof(double));
1411 memcpy(out->valuators.values, in->valuators.values, bits * sizeof(double));
1413 out->raw_values = next_block(&ptr, bits * sizeof(double));
1414 memcpy(out->raw_values, in->raw_values, bits * sizeof(double));
1420 copyBarrierEvent(XGenericEventCookie *in_cookie,
1421 XGenericEventCookie *out_cookie)
1423 XIBarrierEvent *in, *out;
1425 in = in_cookie->data;
1427 out = out_cookie->data = calloc(1, sizeof(XIBarrierEvent));
1436 XInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
1440 XExtDisplayInfo *info = XInput_find_display(dpy);
1442 if (in->extension != info->codes->major_opcode)
1444 printf("XInputCopyCookie: wrong extension opcode %d\n",
1453 switch(in->evtype) {
1455 case XI_ButtonPress:
1456 case XI_ButtonRelease:
1460 case XI_TouchUpdate:
1462 ret = copyDeviceEvent(in, out);
1464 case XI_DeviceChanged:
1465 ret = copyDeviceChangedEvent(in, out);
1467 case XI_HierarchyChanged:
1468 ret = copyHierarchyEvent(in, out);
1474 ret = copyEnterEvent(in, out);
1476 case XI_PropertyEvent:
1477 ret = copyPropertyEvent(in, out);
1479 case XI_TouchOwnership:
1480 ret = copyTouchOwnershipEvent(in, out);
1482 case XI_RawKeyPress:
1483 case XI_RawKeyRelease:
1484 case XI_RawButtonPress:
1485 case XI_RawButtonRelease:
1487 case XI_RawTouchBegin:
1488 case XI_RawTouchUpdate:
1489 case XI_RawTouchEnd:
1490 ret = copyRawEvent(in, out);
1493 case XI_BarrierLeave:
1494 ret = copyBarrierEvent(in, out);
1497 printf("XInputCopyCookie: unknown evtype %d\n", in->evtype);
1502 printf("XInputCopyCookie: Failed to copy evtype %d", in->evtype);
1507 wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* cookie)
1515 ptr = (unsigned char*)&in[1] + in->buttons_len * 4;
1517 len = sizeDeviceEvent(in->buttons_len * 4, in->valuators_len * 4, ptr);
1519 cookie->data = ptr_lib = malloc(len);
1521 out = next_block(&ptr_lib, sizeof(XIDeviceEvent));
1522 out->display = cookie->display;
1523 out->type = in->type;
1524 out->serial = in->sequenceNumber;
1525 out->extension = in->extension;
1526 out->evtype = in->evtype;
1527 out->send_event = ((in->type & 0x80) != 0);
1528 out->time = in->time;
1529 out->deviceid = in->deviceid;
1530 out->sourceid = in->sourceid;
1531 out->detail = in->detail;
1532 out->root = in->root;
1533 out->event = in->event;
1534 out->child = in->child;
1535 out->root_x = FP1616toDBL(in->root_x);
1536 out->root_y = FP1616toDBL(in->root_y);
1537 out->event_x = FP1616toDBL(in->event_x);
1538 out->event_y = FP1616toDBL(in->event_y);
1539 out->flags = in->flags;
1540 out->mods.base = in->mods.base_mods;
1541 out->mods.locked = in->mods.locked_mods;
1542 out->mods.latched = in->mods.latched_mods;
1543 out->mods.effective = in->mods.effective_mods;
1544 out->group.base = in->group.base_group;
1545 out->group.locked = in->group.locked_group;
1546 out->group.latched = in->group.latched_group;
1547 out->group.effective = in->group.effective_group;
1548 out->buttons.mask_len = in->buttons_len * 4;
1549 out->valuators.mask_len = in->valuators_len * 4;
1551 out->buttons.mask = next_block(&ptr_lib, out->buttons.mask_len);
1554 ptr = (unsigned char*)&in[1];
1555 memcpy(out->buttons.mask, ptr, out->buttons.mask_len);
1556 ptr += in->buttons_len * 4;
1559 out->valuators.mask = next_block(&ptr_lib, out->valuators.mask_len);
1560 memcpy(out->valuators.mask, ptr, out->valuators.mask_len);
1561 ptr += in->valuators_len * 4;
1563 len = count_bits(out->valuators.mask, out->valuators.mask_len);
1564 out->valuators.values = next_block(&ptr_lib, len * sizeof(double));
1566 values = (FP3232*)ptr;
1567 for (i = 0; i < len; i++, values++)
1569 out->valuators.values[i] = values->integral;
1570 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16));
1578 size_classes(xXIAnyInfo* from, int nclasses)
1581 xXIAnyInfo *any_wire;
1584 /* len for to->classes */
1585 len = pad_to_double(nclasses * sizeof(XIAnyClassInfo*));
1586 ptr_wire = (char*)from;
1587 for (i = 0; i < nclasses; i++)
1590 any_wire = (xXIAnyInfo*)ptr_wire;
1591 switch(any_wire->type)
1594 l = sizeDeviceClassType(XIButtonClass,
1595 ((xXIButtonInfo*)any_wire)->num_buttons);
1598 l = sizeDeviceClassType(XIKeyClass,
1599 ((xXIKeyInfo*)any_wire)->num_keycodes);
1601 case XIValuatorClass:
1602 l = sizeDeviceClassType(XIValuatorClass, 0);
1605 l = sizeDeviceClassType(XIScrollClass, 0);
1608 l = sizeDeviceClassType(XITouchClass, 0);
1613 ptr_wire += any_wire->length * 4;
1619 /* Copy classes from any into to->classes and return the number of bytes
1620 * copied. Memory layout of to->classes is
1621 * [clsptr][clsptr][clsptr][classinfo][classinfo]...
1622 * |________|___________^
1623 * |______________________^
1626 copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses)
1628 XIAnyClassInfo *any_lib;
1629 xXIAnyInfo *any_wire;
1638 ptr_wire = (char*)from;
1639 ptr_lib = to->classes;
1640 to->classes = next_block(&ptr_lib,
1641 pad_to_double((*nclasses) * sizeof(XIAnyClassInfo*)));
1642 memset(to->classes, 0, (*nclasses) * sizeof(XIAnyClassInfo*));
1643 len = 0; /* count wire length */
1645 for (i = 0; i < *nclasses; i++)
1647 any_lib = (XIAnyClassInfo*)ptr_lib;
1648 any_wire = (xXIAnyInfo*)ptr_wire;
1650 switch(any_wire->type)
1654 XIButtonClassInfo *cls_lib;
1655 xXIButtonInfo *cls_wire;
1663 cls_wire = (xXIButtonInfo*)any_wire;
1664 sizeXIButtonClassType(cls_wire->num_buttons,
1665 &struct_size, &state_size,
1667 cls_lib = next_block(&ptr_lib, struct_size);
1668 wire_mask_size = ((cls_wire->num_buttons + 7)/8 + 3)/4 * 4;
1670 cls_lib->type = cls_wire->type;
1671 cls_lib->sourceid = cls_wire->sourceid;
1672 cls_lib->num_buttons = cls_wire->num_buttons;
1673 cls_lib->state.mask_len = state_size;
1674 cls_lib->state.mask = next_block(&ptr_lib, state_size);
1675 memcpy(cls_lib->state.mask, &cls_wire[1],
1677 if (state_size != wire_mask_size)
1678 memset(&cls_lib->state.mask[wire_mask_size], 0,
1679 state_size - wire_mask_size);
1681 cls_lib->labels = next_block(&ptr_lib, labels_size);
1683 atoms =(uint32_t*)((char*)&cls_wire[1] + wire_mask_size);
1684 for (j = 0; j < cls_lib->num_buttons; j++)
1685 cls_lib->labels[j] = *atoms++;
1687 to->classes[cls_idx++] = any_lib;
1692 XIKeyClassInfo *cls_lib;
1693 xXIKeyInfo *cls_wire;
1697 cls_wire = (xXIKeyInfo*)any_wire;
1698 sizeXIKeyClassType(cls_wire->num_keycodes,
1699 &struct_size, &keycodes_size);
1700 cls_lib = next_block(&ptr_lib, struct_size);
1702 cls_lib->type = cls_wire->type;
1703 cls_lib->sourceid = cls_wire->sourceid;
1704 cls_lib->num_keycodes = cls_wire->num_keycodes;
1705 cls_lib->keycodes = next_block(&ptr_lib, keycodes_size);
1706 memcpy(cls_lib->keycodes, &cls_wire[1],
1707 cls_lib->num_keycodes);
1709 to->classes[cls_idx++] = any_lib;
1712 case XIValuatorClass:
1714 XIValuatorClassInfo *cls_lib;
1715 xXIValuatorInfo *cls_wire;
1718 next_block(&ptr_lib,
1719 sizeDeviceClassType(XIValuatorClass, 0));
1720 cls_wire = (xXIValuatorInfo*)any_wire;
1722 cls_lib->type = cls_wire->type;
1723 cls_lib->sourceid = cls_wire->sourceid;
1724 cls_lib->number = cls_wire->number;
1725 cls_lib->label = cls_wire->label;
1726 cls_lib->resolution = cls_wire->resolution;
1727 cls_lib->min = cls_wire->min.integral;
1728 cls_lib->max = cls_wire->max.integral;
1729 cls_lib->value = cls_wire->value.integral;
1730 /* FIXME: fractional parts */
1731 cls_lib->mode = cls_wire->mode;
1733 to->classes[cls_idx++] = any_lib;
1738 XIScrollClassInfo *cls_lib;
1739 xXIScrollInfo *cls_wire;
1742 next_block(&ptr_lib,
1743 sizeDeviceClassType(XIScrollClass, 0));
1744 cls_wire = (xXIScrollInfo*)any_wire;
1746 cls_lib->type = cls_wire->type;
1747 cls_lib->sourceid = cls_wire->sourceid;
1748 cls_lib->number = cls_wire->number;
1749 cls_lib->scroll_type= cls_wire->scroll_type;
1750 cls_lib->flags = cls_wire->flags;
1751 cls_lib->increment = cls_wire->increment.integral;
1752 cls_lib->increment += (unsigned int)cls_wire->increment.frac/(double)(1ULL << 32);
1754 to->classes[cls_idx++] = any_lib;
1759 XITouchClassInfo *cls_lib;
1760 xXITouchInfo *cls_wire;
1762 cls_wire = (xXITouchInfo*)any_wire;
1763 cls_lib = next_block(&ptr_lib, sizeof(XITouchClassInfo));
1765 cls_lib->type = cls_wire->type;
1766 cls_lib->sourceid = cls_wire->sourceid;
1767 cls_lib->mode = cls_wire->mode;
1768 cls_lib->num_touches = cls_wire->num_touches;
1770 to->classes[cls_idx++] = any_lib;
1774 len += any_wire->length * 4;
1775 ptr_wire += any_wire->length * 4;
1778 /* we may have skipped unknown classes, reset nclasses */
1779 *nclasses = cls_idx;
1785 wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie)
1787 XIDeviceChangedEvent *out;
1790 int nclasses = in->num_classes;
1792 len = size_classes((xXIAnyInfo*)&in[1], in->num_classes);
1794 cookie->data = out = malloc(sizeof(XIDeviceChangedEvent) + len);
1796 out->type = in->type;
1797 out->serial = in->sequenceNumber;
1798 out->display = cookie->display;
1799 out->extension = in->extension;
1800 out->evtype = in->evtype;
1801 out->send_event = ((in->type & 0x80) != 0);
1802 out->time = in->time;
1803 out->deviceid = in->deviceid;
1804 out->sourceid = in->sourceid;
1805 out->reason = in->reason;
1807 out->classes = (XIAnyClassInfo**)&out[1];
1809 info.classes = out->classes;
1811 copy_classes(&info, (xXIAnyInfo*)&in[1], &nclasses);
1812 out->num_classes = nclasses;
1818 wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie)
1821 XIHierarchyInfo *info_out;
1822 xXIHierarchyInfo *info_in;
1823 XIHierarchyEvent *out;
1825 cookie->data = out = malloc(sizeof(XIHierarchyEvent) + in->num_info * sizeof(XIHierarchyInfo));;
1827 out->info = (XIHierarchyInfo*)&out[1];
1828 out->display = cookie->display;
1829 out->type = in->type;
1830 out->serial = in->sequenceNumber;
1831 out->extension = in->extension;
1832 out->evtype = in->evtype;
1833 out->send_event = ((in->type & 0x80) != 0);
1834 out->time = in->time;
1835 out->flags = in->flags;
1836 out->num_info = in->num_info;
1838 info_out = out->info;
1839 info_in = (xXIHierarchyInfo*)&in[1];
1841 for (i = 0; i < out->num_info; i++, info_out++, info_in++)
1843 info_out->deviceid = info_in->deviceid;
1844 info_out->attachment = info_in->attachment;
1845 info_out->use = info_in->use;
1846 info_out->enabled = info_in->enabled;
1847 info_out->flags = info_in->flags;
1854 wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie)
1861 len = sizeof(XIRawEvent) + in->valuators_len * 4;
1862 bits = count_bits((unsigned char*)&in[1], in->valuators_len * 4);
1863 len += bits * sizeof(double) * 2; /* raw + normal */
1865 cookie->data = ptr = calloc(1, len);
1869 out = next_block(&ptr, sizeof(XIRawEvent));
1870 out->type = in->type;
1871 out->serial = in->sequenceNumber;
1872 out->display = cookie->display;
1873 out->extension = in->extension;
1874 out->evtype = in->evtype;
1875 out->send_event = ((in->type & 0x80) != 0);
1876 out->time = in->time;
1877 out->detail = in->detail;
1878 out->deviceid = in->deviceid;
1879 out->flags = in->flags;
1881 /* https://bugs.freedesktop.org/show_bug.cgi?id=34240 */
1882 if (_XiCheckVersion(info, XInput_2_2) >= 0)
1883 out->sourceid = in->sourceid;
1887 out->valuators.mask_len = in->valuators_len * 4;
1888 out->valuators.mask = next_block(&ptr, out->valuators.mask_len);
1889 memcpy(out->valuators.mask, &in[1], out->valuators.mask_len);
1891 out->valuators.values = next_block(&ptr, bits * sizeof(double));
1892 out->raw_values = next_block(&ptr, bits * sizeof(double));
1894 values = (FP3232*)(((char*)&in[1]) + in->valuators_len * 4);
1895 for (i = 0; i < bits; i++)
1897 out->valuators.values[i] = values->integral;
1898 out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16));
1899 out->raw_values[i] = (values + bits)->integral;
1900 out->raw_values[i] += ((double)(values + bits)->frac / (1 << 16) / (1 << 16));
1907 /* Memory layout of XIEnterEvents:
1908 [event][modifiers][group][button]
1911 wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie)
1916 len = sizeof(XIEnterEvent) + in->buttons_len * 4;
1918 cookie->data = out = malloc(len);
1919 out->buttons.mask = (unsigned char*)&out[1];
1921 out->type = in->type;
1922 out->serial = in->sequenceNumber;
1923 out->display = cookie->display;
1924 out->extension = in->extension;
1925 out->evtype = in->evtype;
1926 out->send_event = ((in->type & 0x80) != 0);
1927 out->time = in->time;
1928 out->detail = in->detail;
1929 out->deviceid = in->deviceid;
1930 out->root = in->root;
1931 out->event = in->event;
1932 out->child = in->child;
1933 out->sourceid = in->sourceid;
1934 out->root_x = FP1616toDBL(in->root_x);
1935 out->root_y = FP1616toDBL(in->root_y);
1936 out->event_x = FP1616toDBL(in->event_x);
1937 out->event_y = FP1616toDBL(in->event_y);
1938 out->mode = in->mode;
1939 out->focus = in->focus;
1940 out->same_screen = in->same_screen;
1942 out->mods.base = in->mods.base_mods;
1943 out->mods.locked = in->mods.locked_mods;
1944 out->mods.latched = in->mods.latched_mods;
1945 out->mods.effective = in->mods.effective_mods;
1946 out->group.base = in->group.base_group;
1947 out->group.locked = in->group.locked_group;
1948 out->group.latched = in->group.latched_group;
1949 out->group.effective = in->group.effective_group;
1951 out->buttons.mask_len = in->buttons_len * 4;
1952 memcpy(out->buttons.mask, &in[1], out->buttons.mask_len);
1958 wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie)
1960 XIPropertyEvent *out = malloc(sizeof(XIPropertyEvent));
1964 out->type = in->type;
1965 out->serial = in->sequenceNumber;
1966 out->extension = in->extension;
1967 out->evtype = in->evtype;
1968 out->send_event = ((in->type & 0x80) != 0);
1969 out->time = in->time;
1970 out->property = in->property;
1971 out->what = in->what;
1972 out->deviceid = in->deviceid;
1978 wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in,
1979 XGenericEventCookie *cookie)
1981 XITouchOwnershipEvent *out = malloc(sizeof(XITouchOwnershipEvent));
1985 out->type = in->type;
1986 out->serial = in->sequenceNumber;
1987 out->display = cookie->display;
1988 out->extension = in->extension;
1989 out->evtype = in->evtype;
1990 out->send_event = ((in->type & 0x80) != 0);
1991 out->time = in->time;
1992 out->deviceid = in->deviceid;
1993 out->sourceid = in->sourceid;
1994 out->touchid = in->touchid;
1995 out->root = in->root;
1996 out->event = in->event;
1997 out->child = in->child;
1998 out->flags = in->flags;
2003 #define FP3232_TO_DOUBLE(x) ((double) (x).integral + (x).frac / (1ULL << 32))
2006 wireToBarrierEvent(xXIBarrierEvent *in, XGenericEventCookie *cookie)
2008 XIBarrierEvent *out = malloc(sizeof(XIBarrierEvent));
2012 out->display = cookie->display;
2013 out->type = in->type;
2014 out->serial = in->sequenceNumber;
2015 out->extension = in->extension;
2016 out->evtype = in->evtype;
2017 out->send_event = ((in->type & 0x80) != 0);
2018 out->time = in->time;
2019 out->deviceid = in->deviceid;
2020 out->sourceid = in->sourceid;
2021 out->event = in->event;
2022 out->root = in->root;
2023 out->root_x = FP1616toDBL(in->root_x);
2024 out->root_y = FP1616toDBL(in->root_y);
2025 out->dx = FP3232_TO_DOUBLE (in->dx);
2026 out->dy = FP3232_TO_DOUBLE (in->dy);
2027 out->dtime = in->dtime;
2028 out->flags = in->flags;
2029 out->barrier = in->barrier;
2030 out->eventid = in->eventid;