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