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