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