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