1/************************************************************
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
26
27			All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Hewlett-Packard not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45********************************************************/
46
47/***********************************************************************
48 *
49 * Input Extension library internal functions.
50 *
51 */
52
53#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
76int copy_classes(XIDeviceInfo *to, xXIAnyInfo* from, int *nclasses);
77int size_classes(xXIAnyInfo* from, int nclasses);
78
79static XExtensionInfo *xinput_info;
80static const char *xinput_extension_name = INAME;
81
82static int XInputClose(
83    Display *		/* dpy */,
84    XExtCodes *		/* codes */
85);
86
87static char *XInputError(
88    Display *		/* dpy */,
89    int			/* code */,
90    XExtCodes *		/* codes */,
91    char *		/* buf */,
92    int			/* n */
93);
94
95static Bool XInputWireToEvent(
96    Display *		/* dpy */,
97    XEvent *		/* re */,
98    xEvent *		/* event */
99);
100static Bool XInputWireToCookie(
101    Display*	        /* display */,
102    XGenericEventCookie*	/* re */,
103    xEvent*	        /* event */
104);
105
106static Bool XInputCopyCookie(
107    Display*	        /* display */,
108    XGenericEventCookie*	/* in */,
109    XGenericEventCookie*	/* out */
110);
111
112static int
113wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* out);
114static int
115wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie);
116static int
117wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie);
118static int
119wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie);
120static int
121wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie);
122static int
123wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie);
124static int
125wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in,
126                          XGenericEventCookie *cookie);
127static int
128wireToBarrierEvent(xXIBarrierEvent *in,
129                   XGenericEventCookie *cookie);
130static int
131wireToPinchEvent(xXIGesturePinchEvent *in,
132                 XGenericEventCookie *cookie);
133static int
134wireToSwipeEvent(xXIGestureSwipeEvent *in,
135                 XGenericEventCookie *cookie);
136
137static /* const */ XEvent emptyevent;
138
139typedef Status (*core_event_to_wire)(Display*, XEvent*, xEvent*);
140
141static /* 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
155static 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*/
170static int
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
213out:
214    if (extversion)
215        XFree(extversion);
216    return nevents;
217}
218
219
220_X_HIDDEN
221XExtDisplayInfo *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 (XextHasExtension(dpyinfo)) /* skip 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
242static XEXT_GENERATE_ERROR_STRING(XInputError, xinput_extension_name,
243                                  IERRORS, XInputErrorList)
244/*******************************************************************
245*
246* Input extension versions.
247*
248*/
249static 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
273void
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
283void
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
293void
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
303void
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
313void
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
323static 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
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
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
408static int
409XInputClose(
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
431static int
432Ones(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
441static 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
459int
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
474static Bool
475XInputWireToEvent(
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
920static 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
928static Bool
929XInputWireToCookie(
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 */
1080static inline int
1081sizeDeviceEvent(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. */
1099static int
1100pad_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 */
1113static void
1114sizeXIButtonClassType(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 */
1137static void
1138sizeXIKeyClassType(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 */
1151static int
1152sizeDeviceClassType(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
1186static Bool
1187copyHierarchyEvent(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
1208static Bool
1209copyDeviceChangedEvent(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
1327static Bool
1328copyDeviceEvent(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
1362static Bool
1363copyEnterEvent(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
1387static Bool
1388copyPropertyEvent(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
1403static Bool
1404copyTouchOwnershipEvent(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
1419static Bool
1420copyRawEvent(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 = pad_to_double(sizeof(XIRawEvent))
1432        + pad_to_double(in->valuators.mask_len);
1433    len += bits * sizeof(double) * 2;
1434
1435    ptr = cookie_out->data = malloc(len);
1436    if (!ptr)
1437        return False;
1438
1439    out = next_block(&ptr, pad_to_double(sizeof(XIRawEvent)));
1440    *out = *in;
1441    out->valuators.mask
1442        = next_block(&ptr, pad_to_double(out->valuators.mask_len));
1443    memcpy(out->valuators.mask, in->valuators.mask, out->valuators.mask_len);
1444
1445    out->valuators.values = next_block(&ptr, bits * sizeof(double));
1446    memcpy(out->valuators.values, in->valuators.values, bits * sizeof(double));
1447
1448    out->raw_values = next_block(&ptr, bits * sizeof(double));
1449    memcpy(out->raw_values, in->raw_values, bits * sizeof(double));
1450
1451    return True;
1452}
1453
1454static Bool
1455copyBarrierEvent(XGenericEventCookie *in_cookie,
1456                 XGenericEventCookie *out_cookie)
1457{
1458    XIBarrierEvent *in, *out;
1459
1460    in = in_cookie->data;
1461
1462    out = out_cookie->data = calloc(1, sizeof(XIBarrierEvent));
1463    if (!out)
1464        return False;
1465    *out = *in;
1466
1467    return True;
1468}
1469
1470
1471static Bool
1472copyGesturePinchEvent(XGenericEventCookie *cookie_in,
1473                      XGenericEventCookie *cookie_out)
1474{
1475    XIGesturePinchEvent *in, *out;
1476
1477    in = cookie_in->data;
1478
1479    out = cookie_out->data = malloc(sizeof(XIGesturePinchEvent));
1480    if (!out)
1481        return False;
1482
1483    *out = *in;
1484
1485    return True;
1486}
1487
1488static Bool
1489copyGestureSwipeEvent(XGenericEventCookie *cookie_in,
1490                      XGenericEventCookie *cookie_out)
1491{
1492    XIGestureSwipeEvent *in, *out;
1493
1494    in = cookie_in->data;
1495
1496    out = cookie_out->data = malloc(sizeof(XIGestureSwipeEvent));
1497    if (!out)
1498        return False;
1499
1500    *out = *in;
1501
1502    return True;
1503}
1504
1505static Bool
1506XInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
1507{
1508    int ret = True;
1509
1510    XExtDisplayInfo *info = XInput_find_display(dpy);
1511
1512    if (in->extension != info->codes->major_opcode)
1513    {
1514        printf("XInputCopyCookie: wrong extension opcode %d\n",
1515                in->extension);
1516        return False;
1517    }
1518
1519    *out = *in;
1520    out->data = NULL;
1521    out->cookie = 0;
1522
1523    switch(in->evtype) {
1524        case XI_Motion:
1525        case XI_ButtonPress:
1526        case XI_ButtonRelease:
1527        case XI_KeyPress:
1528        case XI_KeyRelease:
1529        case XI_TouchBegin:
1530        case XI_TouchUpdate:
1531        case XI_TouchEnd:
1532            ret = copyDeviceEvent(in, out);
1533            break;
1534        case XI_DeviceChanged:
1535            ret = copyDeviceChangedEvent(in, out);
1536            break;
1537        case XI_HierarchyChanged:
1538            ret = copyHierarchyEvent(in, out);
1539            break;
1540        case XI_Enter:
1541        case XI_Leave:
1542        case XI_FocusIn:
1543        case XI_FocusOut:
1544            ret = copyEnterEvent(in, out);
1545            break;
1546        case XI_PropertyEvent:
1547            ret = copyPropertyEvent(in, out);
1548            break;
1549        case XI_TouchOwnership:
1550            ret = copyTouchOwnershipEvent(in, out);
1551            break;
1552        case XI_RawKeyPress:
1553        case XI_RawKeyRelease:
1554        case XI_RawButtonPress:
1555        case XI_RawButtonRelease:
1556        case XI_RawMotion:
1557        case XI_RawTouchBegin:
1558        case XI_RawTouchUpdate:
1559        case XI_RawTouchEnd:
1560            ret = copyRawEvent(in, out);
1561            break;
1562        case XI_BarrierHit:
1563        case XI_BarrierLeave:
1564            ret = copyBarrierEvent(in, out);
1565            break;
1566        case XI_GesturePinchBegin:
1567        case XI_GesturePinchUpdate:
1568        case XI_GesturePinchEnd:
1569            ret = copyGesturePinchEvent(in, out);
1570            break;
1571        case XI_GestureSwipeBegin:
1572        case XI_GestureSwipeUpdate:
1573        case XI_GestureSwipeEnd:
1574            ret = copyGestureSwipeEvent(in, out);
1575            break;
1576        default:
1577            printf("XInputCopyCookie: unknown evtype %d\n", in->evtype);
1578            ret = False;
1579    }
1580
1581    if (!ret)
1582        printf("XInputCopyCookie: Failed to copy evtype %d", in->evtype);
1583    return ret;
1584}
1585
1586static int
1587wireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* cookie)
1588{
1589    int len, i;
1590    unsigned char *ptr;
1591    void *ptr_lib;
1592    FP3232 *values;
1593    XIDeviceEvent *out;
1594
1595    ptr = (unsigned char*)&in[1] + in->buttons_len * 4;
1596
1597    len = sizeDeviceEvent(in->buttons_len * 4, in->valuators_len * 4, ptr);
1598
1599    cookie->data = ptr_lib = malloc(len);
1600    if (!ptr_lib)
1601        return 0;
1602
1603    out = next_block(&ptr_lib, sizeof(XIDeviceEvent));
1604    out->display = cookie->display;
1605    out->type = in->type;
1606    out->serial = cookie->serial;
1607    out->extension = in->extension;
1608    out->evtype = in->evtype;
1609    out->send_event = ((in->type & 0x80) != 0);
1610    out->time = in->time;
1611    out->deviceid = in->deviceid;
1612    out->sourceid = in->sourceid;
1613    out->detail = in->detail;
1614    out->root = in->root;
1615    out->event = in->event;
1616    out->child = in->child;
1617    out->root_x = FP1616toDBL(in->root_x);
1618    out->root_y = FP1616toDBL(in->root_y);
1619    out->event_x = FP1616toDBL(in->event_x);
1620    out->event_y = FP1616toDBL(in->event_y);
1621    out->flags = in->flags;
1622    out->mods.base = in->mods.base_mods;
1623    out->mods.locked = in->mods.locked_mods;
1624    out->mods.latched = in->mods.latched_mods;
1625    out->mods.effective = in->mods.effective_mods;
1626    out->group.base = in->group.base_group;
1627    out->group.locked = in->group.locked_group;
1628    out->group.latched = in->group.latched_group;
1629    out->group.effective = in->group.effective_group;
1630    out->buttons.mask_len = in->buttons_len * 4;
1631    out->valuators.mask_len = in->valuators_len * 4;
1632
1633    out->buttons.mask = next_block(&ptr_lib, out->buttons.mask_len);
1634
1635    /* buttons */
1636    ptr = (unsigned char*)&in[1];
1637    memcpy(out->buttons.mask, ptr, out->buttons.mask_len);
1638    ptr += in->buttons_len * 4;
1639
1640    /* valuators */
1641    out->valuators.mask = next_block(&ptr_lib, out->valuators.mask_len);
1642    memcpy(out->valuators.mask, ptr, out->valuators.mask_len);
1643    ptr += in->valuators_len * 4;
1644
1645    len = count_bits(out->valuators.mask, out->valuators.mask_len);
1646    out->valuators.values = next_block(&ptr_lib, len * sizeof(double));
1647
1648    values = (FP3232*)ptr;
1649    for (i = 0; i < len; i++, values++)
1650    {
1651        out->valuators.values[i] = values->integral;
1652        out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16));
1653    }
1654
1655
1656    return 1;
1657}
1658
1659_X_HIDDEN int
1660size_classes(xXIAnyInfo* from, int nclasses)
1661{
1662    int len, i;
1663    xXIAnyInfo *any_wire;
1664    char *ptr_wire;
1665
1666    /* len for to->classes */
1667    len = pad_to_double(nclasses * sizeof(XIAnyClassInfo*));
1668    ptr_wire = (char*)from;
1669    for (i = 0; i < nclasses; i++)
1670    {
1671        int l = 0;
1672        any_wire = (xXIAnyInfo*)ptr_wire;
1673        switch(any_wire->type)
1674        {
1675            case XIButtonClass:
1676                l = sizeDeviceClassType(XIButtonClass,
1677                        ((xXIButtonInfo*)any_wire)->num_buttons);
1678                break;
1679            case XIKeyClass:
1680                l = sizeDeviceClassType(XIKeyClass,
1681                        ((xXIKeyInfo*)any_wire)->num_keycodes);
1682                break;
1683            case XIValuatorClass:
1684                l = sizeDeviceClassType(XIValuatorClass, 0);
1685                break;
1686            case XIScrollClass:
1687                l = sizeDeviceClassType(XIScrollClass, 0);
1688                break;
1689            case XITouchClass:
1690                l = sizeDeviceClassType(XITouchClass, 0);
1691                break;
1692            case XIGestureClass:
1693                l = sizeDeviceClassType(XIGestureClass, 0);
1694                break;
1695        }
1696
1697        len += l;
1698        ptr_wire += any_wire->length * 4;
1699    }
1700
1701    return len;
1702}
1703
1704#define FP3232_TO_DOUBLE(x) ((double) (x).integral + (double) (x).frac / (1ULL << 32))
1705
1706/* Copy classes from any into to->classes and return the number of bytes
1707 * copied. Memory layout of to->classes is
1708 * [clsptr][clsptr][clsptr][classinfo][classinfo]...
1709 *    |________|___________^
1710 *             |______________________^
1711 */
1712_X_HIDDEN int
1713copy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses)
1714{
1715    XIAnyClassInfo *any_lib;
1716    xXIAnyInfo *any_wire;
1717    void *ptr_lib;
1718    char *ptr_wire;
1719    int i, len;
1720    int cls_idx = 0;
1721
1722    if (!to->classes)
1723        return -1;
1724
1725    ptr_wire = (char*)from;
1726    ptr_lib = to->classes;
1727    to->classes = next_block(&ptr_lib,
1728                             pad_to_double((*nclasses) * sizeof(XIAnyClassInfo*)));
1729    memset(to->classes, 0, (*nclasses) * sizeof(XIAnyClassInfo*));
1730    len = 0; /* count wire length */
1731
1732    for (i = 0; i < *nclasses; i++)
1733    {
1734        any_lib = (XIAnyClassInfo*)ptr_lib;
1735        any_wire = (xXIAnyInfo*)ptr_wire;
1736
1737        switch(any_wire->type)
1738        {
1739            case XIButtonClass:
1740                {
1741                    XIButtonClassInfo *cls_lib;
1742                    xXIButtonInfo *cls_wire;
1743                    uint32_t *atoms;
1744                    int j;
1745                    int struct_size;
1746                    int state_size;
1747                    int labels_size;
1748                    int wire_mask_size;
1749
1750                    cls_wire = (xXIButtonInfo*)any_wire;
1751                    sizeXIButtonClassType(cls_wire->num_buttons,
1752                                          &struct_size, &state_size,
1753                                          &labels_size);
1754                    cls_lib = next_block(&ptr_lib, struct_size);
1755                    wire_mask_size = ((cls_wire->num_buttons + 7)/8 + 3)/4 * 4;
1756
1757                    cls_lib->type = cls_wire->type;
1758                    cls_lib->sourceid = cls_wire->sourceid;
1759                    cls_lib->num_buttons = cls_wire->num_buttons;
1760                    cls_lib->state.mask_len = state_size;
1761                    cls_lib->state.mask = next_block(&ptr_lib, state_size);
1762                    memcpy(cls_lib->state.mask, &cls_wire[1],
1763                           wire_mask_size);
1764                    if (state_size != wire_mask_size)
1765                        memset(&cls_lib->state.mask[wire_mask_size], 0,
1766                               state_size - wire_mask_size);
1767
1768                    cls_lib->labels = next_block(&ptr_lib, labels_size);
1769
1770                    atoms =(uint32_t*)((char*)&cls_wire[1] + wire_mask_size);
1771                    for (j = 0; j < cls_lib->num_buttons; j++)
1772                        cls_lib->labels[j] = *atoms++;
1773
1774                    to->classes[cls_idx++] = any_lib;
1775                    break;
1776                }
1777            case XIKeyClass:
1778                {
1779                    XIKeyClassInfo *cls_lib;
1780                    xXIKeyInfo *cls_wire;
1781                    int struct_size;
1782                    int keycodes_size;
1783
1784                    cls_wire = (xXIKeyInfo*)any_wire;
1785                    sizeXIKeyClassType(cls_wire->num_keycodes,
1786                                       &struct_size, &keycodes_size);
1787                    cls_lib = next_block(&ptr_lib, struct_size);
1788
1789                    cls_lib->type = cls_wire->type;
1790                    cls_lib->sourceid = cls_wire->sourceid;
1791                    cls_lib->num_keycodes = cls_wire->num_keycodes;
1792                    cls_lib->keycodes = next_block(&ptr_lib, keycodes_size);
1793                    memcpy(cls_lib->keycodes, &cls_wire[1],
1794                            cls_lib->num_keycodes);
1795
1796                    to->classes[cls_idx++] = any_lib;
1797                    break;
1798                }
1799            case XIValuatorClass:
1800                {
1801                    XIValuatorClassInfo *cls_lib;
1802                    xXIValuatorInfo *cls_wire;
1803
1804                    cls_lib =
1805                      next_block(&ptr_lib,
1806                                 sizeDeviceClassType(XIValuatorClass, 0));
1807                    cls_wire = (xXIValuatorInfo*)any_wire;
1808
1809                    cls_lib->type = cls_wire->type;
1810                    cls_lib->sourceid = cls_wire->sourceid;
1811                    cls_lib->number = cls_wire->number;
1812                    cls_lib->label  = cls_wire->label;
1813                    cls_lib->resolution = cls_wire->resolution;
1814                    cls_lib->min        = FP3232_TO_DOUBLE(cls_wire->min);
1815                    cls_lib->max        = FP3232_TO_DOUBLE(cls_wire->max);
1816                    cls_lib->value      = FP3232_TO_DOUBLE(cls_wire->value);
1817                    cls_lib->mode       = cls_wire->mode;
1818
1819                    to->classes[cls_idx++] = any_lib;
1820                }
1821                break;
1822            case XIScrollClass:
1823                {
1824                    XIScrollClassInfo *cls_lib;
1825                    xXIScrollInfo *cls_wire;
1826
1827                    cls_lib =
1828                      next_block(&ptr_lib,
1829                                 sizeDeviceClassType(XIScrollClass, 0));
1830                    cls_wire = (xXIScrollInfo*)any_wire;
1831
1832                    cls_lib->type = cls_wire->type;
1833                    cls_lib->sourceid = cls_wire->sourceid;
1834                    cls_lib->number     = cls_wire->number;
1835                    cls_lib->scroll_type= cls_wire->scroll_type;
1836                    cls_lib->flags      = cls_wire->flags;
1837                    cls_lib->increment  = FP3232_TO_DOUBLE(cls_wire->increment);
1838
1839                    to->classes[cls_idx++] = any_lib;
1840                }
1841                break;
1842            case XITouchClass:
1843                {
1844                    XITouchClassInfo *cls_lib;
1845                    xXITouchInfo *cls_wire;
1846
1847                    cls_wire = (xXITouchInfo*)any_wire;
1848                    cls_lib = next_block(&ptr_lib, sizeof(XITouchClassInfo));
1849
1850                    cls_lib->type = cls_wire->type;
1851                    cls_lib->sourceid = cls_wire->sourceid;
1852                    cls_lib->mode = cls_wire->mode;
1853                    cls_lib->num_touches = cls_wire->num_touches;
1854
1855                    to->classes[cls_idx++] = any_lib;
1856                }
1857                break;
1858            case XIGestureClass:
1859                {
1860                    XIGestureClassInfo *cls_lib;
1861                    xXIGestureInfo *cls_wire;
1862
1863                    cls_wire = (xXIGestureInfo*)any_wire;
1864                    cls_lib = next_block(&ptr_lib, sizeof(XIGestureClassInfo));
1865
1866                    cls_lib->type = cls_wire->type;
1867                    cls_lib->sourceid = cls_wire->sourceid;
1868                    cls_lib->num_touches = cls_wire->num_touches;
1869
1870                    to->classes[cls_idx++] = any_lib;
1871                }
1872                break;
1873        }
1874        len += any_wire->length * 4;
1875        ptr_wire += any_wire->length * 4;
1876    }
1877
1878    /* we may have skipped unknown classes, reset nclasses */
1879    *nclasses = cls_idx;
1880    return len;
1881}
1882
1883
1884static int
1885wireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie)
1886{
1887    XIDeviceChangedEvent *out;
1888    XIDeviceInfo info;
1889    int len;
1890    int nclasses = in->num_classes;
1891
1892    len = size_classes((xXIAnyInfo*)&in[1], in->num_classes);
1893
1894    cookie->data = out = malloc(sizeof(XIDeviceChangedEvent) + len);
1895    if (!out)
1896        return 0;
1897
1898    out->type = in->type;
1899    out->serial = cookie->serial;
1900    out->display = cookie->display;
1901    out->extension = in->extension;
1902    out->evtype = in->evtype;
1903    out->send_event = ((in->type & 0x80) != 0);
1904    out->time = in->time;
1905    out->deviceid = in->deviceid;
1906    out->sourceid = in->sourceid;
1907    out->reason = in->reason;
1908
1909    out->classes = (XIAnyClassInfo**)&out[1];
1910
1911    info.classes = out->classes;
1912
1913    copy_classes(&info, (xXIAnyInfo*)&in[1], &nclasses);
1914    out->num_classes = nclasses;
1915
1916    return 1;
1917}
1918
1919static int
1920wireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie)
1921{
1922    int i;
1923    XIHierarchyInfo *info_out;
1924    xXIHierarchyInfo *info_in;
1925    XIHierarchyEvent *out;
1926
1927    cookie->data = out = malloc(sizeof(XIHierarchyEvent) + in->num_info * sizeof(XIHierarchyInfo));
1928    if (!out)
1929        return 0;
1930
1931    out->info           = (XIHierarchyInfo*)&out[1];
1932    out->display        = cookie->display;
1933    out->type           = in->type;
1934    out->serial         = cookie->serial;
1935    out->extension      = in->extension;
1936    out->evtype         = in->evtype;
1937    out->send_event = ((in->type & 0x80) != 0);
1938    out->time           = in->time;
1939    out->flags          = in->flags;
1940    out->num_info       = in->num_info;
1941
1942    info_out            = out->info;
1943    info_in             = (xXIHierarchyInfo*)&in[1];
1944
1945    for (i = 0; i < out->num_info; i++, info_out++, info_in++)
1946    {
1947        info_out->deviceid      = info_in->deviceid;
1948        info_out->attachment    = info_in->attachment;
1949        info_out->use           = info_in->use;
1950        info_out->enabled       = info_in->enabled;
1951        info_out->flags         = info_in->flags;
1952    }
1953
1954    return 1;
1955}
1956
1957static int
1958wireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie)
1959{
1960    int len, i, bits;
1961    FP3232 *values;
1962    XIRawEvent *out;
1963    void *ptr;
1964
1965    len = pad_to_double(sizeof(XIRawEvent))
1966        + pad_to_double(in->valuators_len * 4);
1967    bits = count_bits((unsigned char*)&in[1], in->valuators_len * 4);
1968    len += bits * sizeof(double) * 2; /* raw + normal */
1969
1970    cookie->data = ptr = calloc(1, len);
1971    if (!ptr)
1972        return 0;
1973
1974    out = next_block(&ptr, pad_to_double(sizeof(XIRawEvent)));
1975    out->type           = in->type;
1976    out->serial         = cookie->serial;
1977    out->display        = cookie->display;
1978    out->extension      = in->extension;
1979    out->evtype         = in->evtype;
1980    out->send_event = ((in->type & 0x80) != 0);
1981    out->time           = in->time;
1982    out->detail         = in->detail;
1983    out->deviceid       = in->deviceid;
1984    out->flags          = in->flags;
1985
1986    /* https://bugs.freedesktop.org/show_bug.cgi?id=34240 */
1987    if (_XiCheckVersion(info, XInput_2_2) >= 0)
1988        out->sourceid       = in->sourceid;
1989    else
1990        out->sourceid       = 0;
1991
1992    out->valuators.mask_len = in->valuators_len * 4;
1993    out->valuators.mask
1994        = next_block(&ptr, pad_to_double(out->valuators.mask_len));
1995    memcpy(out->valuators.mask, &in[1], out->valuators.mask_len);
1996
1997    out->valuators.values = next_block(&ptr, bits * sizeof(double));
1998    out->raw_values = next_block(&ptr, bits * sizeof(double));
1999
2000    values = (FP3232*)(((char*)&in[1]) + in->valuators_len * 4);
2001    for (i = 0; i < bits; i++)
2002    {
2003        out->valuators.values[i] = values->integral;
2004        out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16));
2005        out->raw_values[i] = (values + bits)->integral;
2006        out->raw_values[i] += ((double)(values + bits)->frac / (1 << 16) / (1 << 16));
2007        values++;
2008    }
2009
2010    return 1;
2011}
2012
2013/* Memory layout of XIEnterEvents:
2014   [event][modifiers][group][button]
2015 */
2016static int
2017wireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie)
2018{
2019    int len;
2020    XIEnterEvent *out;
2021
2022    len = sizeof(XIEnterEvent) + in->buttons_len * 4;
2023
2024    cookie->data = out = malloc(len);
2025    if (!out)
2026        return 0;
2027
2028    out->buttons.mask = (unsigned char*)&out[1];
2029
2030    out->type           = in->type;
2031    out->serial         = cookie->serial;
2032    out->display        = cookie->display;
2033    out->extension      = in->extension;
2034    out->evtype         = in->evtype;
2035    out->send_event = ((in->type & 0x80) != 0);
2036    out->time           = in->time;
2037    out->detail         = in->detail;
2038    out->deviceid       = in->deviceid;
2039    out->root           = in->root;
2040    out->event          = in->event;
2041    out->child          = in->child;
2042    out->sourceid       = in->sourceid;
2043    out->root_x         = FP1616toDBL(in->root_x);
2044    out->root_y         = FP1616toDBL(in->root_y);
2045    out->event_x        = FP1616toDBL(in->event_x);
2046    out->event_y        = FP1616toDBL(in->event_y);
2047    out->mode           = in->mode;
2048    out->focus          = in->focus;
2049    out->same_screen    = in->same_screen;
2050
2051    out->mods.base = in->mods.base_mods;
2052    out->mods.locked = in->mods.locked_mods;
2053    out->mods.latched = in->mods.latched_mods;
2054    out->mods.effective = in->mods.effective_mods;
2055    out->group.base = in->group.base_group;
2056    out->group.locked = in->group.locked_group;
2057    out->group.latched = in->group.latched_group;
2058    out->group.effective = in->group.effective_group;
2059
2060    out->buttons.mask_len = in->buttons_len * 4;
2061    memcpy(out->buttons.mask, &in[1], out->buttons.mask_len);
2062
2063    return 1;
2064}
2065
2066static int
2067wireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie)
2068{
2069    XIPropertyEvent *out = malloc(sizeof(XIPropertyEvent));
2070
2071    cookie->data = out;
2072    if (!out)
2073        return 0;
2074
2075    out->type           = in->type;
2076    out->serial         = cookie->serial;
2077    out->extension      = in->extension;
2078    out->evtype         = in->evtype;
2079    out->send_event = ((in->type & 0x80) != 0);
2080    out->time           = in->time;
2081    out->property       = in->property;
2082    out->what           = in->what;
2083    out->deviceid       = in->deviceid;
2084
2085    return 1;
2086}
2087
2088static int
2089wireToTouchOwnershipEvent(xXITouchOwnershipEvent *in,
2090                          XGenericEventCookie *cookie)
2091{
2092    XITouchOwnershipEvent *out = malloc(sizeof(XITouchOwnershipEvent));
2093
2094    cookie->data = out;
2095    if (!out)
2096        return 0;
2097
2098    out->type           = in->type;
2099    out->serial         = cookie->serial;
2100    out->display        = cookie->display;
2101    out->extension      = in->extension;
2102    out->evtype         = in->evtype;
2103    out->send_event     = ((in->type & 0x80) != 0);
2104    out->time           = in->time;
2105    out->deviceid       = in->deviceid;
2106    out->sourceid       = in->sourceid;
2107    out->touchid        = in->touchid;
2108    out->root           = in->root;
2109    out->event          = in->event;
2110    out->child          = in->child;
2111    out->flags          = in->flags;
2112
2113    return 1;
2114}
2115
2116static int
2117wireToBarrierEvent(xXIBarrierEvent *in, XGenericEventCookie *cookie)
2118{
2119    XIBarrierEvent *out = malloc(sizeof(XIBarrierEvent));
2120
2121    cookie->data = out;
2122    if (!out)
2123        return 0;
2124
2125    out->display    = cookie->display;
2126    out->type       = in->type;
2127    out->serial     = cookie->serial;
2128    out->extension  = in->extension;
2129    out->evtype     = in->evtype;
2130    out->send_event = ((in->type & 0x80) != 0);
2131    out->time       = in->time;
2132    out->deviceid   = in->deviceid;
2133    out->sourceid   = in->sourceid;
2134    out->event      = in->event;
2135    out->root       = in->root;
2136    out->root_x     = FP1616toDBL(in->root_x);
2137    out->root_y     = FP1616toDBL(in->root_y);
2138    out->dx         = FP3232_TO_DOUBLE (in->dx);
2139    out->dy         = FP3232_TO_DOUBLE (in->dy);
2140    out->dtime      = in->dtime;
2141    out->flags      = in->flags;
2142    out->barrier    = in->barrier;
2143    out->eventid    = in->eventid;
2144
2145    return 1;
2146}
2147
2148static int
2149wireToPinchEvent(xXIGesturePinchEvent *in,
2150                 XGenericEventCookie *cookie)
2151{
2152    XIGesturePinchEvent *out;
2153
2154    cookie->data = out = malloc(sizeof(XIGesturePinchEvent));
2155    if (!out)
2156        return 0;
2157
2158    out->display    = cookie->display;
2159    out->type       = in->type;
2160    out->serial     = cookie->serial;
2161    out->extension  = in->extension;
2162    out->evtype     = in->evtype;
2163    out->send_event = ((in->type & 0x80) != 0);
2164    out->time       = in->time;
2165    out->deviceid   = in->deviceid;
2166    out->sourceid   = in->sourceid;
2167    out->detail     = in->detail;
2168    out->root       = in->root;
2169    out->event      = in->event;
2170    out->child      = in->child;
2171    out->root_x     = FP1616toDBL(in->root_x);
2172    out->root_y     = FP1616toDBL(in->root_y);
2173    out->event_x    = FP1616toDBL(in->event_x);
2174    out->event_y    = FP1616toDBL(in->event_y);
2175    out->delta_x    = FP1616toDBL(in->delta_x);
2176    out->delta_y    = FP1616toDBL(in->delta_y);
2177    out->delta_unaccel_x = FP1616toDBL(in->delta_unaccel_x);
2178    out->delta_unaccel_y = FP1616toDBL(in->delta_unaccel_y);
2179    out->scale      = FP1616toDBL(in->scale);
2180    out->delta_angle = FP1616toDBL(in->delta_angle);
2181    out->flags      = in->flags;
2182
2183    out->mods.base = in->mods.base_mods;
2184    out->mods.locked = in->mods.locked_mods;
2185    out->mods.latched = in->mods.latched_mods;
2186    out->mods.effective = in->mods.effective_mods;
2187    out->group.base = in->group.base_group;
2188    out->group.locked = in->group.locked_group;
2189    out->group.latched = in->group.latched_group;
2190    out->group.effective = in->group.effective_group;
2191
2192    return 1;
2193}
2194
2195static int
2196wireToSwipeEvent(xXIGestureSwipeEvent *in,
2197                 XGenericEventCookie *cookie)
2198{
2199    XIGestureSwipeEvent *out;
2200
2201    cookie->data = out = malloc(sizeof(XIGestureSwipeEvent));
2202    if (!out)
2203        return 0;
2204
2205    out->display    = cookie->display;
2206    out->type       = in->type;
2207    out->serial     = cookie->serial;
2208    out->extension  = in->extension;
2209    out->evtype     = in->evtype;
2210    out->send_event = ((in->type & 0x80) != 0);
2211    out->time       = in->time;
2212    out->deviceid   = in->deviceid;
2213    out->sourceid   = in->sourceid;
2214    out->detail     = in->detail;
2215    out->root       = in->root;
2216    out->event      = in->event;
2217    out->child      = in->child;
2218    out->root_x     = FP1616toDBL(in->root_x);
2219    out->root_y     = FP1616toDBL(in->root_y);
2220    out->event_x    = FP1616toDBL(in->event_x);
2221    out->event_y    = FP1616toDBL(in->event_y);
2222    out->delta_x    = FP1616toDBL(in->delta_x);
2223    out->delta_y    = FP1616toDBL(in->delta_y);
2224    out->delta_unaccel_x = FP1616toDBL(in->delta_unaccel_x);
2225    out->delta_unaccel_y = FP1616toDBL(in->delta_unaccel_y);
2226    out->flags      = in->flags;
2227
2228    out->mods.base = in->mods.base_mods;
2229    out->mods.locked = in->mods.locked_mods;
2230    out->mods.latched = in->mods.latched_mods;
2231    out->mods.effective = in->mods.effective_mods;
2232    out->group.base = in->group.base_group;
2233    out->group.locked = in->group.locked_group;
2234    out->group.latched = in->group.latched_group;
2235    out->group.effective = in->group.effective_group;
2236
2237    return 1;
2238}
2239