XExtInt.c revision 87404ef7
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 (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
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 = 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
1452static Bool
1453copyBarrierEvent(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
1469static Bool
1470copyGesturePinchEvent(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
1486static Bool
1487copyGestureSwipeEvent(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
1503static Bool
1504XInputCopyCookie(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
1584static int
1585wireToDeviceEvent(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
1656size_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
1709copy_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
1880static int
1881wireToDeviceChangedEvent(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
1913static int
1914wireToHierarchyChangedEvent(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
1949static int
1950wireToRawEvent(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 */
2006static int
2007wireToEnterLeave(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
2053static int
2054wireToPropertyEvent(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
2073static int
2074wireToTouchOwnershipEvent(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
2099static int
2100wireToBarrierEvent(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
2129static int
2130wireToPinchEvent(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
2174static int
2175wireToSwipeEvent(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