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); 2334e8f48c7Smrg if (XextHasExtension(dpyinfo)) /* skip 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); 1431c6b4a769Smrg len = pad_to_double(sizeof(XIRawEvent)) 1432c6b4a769Smrg + pad_to_double(in->valuators.mask_len); 1433c27c18e8Smrg len += bits * sizeof(double) * 2; 1434c27c18e8Smrg 1435b789ec8aSmrg ptr = cookie_out->data = malloc(len); 1436c27c18e8Smrg if (!ptr) 1437c27c18e8Smrg return False; 1438c27c18e8Smrg 1439c6b4a769Smrg out = next_block(&ptr, pad_to_double(sizeof(XIRawEvent))); 1440c27c18e8Smrg *out = *in; 1441c6b4a769Smrg out->valuators.mask 1442c6b4a769Smrg = next_block(&ptr, pad_to_double(out->valuators.mask_len)); 1443c27c18e8Smrg memcpy(out->valuators.mask, in->valuators.mask, out->valuators.mask_len); 1444c27c18e8Smrg 1445c27c18e8Smrg out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1446c27c18e8Smrg memcpy(out->valuators.values, in->valuators.values, bits * sizeof(double)); 1447c27c18e8Smrg 1448c27c18e8Smrg out->raw_values = next_block(&ptr, bits * sizeof(double)); 1449c27c18e8Smrg memcpy(out->raw_values, in->raw_values, bits * sizeof(double)); 1450c27c18e8Smrg 1451c27c18e8Smrg return True; 1452c27c18e8Smrg} 1453c27c18e8Smrg 1454f1ee322dSmrgstatic Bool 1455f1ee322dSmrgcopyBarrierEvent(XGenericEventCookie *in_cookie, 1456f1ee322dSmrg XGenericEventCookie *out_cookie) 1457f1ee322dSmrg{ 1458f1ee322dSmrg XIBarrierEvent *in, *out; 1459f1ee322dSmrg 1460f1ee322dSmrg in = in_cookie->data; 1461f1ee322dSmrg 1462f1ee322dSmrg out = out_cookie->data = calloc(1, sizeof(XIBarrierEvent)); 1463f1ee322dSmrg if (!out) 1464f1ee322dSmrg return False; 1465f1ee322dSmrg *out = *in; 1466c27c18e8Smrg 1467f1ee322dSmrg return True; 1468f1ee322dSmrg} 1469c27c18e8Smrg 147087404ef7Smrg 147187404ef7Smrgstatic Bool 147287404ef7SmrgcopyGesturePinchEvent(XGenericEventCookie *cookie_in, 147387404ef7Smrg XGenericEventCookie *cookie_out) 147487404ef7Smrg{ 147587404ef7Smrg XIGesturePinchEvent *in, *out; 147687404ef7Smrg 147787404ef7Smrg in = cookie_in->data; 147887404ef7Smrg 147987404ef7Smrg out = cookie_out->data = malloc(sizeof(XIGesturePinchEvent)); 148087404ef7Smrg if (!out) 148187404ef7Smrg return False; 148287404ef7Smrg 148387404ef7Smrg *out = *in; 148487404ef7Smrg 148587404ef7Smrg return True; 148687404ef7Smrg} 148787404ef7Smrg 148887404ef7Smrgstatic Bool 148987404ef7SmrgcopyGestureSwipeEvent(XGenericEventCookie *cookie_in, 149087404ef7Smrg XGenericEventCookie *cookie_out) 149187404ef7Smrg{ 149287404ef7Smrg XIGestureSwipeEvent *in, *out; 149387404ef7Smrg 149487404ef7Smrg in = cookie_in->data; 149587404ef7Smrg 149687404ef7Smrg out = cookie_out->data = malloc(sizeof(XIGestureSwipeEvent)); 149787404ef7Smrg if (!out) 149887404ef7Smrg return False; 149987404ef7Smrg 150087404ef7Smrg *out = *in; 150187404ef7Smrg 150287404ef7Smrg return True; 150387404ef7Smrg} 150487404ef7Smrg 1505c27c18e8Smrgstatic Bool 1506c27c18e8SmrgXInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 1507c27c18e8Smrg{ 1508c27c18e8Smrg int ret = True; 1509c27c18e8Smrg 1510c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 1511c27c18e8Smrg 1512c27c18e8Smrg if (in->extension != info->codes->major_opcode) 1513c43cc173Smrg { 1514c27c18e8Smrg printf("XInputCopyCookie: wrong extension opcode %d\n", 1515c27c18e8Smrg in->extension); 1516c27c18e8Smrg return False; 1517c27c18e8Smrg } 1518c27c18e8Smrg 1519c27c18e8Smrg *out = *in; 1520c27c18e8Smrg out->data = NULL; 1521c27c18e8Smrg out->cookie = 0; 1522c27c18e8Smrg 1523c27c18e8Smrg switch(in->evtype) { 1524c27c18e8Smrg case XI_Motion: 1525c27c18e8Smrg case XI_ButtonPress: 1526c27c18e8Smrg case XI_ButtonRelease: 1527c27c18e8Smrg case XI_KeyPress: 1528c27c18e8Smrg case XI_KeyRelease: 1529f1ee322dSmrg case XI_TouchBegin: 1530f1ee322dSmrg case XI_TouchUpdate: 1531f1ee322dSmrg case XI_TouchEnd: 1532c27c18e8Smrg ret = copyDeviceEvent(in, out); 1533c27c18e8Smrg break; 1534c27c18e8Smrg case XI_DeviceChanged: 1535c27c18e8Smrg ret = copyDeviceChangedEvent(in, out); 1536c27c18e8Smrg break; 1537c27c18e8Smrg case XI_HierarchyChanged: 1538c27c18e8Smrg ret = copyHierarchyEvent(in, out); 1539c27c18e8Smrg break; 1540c27c18e8Smrg case XI_Enter: 1541c27c18e8Smrg case XI_Leave: 1542c27c18e8Smrg case XI_FocusIn: 1543c27c18e8Smrg case XI_FocusOut: 1544c27c18e8Smrg ret = copyEnterEvent(in, out); 1545c27c18e8Smrg break; 1546c27c18e8Smrg case XI_PropertyEvent: 1547c27c18e8Smrg ret = copyPropertyEvent(in, out); 1548c27c18e8Smrg break; 1549f1ee322dSmrg case XI_TouchOwnership: 1550f1ee322dSmrg ret = copyTouchOwnershipEvent(in, out); 1551f1ee322dSmrg break; 1552c27c18e8Smrg case XI_RawKeyPress: 1553c27c18e8Smrg case XI_RawKeyRelease: 1554c27c18e8Smrg case XI_RawButtonPress: 1555c27c18e8Smrg case XI_RawButtonRelease: 1556c27c18e8Smrg case XI_RawMotion: 1557f1ee322dSmrg case XI_RawTouchBegin: 1558f1ee322dSmrg case XI_RawTouchUpdate: 1559f1ee322dSmrg case XI_RawTouchEnd: 1560c27c18e8Smrg ret = copyRawEvent(in, out); 1561c27c18e8Smrg break; 1562f1ee322dSmrg case XI_BarrierHit: 1563f1ee322dSmrg case XI_BarrierLeave: 1564f1ee322dSmrg ret = copyBarrierEvent(in, out); 1565f1ee322dSmrg break; 156687404ef7Smrg case XI_GesturePinchBegin: 156787404ef7Smrg case XI_GesturePinchUpdate: 156887404ef7Smrg case XI_GesturePinchEnd: 156987404ef7Smrg ret = copyGesturePinchEvent(in, out); 157087404ef7Smrg break; 157187404ef7Smrg case XI_GestureSwipeBegin: 157287404ef7Smrg case XI_GestureSwipeUpdate: 157387404ef7Smrg case XI_GestureSwipeEnd: 157487404ef7Smrg ret = copyGestureSwipeEvent(in, out); 157587404ef7Smrg break; 1576c27c18e8Smrg default: 1577c27c18e8Smrg printf("XInputCopyCookie: unknown evtype %d\n", in->evtype); 1578c27c18e8Smrg ret = False; 1579c43cc173Smrg } 1580c27c18e8Smrg 1581c27c18e8Smrg if (!ret) 1582c27c18e8Smrg printf("XInputCopyCookie: Failed to copy evtype %d", in->evtype); 1583c27c18e8Smrg return ret; 1584c27c18e8Smrg} 1585c27c18e8Smrg 1586c27c18e8Smrgstatic int 1587c27c18e8SmrgwireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* cookie) 1588c27c18e8Smrg{ 1589c27c18e8Smrg int len, i; 1590c27c18e8Smrg unsigned char *ptr; 1591c27c18e8Smrg void *ptr_lib; 1592c27c18e8Smrg FP3232 *values; 1593c27c18e8Smrg XIDeviceEvent *out; 1594c27c18e8Smrg 1595c27c18e8Smrg ptr = (unsigned char*)&in[1] + in->buttons_len * 4; 1596c27c18e8Smrg 1597c27c18e8Smrg len = sizeDeviceEvent(in->buttons_len * 4, in->valuators_len * 4, ptr); 1598c27c18e8Smrg 1599c27c18e8Smrg cookie->data = ptr_lib = malloc(len); 1600c6b4a769Smrg if (!ptr_lib) 1601c6b4a769Smrg return 0; 1602c27c18e8Smrg 1603c27c18e8Smrg out = next_block(&ptr_lib, sizeof(XIDeviceEvent)); 160489069ce9Smrg out->display = cookie->display; 1605c27c18e8Smrg out->type = in->type; 160644584a44Smrg out->serial = cookie->serial; 1607c27c18e8Smrg out->extension = in->extension; 1608c27c18e8Smrg out->evtype = in->evtype; 1609c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1610c27c18e8Smrg out->time = in->time; 1611c27c18e8Smrg out->deviceid = in->deviceid; 1612c27c18e8Smrg out->sourceid = in->sourceid; 1613c27c18e8Smrg out->detail = in->detail; 1614c27c18e8Smrg out->root = in->root; 1615c27c18e8Smrg out->event = in->event; 1616c27c18e8Smrg out->child = in->child; 1617c27c18e8Smrg out->root_x = FP1616toDBL(in->root_x); 1618c27c18e8Smrg out->root_y = FP1616toDBL(in->root_y); 1619c27c18e8Smrg out->event_x = FP1616toDBL(in->event_x); 1620c27c18e8Smrg out->event_y = FP1616toDBL(in->event_y); 1621c27c18e8Smrg out->flags = in->flags; 1622c27c18e8Smrg out->mods.base = in->mods.base_mods; 1623c27c18e8Smrg out->mods.locked = in->mods.locked_mods; 1624c27c18e8Smrg out->mods.latched = in->mods.latched_mods; 1625c27c18e8Smrg out->mods.effective = in->mods.effective_mods; 1626c27c18e8Smrg out->group.base = in->group.base_group; 1627c27c18e8Smrg out->group.locked = in->group.locked_group; 1628c27c18e8Smrg out->group.latched = in->group.latched_group; 1629c27c18e8Smrg out->group.effective = in->group.effective_group; 1630c27c18e8Smrg out->buttons.mask_len = in->buttons_len * 4; 1631c27c18e8Smrg out->valuators.mask_len = in->valuators_len * 4; 1632c27c18e8Smrg 1633c27c18e8Smrg out->buttons.mask = next_block(&ptr_lib, out->buttons.mask_len); 1634c27c18e8Smrg 1635c27c18e8Smrg /* buttons */ 1636c27c18e8Smrg ptr = (unsigned char*)&in[1]; 1637c27c18e8Smrg memcpy(out->buttons.mask, ptr, out->buttons.mask_len); 1638c27c18e8Smrg ptr += in->buttons_len * 4; 1639c27c18e8Smrg 1640c27c18e8Smrg /* valuators */ 1641c27c18e8Smrg out->valuators.mask = next_block(&ptr_lib, out->valuators.mask_len); 1642c27c18e8Smrg memcpy(out->valuators.mask, ptr, out->valuators.mask_len); 1643c27c18e8Smrg ptr += in->valuators_len * 4; 1644c27c18e8Smrg 1645c27c18e8Smrg len = count_bits(out->valuators.mask, out->valuators.mask_len); 1646c27c18e8Smrg out->valuators.values = next_block(&ptr_lib, len * sizeof(double)); 1647c27c18e8Smrg 1648c27c18e8Smrg values = (FP3232*)ptr; 1649c27c18e8Smrg for (i = 0; i < len; i++, values++) 1650c43cc173Smrg { 1651c27c18e8Smrg out->valuators.values[i] = values->integral; 1652c27c18e8Smrg out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 1653c43cc173Smrg } 1654c27c18e8Smrg 1655c27c18e8Smrg 1656c27c18e8Smrg return 1; 1657c27c18e8Smrg} 1658c27c18e8Smrg 1659c27c18e8Smrg_X_HIDDEN int 1660c27c18e8Smrgsize_classes(xXIAnyInfo* from, int nclasses) 1661c27c18e8Smrg{ 1662c27c18e8Smrg int len, i; 1663c27c18e8Smrg xXIAnyInfo *any_wire; 1664c27c18e8Smrg char *ptr_wire; 1665c27c18e8Smrg 1666f1ee322dSmrg /* len for to->classes */ 1667f1ee322dSmrg len = pad_to_double(nclasses * sizeof(XIAnyClassInfo*)); 1668c27c18e8Smrg ptr_wire = (char*)from; 1669c27c18e8Smrg for (i = 0; i < nclasses; i++) 1670c43cc173Smrg { 1671c27c18e8Smrg int l = 0; 1672c27c18e8Smrg any_wire = (xXIAnyInfo*)ptr_wire; 1673c27c18e8Smrg switch(any_wire->type) 1674c27c18e8Smrg { 1675c27c18e8Smrg case XIButtonClass: 1676c27c18e8Smrg l = sizeDeviceClassType(XIButtonClass, 1677c27c18e8Smrg ((xXIButtonInfo*)any_wire)->num_buttons); 1678c27c18e8Smrg break; 1679c27c18e8Smrg case XIKeyClass: 1680c27c18e8Smrg l = sizeDeviceClassType(XIKeyClass, 1681c27c18e8Smrg ((xXIKeyInfo*)any_wire)->num_keycodes); 1682c27c18e8Smrg break; 1683c27c18e8Smrg case XIValuatorClass: 1684c27c18e8Smrg l = sizeDeviceClassType(XIValuatorClass, 0); 1685c27c18e8Smrg break; 1686f1ee322dSmrg case XIScrollClass: 1687f1ee322dSmrg l = sizeDeviceClassType(XIScrollClass, 0); 1688f1ee322dSmrg break; 1689f1ee322dSmrg case XITouchClass: 1690f1ee322dSmrg l = sizeDeviceClassType(XITouchClass, 0); 1691f1ee322dSmrg break; 169287404ef7Smrg case XIGestureClass: 169387404ef7Smrg l = sizeDeviceClassType(XIGestureClass, 0); 169487404ef7Smrg break; 1695c27c18e8Smrg } 1696c27c18e8Smrg 1697c27c18e8Smrg len += l; 1698c27c18e8Smrg ptr_wire += any_wire->length * 4; 1699c43cc173Smrg } 1700c27c18e8Smrg 1701c27c18e8Smrg return len; 1702c27c18e8Smrg} 1703c27c18e8Smrg 17044940c694Smrg#define FP3232_TO_DOUBLE(x) ((double) (x).integral + (double) (x).frac / (1ULL << 32)) 17054940c694Smrg 1706c27c18e8Smrg/* Copy classes from any into to->classes and return the number of bytes 1707c27c18e8Smrg * copied. Memory layout of to->classes is 1708c27c18e8Smrg * [clsptr][clsptr][clsptr][classinfo][classinfo]... 1709c27c18e8Smrg * |________|___________^ 1710c27c18e8Smrg * |______________________^ 1711c27c18e8Smrg */ 1712c27c18e8Smrg_X_HIDDEN int 1713f1ee322dSmrgcopy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int *nclasses) 1714c27c18e8Smrg{ 1715c27c18e8Smrg XIAnyClassInfo *any_lib; 1716c27c18e8Smrg xXIAnyInfo *any_wire; 1717c27c18e8Smrg void *ptr_lib; 1718c27c18e8Smrg char *ptr_wire; 1719c27c18e8Smrg int i, len; 1720f1ee322dSmrg int cls_idx = 0; 1721c27c18e8Smrg 1722c27c18e8Smrg if (!to->classes) 1723c27c18e8Smrg return -1; 1724c27c18e8Smrg 1725c27c18e8Smrg ptr_wire = (char*)from; 1726c27c18e8Smrg ptr_lib = to->classes; 1727f1ee322dSmrg to->classes = next_block(&ptr_lib, 1728f1ee322dSmrg pad_to_double((*nclasses) * sizeof(XIAnyClassInfo*))); 1729f1ee322dSmrg memset(to->classes, 0, (*nclasses) * sizeof(XIAnyClassInfo*)); 1730c27c18e8Smrg len = 0; /* count wire length */ 1731c27c18e8Smrg 1732f1ee322dSmrg for (i = 0; i < *nclasses; i++) 1733c43cc173Smrg { 1734c27c18e8Smrg any_lib = (XIAnyClassInfo*)ptr_lib; 1735c27c18e8Smrg any_wire = (xXIAnyInfo*)ptr_wire; 1736c27c18e8Smrg 1737c27c18e8Smrg switch(any_wire->type) 1738c27c18e8Smrg { 1739c27c18e8Smrg case XIButtonClass: 1740c27c18e8Smrg { 1741c27c18e8Smrg XIButtonClassInfo *cls_lib; 1742c27c18e8Smrg xXIButtonInfo *cls_wire; 1743c27c18e8Smrg uint32_t *atoms; 1744c27c18e8Smrg int j; 1745f1ee322dSmrg int struct_size; 1746f1ee322dSmrg int state_size; 1747f1ee322dSmrg int labels_size; 1748f1ee322dSmrg int wire_mask_size; 1749c27c18e8Smrg 1750c27c18e8Smrg cls_wire = (xXIButtonInfo*)any_wire; 1751f1ee322dSmrg sizeXIButtonClassType(cls_wire->num_buttons, 1752f1ee322dSmrg &struct_size, &state_size, 1753f1ee322dSmrg &labels_size); 1754f1ee322dSmrg cls_lib = next_block(&ptr_lib, struct_size); 1755f1ee322dSmrg wire_mask_size = ((cls_wire->num_buttons + 7)/8 + 3)/4 * 4; 1756f1ee322dSmrg 1757f1ee322dSmrg cls_lib->type = cls_wire->type; 1758f1ee322dSmrg cls_lib->sourceid = cls_wire->sourceid; 1759c27c18e8Smrg cls_lib->num_buttons = cls_wire->num_buttons; 1760f1ee322dSmrg cls_lib->state.mask_len = state_size; 1761f1ee322dSmrg cls_lib->state.mask = next_block(&ptr_lib, state_size); 1762c27c18e8Smrg memcpy(cls_lib->state.mask, &cls_wire[1], 1763f1ee322dSmrg wire_mask_size); 1764f1ee322dSmrg if (state_size != wire_mask_size) 1765f1ee322dSmrg memset(&cls_lib->state.mask[wire_mask_size], 0, 1766f1ee322dSmrg state_size - wire_mask_size); 1767c27c18e8Smrg 1768f1ee322dSmrg cls_lib->labels = next_block(&ptr_lib, labels_size); 1769f1ee322dSmrg 1770f1ee322dSmrg atoms =(uint32_t*)((char*)&cls_wire[1] + wire_mask_size); 1771c27c18e8Smrg for (j = 0; j < cls_lib->num_buttons; j++) 1772c27c18e8Smrg cls_lib->labels[j] = *atoms++; 1773c27c18e8Smrg 1774f1ee322dSmrg to->classes[cls_idx++] = any_lib; 1775c27c18e8Smrg break; 1776c27c18e8Smrg } 1777c27c18e8Smrg case XIKeyClass: 1778c27c18e8Smrg { 1779c27c18e8Smrg XIKeyClassInfo *cls_lib; 1780c27c18e8Smrg xXIKeyInfo *cls_wire; 1781f1ee322dSmrg int struct_size; 1782f1ee322dSmrg int keycodes_size; 1783c27c18e8Smrg 1784c27c18e8Smrg cls_wire = (xXIKeyInfo*)any_wire; 1785f1ee322dSmrg sizeXIKeyClassType(cls_wire->num_keycodes, 1786f1ee322dSmrg &struct_size, &keycodes_size); 1787f1ee322dSmrg cls_lib = next_block(&ptr_lib, struct_size); 1788c27c18e8Smrg 1789f1ee322dSmrg cls_lib->type = cls_wire->type; 1790f1ee322dSmrg cls_lib->sourceid = cls_wire->sourceid; 1791c27c18e8Smrg cls_lib->num_keycodes = cls_wire->num_keycodes; 1792f1ee322dSmrg cls_lib->keycodes = next_block(&ptr_lib, keycodes_size); 1793c27c18e8Smrg memcpy(cls_lib->keycodes, &cls_wire[1], 1794c27c18e8Smrg cls_lib->num_keycodes); 1795c27c18e8Smrg 1796f1ee322dSmrg to->classes[cls_idx++] = any_lib; 1797c27c18e8Smrg break; 1798c27c18e8Smrg } 1799c27c18e8Smrg case XIValuatorClass: 1800c27c18e8Smrg { 1801c27c18e8Smrg XIValuatorClassInfo *cls_lib; 1802c27c18e8Smrg xXIValuatorInfo *cls_wire; 1803c27c18e8Smrg 1804f1ee322dSmrg cls_lib = 1805f1ee322dSmrg next_block(&ptr_lib, 1806f1ee322dSmrg sizeDeviceClassType(XIValuatorClass, 0)); 1807c27c18e8Smrg cls_wire = (xXIValuatorInfo*)any_wire; 1808c27c18e8Smrg 1809f1ee322dSmrg cls_lib->type = cls_wire->type; 1810f1ee322dSmrg cls_lib->sourceid = cls_wire->sourceid; 1811c27c18e8Smrg cls_lib->number = cls_wire->number; 1812c27c18e8Smrg cls_lib->label = cls_wire->label; 1813c27c18e8Smrg cls_lib->resolution = cls_wire->resolution; 18144940c694Smrg cls_lib->min = FP3232_TO_DOUBLE(cls_wire->min); 18154940c694Smrg cls_lib->max = FP3232_TO_DOUBLE(cls_wire->max); 18164940c694Smrg cls_lib->value = FP3232_TO_DOUBLE(cls_wire->value); 1817c27c18e8Smrg cls_lib->mode = cls_wire->mode; 1818c27c18e8Smrg 1819f1ee322dSmrg to->classes[cls_idx++] = any_lib; 1820f1ee322dSmrg } 1821f1ee322dSmrg break; 1822f1ee322dSmrg case XIScrollClass: 1823f1ee322dSmrg { 1824f1ee322dSmrg XIScrollClassInfo *cls_lib; 1825f1ee322dSmrg xXIScrollInfo *cls_wire; 1826f1ee322dSmrg 1827f1ee322dSmrg cls_lib = 1828f1ee322dSmrg next_block(&ptr_lib, 1829f1ee322dSmrg sizeDeviceClassType(XIScrollClass, 0)); 1830f1ee322dSmrg cls_wire = (xXIScrollInfo*)any_wire; 1831f1ee322dSmrg 1832f1ee322dSmrg cls_lib->type = cls_wire->type; 1833f1ee322dSmrg cls_lib->sourceid = cls_wire->sourceid; 1834f1ee322dSmrg cls_lib->number = cls_wire->number; 1835f1ee322dSmrg cls_lib->scroll_type= cls_wire->scroll_type; 1836f1ee322dSmrg cls_lib->flags = cls_wire->flags; 18374940c694Smrg cls_lib->increment = FP3232_TO_DOUBLE(cls_wire->increment); 1838f1ee322dSmrg 1839f1ee322dSmrg to->classes[cls_idx++] = any_lib; 1840f1ee322dSmrg } 1841f1ee322dSmrg break; 1842f1ee322dSmrg case XITouchClass: 1843f1ee322dSmrg { 1844f1ee322dSmrg XITouchClassInfo *cls_lib; 1845f1ee322dSmrg xXITouchInfo *cls_wire; 1846f1ee322dSmrg 1847f1ee322dSmrg cls_wire = (xXITouchInfo*)any_wire; 1848f1ee322dSmrg cls_lib = next_block(&ptr_lib, sizeof(XITouchClassInfo)); 1849f1ee322dSmrg 1850f1ee322dSmrg cls_lib->type = cls_wire->type; 1851f1ee322dSmrg cls_lib->sourceid = cls_wire->sourceid; 1852f1ee322dSmrg cls_lib->mode = cls_wire->mode; 1853f1ee322dSmrg cls_lib->num_touches = cls_wire->num_touches; 1854f1ee322dSmrg 1855f1ee322dSmrg to->classes[cls_idx++] = any_lib; 1856c27c18e8Smrg } 1857c27c18e8Smrg break; 185887404ef7Smrg case XIGestureClass: 185987404ef7Smrg { 186087404ef7Smrg XIGestureClassInfo *cls_lib; 186187404ef7Smrg xXIGestureInfo *cls_wire; 186287404ef7Smrg 186387404ef7Smrg cls_wire = (xXIGestureInfo*)any_wire; 186487404ef7Smrg cls_lib = next_block(&ptr_lib, sizeof(XIGestureClassInfo)); 186587404ef7Smrg 186687404ef7Smrg cls_lib->type = cls_wire->type; 186787404ef7Smrg cls_lib->sourceid = cls_wire->sourceid; 186887404ef7Smrg cls_lib->num_touches = cls_wire->num_touches; 186987404ef7Smrg 187087404ef7Smrg to->classes[cls_idx++] = any_lib; 187187404ef7Smrg } 187287404ef7Smrg break; 1873c27c18e8Smrg } 1874c27c18e8Smrg len += any_wire->length * 4; 1875c27c18e8Smrg ptr_wire += any_wire->length * 4; 1876c43cc173Smrg } 1877f1ee322dSmrg 1878f1ee322dSmrg /* we may have skipped unknown classes, reset nclasses */ 1879f1ee322dSmrg *nclasses = cls_idx; 1880c27c18e8Smrg return len; 1881c27c18e8Smrg} 1882c27c18e8Smrg 1883c27c18e8Smrg 1884c27c18e8Smrgstatic int 1885c27c18e8SmrgwireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie) 1886c27c18e8Smrg{ 1887c27c18e8Smrg XIDeviceChangedEvent *out; 1888c27c18e8Smrg XIDeviceInfo info; 1889c27c18e8Smrg int len; 1890f1ee322dSmrg int nclasses = in->num_classes; 1891c27c18e8Smrg 1892c27c18e8Smrg len = size_classes((xXIAnyInfo*)&in[1], in->num_classes); 1893c27c18e8Smrg 1894c27c18e8Smrg cookie->data = out = malloc(sizeof(XIDeviceChangedEvent) + len); 1895c6b4a769Smrg if (!out) 1896c6b4a769Smrg return 0; 1897c27c18e8Smrg 1898c27c18e8Smrg out->type = in->type; 189944584a44Smrg out->serial = cookie->serial; 190089069ce9Smrg out->display = cookie->display; 1901c27c18e8Smrg out->extension = in->extension; 1902c27c18e8Smrg out->evtype = in->evtype; 1903c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1904c27c18e8Smrg out->time = in->time; 1905c27c18e8Smrg out->deviceid = in->deviceid; 1906c27c18e8Smrg out->sourceid = in->sourceid; 1907c27c18e8Smrg out->reason = in->reason; 1908c27c18e8Smrg 1909c27c18e8Smrg out->classes = (XIAnyClassInfo**)&out[1]; 1910c27c18e8Smrg 1911c27c18e8Smrg info.classes = out->classes; 1912c27c18e8Smrg 1913f1ee322dSmrg copy_classes(&info, (xXIAnyInfo*)&in[1], &nclasses); 1914f1ee322dSmrg out->num_classes = nclasses; 1915c27c18e8Smrg 1916c27c18e8Smrg return 1; 1917c27c18e8Smrg} 1918c27c18e8Smrg 1919c27c18e8Smrgstatic int 1920c27c18e8SmrgwireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie) 1921c27c18e8Smrg{ 1922c27c18e8Smrg int i; 1923c27c18e8Smrg XIHierarchyInfo *info_out; 1924c27c18e8Smrg xXIHierarchyInfo *info_in; 1925c27c18e8Smrg XIHierarchyEvent *out; 1926c27c18e8Smrg 1927c6b4a769Smrg cookie->data = out = malloc(sizeof(XIHierarchyEvent) + in->num_info * sizeof(XIHierarchyInfo)); 1928c6b4a769Smrg if (!out) 1929c6b4a769Smrg return 0; 1930c27c18e8Smrg 1931c27c18e8Smrg out->info = (XIHierarchyInfo*)&out[1]; 193289069ce9Smrg out->display = cookie->display; 1933c27c18e8Smrg out->type = in->type; 193444584a44Smrg out->serial = cookie->serial; 1935c27c18e8Smrg out->extension = in->extension; 1936c27c18e8Smrg out->evtype = in->evtype; 1937c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1938c27c18e8Smrg out->time = in->time; 1939c27c18e8Smrg out->flags = in->flags; 1940c27c18e8Smrg out->num_info = in->num_info; 1941c27c18e8Smrg 1942c27c18e8Smrg info_out = out->info; 1943c27c18e8Smrg info_in = (xXIHierarchyInfo*)&in[1]; 1944c27c18e8Smrg 1945c27c18e8Smrg for (i = 0; i < out->num_info; i++, info_out++, info_in++) 1946c43cc173Smrg { 1947c27c18e8Smrg info_out->deviceid = info_in->deviceid; 1948c27c18e8Smrg info_out->attachment = info_in->attachment; 1949c27c18e8Smrg info_out->use = info_in->use; 1950c27c18e8Smrg info_out->enabled = info_in->enabled; 1951c27c18e8Smrg info_out->flags = info_in->flags; 1952c43cc173Smrg } 1953c43cc173Smrg 1954c27c18e8Smrg return 1; 1955c27c18e8Smrg} 1956c27c18e8Smrg 1957c27c18e8Smrgstatic int 1958f1ee322dSmrgwireToRawEvent(XExtDisplayInfo *info, xXIRawEvent *in, XGenericEventCookie *cookie) 1959c27c18e8Smrg{ 1960c27c18e8Smrg int len, i, bits; 1961c27c18e8Smrg FP3232 *values; 1962c27c18e8Smrg XIRawEvent *out; 1963c27c18e8Smrg void *ptr; 1964c27c18e8Smrg 1965c6b4a769Smrg len = pad_to_double(sizeof(XIRawEvent)) 1966c6b4a769Smrg + pad_to_double(in->valuators_len * 4); 1967c27c18e8Smrg bits = count_bits((unsigned char*)&in[1], in->valuators_len * 4); 1968c27c18e8Smrg len += bits * sizeof(double) * 2; /* raw + normal */ 1969c27c18e8Smrg 1970c27c18e8Smrg cookie->data = ptr = calloc(1, len); 1971c27c18e8Smrg if (!ptr) 1972c27c18e8Smrg return 0; 1973c27c18e8Smrg 1974c6b4a769Smrg out = next_block(&ptr, pad_to_double(sizeof(XIRawEvent))); 1975c27c18e8Smrg out->type = in->type; 197644584a44Smrg out->serial = cookie->serial; 197789069ce9Smrg out->display = cookie->display; 1978c27c18e8Smrg out->extension = in->extension; 1979c27c18e8Smrg out->evtype = in->evtype; 1980c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1981c27c18e8Smrg out->time = in->time; 1982c27c18e8Smrg out->detail = in->detail; 1983c27c18e8Smrg out->deviceid = in->deviceid; 1984c27c18e8Smrg out->flags = in->flags; 1985c27c18e8Smrg 1986f1ee322dSmrg /* https://bugs.freedesktop.org/show_bug.cgi?id=34240 */ 1987f1ee322dSmrg if (_XiCheckVersion(info, XInput_2_2) >= 0) 1988f1ee322dSmrg out->sourceid = in->sourceid; 1989f1ee322dSmrg else 1990f1ee322dSmrg out->sourceid = 0; 1991f1ee322dSmrg 1992c27c18e8Smrg out->valuators.mask_len = in->valuators_len * 4; 1993c6b4a769Smrg out->valuators.mask 1994c6b4a769Smrg = next_block(&ptr, pad_to_double(out->valuators.mask_len)); 1995c27c18e8Smrg memcpy(out->valuators.mask, &in[1], out->valuators.mask_len); 1996c27c18e8Smrg 1997c27c18e8Smrg out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1998c27c18e8Smrg out->raw_values = next_block(&ptr, bits * sizeof(double)); 1999c27c18e8Smrg 2000c27c18e8Smrg values = (FP3232*)(((char*)&in[1]) + in->valuators_len * 4); 2001c27c18e8Smrg for (i = 0; i < bits; i++) 2002c43cc173Smrg { 2003c27c18e8Smrg out->valuators.values[i] = values->integral; 2004c27c18e8Smrg out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 2005c27c18e8Smrg out->raw_values[i] = (values + bits)->integral; 200637eb1ca1Smrg out->raw_values[i] += ((double)(values + bits)->frac / (1 << 16) / (1 << 16)); 2007c27c18e8Smrg values++; 2008c43cc173Smrg } 2009c43cc173Smrg 2010c27c18e8Smrg return 1; 2011c27c18e8Smrg} 201221e67964Smrg 2013c27c18e8Smrg/* Memory layout of XIEnterEvents: 2014c27c18e8Smrg [event][modifiers][group][button] 2015c27c18e8Smrg */ 2016c27c18e8Smrgstatic int 2017c27c18e8SmrgwireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie) 2018c27c18e8Smrg{ 2019c27c18e8Smrg int len; 2020c27c18e8Smrg XIEnterEvent *out; 2021c27c18e8Smrg 2022c27c18e8Smrg len = sizeof(XIEnterEvent) + in->buttons_len * 4; 2023c27c18e8Smrg 2024c27c18e8Smrg cookie->data = out = malloc(len); 2025c6b4a769Smrg if (!out) 2026c6b4a769Smrg return 0; 2027c6b4a769Smrg 2028c27c18e8Smrg out->buttons.mask = (unsigned char*)&out[1]; 2029c27c18e8Smrg 2030c27c18e8Smrg out->type = in->type; 203144584a44Smrg out->serial = cookie->serial; 203289069ce9Smrg out->display = cookie->display; 2033c27c18e8Smrg out->extension = in->extension; 2034c27c18e8Smrg out->evtype = in->evtype; 2035c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 2036c27c18e8Smrg out->time = in->time; 2037c27c18e8Smrg out->detail = in->detail; 2038c27c18e8Smrg out->deviceid = in->deviceid; 2039c27c18e8Smrg out->root = in->root; 2040c27c18e8Smrg out->event = in->event; 2041c27c18e8Smrg out->child = in->child; 2042c27c18e8Smrg out->sourceid = in->sourceid; 2043c27c18e8Smrg out->root_x = FP1616toDBL(in->root_x); 2044c27c18e8Smrg out->root_y = FP1616toDBL(in->root_y); 2045c27c18e8Smrg out->event_x = FP1616toDBL(in->event_x); 2046c27c18e8Smrg out->event_y = FP1616toDBL(in->event_y); 2047c27c18e8Smrg out->mode = in->mode; 2048c27c18e8Smrg out->focus = in->focus; 2049c27c18e8Smrg out->same_screen = in->same_screen; 2050c27c18e8Smrg 2051c27c18e8Smrg out->mods.base = in->mods.base_mods; 2052c27c18e8Smrg out->mods.locked = in->mods.locked_mods; 2053c27c18e8Smrg out->mods.latched = in->mods.latched_mods; 2054c27c18e8Smrg out->mods.effective = in->mods.effective_mods; 2055c27c18e8Smrg out->group.base = in->group.base_group; 2056c27c18e8Smrg out->group.locked = in->group.locked_group; 2057c27c18e8Smrg out->group.latched = in->group.latched_group; 2058c27c18e8Smrg out->group.effective = in->group.effective_group; 2059c27c18e8Smrg 2060c27c18e8Smrg out->buttons.mask_len = in->buttons_len * 4; 2061c27c18e8Smrg memcpy(out->buttons.mask, &in[1], out->buttons.mask_len); 206221e67964Smrg 2063c27c18e8Smrg return 1; 2064c27c18e8Smrg} 2065c43cc173Smrg 2066c27c18e8Smrgstatic int 2067c27c18e8SmrgwireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie) 2068c27c18e8Smrg{ 2069c27c18e8Smrg XIPropertyEvent *out = malloc(sizeof(XIPropertyEvent)); 2070c27c18e8Smrg 2071c27c18e8Smrg cookie->data = out; 2072c6b4a769Smrg if (!out) 2073c6b4a769Smrg return 0; 2074c27c18e8Smrg 2075c27c18e8Smrg out->type = in->type; 207644584a44Smrg out->serial = cookie->serial; 2077c27c18e8Smrg out->extension = in->extension; 2078c27c18e8Smrg out->evtype = in->evtype; 2079c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 2080c27c18e8Smrg out->time = in->time; 2081c27c18e8Smrg out->property = in->property; 2082c27c18e8Smrg out->what = in->what; 2083c27c18e8Smrg out->deviceid = in->deviceid; 2084c27c18e8Smrg 2085c27c18e8Smrg return 1; 2086c43cc173Smrg} 2087f1ee322dSmrg 2088f1ee322dSmrgstatic int 2089f1ee322dSmrgwireToTouchOwnershipEvent(xXITouchOwnershipEvent *in, 2090f1ee322dSmrg XGenericEventCookie *cookie) 2091f1ee322dSmrg{ 2092f1ee322dSmrg XITouchOwnershipEvent *out = malloc(sizeof(XITouchOwnershipEvent)); 2093f1ee322dSmrg 2094f1ee322dSmrg cookie->data = out; 2095c6b4a769Smrg if (!out) 2096c6b4a769Smrg return 0; 2097f1ee322dSmrg 2098f1ee322dSmrg out->type = in->type; 209944584a44Smrg out->serial = cookie->serial; 2100f1ee322dSmrg out->display = cookie->display; 2101f1ee322dSmrg out->extension = in->extension; 2102f1ee322dSmrg out->evtype = in->evtype; 2103f1ee322dSmrg out->send_event = ((in->type & 0x80) != 0); 2104f1ee322dSmrg out->time = in->time; 2105f1ee322dSmrg out->deviceid = in->deviceid; 2106f1ee322dSmrg out->sourceid = in->sourceid; 2107f1ee322dSmrg out->touchid = in->touchid; 2108f1ee322dSmrg out->root = in->root; 2109f1ee322dSmrg out->event = in->event; 2110f1ee322dSmrg out->child = in->child; 2111f1ee322dSmrg out->flags = in->flags; 2112f1ee322dSmrg 2113f1ee322dSmrg return 1; 2114f1ee322dSmrg} 2115f1ee322dSmrg 2116f1ee322dSmrgstatic int 2117f1ee322dSmrgwireToBarrierEvent(xXIBarrierEvent *in, XGenericEventCookie *cookie) 2118f1ee322dSmrg{ 2119f1ee322dSmrg XIBarrierEvent *out = malloc(sizeof(XIBarrierEvent)); 2120f1ee322dSmrg 2121f1ee322dSmrg cookie->data = out; 2122c6b4a769Smrg if (!out) 2123c6b4a769Smrg return 0; 2124f1ee322dSmrg 2125f1ee322dSmrg out->display = cookie->display; 2126f1ee322dSmrg out->type = in->type; 212744584a44Smrg out->serial = cookie->serial; 2128f1ee322dSmrg out->extension = in->extension; 2129f1ee322dSmrg out->evtype = in->evtype; 2130f1ee322dSmrg out->send_event = ((in->type & 0x80) != 0); 2131f1ee322dSmrg out->time = in->time; 2132f1ee322dSmrg out->deviceid = in->deviceid; 2133f1ee322dSmrg out->sourceid = in->sourceid; 2134f1ee322dSmrg out->event = in->event; 2135f1ee322dSmrg out->root = in->root; 2136f1ee322dSmrg out->root_x = FP1616toDBL(in->root_x); 2137f1ee322dSmrg out->root_y = FP1616toDBL(in->root_y); 2138f1ee322dSmrg out->dx = FP3232_TO_DOUBLE (in->dx); 2139f1ee322dSmrg out->dy = FP3232_TO_DOUBLE (in->dy); 2140f1ee322dSmrg out->dtime = in->dtime; 2141f1ee322dSmrg out->flags = in->flags; 2142f1ee322dSmrg out->barrier = in->barrier; 2143f1ee322dSmrg out->eventid = in->eventid; 2144f1ee322dSmrg 2145f1ee322dSmrg return 1; 2146f1ee322dSmrg} 214787404ef7Smrg 214887404ef7Smrgstatic int 214987404ef7SmrgwireToPinchEvent(xXIGesturePinchEvent *in, 215087404ef7Smrg XGenericEventCookie *cookie) 215187404ef7Smrg{ 215287404ef7Smrg XIGesturePinchEvent *out; 215387404ef7Smrg 215487404ef7Smrg cookie->data = out = malloc(sizeof(XIGesturePinchEvent)); 2155c6b4a769Smrg if (!out) 2156c6b4a769Smrg return 0; 215787404ef7Smrg 215887404ef7Smrg out->display = cookie->display; 215987404ef7Smrg out->type = in->type; 216087404ef7Smrg out->serial = cookie->serial; 216187404ef7Smrg out->extension = in->extension; 216287404ef7Smrg out->evtype = in->evtype; 216387404ef7Smrg out->send_event = ((in->type & 0x80) != 0); 216487404ef7Smrg out->time = in->time; 216587404ef7Smrg out->deviceid = in->deviceid; 216687404ef7Smrg out->sourceid = in->sourceid; 216787404ef7Smrg out->detail = in->detail; 216887404ef7Smrg out->root = in->root; 216987404ef7Smrg out->event = in->event; 217087404ef7Smrg out->child = in->child; 217187404ef7Smrg out->root_x = FP1616toDBL(in->root_x); 217287404ef7Smrg out->root_y = FP1616toDBL(in->root_y); 217387404ef7Smrg out->event_x = FP1616toDBL(in->event_x); 217487404ef7Smrg out->event_y = FP1616toDBL(in->event_y); 217587404ef7Smrg out->delta_x = FP1616toDBL(in->delta_x); 217687404ef7Smrg out->delta_y = FP1616toDBL(in->delta_y); 217787404ef7Smrg out->delta_unaccel_x = FP1616toDBL(in->delta_unaccel_x); 217887404ef7Smrg out->delta_unaccel_y = FP1616toDBL(in->delta_unaccel_y); 217987404ef7Smrg out->scale = FP1616toDBL(in->scale); 218087404ef7Smrg out->delta_angle = FP1616toDBL(in->delta_angle); 218187404ef7Smrg out->flags = in->flags; 218287404ef7Smrg 218387404ef7Smrg out->mods.base = in->mods.base_mods; 218487404ef7Smrg out->mods.locked = in->mods.locked_mods; 218587404ef7Smrg out->mods.latched = in->mods.latched_mods; 218687404ef7Smrg out->mods.effective = in->mods.effective_mods; 218787404ef7Smrg out->group.base = in->group.base_group; 218887404ef7Smrg out->group.locked = in->group.locked_group; 218987404ef7Smrg out->group.latched = in->group.latched_group; 219087404ef7Smrg out->group.effective = in->group.effective_group; 219187404ef7Smrg 219287404ef7Smrg return 1; 219387404ef7Smrg} 219487404ef7Smrg 219587404ef7Smrgstatic int 219687404ef7SmrgwireToSwipeEvent(xXIGestureSwipeEvent *in, 219787404ef7Smrg XGenericEventCookie *cookie) 219887404ef7Smrg{ 219987404ef7Smrg XIGestureSwipeEvent *out; 220087404ef7Smrg 220187404ef7Smrg cookie->data = out = malloc(sizeof(XIGestureSwipeEvent)); 2202c6b4a769Smrg if (!out) 2203c6b4a769Smrg return 0; 220487404ef7Smrg 220587404ef7Smrg out->display = cookie->display; 220687404ef7Smrg out->type = in->type; 220787404ef7Smrg out->serial = cookie->serial; 220887404ef7Smrg out->extension = in->extension; 220987404ef7Smrg out->evtype = in->evtype; 221087404ef7Smrg out->send_event = ((in->type & 0x80) != 0); 221187404ef7Smrg out->time = in->time; 221287404ef7Smrg out->deviceid = in->deviceid; 221387404ef7Smrg out->sourceid = in->sourceid; 221487404ef7Smrg out->detail = in->detail; 221587404ef7Smrg out->root = in->root; 221687404ef7Smrg out->event = in->event; 221787404ef7Smrg out->child = in->child; 221887404ef7Smrg out->root_x = FP1616toDBL(in->root_x); 221987404ef7Smrg out->root_y = FP1616toDBL(in->root_y); 222087404ef7Smrg out->event_x = FP1616toDBL(in->event_x); 222187404ef7Smrg out->event_y = FP1616toDBL(in->event_y); 222287404ef7Smrg out->delta_x = FP1616toDBL(in->delta_x); 222387404ef7Smrg out->delta_y = FP1616toDBL(in->delta_y); 222487404ef7Smrg out->delta_unaccel_x = FP1616toDBL(in->delta_unaccel_x); 222587404ef7Smrg out->delta_unaccel_y = FP1616toDBL(in->delta_unaccel_y); 222687404ef7Smrg out->flags = in->flags; 222787404ef7Smrg 222887404ef7Smrg out->mods.base = in->mods.base_mods; 222987404ef7Smrg out->mods.locked = in->mods.locked_mods; 223087404ef7Smrg out->mods.latched = in->mods.latched_mods; 223187404ef7Smrg out->mods.effective = in->mods.effective_mods; 223287404ef7Smrg out->group.base = in->group.base_group; 223387404ef7Smrg out->group.locked = in->group.locked_group; 223487404ef7Smrg out->group.latched = in->group.latched_group; 223587404ef7Smrg out->group.effective = in->group.effective_group; 223687404ef7Smrg 223787404ef7Smrg return 1; 223887404ef7Smrg} 2239