XExtInt.c revision c27c18e8
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 53c43cc173Smrg#define NEED_EVENTS 54c43cc173Smrg#define NEED_REPLIES 55c43cc173Smrg#include <stdio.h> 56c27c18e8Smrg#include <stdint.h> 57c43cc173Smrg#include <X11/extensions/XI.h> 58c27c18e8Smrg#include <X11/extensions/XI2.h> 59c43cc173Smrg#include <X11/extensions/XIproto.h> 60c27c18e8Smrg#include <X11/extensions/XI2proto.h> 61c43cc173Smrg#include <X11/Xlibint.h> 62c43cc173Smrg#include <X11/extensions/XInput.h> 63c27c18e8Smrg#include <X11/extensions/XInput2.h> 64c43cc173Smrg#include <X11/extensions/extutil.h> 65c27c18e8Smrg#include <X11/extensions/geproto.h> 66c27c18e8Smrg#include <X11/extensions/ge.h> 67c27c18e8Smrg#include <X11/extensions/Xge.h> 68c43cc173Smrg#include "XIint.h" 69c43cc173Smrg 70c43cc173Smrg#define ENQUEUE_EVENT True 71c43cc173Smrg#define DONT_ENQUEUE False 72c27c18e8Smrg#define FP1616toDBL(x) ((x) * 1.0 / (1 << 16)) 73c27c18e8Smrg 74c27c18e8Smrgextern void _xibaddevice( 75c27c18e8Smrg Display * /* dpy */, 76c27c18e8Smrg int * /* error */ 77c27c18e8Smrg); 78c27c18e8Smrg 79c27c18e8Smrgextern void _xibadclass( 80c27c18e8Smrg Display * /* dpy */, 81c27c18e8Smrg int * /* error */ 82c27c18e8Smrg); 83c27c18e8Smrg 84c27c18e8Smrgextern void _xibadevent( 85c27c18e8Smrg Display * /* dpy */, 86c27c18e8Smrg int * /* error */ 87c27c18e8Smrg); 88c27c18e8Smrg 89c27c18e8Smrgextern void _xibadmode( 90c27c18e8Smrg Display * /* dpy */, 91c27c18e8Smrg int * /* error */ 92c27c18e8Smrg); 93c27c18e8Smrg 94c27c18e8Smrgextern void _xidevicebusy( 95c27c18e8Smrg Display * /* dpy */, 96c27c18e8Smrg int * /* error */ 97c27c18e8Smrg); 98c27c18e8Smrg 99c27c18e8Smrgextern int _XiGetDevicePresenceNotifyEvent( 100c27c18e8Smrg Display * /* dpy */ 101c27c18e8Smrg); 102c27c18e8Smrg 103c27c18e8Smrgint copy_classes(XIDeviceInfo *to, xXIAnyInfo* from, int nclasses); 104c27c18e8Smrgint size_classes(xXIAnyInfo* from, int nclasses); 105c43cc173Smrg 106c43cc173Smrgstatic XExtensionInfo *xinput_info; 107c43cc173Smrgstatic /* const */ char *xinput_extension_name = INAME; 108c43cc173Smrg 109c27c18e8Smrgstatic int XInputClose( 110c27c18e8Smrg Display * /* dpy */, 111c27c18e8Smrg XExtCodes * /* codes */ 112c27c18e8Smrg); 113c27c18e8Smrg 114c27c18e8Smrgstatic char *XInputError( 115c27c18e8Smrg Display * /* dpy */, 116c27c18e8Smrg int /* code */, 117c27c18e8Smrg XExtCodes * /* codes */, 118c27c18e8Smrg char * /* buf */, 119c27c18e8Smrg int /* n */ 120c27c18e8Smrg); 121c27c18e8Smrg 122c27c18e8Smrgstatic Bool XInputWireToEvent( 123c27c18e8Smrg Display * /* dpy */, 124c27c18e8Smrg XEvent * /* re */, 125c27c18e8Smrg xEvent * /* event */ 126c27c18e8Smrg); 127c27c18e8Smrgstatic Bool XInputWireToCookie( 128c27c18e8Smrg Display* /* display */, 129c27c18e8Smrg XGenericEventCookie* /* re */, 130c27c18e8Smrg xEvent* /* event */ 131c27c18e8Smrg); 132c27c18e8Smrg 133c27c18e8Smrgstatic Bool XInputCopyCookie( 134c27c18e8Smrg Display* /* display */, 135c27c18e8Smrg XGenericEventCookie* /* in */, 136c27c18e8Smrg XGenericEventCookie* /* out */ 137c27c18e8Smrg); 138c27c18e8Smrg 139c27c18e8Smrgstatic int 140c27c18e8SmrgwireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* out); 141c27c18e8Smrgstatic int 142c27c18e8SmrgwireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie); 143c27c18e8Smrgstatic int 144c27c18e8SmrgwireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie); 145c27c18e8Smrgstatic int 146c27c18e8SmrgwireToRawEvent(xXIRawEvent *in, XGenericEventCookie *cookie); 147c27c18e8Smrgstatic int 148c27c18e8SmrgwireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie); 149c27c18e8Smrgstatic int 150c27c18e8SmrgwireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie); 151c27c18e8Smrg 152c27c18e8Smrgstatic /* const */ XEvent emptyevent; 153c43cc173Smrg 154c43cc173Smrgstatic /* const */ XExtensionHooks xinput_extension_hooks = { 155c43cc173Smrg NULL, /* create_gc */ 156c43cc173Smrg NULL, /* copy_gc */ 157c43cc173Smrg NULL, /* flush_gc */ 158c43cc173Smrg NULL, /* free_gc */ 159c43cc173Smrg NULL, /* create_font */ 160c43cc173Smrg NULL, /* free_font */ 161c43cc173Smrg XInputClose, /* close_display */ 162c43cc173Smrg XInputWireToEvent, /* wire_to_event */ 163c43cc173Smrg _XiEventToWire, /* event_to_wire */ 164c43cc173Smrg NULL, /* error */ 165c43cc173Smrg XInputError, /* error_string */ 166c43cc173Smrg}; 167c43cc173Smrg 168c43cc173Smrgstatic char *XInputErrorList[] = { 169c43cc173Smrg "BadDevice, invalid or uninitialized input device", /* BadDevice */ 170c43cc173Smrg "BadEvent, invalid event type", /* BadEvent */ 171c43cc173Smrg "BadMode, invalid mode parameter", /* BadMode */ 172c43cc173Smrg "DeviceBusy, device is busy", /* DeviceBusy */ 173c43cc173Smrg "BadClass, invalid event class", /* BadClass */ 174c43cc173Smrg}; 175c43cc173Smrg 176c27c18e8Smrg_X_HIDDEN 177c27c18e8SmrgXExtDisplayInfo *XInput_find_display (Display *dpy) 178c27c18e8Smrg{ 179c27c18e8Smrg XExtDisplayInfo *dpyinfo; 180c27c18e8Smrg if (!xinput_info) { if (!(xinput_info = XextCreateExtension())) return NULL; } 181c27c18e8Smrg if (!(dpyinfo = XextFindDisplay (xinput_info, dpy))) 182c27c18e8Smrg { 183c27c18e8Smrg dpyinfo = XextAddDisplay (xinput_info, dpy, 184c27c18e8Smrg xinput_extension_name, 185c27c18e8Smrg &xinput_extension_hooks, 186c27c18e8Smrg IEVENTS, NULL); 187c27c18e8Smrg XESetWireToEventCookie(dpy, dpyinfo->codes->major_opcode, XInputWireToCookie); 188c27c18e8Smrg XESetCopyEventCookie(dpy, dpyinfo->codes->major_opcode, XInputCopyCookie); 189c27c18e8Smrg } 190c27c18e8Smrg return dpyinfo; 191c27c18e8Smrg} 192c43cc173Smrg 193c27c18e8Smrgstatic XEXT_GENERATE_ERROR_STRING(XInputError, xinput_extension_name, 194c27c18e8Smrg IERRORS, XInputErrorList) 195c43cc173Smrg/******************************************************************* 196c27c18e8Smrg* 197c27c18e8Smrg* Input extension versions. 198c27c18e8Smrg* 199c27c18e8Smrg*/ 200c27c18e8Smrgstatic XExtensionVersion versions[] = { {XI_Absent, 0, 0}, 201c27c18e8Smrg{XI_Present, XI_Initial_Release_Major, XI_Initial_Release_Minor}, 202c27c18e8Smrg{XI_Present, XI_Add_XDeviceBell_Major, XI_Add_XDeviceBell_Minor}, 203c27c18e8Smrg{XI_Present, XI_Add_XSetDeviceValuators_Major, 204c27c18e8Smrg XI_Add_XSetDeviceValuators_Minor}, 205c27c18e8Smrg{XI_Present, XI_Add_XChangeDeviceControl_Major, 206c27c18e8Smrg XI_Add_XChangeDeviceControl_Minor}, 207c27c18e8Smrg{XI_Present, XI_Add_DevicePresenceNotify_Major, 208c27c18e8Smrg XI_Add_DevicePresenceNotify_Minor}, 209c27c18e8Smrg{XI_Present, XI_Add_DeviceProperties_Major, 210c27c18e8Smrg XI_Add_DeviceProperties_Minor}, 211c27c18e8Smrg{XI_Present, XI_2_Major, XI_2_Minor} 212c27c18e8Smrg}; 213c43cc173Smrg 214c43cc173Smrg/*********************************************************************** 215c43cc173Smrg * 216c43cc173Smrg * Return errors reported by this extension. 217c43cc173Smrg * 218c43cc173Smrg */ 219c43cc173Smrg 220c43cc173Smrgvoid 221c27c18e8Smrg_xibaddevice( 222c27c18e8Smrg Display *dpy, 223c27c18e8Smrg int *error) 224c43cc173Smrg{ 225c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 226c43cc173Smrg 227c43cc173Smrg *error = info->codes->first_error + XI_BadDevice; 228c43cc173Smrg} 229c43cc173Smrg 230c43cc173Smrgvoid 231c27c18e8Smrg_xibadclass( 232c27c18e8Smrg Display *dpy, 233c27c18e8Smrg int *error) 234c43cc173Smrg{ 235c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 236c43cc173Smrg 237c43cc173Smrg *error = info->codes->first_error + XI_BadClass; 238c43cc173Smrg} 239c43cc173Smrg 240c43cc173Smrgvoid 241c27c18e8Smrg_xibadevent( 242c27c18e8Smrg Display *dpy, 243c27c18e8Smrg int *error) 244c43cc173Smrg{ 245c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 246c43cc173Smrg 247c43cc173Smrg *error = info->codes->first_error + XI_BadEvent; 248c43cc173Smrg} 249c43cc173Smrg 250c43cc173Smrgvoid 251c27c18e8Smrg_xibadmode( 252c27c18e8Smrg Display *dpy, 253c27c18e8Smrg int *error) 254c43cc173Smrg{ 255c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 256c43cc173Smrg 257c43cc173Smrg *error = info->codes->first_error + XI_BadMode; 258c43cc173Smrg} 259c43cc173Smrg 260c43cc173Smrgvoid 261c27c18e8Smrg_xidevicebusy( 262c27c18e8Smrg Display *dpy, 263c27c18e8Smrg int *error) 264c43cc173Smrg{ 265c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 266c43cc173Smrg 267c43cc173Smrg *error = info->codes->first_error + XI_DeviceBusy; 268c43cc173Smrg} 269c43cc173Smrg 270c43cc173Smrgstatic int XInputCheckExtension(Display *dpy, XExtDisplayInfo *info) 271c43cc173Smrg{ 272c43cc173Smrg XextCheckExtension (dpy, info, xinput_extension_name, 0); 273c43cc173Smrg return 1; 274c43cc173Smrg} 275c43cc173Smrg 276c43cc173Smrg/*********************************************************************** 277c43cc173Smrg * 278c43cc173Smrg * Check to see if the input extension is installed in the server. 279c43cc173Smrg * Also check to see if the version is >= the requested version. 280c43cc173Smrg * 281c43cc173Smrg */ 282c43cc173Smrg 283c27c18e8Smrg_X_HIDDEN int 284c27c18e8Smrg_XiCheckExtInit( 285c27c18e8Smrg register Display *dpy, 286c27c18e8Smrg register int version_index, 287c27c18e8Smrg XExtDisplayInfo *info) 288c43cc173Smrg{ 289c43cc173Smrg XExtensionVersion *ext; 290c43cc173Smrg 291c43cc173Smrg if (!XInputCheckExtension(dpy, info)) { 292c43cc173Smrg UnlockDisplay(dpy); 293c43cc173Smrg return (-1); 294c43cc173Smrg } 295c43cc173Smrg 296c43cc173Smrg if (info->data == NULL) { 297c43cc173Smrg info->data = (XPointer) Xmalloc(sizeof(XInputData)); 298c43cc173Smrg if (!info->data) { 299c43cc173Smrg UnlockDisplay(dpy); 300c43cc173Smrg return (-1); 301c43cc173Smrg } 302c43cc173Smrg ((XInputData *) info->data)->vers = 303c43cc173Smrg _XiGetExtensionVersion(dpy, "XInputExtension", info); 304c43cc173Smrg } 305c43cc173Smrg 306c43cc173Smrg if (versions[version_index].major_version > Dont_Check) { 307c43cc173Smrg ext = ((XInputData *) info->data)->vers; 308c43cc173Smrg if ((ext->major_version < versions[version_index].major_version) || 309c43cc173Smrg ((ext->major_version == versions[version_index].major_version) && 310c43cc173Smrg (ext->minor_version < versions[version_index].minor_version))) { 311c43cc173Smrg UnlockDisplay(dpy); 312c43cc173Smrg return (-1); 313c43cc173Smrg } 314c43cc173Smrg } 315c43cc173Smrg return (0); 316c43cc173Smrg} 317c43cc173Smrg 318c43cc173Smrg/*********************************************************************** 319c43cc173Smrg * 320c43cc173Smrg * Close display routine. 321c43cc173Smrg * 322c43cc173Smrg */ 323c43cc173Smrg 324c43cc173Smrgstatic int 325c27c18e8SmrgXInputClose( 326c27c18e8Smrg Display *dpy, 327c27c18e8Smrg XExtCodes *codes) 328c43cc173Smrg{ 329c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 330c43cc173Smrg 331c43cc173Smrg if (info->data != NULL) { 332c43cc173Smrg XFree((char *)((XInputData *) info->data)->vers); 333c43cc173Smrg XFree((char *)info->data); 334c43cc173Smrg } 335c43cc173Smrg return XextRemoveDisplay(xinput_info, dpy); 336c43cc173Smrg} 337c43cc173Smrg 338c43cc173Smrgstatic int 339c27c18e8SmrgOnes(Mask mask) 340c43cc173Smrg{ 341c43cc173Smrg register Mask y; 342c43cc173Smrg 343c43cc173Smrg y = (mask >> 1) & 033333333333; 344c43cc173Smrg y = mask - y - ((y >> 1) & 033333333333); 345c43cc173Smrg return (((y + (y >> 3)) & 030707070707) % 077); 346c43cc173Smrg} 347c43cc173Smrg 348c27c18e8Smrgstatic int count_bits(unsigned char* ptr, int len) 349c27c18e8Smrg{ 350c27c18e8Smrg int bits = 0; 351c27c18e8Smrg unsigned int i; 352c27c18e8Smrg unsigned char x; 353c27c18e8Smrg 354c27c18e8Smrg for (i = 0; i < len; i++) 355c27c18e8Smrg { 356c27c18e8Smrg x = ptr[i]; 357c27c18e8Smrg while(x > 0) 358c27c18e8Smrg { 359c27c18e8Smrg bits += (x & 0x1); 360c27c18e8Smrg x >>= 1; 361c27c18e8Smrg } 362c27c18e8Smrg } 363c27c18e8Smrg return bits; 364c27c18e8Smrg} 365c27c18e8Smrg 366c43cc173Smrgint 367c43cc173Smrg_XiGetDevicePresenceNotifyEvent(Display * dpy) 368c43cc173Smrg{ 369c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 370c43cc173Smrg 371c43cc173Smrg return info->codes->first_event + XI_DevicePresenceNotify; 372c43cc173Smrg} 373c43cc173Smrg 374c43cc173Smrg/*********************************************************************** 375c43cc173Smrg * 376c43cc173Smrg * Handle Input extension events. 377c43cc173Smrg * Reformat a wire event into an XEvent structure of the right type. 378c43cc173Smrg * 379c43cc173Smrg */ 380c43cc173Smrg 381c43cc173Smrgstatic Bool 382c27c18e8SmrgXInputWireToEvent( 383c27c18e8Smrg Display *dpy, 384c27c18e8Smrg XEvent *re, 385c27c18e8Smrg xEvent *event) 386c43cc173Smrg{ 387c43cc173Smrg unsigned int type, reltype; 388c43cc173Smrg unsigned int i, j; 389c43cc173Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 390c43cc173Smrg XEvent *save = (XEvent *) info->data; 391c43cc173Smrg 392c43cc173Smrg type = event->u.u.type & 0x7f; 393c43cc173Smrg reltype = (type - info->codes->first_event); 394c43cc173Smrg 395c27c18e8Smrg if (type == GenericEvent || 396c27c18e8Smrg (reltype != XI_DeviceValuator && 397c43cc173Smrg reltype != XI_DeviceKeystateNotify && 398c27c18e8Smrg reltype != XI_DeviceButtonstateNotify)) { 399c43cc173Smrg *save = emptyevent; 400c43cc173Smrg save->type = type; 401c43cc173Smrg ((XAnyEvent *) save)->serial = _XSetLastRequestRead(dpy, 402c43cc173Smrg (xGenericReply *) 403c43cc173Smrg event); 404c43cc173Smrg ((XAnyEvent *) save)->send_event = ((event->u.u.type & 0x80) != 0); 405c43cc173Smrg ((XAnyEvent *) save)->display = dpy; 406c43cc173Smrg } 407c43cc173Smrg 408c27c18e8Smrg /* Process traditional events */ 409c27c18e8Smrg if (type != GenericEvent) 410c43cc173Smrg { 411c27c18e8Smrg switch (reltype) { 412c27c18e8Smrg case XI_DeviceMotionNotify: 413c27c18e8Smrg { 414c27c18e8Smrg register XDeviceMotionEvent *ev = (XDeviceMotionEvent *) save; 415c27c18e8Smrg deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 416c27c18e8Smrg 417c27c18e8Smrg ev->root = ev2->root; 418c27c18e8Smrg ev->window = ev2->event; 419c27c18e8Smrg ev->subwindow = ev2->child; 420c27c18e8Smrg ev->time = ev2->time; 421c27c18e8Smrg ev->x_root = ev2->root_x; 422c27c18e8Smrg ev->y_root = ev2->root_y; 423c27c18e8Smrg ev->x = ev2->event_x; 424c27c18e8Smrg ev->y = ev2->event_y; 425c27c18e8Smrg ev->state = ev2->state; 426c27c18e8Smrg ev->same_screen = ev2->same_screen; 427c27c18e8Smrg ev->is_hint = ev2->detail; 428c27c18e8Smrg ev->deviceid = ev2->deviceid & DEVICE_BITS; 429c27c18e8Smrg return (DONT_ENQUEUE); 430c27c18e8Smrg } 431c27c18e8Smrg break; 432c27c18e8Smrg case XI_DeviceKeyPress: 433c27c18e8Smrg case XI_DeviceKeyRelease: 434c27c18e8Smrg { 435c27c18e8Smrg register XDeviceKeyEvent *ev = (XDeviceKeyEvent *) save; 436c27c18e8Smrg deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 437c27c18e8Smrg 438c27c18e8Smrg ev->root = ev2->root; 439c27c18e8Smrg ev->window = ev2->event; 440c27c18e8Smrg ev->subwindow = ev2->child; 441c27c18e8Smrg ev->time = ev2->time; 442c27c18e8Smrg ev->x_root = ev2->root_x; 443c27c18e8Smrg ev->y_root = ev2->root_y; 444c27c18e8Smrg ev->x = ev2->event_x; 445c27c18e8Smrg ev->y = ev2->event_y; 446c27c18e8Smrg ev->state = ev2->state; 447c27c18e8Smrg ev->same_screen = ev2->same_screen; 448c27c18e8Smrg ev->keycode = ev2->detail; 449c27c18e8Smrg ev->deviceid = ev2->deviceid & DEVICE_BITS; 450c27c18e8Smrg if (ev2->deviceid & MORE_EVENTS) 451c27c18e8Smrg return (DONT_ENQUEUE); 452c27c18e8Smrg else { 453c27c18e8Smrg *re = *save; 454c27c18e8Smrg return (ENQUEUE_EVENT); 455c27c18e8Smrg } 456c27c18e8Smrg } 457c27c18e8Smrg break; 458c27c18e8Smrg case XI_DeviceButtonPress: 459c27c18e8Smrg case XI_DeviceButtonRelease: 460c27c18e8Smrg { 461c27c18e8Smrg register XDeviceButtonEvent *ev = (XDeviceButtonEvent *) save; 462c27c18e8Smrg deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 463c27c18e8Smrg 464c27c18e8Smrg ev->root = ev2->root; 465c27c18e8Smrg ev->window = ev2->event; 466c27c18e8Smrg ev->subwindow = ev2->child; 467c27c18e8Smrg ev->time = ev2->time; 468c27c18e8Smrg ev->x_root = ev2->root_x; 469c27c18e8Smrg ev->y_root = ev2->root_y; 470c27c18e8Smrg ev->x = ev2->event_x; 471c27c18e8Smrg ev->y = ev2->event_y; 472c27c18e8Smrg ev->state = ev2->state; 473c27c18e8Smrg ev->same_screen = ev2->same_screen; 474c27c18e8Smrg ev->button = ev2->detail; 475c27c18e8Smrg ev->deviceid = ev2->deviceid & DEVICE_BITS; 476c27c18e8Smrg if (ev2->deviceid & MORE_EVENTS) 477c27c18e8Smrg return (DONT_ENQUEUE); 478c27c18e8Smrg else { 479c27c18e8Smrg *re = *save; 480c27c18e8Smrg return (ENQUEUE_EVENT); 481c27c18e8Smrg } 482c27c18e8Smrg } 483c27c18e8Smrg break; 484c27c18e8Smrg case XI_ProximityIn: 485c27c18e8Smrg case XI_ProximityOut: 486c27c18e8Smrg { 487c27c18e8Smrg register XProximityNotifyEvent *ev = (XProximityNotifyEvent *) save; 488c27c18e8Smrg deviceKeyButtonPointer *ev2 = (deviceKeyButtonPointer *) event; 489c27c18e8Smrg 490c27c18e8Smrg ev->root = ev2->root; 491c27c18e8Smrg ev->window = ev2->event; 492c27c18e8Smrg ev->subwindow = ev2->child; 493c27c18e8Smrg ev->time = ev2->time; 494c27c18e8Smrg ev->x_root = ev2->root_x; 495c27c18e8Smrg ev->y_root = ev2->root_y; 496c27c18e8Smrg ev->x = ev2->event_x; 497c27c18e8Smrg ev->y = ev2->event_y; 498c27c18e8Smrg ev->state = ev2->state; 499c27c18e8Smrg ev->same_screen = ev2->same_screen; 500c27c18e8Smrg ev->deviceid = ev2->deviceid & DEVICE_BITS; 501c27c18e8Smrg if (ev2->deviceid & MORE_EVENTS) 502c27c18e8Smrg return (DONT_ENQUEUE); 503c27c18e8Smrg else { 504c27c18e8Smrg *re = *save; 505c27c18e8Smrg return (ENQUEUE_EVENT); 506c27c18e8Smrg } 507c27c18e8Smrg } 508c27c18e8Smrg break; 509c27c18e8Smrg case XI_DeviceValuator: 510c27c18e8Smrg { 511c27c18e8Smrg deviceValuator *xev = (deviceValuator *) event; 512c27c18e8Smrg int save_type = save->type - info->codes->first_event; 513c27c18e8Smrg 514c27c18e8Smrg if (save_type == XI_DeviceKeyPress || save_type == XI_DeviceKeyRelease) { 515c27c18e8Smrg XDeviceKeyEvent *kev = (XDeviceKeyEvent *) save; 516c27c18e8Smrg 517c27c18e8Smrg kev->device_state = xev->device_state; 518c27c18e8Smrg kev->axes_count = xev->num_valuators; 519c27c18e8Smrg kev->first_axis = xev->first_valuator; 520c27c18e8Smrg i = xev->num_valuators; 521c27c18e8Smrg if (i > 6) 522c27c18e8Smrg i = 6; 523c27c18e8Smrg switch (i) { 524c27c18e8Smrg case 6: 525c27c18e8Smrg kev->axis_data[5] = xev->valuator5; 526c27c18e8Smrg case 5: 527c27c18e8Smrg kev->axis_data[4] = xev->valuator4; 528c27c18e8Smrg case 4: 529c27c18e8Smrg kev->axis_data[3] = xev->valuator3; 530c27c18e8Smrg case 3: 531c27c18e8Smrg kev->axis_data[2] = xev->valuator2; 532c27c18e8Smrg case 2: 533c27c18e8Smrg kev->axis_data[1] = xev->valuator1; 534c27c18e8Smrg case 1: 535c27c18e8Smrg kev->axis_data[0] = xev->valuator0; 536c27c18e8Smrg } 537c27c18e8Smrg } else if (save_type == XI_DeviceButtonPress || 538c27c18e8Smrg save_type == XI_DeviceButtonRelease) { 539c27c18e8Smrg XDeviceButtonEvent *bev = (XDeviceButtonEvent *) save; 540c27c18e8Smrg 541c27c18e8Smrg bev->device_state = xev->device_state; 542c27c18e8Smrg bev->axes_count = xev->num_valuators; 543c27c18e8Smrg bev->first_axis = xev->first_valuator; 544c27c18e8Smrg i = xev->num_valuators; 545c27c18e8Smrg if (i > 6) 546c27c18e8Smrg i = 6; 547c27c18e8Smrg switch (i) { 548c27c18e8Smrg case 6: 549c27c18e8Smrg bev->axis_data[5] = xev->valuator5; 550c27c18e8Smrg case 5: 551c27c18e8Smrg bev->axis_data[4] = xev->valuator4; 552c27c18e8Smrg case 4: 553c27c18e8Smrg bev->axis_data[3] = xev->valuator3; 554c27c18e8Smrg case 3: 555c27c18e8Smrg bev->axis_data[2] = xev->valuator2; 556c27c18e8Smrg case 2: 557c27c18e8Smrg bev->axis_data[1] = xev->valuator1; 558c27c18e8Smrg case 1: 559c27c18e8Smrg bev->axis_data[0] = xev->valuator0; 560c27c18e8Smrg } 561c27c18e8Smrg } else if (save_type == XI_DeviceMotionNotify) { 562c27c18e8Smrg XDeviceMotionEvent *mev = (XDeviceMotionEvent *) save; 563c27c18e8Smrg 564c27c18e8Smrg mev->device_state = xev->device_state; 565c27c18e8Smrg mev->axes_count = xev->num_valuators; 566c27c18e8Smrg mev->first_axis = xev->first_valuator; 567c27c18e8Smrg i = xev->num_valuators; 568c27c18e8Smrg if (i > 6) 569c27c18e8Smrg i = 6; 570c27c18e8Smrg switch (i) { 571c27c18e8Smrg case 6: 572c27c18e8Smrg mev->axis_data[5] = xev->valuator5; 573c27c18e8Smrg case 5: 574c27c18e8Smrg mev->axis_data[4] = xev->valuator4; 575c27c18e8Smrg case 4: 576c27c18e8Smrg mev->axis_data[3] = xev->valuator3; 577c27c18e8Smrg case 3: 578c27c18e8Smrg mev->axis_data[2] = xev->valuator2; 579c27c18e8Smrg case 2: 580c27c18e8Smrg mev->axis_data[1] = xev->valuator1; 581c27c18e8Smrg case 1: 582c27c18e8Smrg mev->axis_data[0] = xev->valuator0; 583c27c18e8Smrg } 584c27c18e8Smrg } else if (save_type == XI_ProximityIn || save_type == XI_ProximityOut) { 585c27c18e8Smrg XProximityNotifyEvent *pev = (XProximityNotifyEvent *) save; 586c27c18e8Smrg 587c27c18e8Smrg pev->device_state = xev->device_state; 588c27c18e8Smrg pev->axes_count = xev->num_valuators; 589c27c18e8Smrg pev->first_axis = xev->first_valuator; 590c27c18e8Smrg i = xev->num_valuators; 591c27c18e8Smrg if (i > 6) 592c27c18e8Smrg i = 6; 593c27c18e8Smrg switch (i) { 594c27c18e8Smrg case 6: 595c27c18e8Smrg pev->axis_data[5] = xev->valuator5; 596c27c18e8Smrg case 5: 597c27c18e8Smrg pev->axis_data[4] = xev->valuator4; 598c27c18e8Smrg case 4: 599c27c18e8Smrg pev->axis_data[3] = xev->valuator3; 600c27c18e8Smrg case 3: 601c27c18e8Smrg pev->axis_data[2] = xev->valuator2; 602c27c18e8Smrg case 2: 603c27c18e8Smrg pev->axis_data[1] = xev->valuator1; 604c27c18e8Smrg case 1: 605c27c18e8Smrg pev->axis_data[0] = xev->valuator0; 606c27c18e8Smrg } 607c27c18e8Smrg } else if (save_type == XI_DeviceStateNotify) { 608c27c18e8Smrg XDeviceStateNotifyEvent *sev = (XDeviceStateNotifyEvent *) save; 609c27c18e8Smrg XInputClass *any = (XInputClass *) & sev->data[0]; 610c27c18e8Smrg XValuatorStatus *v; 611c27c18e8Smrg 612c27c18e8Smrg for (i = 0; i < sev->num_classes; i++) 613c27c18e8Smrg if (any->class != ValuatorClass) 614c27c18e8Smrg any = (XInputClass *) ((char *)any + any->length); 615c27c18e8Smrg v = (XValuatorStatus *) any; 616c27c18e8Smrg i = v->num_valuators; 617c27c18e8Smrg j = xev->num_valuators; 618c27c18e8Smrg if (j > 3) 619c27c18e8Smrg j = 3; 620c27c18e8Smrg switch (j) { 621c27c18e8Smrg case 3: 622c27c18e8Smrg v->valuators[i + 2] = xev->valuator2; 623c27c18e8Smrg case 2: 624c27c18e8Smrg v->valuators[i + 1] = xev->valuator1; 625c27c18e8Smrg case 1: 626c27c18e8Smrg v->valuators[i + 0] = xev->valuator0; 627c27c18e8Smrg } 628c27c18e8Smrg v->num_valuators += j; 629c27c18e8Smrg 630c27c18e8Smrg } 631c27c18e8Smrg *re = *save; 632c27c18e8Smrg return (ENQUEUE_EVENT); 633c27c18e8Smrg } 634c27c18e8Smrg break; 635c27c18e8Smrg case XI_DeviceFocusIn: 636c27c18e8Smrg case XI_DeviceFocusOut: 637c27c18e8Smrg { 638c27c18e8Smrg register XDeviceFocusChangeEvent *ev = (XDeviceFocusChangeEvent *) re; 639c27c18e8Smrg deviceFocus *fev = (deviceFocus *) event; 640c27c18e8Smrg 641c27c18e8Smrg *ev = *((XDeviceFocusChangeEvent *) save); 642c27c18e8Smrg ev->window = fev->window; 643c27c18e8Smrg ev->time = fev->time; 644c27c18e8Smrg ev->mode = fev->mode; 645c27c18e8Smrg ev->detail = fev->detail; 646c27c18e8Smrg ev->deviceid = fev->deviceid & DEVICE_BITS; 647c27c18e8Smrg return (ENQUEUE_EVENT); 648c27c18e8Smrg } 649c27c18e8Smrg break; 650c27c18e8Smrg case XI_DeviceStateNotify: 651c27c18e8Smrg { 652c27c18e8Smrg XDeviceStateNotifyEvent *stev = (XDeviceStateNotifyEvent *) save; 653c27c18e8Smrg deviceStateNotify *sev = (deviceStateNotify *) event; 654c27c18e8Smrg char *data; 655c27c18e8Smrg 656c27c18e8Smrg stev->window = None; 657c27c18e8Smrg stev->deviceid = sev->deviceid & DEVICE_BITS; 658c27c18e8Smrg stev->time = sev->time; 659c27c18e8Smrg stev->num_classes = Ones((Mask) sev->classes_reported & InputClassBits); 660c27c18e8Smrg data = (char *)&stev->data[0]; 661c27c18e8Smrg if (sev->classes_reported & (1 << KeyClass)) { 662c27c18e8Smrg register XKeyStatus *kstev = (XKeyStatus *) data; 663c27c18e8Smrg 664c27c18e8Smrg kstev->class = KeyClass; 665c27c18e8Smrg kstev->length = sizeof(XKeyStatus); 666c27c18e8Smrg kstev->num_keys = sev->num_keys; 667c27c18e8Smrg memcpy((char *)&kstev->keys[0], (char *)&sev->keys[0], 4); 668c27c18e8Smrg data += sizeof(XKeyStatus); 669c27c18e8Smrg } 670c27c18e8Smrg if (sev->classes_reported & (1 << ButtonClass)) { 671c27c18e8Smrg register XButtonStatus *bev = (XButtonStatus *) data; 672c27c18e8Smrg 673c27c18e8Smrg bev->class = ButtonClass; 674c27c18e8Smrg bev->length = sizeof(XButtonStatus); 675c27c18e8Smrg bev->num_buttons = sev->num_buttons; 676c27c18e8Smrg memcpy((char *)bev->buttons, (char *)sev->buttons, 4); 677c27c18e8Smrg data += sizeof(XButtonStatus); 678c27c18e8Smrg } 679c27c18e8Smrg if (sev->classes_reported & (1 << ValuatorClass)) { 680c27c18e8Smrg register XValuatorStatus *vev = (XValuatorStatus *) data; 681c27c18e8Smrg 682c27c18e8Smrg vev->class = ValuatorClass; 683c27c18e8Smrg vev->length = sizeof(XValuatorStatus); 684c27c18e8Smrg vev->num_valuators = sev->num_valuators; 685c27c18e8Smrg vev->mode = sev->classes_reported >> ModeBitsShift; 686c27c18e8Smrg j = sev->num_valuators; 687c27c18e8Smrg if (j > 3) 688c27c18e8Smrg j = 3; 689c27c18e8Smrg switch (j) { 690c27c18e8Smrg case 3: 691c27c18e8Smrg vev->valuators[2] = sev->valuator2; 692c27c18e8Smrg case 2: 693c27c18e8Smrg vev->valuators[1] = sev->valuator1; 694c27c18e8Smrg case 1: 695c27c18e8Smrg vev->valuators[0] = sev->valuator0; 696c27c18e8Smrg } 697c27c18e8Smrg data += sizeof(XValuatorStatus); 698c27c18e8Smrg } 699c27c18e8Smrg if (sev->deviceid & MORE_EVENTS) 700c27c18e8Smrg return (DONT_ENQUEUE); 701c27c18e8Smrg else { 702c27c18e8Smrg *re = *save; 703c27c18e8Smrg stev = (XDeviceStateNotifyEvent *) re; 704c27c18e8Smrg return (ENQUEUE_EVENT); 705c27c18e8Smrg } 706c27c18e8Smrg } 707c27c18e8Smrg break; 708c27c18e8Smrg case XI_DeviceKeystateNotify: 709c27c18e8Smrg { 710c27c18e8Smrg int i; 711c27c18e8Smrg XInputClass *anyclass; 712c27c18e8Smrg register XKeyStatus *kv; 713c27c18e8Smrg deviceKeyStateNotify *ksev = (deviceKeyStateNotify *) event; 714c27c18e8Smrg XDeviceStateNotifyEvent *kstev = (XDeviceStateNotifyEvent *) save; 715c27c18e8Smrg 716c27c18e8Smrg anyclass = (XInputClass *) & kstev->data[0]; 717c27c18e8Smrg for (i = 0; i < kstev->num_classes; i++) 718c27c18e8Smrg if (anyclass->class == KeyClass) 719c27c18e8Smrg break; 720c27c18e8Smrg else 721c27c18e8Smrg anyclass = (XInputClass *) ((char *)anyclass + 722c27c18e8Smrg anyclass->length); 723c27c18e8Smrg 724c27c18e8Smrg kv = (XKeyStatus *) anyclass; 725c27c18e8Smrg kv->num_keys = 256; 726c27c18e8Smrg memcpy((char *)&kv->keys[4], (char *)ksev->keys, 28); 727c27c18e8Smrg if (ksev->deviceid & MORE_EVENTS) 728c27c18e8Smrg return (DONT_ENQUEUE); 729c27c18e8Smrg else { 730c27c18e8Smrg *re = *save; 731c27c18e8Smrg kstev = (XDeviceStateNotifyEvent *) re; 732c27c18e8Smrg return (ENQUEUE_EVENT); 733c27c18e8Smrg } 734c27c18e8Smrg } 735c27c18e8Smrg break; 736c27c18e8Smrg case XI_DeviceButtonstateNotify: 737c27c18e8Smrg { 738c27c18e8Smrg int i; 739c27c18e8Smrg XInputClass *anyclass; 740c27c18e8Smrg register XButtonStatus *bv; 741c27c18e8Smrg deviceButtonStateNotify *bsev = (deviceButtonStateNotify *) event; 742c27c18e8Smrg XDeviceStateNotifyEvent *bstev = (XDeviceStateNotifyEvent *) save; 743c27c18e8Smrg 744c27c18e8Smrg anyclass = (XInputClass *) & bstev->data[0]; 745c27c18e8Smrg for (i = 0; i < bstev->num_classes; i++) 746c27c18e8Smrg if (anyclass->class == ButtonClass) 747c27c18e8Smrg break; 748c27c18e8Smrg else 749c27c18e8Smrg anyclass = (XInputClass *) ((char *)anyclass + 750c27c18e8Smrg anyclass->length); 751c27c18e8Smrg 752c27c18e8Smrg bv = (XButtonStatus *) anyclass; 753c27c18e8Smrg bv->num_buttons = 256; 754c27c18e8Smrg memcpy((char *)&bv->buttons[4], (char *)bsev->buttons, 28); 755c27c18e8Smrg if (bsev->deviceid & MORE_EVENTS) 756c27c18e8Smrg return (DONT_ENQUEUE); 757c27c18e8Smrg else { 758c27c18e8Smrg *re = *save; 759c27c18e8Smrg bstev = (XDeviceStateNotifyEvent *) re; 760c27c18e8Smrg return (ENQUEUE_EVENT); 761c27c18e8Smrg } 762c27c18e8Smrg } 763c27c18e8Smrg break; 764c27c18e8Smrg case XI_DeviceMappingNotify: 765c27c18e8Smrg { 766c27c18e8Smrg register XDeviceMappingEvent *ev = (XDeviceMappingEvent *) re; 767c27c18e8Smrg deviceMappingNotify *ev2 = (deviceMappingNotify *) event; 768c27c18e8Smrg 769c27c18e8Smrg *ev = *((XDeviceMappingEvent *) save); 770c27c18e8Smrg ev->window = 0; 771c27c18e8Smrg ev->first_keycode = ev2->firstKeyCode; 772c27c18e8Smrg ev->request = ev2->request; 773c27c18e8Smrg ev->count = ev2->count; 774c27c18e8Smrg ev->time = ev2->time; 775c27c18e8Smrg ev->deviceid = ev2->deviceid & DEVICE_BITS; 776c27c18e8Smrg return (ENQUEUE_EVENT); 777c27c18e8Smrg } 778c27c18e8Smrg break; 779c27c18e8Smrg case XI_ChangeDeviceNotify: 780c27c18e8Smrg { 781c27c18e8Smrg register XChangeDeviceNotifyEvent *ev = (XChangeDeviceNotifyEvent *) re; 782c27c18e8Smrg changeDeviceNotify *ev2 = (changeDeviceNotify *) event; 783c27c18e8Smrg 784c27c18e8Smrg *ev = *((XChangeDeviceNotifyEvent *) save); 785c27c18e8Smrg ev->window = 0; 786c27c18e8Smrg ev->request = ev2->request; 787c27c18e8Smrg ev->time = ev2->time; 788c27c18e8Smrg ev->deviceid = ev2->deviceid & DEVICE_BITS; 789c27c18e8Smrg return (ENQUEUE_EVENT); 790c27c18e8Smrg } 791c27c18e8Smrg break; 792c27c18e8Smrg 793c27c18e8Smrg case XI_DevicePresenceNotify: 794c27c18e8Smrg { 795c27c18e8Smrg XDevicePresenceNotifyEvent *ev = (XDevicePresenceNotifyEvent *) re; 796c27c18e8Smrg devicePresenceNotify *ev2 = (devicePresenceNotify *) event; 797c27c18e8Smrg 798c27c18e8Smrg *ev = *(XDevicePresenceNotifyEvent *) save; 799c27c18e8Smrg ev->window = 0; 800c27c18e8Smrg ev->time = ev2->time; 801c27c18e8Smrg ev->devchange = ev2->devchange; 802c27c18e8Smrg ev->deviceid = ev2->deviceid; 803c27c18e8Smrg ev->control = ev2->control; 804c27c18e8Smrg return (ENQUEUE_EVENT); 805c27c18e8Smrg } 806c27c18e8Smrg break; 807c27c18e8Smrg case XI_DevicePropertyNotify: 808c27c18e8Smrg { 809c27c18e8Smrg XDevicePropertyNotifyEvent* ev = (XDevicePropertyNotifyEvent*)re; 810c27c18e8Smrg devicePropertyNotify *ev2 = (devicePropertyNotify*)event; 811c27c18e8Smrg 812c27c18e8Smrg *ev = *(XDevicePropertyNotifyEvent*)save; 813c27c18e8Smrg ev->time = ev2->time; 814c27c18e8Smrg ev->deviceid = ev2->deviceid; 815c27c18e8Smrg ev->atom = ev2->atom; 816c27c18e8Smrg ev->state = ev2->state; 817c27c18e8Smrg return ENQUEUE_EVENT; 818c27c18e8Smrg } 819c27c18e8Smrg break; 820c27c18e8Smrg default: 821c27c18e8Smrg printf("XInputWireToEvent: UNKNOWN WIRE EVENT! type=%d\n", type); 822c27c18e8Smrg break; 823c27c18e8Smrg } 824c43cc173Smrg } 825c27c18e8Smrg return (DONT_ENQUEUE); 826c27c18e8Smrg} 827c27c18e8Smrg 828c27c18e8Smrgstatic void xge_copy_to_cookie(xGenericEvent* ev, 829c27c18e8Smrg XGenericEventCookie *cookie) 830c27c18e8Smrg{ 831c27c18e8Smrg cookie->type = ev->type; 832c27c18e8Smrg cookie->evtype = ev->evtype; 833c27c18e8Smrg cookie->extension = ev->extension; 834c27c18e8Smrg} 835c27c18e8Smrg 836c27c18e8Smrgstatic Bool 837c27c18e8SmrgXInputWireToCookie( 838c27c18e8Smrg Display *dpy, 839c27c18e8Smrg XGenericEventCookie *cookie, 840c27c18e8Smrg xEvent *event) 841c27c18e8Smrg{ 842c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 843c27c18e8Smrg XEvent *save = (XEvent *) info->data; 844c27c18e8Smrg xGenericEvent* ge = (xGenericEvent*)event; 845c27c18e8Smrg 846c27c18e8Smrg if (ge->extension != info->codes->major_opcode) 847c43cc173Smrg { 848c27c18e8Smrg printf("XInputWireToCookie: wrong extension opcode %d\n", 849c27c18e8Smrg ge->extension); 850c27c18e8Smrg return DONT_ENQUEUE; 851c43cc173Smrg } 852c27c18e8Smrg 853c27c18e8Smrg *save = emptyevent; 854c27c18e8Smrg save->type = event->u.u.type; 855c27c18e8Smrg ((XAnyEvent*)save)->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event); 856c27c18e8Smrg ((XAnyEvent*)save)->send_event = ((event->u.u.type & 0x80) != 0); 857c27c18e8Smrg ((XAnyEvent*)save)->display = dpy; 858c27c18e8Smrg 859c27c18e8Smrg xge_copy_to_cookie((xGenericEvent*)event, (XGenericEventCookie*)save); 860c27c18e8Smrg switch(ge->evtype) 861c43cc173Smrg { 862c27c18e8Smrg case XI_Motion: 863c27c18e8Smrg case XI_ButtonPress: 864c27c18e8Smrg case XI_ButtonRelease: 865c27c18e8Smrg case XI_KeyPress: 866c27c18e8Smrg case XI_KeyRelease: 867c27c18e8Smrg *cookie = *(XGenericEventCookie*)save; 868c27c18e8Smrg if (!wireToDeviceEvent((xXIDeviceEvent*)event, cookie)) 869c27c18e8Smrg { 870c27c18e8Smrg printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 871c27c18e8Smrg ge->evtype); 872c27c18e8Smrg break; 873c27c18e8Smrg } 874c27c18e8Smrg return ENQUEUE_EVENT; 875c27c18e8Smrg case XI_DeviceChanged: 876c27c18e8Smrg *cookie = *(XGenericEventCookie*)save; 877c27c18e8Smrg if (!wireToDeviceChangedEvent((xXIDeviceChangedEvent*)event, cookie)) 878c27c18e8Smrg { 879c27c18e8Smrg printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 880c27c18e8Smrg ge->evtype); 881c27c18e8Smrg break; 882c27c18e8Smrg } 883c27c18e8Smrg return ENQUEUE_EVENT; 884c27c18e8Smrg case XI_HierarchyChanged: 885c27c18e8Smrg *cookie = *(XGenericEventCookie*)save; 886c27c18e8Smrg if (!wireToHierarchyChangedEvent((xXIHierarchyEvent*)event, cookie)) 887c27c18e8Smrg { 888c27c18e8Smrg printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 889c27c18e8Smrg ge->evtype); 890c27c18e8Smrg break; 891c27c18e8Smrg } 892c27c18e8Smrg return ENQUEUE_EVENT; 893c27c18e8Smrg 894c27c18e8Smrg case XI_RawKeyPress: 895c27c18e8Smrg case XI_RawKeyRelease: 896c27c18e8Smrg case XI_RawButtonPress: 897c27c18e8Smrg case XI_RawButtonRelease: 898c27c18e8Smrg case XI_RawMotion: 899c27c18e8Smrg *cookie = *(XGenericEventCookie*)save; 900c27c18e8Smrg if (!wireToRawEvent((xXIRawEvent*)event, cookie)) 901c27c18e8Smrg { 902c27c18e8Smrg printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 903c27c18e8Smrg ge->evtype); 904c27c18e8Smrg break; 905c27c18e8Smrg } 906c27c18e8Smrg return ENQUEUE_EVENT; 907c27c18e8Smrg case XI_Enter: 908c27c18e8Smrg case XI_Leave: 909c27c18e8Smrg case XI_FocusIn: 910c27c18e8Smrg case XI_FocusOut: 911c27c18e8Smrg *cookie = *(XGenericEventCookie*)save; 912c27c18e8Smrg if (!wireToEnterLeave((xXIEnterEvent*)event, cookie)) 913c27c18e8Smrg { 914c27c18e8Smrg printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 915c27c18e8Smrg ge->evtype); 916c27c18e8Smrg break; 917c27c18e8Smrg } 918c27c18e8Smrg return ENQUEUE_EVENT; 919c27c18e8Smrg case XI_PropertyEvent: 920c27c18e8Smrg *cookie = *(XGenericEventCookie*)save; 921c27c18e8Smrg if (!wireToPropertyEvent((xXIPropertyEvent*)event, cookie)) 922c27c18e8Smrg { 923c27c18e8Smrg printf("XInputWireToCookie: CONVERSION FAILURE! evtype=%d\n", 924c27c18e8Smrg ge->evtype); 925c27c18e8Smrg break; 926c27c18e8Smrg } 927c27c18e8Smrg return ENQUEUE_EVENT; 928c27c18e8Smrg default: 929c27c18e8Smrg printf("XInputWireToCookie: Unknown generic event. type %d\n", ge->evtype); 930c27c18e8Smrg 931c43cc173Smrg } 932c27c18e8Smrg return DONT_ENQUEUE; 933c27c18e8Smrg} 934c27c18e8Smrg 935c27c18e8Smrg/** 936c27c18e8Smrg * Calculate length in bytes needed for the device event with the given 937c27c18e8Smrg * button mask length, valuator mask length + valuator mask. All parameters 938c27c18e8Smrg * in bytes. 939c27c18e8Smrg */ 940c27c18e8Smrgstatic inline int 941c27c18e8SmrgsizeDeviceEvent(int buttons_len, int valuators_len, 942c27c18e8Smrg unsigned char *valuators_mask) 943c27c18e8Smrg{ 944c27c18e8Smrg int len; 945c27c18e8Smrg 946c27c18e8Smrg len = sizeof(XIDeviceEvent); 947c27c18e8Smrg len += sizeof(XIButtonState) + buttons_len; 948c27c18e8Smrg len += sizeof(XIValuatorState) + valuators_len; 949c27c18e8Smrg len += count_bits(valuators_mask, valuators_len) * sizeof(double); 950c27c18e8Smrg len += sizeof(XIModifierState) + sizeof(XIGroupState); 951c27c18e8Smrg 952c27c18e8Smrg return len; 953c27c18e8Smrg} 954c27c18e8Smrg 955c27c18e8Smrg/** 956c27c18e8Smrg * Return the size in bytes required to store the matching class type 957c27c18e8Smrg * num_elements is num_buttons for XIButtonClass or num_keycodes for 958c27c18e8Smrg * XIKeyClass. 959c27c18e8Smrg * 960c27c18e8Smrg * Also used from copy_classes in XIQueryDevice.c 961c27c18e8Smrg */ 962c27c18e8Smrgstatic int 963c27c18e8SmrgsizeDeviceClassType(int type, int num_elements) 964c27c18e8Smrg{ 965c27c18e8Smrg int l = 0; 966c27c18e8Smrg switch(type) 967c43cc173Smrg { 968c27c18e8Smrg case XIButtonClass: 969c27c18e8Smrg l = sizeof(XIButtonClassInfo); 970c27c18e8Smrg l += num_elements * sizeof(Atom); 971c27c18e8Smrg l += ((((num_elements + 7)/8) + 3)/4) * 4; 972c27c18e8Smrg break; 973c27c18e8Smrg case XIKeyClass: 974c27c18e8Smrg l = sizeof(XIKeyClassInfo); 975c27c18e8Smrg l += num_elements * sizeof(int); 976c27c18e8Smrg break; 977c27c18e8Smrg case XIValuatorClass: 978c27c18e8Smrg l = sizeof(XIValuatorClassInfo); 979c27c18e8Smrg break; 980c27c18e8Smrg default: 981c27c18e8Smrg printf("sizeDeviceClassType: unknown type %d\n", type); 982c27c18e8Smrg break; 983c43cc173Smrg } 984c27c18e8Smrg return l; 985c27c18e8Smrg} 986c27c18e8Smrg 987c27c18e8Smrgstatic Bool 988c27c18e8SmrgcopyHierarchyEvent(XGenericEventCookie *cookie_in, 989c27c18e8Smrg XGenericEventCookie *cookie_out) 990c27c18e8Smrg{ 991c27c18e8Smrg XIHierarchyEvent *in, *out; 992c27c18e8Smrg void *ptr; 993c27c18e8Smrg 994c27c18e8Smrg in = cookie_in->data; 995c27c18e8Smrg 996c27c18e8Smrg ptr = cookie_out->data = malloc(sizeof(XIHierarchyEvent) + 997c27c18e8Smrg in->num_info * sizeof(XIHierarchyInfo)); 998c27c18e8Smrg if (!ptr) 999c27c18e8Smrg return False; 1000c27c18e8Smrg 1001c27c18e8Smrg out = next_block(&ptr, sizeof(XIHierarchyEvent)); 1002c27c18e8Smrg *out = *in; 1003c27c18e8Smrg out->info = next_block(&ptr, in->num_info * sizeof(XIHierarchyInfo)); 1004c27c18e8Smrg memcpy(out->info, in->info, in->num_info * sizeof(XIHierarchyInfo)); 1005c27c18e8Smrg 1006c27c18e8Smrg return True; 1007c27c18e8Smrg} 1008c27c18e8Smrg 1009c27c18e8Smrgstatic Bool 1010c27c18e8SmrgcopyDeviceChangedEvent(XGenericEventCookie *in_cookie, 1011c27c18e8Smrg XGenericEventCookie *out_cookie) 1012c27c18e8Smrg{ 1013c27c18e8Smrg int len, i; 1014c27c18e8Smrg XIDeviceChangedEvent *in, *out; 1015c27c18e8Smrg XIAnyClassInfo *any; 1016c27c18e8Smrg void *ptr; 1017c27c18e8Smrg 1018c27c18e8Smrg in = in_cookie->data; 1019c27c18e8Smrg 1020c27c18e8Smrg len = sizeof(XIDeviceChangedEvent); 1021c27c18e8Smrg len += in->num_classes * sizeof(XIAnyClassInfo*); 1022c27c18e8Smrg 1023c27c18e8Smrg for (i = 0; i < in->num_classes; i++) 1024c43cc173Smrg { 1025c27c18e8Smrg any = in->classes[i]; 1026c27c18e8Smrg switch(any->type) 1027c27c18e8Smrg { 1028c27c18e8Smrg case XIButtonClass: 1029c27c18e8Smrg len += sizeDeviceClassType(XIButtonClass, 1030c27c18e8Smrg ((XIButtonClassInfo*)any)->num_buttons); 1031c27c18e8Smrg break; 1032c27c18e8Smrg case XIKeyClass: 1033c27c18e8Smrg len += sizeDeviceClassType(XIKeyClass, 1034c27c18e8Smrg ((XIKeyClassInfo*)any)->num_keycodes); 1035c27c18e8Smrg break; 1036c27c18e8Smrg case XIValuatorClass: 1037c27c18e8Smrg len += sizeDeviceClassType(XIValuatorClass, 0); 1038c27c18e8Smrg break; 1039c27c18e8Smrg default: 1040c27c18e8Smrg printf("copyDeviceChangedEvent: unknown type %d\n", 1041c27c18e8Smrg any->type); 1042c27c18e8Smrg break; 1043c27c18e8Smrg } 1044c43cc173Smrg 1045c43cc173Smrg } 1046c27c18e8Smrg 1047c27c18e8Smrg ptr = out_cookie->data = malloc(len); 1048c27c18e8Smrg if (!ptr) 1049c27c18e8Smrg return False; 1050c27c18e8Smrg out = next_block(&ptr, sizeof(XIDeviceChangedEvent)); 1051c27c18e8Smrg *out = *in; 1052c27c18e8Smrg 1053c27c18e8Smrg out->classes = next_block(&ptr, 1054c27c18e8Smrg out->num_classes * sizeof(XIAnyClassInfo*)); 1055c27c18e8Smrg 1056c27c18e8Smrg for (i = 0; i < in->num_classes; i++) 1057c43cc173Smrg { 1058c27c18e8Smrg any = in->classes[i]; 1059c27c18e8Smrg 1060c27c18e8Smrg switch(any->type) 1061c27c18e8Smrg { 1062c27c18e8Smrg case XIButtonClass: 1063c27c18e8Smrg { 1064c27c18e8Smrg XIButtonClassInfo *bin, *bout; 1065c27c18e8Smrg bin = (XIButtonClassInfo*)any; 1066c27c18e8Smrg bout = next_block(&ptr, sizeof(XIButtonClass)); 1067c27c18e8Smrg 1068c27c18e8Smrg *bout = *bin; 1069c27c18e8Smrg bout->state.mask = next_block(&ptr, bout->state.mask_len); 1070c27c18e8Smrg memcpy(bout->state.mask, bin->state.mask, 1071c27c18e8Smrg bout->state.mask_len); 1072c27c18e8Smrg 1073c27c18e8Smrg bout->labels = next_block(&ptr, bout->num_buttons * sizeof(Atom)); 1074c27c18e8Smrg memcpy(bout->labels, bin->labels, bout->num_buttons * sizeof(Atom)); 1075c27c18e8Smrg out->classes[i] = (XIAnyClassInfo*)bout; 1076c27c18e8Smrg break; 1077c27c18e8Smrg } 1078c27c18e8Smrg case XIKeyClass: 1079c27c18e8Smrg { 1080c27c18e8Smrg XIKeyClassInfo *kin, *kout; 1081c27c18e8Smrg kin = (XIKeyClassInfo*)any; 1082c27c18e8Smrg 1083c27c18e8Smrg kout = next_block(&ptr, sizeof(XIKeyClass)); 1084c27c18e8Smrg *kout = *kin; 1085c27c18e8Smrg kout->keycodes = next_block(&ptr, kout->num_keycodes * sizeof(int)); 1086c27c18e8Smrg memcpy(kout->keycodes, kin->keycodes, kout->num_keycodes * sizeof(int)); 1087c27c18e8Smrg out->classes[i] = (XIAnyClassInfo*)kout; 1088c27c18e8Smrg break; 1089c27c18e8Smrg } 1090c27c18e8Smrg case XIValuatorClass: 1091c27c18e8Smrg { 1092c27c18e8Smrg XIValuatorClassInfo *vin, *vout; 1093c27c18e8Smrg vin = (XIValuatorClassInfo*)any; 1094c27c18e8Smrg vout = next_block(&ptr, sizeof(XIValuatorClass)); 1095c27c18e8Smrg *vout = *vin; 1096c27c18e8Smrg out->classes[i] = (XIAnyClassInfo*)vout; 1097c27c18e8Smrg break; 1098c27c18e8Smrg } 1099c27c18e8Smrg } 1100c43cc173Smrg } 1101c27c18e8Smrg 1102c27c18e8Smrg return True; 1103c27c18e8Smrg} 1104c27c18e8Smrg 1105c27c18e8Smrgstatic Bool 1106c27c18e8SmrgcopyDeviceEvent(XGenericEventCookie *cookie_in, 1107c27c18e8Smrg XGenericEventCookie *cookie_out) 1108c27c18e8Smrg{ 1109c27c18e8Smrg int len; 1110c27c18e8Smrg XIDeviceEvent *in, *out; 1111c27c18e8Smrg int bits; /* valuator bits */ 1112c27c18e8Smrg void *ptr; 1113c27c18e8Smrg 1114c27c18e8Smrg in = cookie_in->data; 1115c27c18e8Smrg bits = count_bits(in->valuators.mask, in->valuators.mask_len); 1116c27c18e8Smrg 1117c27c18e8Smrg len = sizeDeviceEvent(in->buttons.mask_len, in->valuators.mask_len, 1118c27c18e8Smrg in->valuators.mask); 1119c27c18e8Smrg 1120c27c18e8Smrg ptr = cookie_out->data = malloc(len); 1121c27c18e8Smrg if (!ptr) 1122c27c18e8Smrg return False; 1123c27c18e8Smrg 1124c27c18e8Smrg out = next_block(&ptr, sizeof(XIDeviceEvent)); 1125c27c18e8Smrg *out = *in; 1126c27c18e8Smrg 1127c27c18e8Smrg out->buttons.mask = next_block(&ptr, in->buttons.mask_len); 1128c27c18e8Smrg memcpy(out->buttons.mask, in->buttons.mask, 1129c27c18e8Smrg out->buttons.mask_len); 1130c27c18e8Smrg out->valuators.mask = next_block(&ptr, in->valuators.mask_len); 1131c27c18e8Smrg memcpy(out->valuators.mask, in->valuators.mask, 1132c27c18e8Smrg out->valuators.mask_len); 1133c27c18e8Smrg out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1134c27c18e8Smrg memcpy(out->valuators.values, in->valuators.values, 1135c27c18e8Smrg bits * sizeof(double)); 1136c27c18e8Smrg 1137c27c18e8Smrg return True; 1138c27c18e8Smrg} 1139c27c18e8Smrg 1140c27c18e8Smrgstatic Bool 1141c27c18e8SmrgcopyEnterEvent(XGenericEventCookie *cookie_in, 1142c27c18e8Smrg XGenericEventCookie *cookie_out) 1143c27c18e8Smrg{ 1144c27c18e8Smrg int len; 1145c27c18e8Smrg XIEnterEvent *in, *out; 1146c27c18e8Smrg void *ptr; 1147c27c18e8Smrg 1148c27c18e8Smrg in = cookie_in->data; 1149c27c18e8Smrg 1150c27c18e8Smrg len = sizeof(XIEnterEvent) + in->buttons.mask_len; 1151c27c18e8Smrg 1152c27c18e8Smrg ptr = cookie_out->data = malloc(len); 1153c27c18e8Smrg if (!ptr) 1154c27c18e8Smrg return False; 1155c27c18e8Smrg 1156c27c18e8Smrg out = next_block(&ptr, sizeof(XIEnterEvent)); 1157c27c18e8Smrg *out = *in; 1158c27c18e8Smrg 1159c27c18e8Smrg out->buttons.mask = next_block(&ptr, in->buttons.mask_len); 1160c27c18e8Smrg memcpy(out->buttons.mask, in->buttons.mask, out->buttons.mask_len); 1161c27c18e8Smrg 1162c27c18e8Smrg return True; 1163c27c18e8Smrg} 1164c27c18e8Smrg 1165c27c18e8Smrgstatic Bool 1166c27c18e8SmrgcopyPropertyEvent(XGenericEventCookie *cookie_in, 1167c27c18e8Smrg XGenericEventCookie *cookie_out) 1168c27c18e8Smrg{ 1169c27c18e8Smrg XIPropertyEvent *in, *out; 1170c27c18e8Smrg 1171c27c18e8Smrg in = cookie_in->data; 1172c27c18e8Smrg 1173c27c18e8Smrg out = cookie_out->data = malloc(sizeof(XIPropertyEvent)); 1174c27c18e8Smrg if (!out) 1175c27c18e8Smrg return False; 1176c27c18e8Smrg 1177c27c18e8Smrg *out = *in; 1178c27c18e8Smrg return True; 1179c27c18e8Smrg} 1180c27c18e8Smrg 1181c27c18e8Smrgstatic Bool 1182c27c18e8SmrgcopyRawEvent(XGenericEventCookie *cookie_in, 1183c27c18e8Smrg XGenericEventCookie *cookie_out) 1184c27c18e8Smrg{ 1185c27c18e8Smrg XIRawEvent *in, *out; 1186c27c18e8Smrg void *ptr; 1187c27c18e8Smrg int len; 1188c27c18e8Smrg int bits; 1189c27c18e8Smrg 1190c27c18e8Smrg in = cookie_in->data; 1191c27c18e8Smrg 1192c27c18e8Smrg bits = count_bits(in->valuators.mask, in->valuators.mask_len); 1193c27c18e8Smrg len = sizeof(XIRawEvent) + in->valuators.mask_len; 1194c27c18e8Smrg len += bits * sizeof(double) * 2; 1195c27c18e8Smrg 1196c27c18e8Smrg ptr = cookie_out->data = malloc(sizeof(XIRawEvent)); 1197c27c18e8Smrg if (!ptr) 1198c27c18e8Smrg return False; 1199c27c18e8Smrg 1200c27c18e8Smrg out = next_block(&ptr, sizeof(XIRawEvent)); 1201c27c18e8Smrg *out = *in; 1202c27c18e8Smrg out->valuators.mask = next_block(&ptr, out->valuators.mask_len); 1203c27c18e8Smrg memcpy(out->valuators.mask, in->valuators.mask, out->valuators.mask_len); 1204c27c18e8Smrg 1205c27c18e8Smrg out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1206c27c18e8Smrg memcpy(out->valuators.values, in->valuators.values, bits * sizeof(double)); 1207c27c18e8Smrg 1208c27c18e8Smrg out->raw_values = next_block(&ptr, bits * sizeof(double)); 1209c27c18e8Smrg memcpy(out->raw_values, in->raw_values, bits * sizeof(double)); 1210c27c18e8Smrg 1211c27c18e8Smrg return True; 1212c27c18e8Smrg} 1213c27c18e8Smrg 1214c27c18e8Smrg 1215c27c18e8Smrg 1216c27c18e8Smrgstatic Bool 1217c27c18e8SmrgXInputCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out) 1218c27c18e8Smrg{ 1219c27c18e8Smrg int ret = True; 1220c27c18e8Smrg 1221c27c18e8Smrg XExtDisplayInfo *info = XInput_find_display(dpy); 1222c27c18e8Smrg 1223c27c18e8Smrg if (in->extension != info->codes->major_opcode) 1224c43cc173Smrg { 1225c27c18e8Smrg printf("XInputCopyCookie: wrong extension opcode %d\n", 1226c27c18e8Smrg in->extension); 1227c27c18e8Smrg return False; 1228c27c18e8Smrg } 1229c27c18e8Smrg 1230c27c18e8Smrg *out = *in; 1231c27c18e8Smrg out->data = NULL; 1232c27c18e8Smrg out->cookie = 0; 1233c27c18e8Smrg 1234c27c18e8Smrg switch(in->evtype) { 1235c27c18e8Smrg case XI_Motion: 1236c27c18e8Smrg case XI_ButtonPress: 1237c27c18e8Smrg case XI_ButtonRelease: 1238c27c18e8Smrg case XI_KeyPress: 1239c27c18e8Smrg case XI_KeyRelease: 1240c27c18e8Smrg ret = copyDeviceEvent(in, out); 1241c27c18e8Smrg break; 1242c27c18e8Smrg case XI_DeviceChanged: 1243c27c18e8Smrg ret = copyDeviceChangedEvent(in, out); 1244c27c18e8Smrg break; 1245c27c18e8Smrg case XI_HierarchyChanged: 1246c27c18e8Smrg ret = copyHierarchyEvent(in, out); 1247c27c18e8Smrg break; 1248c27c18e8Smrg case XI_Enter: 1249c27c18e8Smrg case XI_Leave: 1250c27c18e8Smrg case XI_FocusIn: 1251c27c18e8Smrg case XI_FocusOut: 1252c27c18e8Smrg ret = copyEnterEvent(in, out); 1253c27c18e8Smrg break; 1254c27c18e8Smrg case XI_PropertyEvent: 1255c27c18e8Smrg ret = copyPropertyEvent(in, out); 1256c27c18e8Smrg break; 1257c27c18e8Smrg case XI_RawKeyPress: 1258c27c18e8Smrg case XI_RawKeyRelease: 1259c27c18e8Smrg case XI_RawButtonPress: 1260c27c18e8Smrg case XI_RawButtonRelease: 1261c27c18e8Smrg case XI_RawMotion: 1262c27c18e8Smrg ret = copyRawEvent(in, out); 1263c27c18e8Smrg break; 1264c27c18e8Smrg default: 1265c27c18e8Smrg printf("XInputCopyCookie: unknown evtype %d\n", in->evtype); 1266c27c18e8Smrg ret = False; 1267c43cc173Smrg } 1268c27c18e8Smrg 1269c27c18e8Smrg if (!ret) 1270c27c18e8Smrg printf("XInputCopyCookie: Failed to copy evtype %d", in->evtype); 1271c27c18e8Smrg return ret; 1272c27c18e8Smrg} 1273c27c18e8Smrg 1274c27c18e8Smrgstatic int 1275c27c18e8SmrgwireToDeviceEvent(xXIDeviceEvent *in, XGenericEventCookie* cookie) 1276c27c18e8Smrg{ 1277c27c18e8Smrg int len, i; 1278c27c18e8Smrg unsigned char *ptr; 1279c27c18e8Smrg void *ptr_lib; 1280c27c18e8Smrg FP3232 *values; 1281c27c18e8Smrg XIDeviceEvent *out; 1282c27c18e8Smrg 1283c27c18e8Smrg ptr = (unsigned char*)&in[1] + in->buttons_len * 4; 1284c27c18e8Smrg 1285c27c18e8Smrg len = sizeDeviceEvent(in->buttons_len * 4, in->valuators_len * 4, ptr); 1286c27c18e8Smrg 1287c27c18e8Smrg cookie->data = ptr_lib = malloc(len); 1288c27c18e8Smrg 1289c27c18e8Smrg out = next_block(&ptr_lib, sizeof(XIDeviceEvent)); 1290c27c18e8Smrg out->type = in->type; 1291c27c18e8Smrg out->extension = in->extension; 1292c27c18e8Smrg out->evtype = in->evtype; 1293c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1294c27c18e8Smrg out->time = in->time; 1295c27c18e8Smrg out->deviceid = in->deviceid; 1296c27c18e8Smrg out->sourceid = in->sourceid; 1297c27c18e8Smrg out->detail = in->detail; 1298c27c18e8Smrg out->root = in->root; 1299c27c18e8Smrg out->event = in->event; 1300c27c18e8Smrg out->child = in->child; 1301c27c18e8Smrg out->root_x = FP1616toDBL(in->root_x); 1302c27c18e8Smrg out->root_y = FP1616toDBL(in->root_y); 1303c27c18e8Smrg out->event_x = FP1616toDBL(in->event_x); 1304c27c18e8Smrg out->event_y = FP1616toDBL(in->event_y); 1305c27c18e8Smrg out->flags = in->flags; 1306c27c18e8Smrg out->mods.base = in->mods.base_mods; 1307c27c18e8Smrg out->mods.locked = in->mods.locked_mods; 1308c27c18e8Smrg out->mods.latched = in->mods.latched_mods; 1309c27c18e8Smrg out->mods.effective = in->mods.effective_mods; 1310c27c18e8Smrg out->group.base = in->group.base_group; 1311c27c18e8Smrg out->group.locked = in->group.locked_group; 1312c27c18e8Smrg out->group.latched = in->group.latched_group; 1313c27c18e8Smrg out->group.effective = in->group.effective_group; 1314c27c18e8Smrg out->buttons.mask_len = in->buttons_len * 4; 1315c27c18e8Smrg out->valuators.mask_len = in->valuators_len * 4; 1316c27c18e8Smrg 1317c27c18e8Smrg out->buttons.mask = next_block(&ptr_lib, out->buttons.mask_len); 1318c27c18e8Smrg 1319c27c18e8Smrg /* buttons */ 1320c27c18e8Smrg ptr = (unsigned char*)&in[1]; 1321c27c18e8Smrg memcpy(out->buttons.mask, ptr, out->buttons.mask_len); 1322c27c18e8Smrg ptr += in->buttons_len * 4; 1323c27c18e8Smrg 1324c27c18e8Smrg /* valuators */ 1325c27c18e8Smrg out->valuators.mask = next_block(&ptr_lib, out->valuators.mask_len); 1326c27c18e8Smrg memcpy(out->valuators.mask, ptr, out->valuators.mask_len); 1327c27c18e8Smrg ptr += in->valuators_len * 4; 1328c27c18e8Smrg 1329c27c18e8Smrg len = count_bits(out->valuators.mask, out->valuators.mask_len); 1330c27c18e8Smrg out->valuators.values = next_block(&ptr_lib, len * sizeof(double)); 1331c27c18e8Smrg 1332c27c18e8Smrg values = (FP3232*)ptr; 1333c27c18e8Smrg for (i = 0; i < len; i++, values++) 1334c43cc173Smrg { 1335c27c18e8Smrg out->valuators.values[i] = values->integral; 1336c27c18e8Smrg out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 1337c43cc173Smrg } 1338c27c18e8Smrg 1339c27c18e8Smrg 1340c27c18e8Smrg return 1; 1341c27c18e8Smrg} 1342c27c18e8Smrg 1343c27c18e8Smrg_X_HIDDEN int 1344c27c18e8Smrgsize_classes(xXIAnyInfo* from, int nclasses) 1345c27c18e8Smrg{ 1346c27c18e8Smrg int len, i; 1347c27c18e8Smrg xXIAnyInfo *any_wire; 1348c27c18e8Smrg char *ptr_wire; 1349c27c18e8Smrg 1350c27c18e8Smrg len = nclasses * sizeof(XIAnyClassInfo*); /* len for to->classes */ 1351c27c18e8Smrg ptr_wire = (char*)from; 1352c27c18e8Smrg for (i = 0; i < nclasses; i++) 1353c43cc173Smrg { 1354c27c18e8Smrg int l = 0; 1355c27c18e8Smrg any_wire = (xXIAnyInfo*)ptr_wire; 1356c27c18e8Smrg switch(any_wire->type) 1357c27c18e8Smrg { 1358c27c18e8Smrg case XIButtonClass: 1359c27c18e8Smrg l = sizeDeviceClassType(XIButtonClass, 1360c27c18e8Smrg ((xXIButtonInfo*)any_wire)->num_buttons); 1361c27c18e8Smrg break; 1362c27c18e8Smrg case XIKeyClass: 1363c27c18e8Smrg l = sizeDeviceClassType(XIKeyClass, 1364c27c18e8Smrg ((xXIKeyInfo*)any_wire)->num_keycodes); 1365c27c18e8Smrg break; 1366c27c18e8Smrg case XIValuatorClass: 1367c27c18e8Smrg l = sizeDeviceClassType(XIValuatorClass, 0); 1368c27c18e8Smrg break; 1369c27c18e8Smrg } 1370c27c18e8Smrg 1371c27c18e8Smrg len += l; 1372c27c18e8Smrg ptr_wire += any_wire->length * 4; 1373c43cc173Smrg } 1374c27c18e8Smrg 1375c27c18e8Smrg return len; 1376c27c18e8Smrg} 1377c27c18e8Smrg 1378c27c18e8Smrg/* Copy classes from any into to->classes and return the number of bytes 1379c27c18e8Smrg * copied. Memory layout of to->classes is 1380c27c18e8Smrg * [clsptr][clsptr][clsptr][classinfo][classinfo]... 1381c27c18e8Smrg * |________|___________^ 1382c27c18e8Smrg * |______________________^ 1383c27c18e8Smrg */ 1384c27c18e8Smrg_X_HIDDEN int 1385c27c18e8Smrgcopy_classes(XIDeviceInfo* to, xXIAnyInfo* from, int nclasses) 1386c27c18e8Smrg{ 1387c27c18e8Smrg XIAnyClassInfo *any_lib; 1388c27c18e8Smrg xXIAnyInfo *any_wire; 1389c27c18e8Smrg void *ptr_lib; 1390c27c18e8Smrg char *ptr_wire; 1391c27c18e8Smrg int i, len; 1392c27c18e8Smrg 1393c27c18e8Smrg if (!to->classes) 1394c27c18e8Smrg return -1; 1395c27c18e8Smrg 1396c27c18e8Smrg ptr_wire = (char*)from; 1397c27c18e8Smrg ptr_lib = to->classes; 1398c27c18e8Smrg to->classes = next_block(&ptr_lib, nclasses * sizeof(XIAnyClassInfo*)); 1399c27c18e8Smrg len = 0; /* count wire length */ 1400c27c18e8Smrg 1401c27c18e8Smrg for (i = 0; i < nclasses; i++) 1402c43cc173Smrg { 1403c27c18e8Smrg any_lib = (XIAnyClassInfo*)ptr_lib; 1404c27c18e8Smrg any_wire = (xXIAnyInfo*)ptr_wire; 1405c27c18e8Smrg 1406c27c18e8Smrg to->classes[i] = any_lib; 1407c27c18e8Smrg any_lib->type = any_wire->type; 1408c27c18e8Smrg any_lib->sourceid = any_wire->sourceid; 1409c27c18e8Smrg switch(any_wire->type) 1410c27c18e8Smrg { 1411c27c18e8Smrg case XIButtonClass: 1412c27c18e8Smrg { 1413c27c18e8Smrg XIButtonClassInfo *cls_lib; 1414c27c18e8Smrg xXIButtonInfo *cls_wire; 1415c27c18e8Smrg uint32_t *atoms; 1416c27c18e8Smrg int j; 1417c27c18e8Smrg 1418c27c18e8Smrg cls_lib = next_block(&ptr_lib, sizeof(XIButtonClassInfo)); 1419c27c18e8Smrg cls_wire = (xXIButtonInfo*)any_wire; 1420c27c18e8Smrg 1421c27c18e8Smrg cls_lib->num_buttons = cls_wire->num_buttons; 1422c27c18e8Smrg cls_lib->state.mask_len = ((((cls_wire->num_buttons + 7)/8) + 3)/4) * 4; 1423c27c18e8Smrg cls_lib->state.mask = next_block(&ptr_lib, cls_lib->state.mask_len); 1424c27c18e8Smrg memcpy(cls_lib->state.mask, &cls_wire[1], 1425c27c18e8Smrg cls_lib->state.mask_len); 1426c27c18e8Smrg 1427c27c18e8Smrg cls_lib->labels = next_block(&ptr_lib, cls_lib->num_buttons * sizeof(Atom)); 1428c27c18e8Smrg atoms =(uint32_t*)((char*)&cls_wire[1] + cls_lib->state.mask_len); 1429c27c18e8Smrg for (j = 0; j < cls_lib->num_buttons; j++) 1430c27c18e8Smrg cls_lib->labels[j] = *atoms++; 1431c27c18e8Smrg 1432c27c18e8Smrg break; 1433c27c18e8Smrg } 1434c27c18e8Smrg case XIKeyClass: 1435c27c18e8Smrg { 1436c27c18e8Smrg XIKeyClassInfo *cls_lib; 1437c27c18e8Smrg xXIKeyInfo *cls_wire; 1438c27c18e8Smrg 1439c27c18e8Smrg cls_lib = next_block(&ptr_lib, sizeof(XIKeyClassInfo)); 1440c27c18e8Smrg cls_wire = (xXIKeyInfo*)any_wire; 1441c27c18e8Smrg 1442c27c18e8Smrg cls_lib->num_keycodes = cls_wire->num_keycodes; 1443c27c18e8Smrg cls_lib->keycodes = next_block(&ptr_lib, 1444c27c18e8Smrg cls_lib->num_keycodes * sizeof(int)); 1445c27c18e8Smrg memcpy(cls_lib->keycodes, &cls_wire[1], 1446c27c18e8Smrg cls_lib->num_keycodes); 1447c27c18e8Smrg 1448c27c18e8Smrg break; 1449c27c18e8Smrg } 1450c27c18e8Smrg case XIValuatorClass: 1451c27c18e8Smrg { 1452c27c18e8Smrg XIValuatorClassInfo *cls_lib; 1453c27c18e8Smrg xXIValuatorInfo *cls_wire; 1454c27c18e8Smrg 1455c27c18e8Smrg cls_lib = next_block(&ptr_lib, sizeof(XIValuatorClassInfo)); 1456c27c18e8Smrg cls_wire = (xXIValuatorInfo*)any_wire; 1457c27c18e8Smrg 1458c27c18e8Smrg cls_lib->number = cls_wire->number; 1459c27c18e8Smrg cls_lib->label = cls_wire->label; 1460c27c18e8Smrg cls_lib->resolution = cls_wire->resolution; 1461c27c18e8Smrg cls_lib->min = cls_wire->min.integral; 1462c27c18e8Smrg cls_lib->max = cls_wire->max.integral; 1463c27c18e8Smrg cls_lib->value = cls_wire->value.integral; 1464c27c18e8Smrg /* FIXME: fractional parts */ 1465c27c18e8Smrg cls_lib->mode = cls_wire->mode; 1466c27c18e8Smrg 1467c27c18e8Smrg } 1468c27c18e8Smrg break; 1469c27c18e8Smrg } 1470c27c18e8Smrg len += any_wire->length * 4; 1471c27c18e8Smrg ptr_wire += any_wire->length * 4; 1472c43cc173Smrg } 1473c27c18e8Smrg return len; 1474c27c18e8Smrg} 1475c27c18e8Smrg 1476c27c18e8Smrg 1477c27c18e8Smrgstatic int 1478c27c18e8SmrgwireToDeviceChangedEvent(xXIDeviceChangedEvent *in, XGenericEventCookie *cookie) 1479c27c18e8Smrg{ 1480c27c18e8Smrg XIDeviceChangedEvent *out; 1481c27c18e8Smrg XIDeviceInfo info; 1482c27c18e8Smrg int len; 1483c27c18e8Smrg 1484c27c18e8Smrg len = size_classes((xXIAnyInfo*)&in[1], in->num_classes); 1485c27c18e8Smrg 1486c27c18e8Smrg cookie->data = out = malloc(sizeof(XIDeviceChangedEvent) + len); 1487c27c18e8Smrg 1488c27c18e8Smrg out->type = in->type; 1489c27c18e8Smrg out->extension = in->extension; 1490c27c18e8Smrg out->evtype = in->evtype; 1491c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1492c27c18e8Smrg out->time = in->time; 1493c27c18e8Smrg out->deviceid = in->deviceid; 1494c27c18e8Smrg out->sourceid = in->sourceid; 1495c27c18e8Smrg out->reason = in->reason; 1496c27c18e8Smrg out->num_classes = in->num_classes; 1497c27c18e8Smrg 1498c27c18e8Smrg out->classes = (XIAnyClassInfo**)&out[1]; 1499c27c18e8Smrg 1500c27c18e8Smrg info.classes = out->classes; 1501c27c18e8Smrg 1502c27c18e8Smrg copy_classes(&info, (xXIAnyInfo*)&in[1], in->num_classes); 1503c27c18e8Smrg 1504c27c18e8Smrg return 1; 1505c27c18e8Smrg} 1506c27c18e8Smrg 1507c27c18e8Smrgstatic int 1508c27c18e8SmrgwireToHierarchyChangedEvent(xXIHierarchyEvent *in, XGenericEventCookie *cookie) 1509c27c18e8Smrg{ 1510c27c18e8Smrg int i; 1511c27c18e8Smrg XIHierarchyInfo *info_out; 1512c27c18e8Smrg xXIHierarchyInfo *info_in; 1513c27c18e8Smrg XIHierarchyEvent *out; 1514c27c18e8Smrg 1515c27c18e8Smrg cookie->data = out = malloc(sizeof(XIHierarchyEvent) + in->num_info * sizeof(XIHierarchyInfo));; 1516c27c18e8Smrg 1517c27c18e8Smrg out->info = (XIHierarchyInfo*)&out[1]; 1518c27c18e8Smrg out->type = in->type; 1519c27c18e8Smrg out->extension = in->extension; 1520c27c18e8Smrg out->evtype = in->evtype; 1521c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1522c27c18e8Smrg out->time = in->time; 1523c27c18e8Smrg out->flags = in->flags; 1524c27c18e8Smrg out->num_info = in->num_info; 1525c27c18e8Smrg 1526c27c18e8Smrg info_out = out->info; 1527c27c18e8Smrg info_in = (xXIHierarchyInfo*)&in[1]; 1528c27c18e8Smrg 1529c27c18e8Smrg for (i = 0; i < out->num_info; i++, info_out++, info_in++) 1530c43cc173Smrg { 1531c27c18e8Smrg info_out->deviceid = info_in->deviceid; 1532c27c18e8Smrg info_out->attachment = info_in->attachment; 1533c27c18e8Smrg info_out->use = info_in->use; 1534c27c18e8Smrg info_out->enabled = info_in->enabled; 1535c27c18e8Smrg info_out->flags = info_in->flags; 1536c43cc173Smrg } 1537c43cc173Smrg 1538c27c18e8Smrg return 1; 1539c27c18e8Smrg} 1540c27c18e8Smrg 1541c27c18e8Smrgstatic int 1542c27c18e8SmrgwireToRawEvent(xXIRawEvent *in, XGenericEventCookie *cookie) 1543c27c18e8Smrg{ 1544c27c18e8Smrg int len, i, bits; 1545c27c18e8Smrg FP3232 *values; 1546c27c18e8Smrg XIRawEvent *out; 1547c27c18e8Smrg void *ptr; 1548c27c18e8Smrg 1549c27c18e8Smrg 1550c27c18e8Smrg len = sizeof(XIRawEvent) + in->valuators_len * 4; 1551c27c18e8Smrg bits = count_bits((unsigned char*)&in[1], in->valuators_len * 4); 1552c27c18e8Smrg len += bits * sizeof(double) * 2; /* raw + normal */ 1553c27c18e8Smrg 1554c27c18e8Smrg cookie->data = ptr = calloc(1, len); 1555c27c18e8Smrg if (!ptr) 1556c27c18e8Smrg return 0; 1557c27c18e8Smrg 1558c27c18e8Smrg out = next_block(&ptr, sizeof(XIRawEvent)); 1559c27c18e8Smrg out->type = in->type; 1560c27c18e8Smrg out->extension = in->extension; 1561c27c18e8Smrg out->evtype = in->evtype; 1562c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1563c27c18e8Smrg out->time = in->time; 1564c27c18e8Smrg out->detail = in->detail; 1565c27c18e8Smrg out->deviceid = in->deviceid; 1566c27c18e8Smrg out->flags = in->flags; 1567c27c18e8Smrg 1568c27c18e8Smrg out->valuators.mask_len = in->valuators_len * 4; 1569c27c18e8Smrg out->valuators.mask = next_block(&ptr, out->valuators.mask_len); 1570c27c18e8Smrg memcpy(out->valuators.mask, &in[1], out->valuators.mask_len); 1571c27c18e8Smrg 1572c27c18e8Smrg out->valuators.values = next_block(&ptr, bits * sizeof(double)); 1573c27c18e8Smrg out->raw_values = next_block(&ptr, bits * sizeof(double)); 1574c27c18e8Smrg 1575c27c18e8Smrg values = (FP3232*)(((char*)&in[1]) + in->valuators_len * 4); 1576c27c18e8Smrg for (i = 0; i < bits; i++) 1577c43cc173Smrg { 1578c27c18e8Smrg out->valuators.values[i] = values->integral; 1579c27c18e8Smrg out->valuators.values[i] += ((double)values->frac / (1 << 16) / (1 << 16)); 1580c27c18e8Smrg out->raw_values[i] = (values + bits)->integral; 1581c27c18e8Smrg out->valuators.values[i] += ((double)(values + bits)->frac / (1 << 16) / (1 << 16)); 1582c27c18e8Smrg values++; 1583c43cc173Smrg } 1584c43cc173Smrg 1585c27c18e8Smrg return 1; 1586c27c18e8Smrg} 158721e67964Smrg 1588c27c18e8Smrg/* Memory layout of XIEnterEvents: 1589c27c18e8Smrg [event][modifiers][group][button] 1590c27c18e8Smrg */ 1591c27c18e8Smrgstatic int 1592c27c18e8SmrgwireToEnterLeave(xXIEnterEvent *in, XGenericEventCookie *cookie) 1593c27c18e8Smrg{ 1594c27c18e8Smrg int len; 1595c27c18e8Smrg XIEnterEvent *out; 1596c27c18e8Smrg 1597c27c18e8Smrg len = sizeof(XIEnterEvent) + in->buttons_len * 4; 1598c27c18e8Smrg 1599c27c18e8Smrg cookie->data = out = malloc(len); 1600c27c18e8Smrg out->buttons.mask = (unsigned char*)&out[1]; 1601c27c18e8Smrg 1602c27c18e8Smrg out->type = in->type; 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->detail = in->detail; 1608c27c18e8Smrg out->deviceid = in->deviceid; 1609c27c18e8Smrg out->root = in->root; 1610c27c18e8Smrg out->event = in->event; 1611c27c18e8Smrg out->child = in->child; 1612c27c18e8Smrg out->sourceid = in->sourceid; 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->mode = in->mode; 1618c27c18e8Smrg out->focus = in->focus; 1619c27c18e8Smrg out->same_screen = in->same_screen; 1620c27c18e8Smrg 1621c27c18e8Smrg out->mods.base = in->mods.base_mods; 1622c27c18e8Smrg out->mods.locked = in->mods.locked_mods; 1623c27c18e8Smrg out->mods.latched = in->mods.latched_mods; 1624c27c18e8Smrg out->mods.effective = in->mods.effective_mods; 1625c27c18e8Smrg out->group.base = in->group.base_group; 1626c27c18e8Smrg out->group.locked = in->group.locked_group; 1627c27c18e8Smrg out->group.latched = in->group.latched_group; 1628c27c18e8Smrg out->group.effective = in->group.effective_group; 1629c27c18e8Smrg 1630c27c18e8Smrg out->buttons.mask_len = in->buttons_len * 4; 1631c27c18e8Smrg memcpy(out->buttons.mask, &in[1], out->buttons.mask_len); 163221e67964Smrg 1633c27c18e8Smrg return 1; 1634c27c18e8Smrg} 1635c43cc173Smrg 1636c27c18e8Smrgstatic int 1637c27c18e8SmrgwireToPropertyEvent(xXIPropertyEvent *in, XGenericEventCookie *cookie) 1638c27c18e8Smrg{ 1639c27c18e8Smrg XIPropertyEvent *out = malloc(sizeof(XIPropertyEvent)); 1640c27c18e8Smrg 1641c27c18e8Smrg cookie->data = out; 1642c27c18e8Smrg 1643c27c18e8Smrg out->type = in->type; 1644c27c18e8Smrg out->extension = in->extension; 1645c27c18e8Smrg out->evtype = in->evtype; 1646c27c18e8Smrg out->send_event = ((in->type & 0x80) != 0); 1647c27c18e8Smrg out->time = in->time; 1648c27c18e8Smrg out->property = in->property; 1649c27c18e8Smrg out->what = in->what; 1650c27c18e8Smrg out->deviceid = in->deviceid; 1651c27c18e8Smrg 1652c27c18e8Smrg return 1; 1653c43cc173Smrg} 1654