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