16747b715Smrg/* 26747b715Smrg * Copyright © 2009 Red Hat, Inc. 36747b715Smrg * 46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a 56747b715Smrg * copy of this software and associated documentation files (the "Software"), 66747b715Smrg * to deal in the Software without restriction, including without limitation 76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 96747b715Smrg * Software is furnished to do so, subject to the following conditions: 106747b715Smrg * 116747b715Smrg * The above copyright notice and this permission notice (including the next 126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 136747b715Smrg * Software. 146747b715Smrg * 156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 206747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 216747b715Smrg * DEALINGS IN THE SOFTWARE. 226747b715Smrg * 236747b715Smrg */ 246747b715Smrg 256747b715Smrg/** 266747b715Smrg * @file eventconvert.c 276747b715Smrg * This file contains event conversion routines from InternalEvent to the 286747b715Smrg * matching protocol events. 296747b715Smrg */ 306747b715Smrg 316747b715Smrg#ifdef HAVE_DIX_CONFIG_H 326747b715Smrg#include <dix-config.h> 336747b715Smrg#endif 346747b715Smrg 356747b715Smrg#include <stdint.h> 366747b715Smrg#include <X11/X.h> 376747b715Smrg#include <X11/extensions/XIproto.h> 386747b715Smrg#include <X11/extensions/XI2proto.h> 396747b715Smrg#include <X11/extensions/XI.h> 406747b715Smrg#include <X11/extensions/XI2.h> 416747b715Smrg 426747b715Smrg#include "dix.h" 436747b715Smrg#include "inputstr.h" 446747b715Smrg#include "misc.h" 456747b715Smrg#include "eventstr.h" 4635c4bbdfSmrg#include "exevents.h" 476747b715Smrg#include "exglobals.h" 486747b715Smrg#include "eventconvert.h" 4935c4bbdfSmrg#include "inpututils.h" 506747b715Smrg#include "xiquerydevice.h" 516747b715Smrg#include "xkbsrv.h" 5235c4bbdfSmrg#include "inpututils.h" 536747b715Smrg 546747b715Smrgstatic int countValuators(DeviceEvent *ev, int *first); 5535c4bbdfSmrgstatic int getValuatorEvents(DeviceEvent *ev, deviceValuator * xv); 566747b715Smrgstatic int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count); 576747b715Smrgstatic int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce); 586747b715Smrgstatic int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi); 596747b715Smrgstatic int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi); 6035c4bbdfSmrgstatic int eventToBarrierEvent(BarrierEvent *ev, xEvent **xi); 6135c4bbdfSmrgstatic int eventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi); 62ed6184dfSmrgstatic int eventToGestureSwipeEvent(GestureEvent *ev, xEvent **xi); 63ed6184dfSmrgstatic int eventToGesturePinchEvent(GestureEvent *ev, xEvent **xi); 646747b715Smrg 656747b715Smrg/* Do not use, read comments below */ 666747b715SmrgBOOL EventIsKeyRepeat(xEvent *event); 676747b715Smrg 686747b715Smrg/** 696747b715Smrg * Hack to allow detectable autorepeat for core and XI1 events. 706747b715Smrg * The sequence number is unused until we send to the client and can be 716747b715Smrg * misused to store data. More or less, anyway. 726747b715Smrg * 736747b715Smrg * Do not use this. It may change any time without warning, eat your babies 746747b715Smrg * and piss on your cat. 756747b715Smrg */ 766747b715Smrgstatic void 776747b715SmrgEventSetKeyRepeatFlag(xEvent *event, BOOL on) 786747b715Smrg{ 796747b715Smrg event->u.u.sequenceNumber = on; 806747b715Smrg} 816747b715Smrg 826747b715Smrg/** 836747b715Smrg * Check if the event was marked as a repeat event before. 846747b715Smrg * NOTE: This is a nasty hack and should NOT be used by anyone else but 856747b715Smrg * TryClientEvents. 866747b715Smrg */ 876747b715SmrgBOOL 886747b715SmrgEventIsKeyRepeat(xEvent *event) 896747b715Smrg{ 9035c4bbdfSmrg return ! !event->u.u.sequenceNumber; 916747b715Smrg} 926747b715Smrg 936747b715Smrg/** 946747b715Smrg * Convert the given event to the respective core event. 956747b715Smrg * 966747b715Smrg * Return values: 976747b715Smrg * Success ... core contains the matching core event. 986747b715Smrg * BadValue .. One or more values in the internal event are invalid. 996747b715Smrg * BadMatch .. The event has no core equivalent. 1006747b715Smrg * 1016747b715Smrg * @param[in] event The event to convert into a core event. 1026747b715Smrg * @param[in] core The memory location to store the core event at. 1036747b715Smrg * @return Success or the matching error code. 1046747b715Smrg */ 1056747b715Smrgint 10635c4bbdfSmrgEventToCore(InternalEvent *event, xEvent **core_out, int *count_out) 1076747b715Smrg{ 10835c4bbdfSmrg xEvent *core = NULL; 10935c4bbdfSmrg int count = 0; 11035c4bbdfSmrg int ret = BadImplementation; 11135c4bbdfSmrg 11235c4bbdfSmrg switch (event->any.type) { 11335c4bbdfSmrg case ET_Motion: 1146747b715Smrg { 11535c4bbdfSmrg DeviceEvent *e = &event->device_event; 11635c4bbdfSmrg 11735c4bbdfSmrg /* Don't create core motion event if neither x nor y are 11835c4bbdfSmrg * present */ 11935c4bbdfSmrg if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) { 12035c4bbdfSmrg ret = BadMatch; 12135c4bbdfSmrg goto out; 12235c4bbdfSmrg } 1236747b715Smrg } 12435c4bbdfSmrg /* fallthrough */ 12535c4bbdfSmrg case ET_ButtonPress: 12635c4bbdfSmrg case ET_ButtonRelease: 12735c4bbdfSmrg case ET_KeyPress: 12835c4bbdfSmrg case ET_KeyRelease: 12935c4bbdfSmrg { 13035c4bbdfSmrg DeviceEvent *e = &event->device_event; 13135c4bbdfSmrg 13235c4bbdfSmrg if (e->detail.key > 0xFF) { 13335c4bbdfSmrg ret = BadMatch; 13435c4bbdfSmrg goto out; 13535c4bbdfSmrg } 13635c4bbdfSmrg 13735c4bbdfSmrg core = calloc(1, sizeof(*core)); 13835c4bbdfSmrg if (!core) 13935c4bbdfSmrg return BadAlloc; 14035c4bbdfSmrg count = 1; 14135c4bbdfSmrg core->u.u.type = e->type - ET_KeyPress + KeyPress; 14235c4bbdfSmrg core->u.u.detail = e->detail.key & 0xFF; 14335c4bbdfSmrg core->u.keyButtonPointer.time = e->time; 14435c4bbdfSmrg core->u.keyButtonPointer.rootX = e->root_x; 14535c4bbdfSmrg core->u.keyButtonPointer.rootY = e->root_y; 14635c4bbdfSmrg core->u.keyButtonPointer.state = e->corestate; 14735c4bbdfSmrg core->u.keyButtonPointer.root = e->root; 14835c4bbdfSmrg EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); 14935c4bbdfSmrg ret = Success; 15035c4bbdfSmrg } 15135c4bbdfSmrg break; 15235c4bbdfSmrg case ET_ProximityIn: 15335c4bbdfSmrg case ET_ProximityOut: 15435c4bbdfSmrg case ET_RawKeyPress: 15535c4bbdfSmrg case ET_RawKeyRelease: 15635c4bbdfSmrg case ET_RawButtonPress: 15735c4bbdfSmrg case ET_RawButtonRelease: 15835c4bbdfSmrg case ET_RawMotion: 15935c4bbdfSmrg case ET_RawTouchBegin: 16035c4bbdfSmrg case ET_RawTouchUpdate: 16135c4bbdfSmrg case ET_RawTouchEnd: 16235c4bbdfSmrg case ET_TouchBegin: 16335c4bbdfSmrg case ET_TouchUpdate: 16435c4bbdfSmrg case ET_TouchEnd: 16535c4bbdfSmrg case ET_TouchOwnership: 16635c4bbdfSmrg case ET_BarrierHit: 16735c4bbdfSmrg case ET_BarrierLeave: 168ed6184dfSmrg case ET_GesturePinchBegin: 169ed6184dfSmrg case ET_GesturePinchUpdate: 170ed6184dfSmrg case ET_GesturePinchEnd: 171ed6184dfSmrg case ET_GestureSwipeBegin: 172ed6184dfSmrg case ET_GestureSwipeUpdate: 173ed6184dfSmrg case ET_GestureSwipeEnd: 17435c4bbdfSmrg ret = BadMatch; 17535c4bbdfSmrg break; 17635c4bbdfSmrg default: 17735c4bbdfSmrg /* XXX: */ 17835c4bbdfSmrg ErrorF("[dix] EventToCore: Not implemented yet \n"); 17935c4bbdfSmrg ret = BadImplementation; 18035c4bbdfSmrg } 18135c4bbdfSmrg 18235c4bbdfSmrg out: 18335c4bbdfSmrg *core_out = core; 18435c4bbdfSmrg *count_out = count; 18535c4bbdfSmrg return ret; 1866747b715Smrg} 1876747b715Smrg 1886747b715Smrg/** 1896747b715Smrg * Convert the given event to the respective XI 1.x event and store it in 1906747b715Smrg * xi. xi is allocated on demand and must be freed by the caller. 1916747b715Smrg * count returns the number of events in xi. If count is 1, and the type of 1926747b715Smrg * xi is GenericEvent, then xi may be larger than 32 bytes. 1936747b715Smrg * 1946747b715Smrg * Return values: 1956747b715Smrg * Success ... core contains the matching core event. 1966747b715Smrg * BadValue .. One or more values in the internal event are invalid. 1976747b715Smrg * BadMatch .. The event has no XI equivalent. 1986747b715Smrg * 1996747b715Smrg * @param[in] ev The event to convert into an XI 1 event. 2006747b715Smrg * @param[out] xi Future memory location for the XI event. 2016747b715Smrg * @param[out] count Number of elements in xi. 2026747b715Smrg * 2036747b715Smrg * @return Success or the error code. 2046747b715Smrg */ 2056747b715Smrgint 2066747b715SmrgEventToXI(InternalEvent *ev, xEvent **xi, int *count) 2076747b715Smrg{ 20835c4bbdfSmrg switch (ev->any.type) { 20935c4bbdfSmrg case ET_Motion: 21035c4bbdfSmrg case ET_ButtonPress: 21135c4bbdfSmrg case ET_ButtonRelease: 21235c4bbdfSmrg case ET_KeyPress: 21335c4bbdfSmrg case ET_KeyRelease: 21435c4bbdfSmrg case ET_ProximityIn: 21535c4bbdfSmrg case ET_ProximityOut: 21635c4bbdfSmrg return eventToKeyButtonPointer(&ev->device_event, xi, count); 21735c4bbdfSmrg case ET_DeviceChanged: 21835c4bbdfSmrg case ET_RawKeyPress: 21935c4bbdfSmrg case ET_RawKeyRelease: 22035c4bbdfSmrg case ET_RawButtonPress: 22135c4bbdfSmrg case ET_RawButtonRelease: 22235c4bbdfSmrg case ET_RawMotion: 22335c4bbdfSmrg case ET_RawTouchBegin: 22435c4bbdfSmrg case ET_RawTouchUpdate: 22535c4bbdfSmrg case ET_RawTouchEnd: 22635c4bbdfSmrg case ET_TouchBegin: 22735c4bbdfSmrg case ET_TouchUpdate: 22835c4bbdfSmrg case ET_TouchEnd: 22935c4bbdfSmrg case ET_TouchOwnership: 23035c4bbdfSmrg case ET_BarrierHit: 23135c4bbdfSmrg case ET_BarrierLeave: 232ed6184dfSmrg case ET_GesturePinchBegin: 233ed6184dfSmrg case ET_GesturePinchUpdate: 234ed6184dfSmrg case ET_GesturePinchEnd: 235ed6184dfSmrg case ET_GestureSwipeBegin: 236ed6184dfSmrg case ET_GestureSwipeUpdate: 237ed6184dfSmrg case ET_GestureSwipeEnd: 23835c4bbdfSmrg *count = 0; 23935c4bbdfSmrg *xi = NULL; 24035c4bbdfSmrg return BadMatch; 24135c4bbdfSmrg default: 24235c4bbdfSmrg break; 2436747b715Smrg } 2446747b715Smrg 2456747b715Smrg ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type); 2466747b715Smrg return BadImplementation; 2476747b715Smrg} 2486747b715Smrg 2496747b715Smrg/** 2506747b715Smrg * Convert the given event to the respective XI 2.x event and store it in xi. 2516747b715Smrg * xi is allocated on demand and must be freed by the caller. 2526747b715Smrg * 2536747b715Smrg * Return values: 2546747b715Smrg * Success ... core contains the matching core event. 2556747b715Smrg * BadValue .. One or more values in the internal event are invalid. 2566747b715Smrg * BadMatch .. The event has no XI2 equivalent. 2576747b715Smrg * 2586747b715Smrg * @param[in] ev The event to convert into an XI2 event 2596747b715Smrg * @param[out] xi Future memory location for the XI2 event. 2606747b715Smrg * 2616747b715Smrg * @return Success or the error code. 2626747b715Smrg */ 2636747b715Smrgint 2646747b715SmrgEventToXI2(InternalEvent *ev, xEvent **xi) 2656747b715Smrg{ 26635c4bbdfSmrg switch (ev->any.type) { 2676747b715Smrg /* Enter/FocusIn are for grabs. We don't need an actual event, since 2686747b715Smrg * the real events delivered are triggered elsewhere */ 26935c4bbdfSmrg case ET_Enter: 27035c4bbdfSmrg case ET_FocusIn: 27135c4bbdfSmrg *xi = NULL; 27235c4bbdfSmrg return Success; 27335c4bbdfSmrg case ET_Motion: 27435c4bbdfSmrg case ET_ButtonPress: 27535c4bbdfSmrg case ET_ButtonRelease: 27635c4bbdfSmrg case ET_KeyPress: 27735c4bbdfSmrg case ET_KeyRelease: 27835c4bbdfSmrg case ET_TouchBegin: 27935c4bbdfSmrg case ET_TouchUpdate: 28035c4bbdfSmrg case ET_TouchEnd: 28135c4bbdfSmrg return eventToDeviceEvent(&ev->device_event, xi); 28235c4bbdfSmrg case ET_TouchOwnership: 28335c4bbdfSmrg return eventToTouchOwnershipEvent(&ev->touch_ownership_event, xi); 28435c4bbdfSmrg case ET_ProximityIn: 28535c4bbdfSmrg case ET_ProximityOut: 28635c4bbdfSmrg *xi = NULL; 28735c4bbdfSmrg return BadMatch; 28835c4bbdfSmrg case ET_DeviceChanged: 28935c4bbdfSmrg return eventToDeviceChanged(&ev->changed_event, xi); 29035c4bbdfSmrg case ET_RawKeyPress: 29135c4bbdfSmrg case ET_RawKeyRelease: 29235c4bbdfSmrg case ET_RawButtonPress: 29335c4bbdfSmrg case ET_RawButtonRelease: 29435c4bbdfSmrg case ET_RawMotion: 29535c4bbdfSmrg case ET_RawTouchBegin: 29635c4bbdfSmrg case ET_RawTouchUpdate: 29735c4bbdfSmrg case ET_RawTouchEnd: 29835c4bbdfSmrg return eventToRawEvent(&ev->raw_event, xi); 29935c4bbdfSmrg case ET_BarrierHit: 30035c4bbdfSmrg case ET_BarrierLeave: 30135c4bbdfSmrg return eventToBarrierEvent(&ev->barrier_event, xi); 302ed6184dfSmrg case ET_GesturePinchBegin: 303ed6184dfSmrg case ET_GesturePinchUpdate: 304ed6184dfSmrg case ET_GesturePinchEnd: 305ed6184dfSmrg return eventToGesturePinchEvent(&ev->gesture_event, xi); 306ed6184dfSmrg case ET_GestureSwipeBegin: 307ed6184dfSmrg case ET_GestureSwipeUpdate: 308ed6184dfSmrg case ET_GestureSwipeEnd: 309ed6184dfSmrg return eventToGestureSwipeEvent(&ev->gesture_event, xi); 31035c4bbdfSmrg default: 31135c4bbdfSmrg break; 3126747b715Smrg } 3136747b715Smrg 3146747b715Smrg ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type); 3156747b715Smrg return BadImplementation; 3166747b715Smrg} 3176747b715Smrg 3186747b715Smrgstatic int 3196747b715SmrgeventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count) 3206747b715Smrg{ 3216747b715Smrg int num_events; 32235c4bbdfSmrg int first; /* dummy */ 3236747b715Smrg deviceKeyButtonPointer *kbp; 3246747b715Smrg 3256747b715Smrg /* Sorry, XI 1.x protocol restrictions. */ 32635c4bbdfSmrg if (ev->detail.button > 0xFF || ev->deviceid >= 0x80) { 3276747b715Smrg *count = 0; 3286747b715Smrg return Success; 3296747b715Smrg } 3306747b715Smrg 33135c4bbdfSmrg num_events = (countValuators(ev, &first) + 5) / 6; /* valuator ev */ 33235c4bbdfSmrg if (num_events <= 0) { 33335c4bbdfSmrg switch (ev->type) { 33435c4bbdfSmrg case ET_KeyPress: 33535c4bbdfSmrg case ET_KeyRelease: 33635c4bbdfSmrg case ET_ButtonPress: 33735c4bbdfSmrg case ET_ButtonRelease: 33835c4bbdfSmrg /* no axes is ok */ 33935c4bbdfSmrg break; 34035c4bbdfSmrg case ET_Motion: 34135c4bbdfSmrg case ET_ProximityIn: 34235c4bbdfSmrg case ET_ProximityOut: 34335c4bbdfSmrg *count = 0; 34435c4bbdfSmrg return BadMatch; 34535c4bbdfSmrg default: 34635c4bbdfSmrg *count = 0; 34735c4bbdfSmrg return BadImplementation; 3489ace9065Smrg } 3499ace9065Smrg } 3509ace9065Smrg 35135c4bbdfSmrg num_events++; /* the actual event event */ 3526747b715Smrg 3536747b715Smrg *xi = calloc(num_events, sizeof(xEvent)); 35435c4bbdfSmrg if (!(*xi)) { 3556747b715Smrg return BadAlloc; 3566747b715Smrg } 3576747b715Smrg 35835c4bbdfSmrg kbp = (deviceKeyButtonPointer *) (*xi); 35935c4bbdfSmrg kbp->detail = ev->detail.button; 36035c4bbdfSmrg kbp->time = ev->time; 36135c4bbdfSmrg kbp->root = ev->root; 36235c4bbdfSmrg kbp->root_x = ev->root_x; 36335c4bbdfSmrg kbp->root_y = ev->root_y; 3646747b715Smrg kbp->deviceid = ev->deviceid; 36535c4bbdfSmrg kbp->state = ev->corestate; 36635c4bbdfSmrg EventSetKeyRepeatFlag((xEvent *) kbp, 3676747b715Smrg (ev->type == ET_KeyPress && ev->key_repeat)); 3686747b715Smrg 3696747b715Smrg if (num_events > 1) 3706747b715Smrg kbp->deviceid |= MORE_EVENTS; 3716747b715Smrg 37235c4bbdfSmrg switch (ev->type) { 37335c4bbdfSmrg case ET_Motion: 37435c4bbdfSmrg kbp->type = DeviceMotionNotify; 37535c4bbdfSmrg break; 37635c4bbdfSmrg case ET_ButtonPress: 37735c4bbdfSmrg kbp->type = DeviceButtonPress; 37835c4bbdfSmrg break; 37935c4bbdfSmrg case ET_ButtonRelease: 38035c4bbdfSmrg kbp->type = DeviceButtonRelease; 38135c4bbdfSmrg break; 38235c4bbdfSmrg case ET_KeyPress: 38335c4bbdfSmrg kbp->type = DeviceKeyPress; 38435c4bbdfSmrg break; 38535c4bbdfSmrg case ET_KeyRelease: 38635c4bbdfSmrg kbp->type = DeviceKeyRelease; 38735c4bbdfSmrg break; 38835c4bbdfSmrg case ET_ProximityIn: 38935c4bbdfSmrg kbp->type = ProximityIn; 39035c4bbdfSmrg break; 39135c4bbdfSmrg case ET_ProximityOut: 39235c4bbdfSmrg kbp->type = ProximityOut; 39335c4bbdfSmrg break; 39435c4bbdfSmrg default: 39535c4bbdfSmrg break; 3966747b715Smrg } 3976747b715Smrg 39835c4bbdfSmrg if (num_events > 1) { 39935c4bbdfSmrg getValuatorEvents(ev, (deviceValuator *) (kbp + 1)); 4006747b715Smrg } 4016747b715Smrg 4026747b715Smrg *count = num_events; 4036747b715Smrg return Success; 4046747b715Smrg} 4056747b715Smrg 4066747b715Smrg/** 4076747b715Smrg * Set first to the first valuator in the event ev and return the number of 4086747b715Smrg * valuators from first to the last set valuator. 4096747b715Smrg */ 4106747b715Smrgstatic int 4116747b715SmrgcountValuators(DeviceEvent *ev, int *first) 4126747b715Smrg{ 4136747b715Smrg int first_valuator = -1, last_valuator = -1, num_valuators = 0; 4146747b715Smrg int i; 4156747b715Smrg 41635c4bbdfSmrg for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { 41735c4bbdfSmrg if (BitIsOn(ev->valuators.mask, i)) { 4186747b715Smrg if (first_valuator == -1) 4196747b715Smrg first_valuator = i; 4206747b715Smrg last_valuator = i; 4216747b715Smrg } 4226747b715Smrg } 4236747b715Smrg 42435c4bbdfSmrg if (first_valuator != -1) { 4256747b715Smrg num_valuators = last_valuator - first_valuator + 1; 4266747b715Smrg *first = first_valuator; 4276747b715Smrg } 4286747b715Smrg 4296747b715Smrg return num_valuators; 4306747b715Smrg} 4316747b715Smrg 4326747b715Smrgstatic int 43335c4bbdfSmrggetValuatorEvents(DeviceEvent *ev, deviceValuator * xv) 4346747b715Smrg{ 4356747b715Smrg int i; 4366747b715Smrg int state = 0; 4376747b715Smrg int first_valuator, num_valuators; 4386747b715Smrg 4396747b715Smrg num_valuators = countValuators(ev, &first_valuator); 44035c4bbdfSmrg if (num_valuators > 0) { 4416747b715Smrg DeviceIntPtr dev = NULL; 44235c4bbdfSmrg 4436747b715Smrg dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess); 4446747b715Smrg /* State needs to be assembled BEFORE the device is updated. */ 44535c4bbdfSmrg state = (dev && 44635c4bbdfSmrg dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo-> 44735c4bbdfSmrg state) : 0; 4486747b715Smrg state |= (dev && dev->button) ? (dev->button->state) : 0; 4496747b715Smrg } 4506747b715Smrg 4516747b715Smrg for (i = 0; i < num_valuators; i += 6, xv++) { 45235c4bbdfSmrg INT32 *valuators = &xv->valuator0; // Treat all 6 vals as an array 4539ace9065Smrg int j; 4549ace9065Smrg 4556747b715Smrg xv->type = DeviceValuator; 4566747b715Smrg xv->first_valuator = first_valuator + i; 4576747b715Smrg xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); 4586747b715Smrg xv->deviceid = ev->deviceid; 4596747b715Smrg xv->device_state = state; 4609ace9065Smrg 4619ace9065Smrg /* Unset valuators in masked valuator events have the proper data values 4629ace9065Smrg * in the case of an absolute axis in between two set valuators. */ 4639ace9065Smrg for (j = 0; j < xv->num_valuators; j++) 4649ace9065Smrg valuators[j] = ev->valuators.data[xv->first_valuator + j]; 4656747b715Smrg 4666747b715Smrg if (i + 6 < num_valuators) 4676747b715Smrg xv->deviceid |= MORE_EVENTS; 4686747b715Smrg } 4696747b715Smrg 4706747b715Smrg return (num_valuators + 5) / 6; 4716747b715Smrg} 4726747b715Smrg 4736747b715Smrgstatic int 47435c4bbdfSmrgappendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo * info) 4756747b715Smrg{ 4766747b715Smrg uint32_t *kc; 4776747b715Smrg int i; 4786747b715Smrg 4796747b715Smrg info->type = XIKeyClass; 4806747b715Smrg info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1; 48135c4bbdfSmrg info->length = sizeof(xXIKeyInfo) / 4 + info->num_keycodes; 4826747b715Smrg info->sourceid = dce->sourceid; 4836747b715Smrg 48435c4bbdfSmrg kc = (uint32_t *) &info[1]; 4856747b715Smrg for (i = 0; i < info->num_keycodes; i++) 4866747b715Smrg *kc++ = i + dce->keys.min_keycode; 4876747b715Smrg 4886747b715Smrg return info->length * 4; 4896747b715Smrg} 4906747b715Smrg 4916747b715Smrgstatic int 49235c4bbdfSmrgappendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo * info) 4936747b715Smrg{ 4946747b715Smrg unsigned char *bits; 4956747b715Smrg int mask_len; 4966747b715Smrg 4976747b715Smrg mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons)); 4986747b715Smrg 4996747b715Smrg info->type = XIButtonClass; 5006747b715Smrg info->num_buttons = dce->buttons.num_buttons; 5016747b715Smrg info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + 50235c4bbdfSmrg info->num_buttons + mask_len; 5036747b715Smrg info->sourceid = dce->sourceid; 5046747b715Smrg 50535c4bbdfSmrg bits = (unsigned char *) &info[1]; 5066747b715Smrg memset(bits, 0, mask_len * 4); 5076747b715Smrg /* FIXME: is_down? */ 5086747b715Smrg 5096747b715Smrg bits += mask_len * 4; 5106747b715Smrg memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom)); 5116747b715Smrg 5126747b715Smrg return info->length * 4; 5136747b715Smrg} 5146747b715Smrg 5156747b715Smrgstatic int 51635c4bbdfSmrgappendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo * info, 51735c4bbdfSmrg int axisnumber) 5186747b715Smrg{ 5196747b715Smrg info->type = XIValuatorClass; 52035c4bbdfSmrg info->length = sizeof(xXIValuatorInfo) / 4; 5216747b715Smrg info->label = dce->valuators[axisnumber].name; 5226747b715Smrg info->min.integral = dce->valuators[axisnumber].min; 5236747b715Smrg info->min.frac = 0; 5246747b715Smrg info->max.integral = dce->valuators[axisnumber].max; 5256747b715Smrg info->max.frac = 0; 52635c4bbdfSmrg info->value = double_to_fp3232(dce->valuators[axisnumber].value); 5276747b715Smrg info->resolution = dce->valuators[axisnumber].resolution; 5286747b715Smrg info->number = axisnumber; 5299ace9065Smrg info->mode = dce->valuators[axisnumber].mode; 5306747b715Smrg info->sourceid = dce->sourceid; 5316747b715Smrg 5326747b715Smrg return info->length * 4; 5336747b715Smrg} 5346747b715Smrg 53535c4bbdfSmrgstatic int 53635c4bbdfSmrgappendScrollInfo(DeviceChangedEvent *dce, xXIScrollInfo * info, int axisnumber) 53735c4bbdfSmrg{ 53835c4bbdfSmrg if (dce->valuators[axisnumber].scroll.type == SCROLL_TYPE_NONE) 53935c4bbdfSmrg return 0; 54035c4bbdfSmrg 54135c4bbdfSmrg info->type = XIScrollClass; 54235c4bbdfSmrg info->length = sizeof(xXIScrollInfo) / 4; 54335c4bbdfSmrg info->number = axisnumber; 54435c4bbdfSmrg switch (dce->valuators[axisnumber].scroll.type) { 54535c4bbdfSmrg case SCROLL_TYPE_VERTICAL: 54635c4bbdfSmrg info->scroll_type = XIScrollTypeVertical; 54735c4bbdfSmrg break; 54835c4bbdfSmrg case SCROLL_TYPE_HORIZONTAL: 54935c4bbdfSmrg info->scroll_type = XIScrollTypeHorizontal; 55035c4bbdfSmrg break; 55135c4bbdfSmrg default: 55235c4bbdfSmrg ErrorF("[Xi] Unknown scroll type %d. This is a bug.\n", 55335c4bbdfSmrg dce->valuators[axisnumber].scroll.type); 55435c4bbdfSmrg break; 55535c4bbdfSmrg } 55635c4bbdfSmrg info->increment = 55735c4bbdfSmrg double_to_fp3232(dce->valuators[axisnumber].scroll.increment); 55835c4bbdfSmrg info->sourceid = dce->sourceid; 55935c4bbdfSmrg 56035c4bbdfSmrg info->flags = 0; 56135c4bbdfSmrg 56235c4bbdfSmrg if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_DONT_EMULATE) 56335c4bbdfSmrg info->flags |= XIScrollFlagNoEmulation; 56435c4bbdfSmrg if (dce->valuators[axisnumber].scroll.flags & SCROLL_FLAG_PREFERRED) 56535c4bbdfSmrg info->flags |= XIScrollFlagPreferred; 56635c4bbdfSmrg 56735c4bbdfSmrg return info->length * 4; 56835c4bbdfSmrg} 56935c4bbdfSmrg 5706747b715Smrgstatic int 5716747b715SmrgeventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi) 5726747b715Smrg{ 5736747b715Smrg xXIDeviceChangedEvent *dcce; 5746747b715Smrg int len = sizeof(xXIDeviceChangedEvent); 5756747b715Smrg int nkeys; 5766747b715Smrg char *ptr; 5776747b715Smrg 57835c4bbdfSmrg if (dce->buttons.num_buttons) { 5796747b715Smrg len += sizeof(xXIButtonInfo); 5806747b715Smrg len += dce->buttons.num_buttons * sizeof(Atom); /* button names */ 5816747b715Smrg len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons)); 5826747b715Smrg } 58335c4bbdfSmrg if (dce->num_valuators) { 58435c4bbdfSmrg int i; 58535c4bbdfSmrg 5866747b715Smrg len += sizeof(xXIValuatorInfo) * dce->num_valuators; 5876747b715Smrg 58835c4bbdfSmrg for (i = 0; i < dce->num_valuators; i++) 58935c4bbdfSmrg if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) 59035c4bbdfSmrg len += sizeof(xXIScrollInfo); 59135c4bbdfSmrg } 59235c4bbdfSmrg 5936747b715Smrg nkeys = (dce->keys.max_keycode > 0) ? 59435c4bbdfSmrg dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0; 59535c4bbdfSmrg if (nkeys > 0) { 5966747b715Smrg len += sizeof(xXIKeyInfo); 59735c4bbdfSmrg len += sizeof(CARD32) * nkeys; /* keycodes */ 5986747b715Smrg } 5996747b715Smrg 6006747b715Smrg dcce = calloc(1, len); 60135c4bbdfSmrg if (!dcce) { 6026747b715Smrg ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n"); 6036747b715Smrg return BadAlloc; 6046747b715Smrg } 6056747b715Smrg 60635c4bbdfSmrg dcce->type = GenericEvent; 60735c4bbdfSmrg dcce->extension = IReqCode; 60835c4bbdfSmrg dcce->evtype = XI_DeviceChanged; 60935c4bbdfSmrg dcce->time = dce->time; 61035c4bbdfSmrg dcce->deviceid = dce->deviceid; 61135c4bbdfSmrg dcce->sourceid = dce->sourceid; 61235c4bbdfSmrg dcce->reason = 61335c4bbdfSmrg (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch; 61435c4bbdfSmrg dcce->num_classes = 0; 6156747b715Smrg dcce->length = bytes_to_int32(len - sizeof(xEvent)); 6166747b715Smrg 61735c4bbdfSmrg ptr = (char *) &dcce[1]; 61835c4bbdfSmrg if (dce->buttons.num_buttons) { 6196747b715Smrg dcce->num_classes++; 62035c4bbdfSmrg ptr += appendButtonInfo(dce, (xXIButtonInfo *) ptr); 6216747b715Smrg } 6226747b715Smrg 62335c4bbdfSmrg if (nkeys) { 6246747b715Smrg dcce->num_classes++; 62535c4bbdfSmrg ptr += appendKeyInfo(dce, (xXIKeyInfo *) ptr); 6266747b715Smrg } 6276747b715Smrg 62835c4bbdfSmrg if (dce->num_valuators) { 6296747b715Smrg int i; 6306747b715Smrg 6316747b715Smrg dcce->num_classes += dce->num_valuators; 6326747b715Smrg for (i = 0; i < dce->num_valuators; i++) 63335c4bbdfSmrg ptr += appendValuatorInfo(dce, (xXIValuatorInfo *) ptr, i); 63435c4bbdfSmrg 63535c4bbdfSmrg for (i = 0; i < dce->num_valuators; i++) { 63635c4bbdfSmrg if (dce->valuators[i].scroll.type != SCROLL_TYPE_NONE) { 63735c4bbdfSmrg dcce->num_classes++; 63835c4bbdfSmrg ptr += appendScrollInfo(dce, (xXIScrollInfo *) ptr, i); 63935c4bbdfSmrg } 64035c4bbdfSmrg } 6416747b715Smrg } 6426747b715Smrg 64335c4bbdfSmrg *xi = (xEvent *) dcce; 6446747b715Smrg 6456747b715Smrg return Success; 6466747b715Smrg} 6476747b715Smrg 64835c4bbdfSmrgstatic int 64935c4bbdfSmrgcount_bits(unsigned char *ptr, int len) 6506747b715Smrg{ 6516747b715Smrg int bits = 0; 6526747b715Smrg unsigned int i; 6536747b715Smrg unsigned char x; 6546747b715Smrg 65535c4bbdfSmrg for (i = 0; i < len; i++) { 6566747b715Smrg x = ptr[i]; 65735c4bbdfSmrg while (x > 0) { 6586747b715Smrg bits += (x & 0x1); 6596747b715Smrg x >>= 1; 6606747b715Smrg } 6616747b715Smrg } 6626747b715Smrg return bits; 6636747b715Smrg} 6646747b715Smrg 6656747b715Smrgstatic int 6666747b715SmrgeventToDeviceEvent(DeviceEvent *ev, xEvent **xi) 6676747b715Smrg{ 6686747b715Smrg int len = sizeof(xXIDeviceEvent); 6696747b715Smrg xXIDeviceEvent *xde; 6706747b715Smrg int i, btlen, vallen; 6716747b715Smrg char *ptr; 6726747b715Smrg FP3232 *axisval; 6736747b715Smrg 6746747b715Smrg /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same 6756747b715Smrg * with MAX_VALUATORS below */ 6766747b715Smrg /* btlen is in 4 byte units */ 6776747b715Smrg btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS)); 67835c4bbdfSmrg len += btlen * 4; /* buttonmask len */ 6796747b715Smrg 6801b5d61b8Smrg vallen = count_bits(ev->valuators.mask, ARRAY_SIZE(ev->valuators.mask)); 68135c4bbdfSmrg len += vallen * 2 * sizeof(uint32_t); /* axisvalues */ 6826747b715Smrg vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); 68335c4bbdfSmrg len += vallen * 4; /* valuators mask */ 6846747b715Smrg 6856747b715Smrg *xi = calloc(1, len); 68658cf2af7Smrg if (*xi == NULL) 68758cf2af7Smrg return BadAlloc; 68835c4bbdfSmrg xde = (xXIDeviceEvent *) * xi; 68935c4bbdfSmrg xde->type = GenericEvent; 69035c4bbdfSmrg xde->extension = IReqCode; 69135c4bbdfSmrg xde->evtype = GetXI2Type(ev->type); 69235c4bbdfSmrg xde->time = ev->time; 69335c4bbdfSmrg xde->length = bytes_to_int32(len - sizeof(xEvent)); 69435c4bbdfSmrg if (IsTouchEvent((InternalEvent *) ev)) 69535c4bbdfSmrg xde->detail = ev->touchid; 69635c4bbdfSmrg else 69735c4bbdfSmrg xde->detail = ev->detail.button; 69835c4bbdfSmrg 69935c4bbdfSmrg xde->root = ev->root; 70035c4bbdfSmrg xde->buttons_len = btlen; 70135c4bbdfSmrg xde->valuators_len = vallen; 70235c4bbdfSmrg xde->deviceid = ev->deviceid; 70335c4bbdfSmrg xde->sourceid = ev->sourceid; 70435c4bbdfSmrg xde->root_x = double_to_fp1616(ev->root_x + ev->root_x_frac); 70535c4bbdfSmrg xde->root_y = double_to_fp1616(ev->root_y + ev->root_y_frac); 70635c4bbdfSmrg 70735c4bbdfSmrg if (IsTouchEvent((InternalEvent *)ev)) { 70835c4bbdfSmrg if (ev->type == ET_TouchUpdate) 70935c4bbdfSmrg xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0; 71035c4bbdfSmrg 71135c4bbdfSmrg if (ev->flags & TOUCH_POINTER_EMULATED) 71235c4bbdfSmrg xde->flags |= XITouchEmulatingPointer; 71335c4bbdfSmrg } else { 71435c4bbdfSmrg xde->flags = ev->flags; 71535c4bbdfSmrg 71635c4bbdfSmrg if (ev->key_repeat) 71735c4bbdfSmrg xde->flags |= XIKeyRepeat; 71835c4bbdfSmrg } 71935c4bbdfSmrg 72035c4bbdfSmrg xde->mods.base_mods = ev->mods.base; 72135c4bbdfSmrg xde->mods.latched_mods = ev->mods.latched; 72235c4bbdfSmrg xde->mods.locked_mods = ev->mods.locked; 72335c4bbdfSmrg xde->mods.effective_mods = ev->mods.effective; 72435c4bbdfSmrg 72535c4bbdfSmrg xde->group.base_group = ev->group.base; 72635c4bbdfSmrg xde->group.latched_group = ev->group.latched; 72735c4bbdfSmrg xde->group.locked_group = ev->group.locked; 72835c4bbdfSmrg xde->group.effective_group = ev->group.effective; 72935c4bbdfSmrg 73035c4bbdfSmrg ptr = (char *) &xde[1]; 73135c4bbdfSmrg for (i = 0; i < sizeof(ev->buttons) * 8; i++) { 7326747b715Smrg if (BitIsOn(ev->buttons, i)) 7336747b715Smrg SetBit(ptr, i); 7346747b715Smrg } 7356747b715Smrg 7366747b715Smrg ptr += xde->buttons_len * 4; 73735c4bbdfSmrg axisval = (FP3232 *) (ptr + xde->valuators_len * 4); 738f2346221Smrg for (i = 0; i < MAX_VALUATORS; i++) { 73935c4bbdfSmrg if (BitIsOn(ev->valuators.mask, i)) { 7406747b715Smrg SetBit(ptr, i); 74135c4bbdfSmrg *axisval = double_to_fp3232(ev->valuators.data[i]); 7426747b715Smrg axisval++; 7436747b715Smrg } 7446747b715Smrg } 7456747b715Smrg 7466747b715Smrg return Success; 7476747b715Smrg} 7486747b715Smrg 74935c4bbdfSmrgstatic int 75035c4bbdfSmrgeventToTouchOwnershipEvent(TouchOwnershipEvent *ev, xEvent **xi) 75135c4bbdfSmrg{ 75235c4bbdfSmrg int len = sizeof(xXITouchOwnershipEvent); 75335c4bbdfSmrg xXITouchOwnershipEvent *xtoe; 75435c4bbdfSmrg 75535c4bbdfSmrg *xi = calloc(1, len); 75658cf2af7Smrg if (*xi == NULL) 75758cf2af7Smrg return BadAlloc; 75835c4bbdfSmrg xtoe = (xXITouchOwnershipEvent *) * xi; 75935c4bbdfSmrg xtoe->type = GenericEvent; 76035c4bbdfSmrg xtoe->extension = IReqCode; 76135c4bbdfSmrg xtoe->length = bytes_to_int32(len - sizeof(xEvent)); 76235c4bbdfSmrg xtoe->evtype = GetXI2Type(ev->type); 76335c4bbdfSmrg xtoe->deviceid = ev->deviceid; 76435c4bbdfSmrg xtoe->time = ev->time; 76535c4bbdfSmrg xtoe->sourceid = ev->sourceid; 76635c4bbdfSmrg xtoe->touchid = ev->touchid; 76735c4bbdfSmrg xtoe->flags = 0; /* we don't have wire flags for ownership yet */ 76835c4bbdfSmrg 76935c4bbdfSmrg return Success; 77035c4bbdfSmrg} 77135c4bbdfSmrg 7726747b715Smrgstatic int 7736747b715SmrgeventToRawEvent(RawDeviceEvent *ev, xEvent **xi) 7746747b715Smrg{ 77535c4bbdfSmrg xXIRawEvent *raw; 7766747b715Smrg int vallen, nvals; 7776747b715Smrg int i, len = sizeof(xXIRawEvent); 7786747b715Smrg char *ptr; 77935c4bbdfSmrg FP3232 *axisval, *axisval_raw; 7806747b715Smrg 7816747b715Smrg nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)); 78235c4bbdfSmrg len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once 78335c4bbdfSmrg raw, once processed */ 7846747b715Smrg vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); 78535c4bbdfSmrg len += vallen * 4; /* valuators mask */ 7866747b715Smrg 7876747b715Smrg *xi = calloc(1, len); 78858cf2af7Smrg if (*xi == NULL) 78958cf2af7Smrg return BadAlloc; 79035c4bbdfSmrg raw = (xXIRawEvent *) * xi; 79135c4bbdfSmrg raw->type = GenericEvent; 79235c4bbdfSmrg raw->extension = IReqCode; 79335c4bbdfSmrg raw->evtype = GetXI2Type(ev->type); 79435c4bbdfSmrg raw->time = ev->time; 79535c4bbdfSmrg raw->length = bytes_to_int32(len - sizeof(xEvent)); 79635c4bbdfSmrg raw->detail = ev->detail.button; 79735c4bbdfSmrg raw->deviceid = ev->deviceid; 79835c4bbdfSmrg raw->sourceid = ev->sourceid; 79935c4bbdfSmrg raw->valuators_len = vallen; 80035c4bbdfSmrg raw->flags = ev->flags; 80135c4bbdfSmrg 80235c4bbdfSmrg ptr = (char *) &raw[1]; 80335c4bbdfSmrg axisval = (FP3232 *) (ptr + raw->valuators_len * 4); 80435c4bbdfSmrg axisval_raw = axisval + nvals; 805f2346221Smrg for (i = 0; i < MAX_VALUATORS; i++) { 80635c4bbdfSmrg if (BitIsOn(ev->valuators.mask, i)) { 8076747b715Smrg SetBit(ptr, i); 80835c4bbdfSmrg *axisval = double_to_fp3232(ev->valuators.data[i]); 80935c4bbdfSmrg *axisval_raw = double_to_fp3232(ev->valuators.data_raw[i]); 8106747b715Smrg axisval++; 81135c4bbdfSmrg axisval_raw++; 8126747b715Smrg } 8136747b715Smrg } 8146747b715Smrg 8156747b715Smrg return Success; 8166747b715Smrg} 8176747b715Smrg 81835c4bbdfSmrgstatic int 81935c4bbdfSmrgeventToBarrierEvent(BarrierEvent *ev, xEvent **xi) 82035c4bbdfSmrg{ 82135c4bbdfSmrg xXIBarrierEvent *barrier; 82235c4bbdfSmrg int len = sizeof(xXIBarrierEvent); 82335c4bbdfSmrg 82435c4bbdfSmrg *xi = calloc(1, len); 82558cf2af7Smrg if (*xi == NULL) 82658cf2af7Smrg return BadAlloc; 82735c4bbdfSmrg barrier = (xXIBarrierEvent*) *xi; 82835c4bbdfSmrg barrier->type = GenericEvent; 82935c4bbdfSmrg barrier->extension = IReqCode; 83035c4bbdfSmrg barrier->evtype = GetXI2Type(ev->type); 83135c4bbdfSmrg barrier->length = bytes_to_int32(len - sizeof(xEvent)); 83235c4bbdfSmrg barrier->deviceid = ev->deviceid; 83335c4bbdfSmrg barrier->sourceid = ev->sourceid; 83435c4bbdfSmrg barrier->time = ev->time; 83535c4bbdfSmrg barrier->event = ev->window; 83635c4bbdfSmrg barrier->root = ev->root; 83735c4bbdfSmrg barrier->dx = double_to_fp3232(ev->dx); 83835c4bbdfSmrg barrier->dy = double_to_fp3232(ev->dy); 83935c4bbdfSmrg barrier->dtime = ev->dt; 84035c4bbdfSmrg barrier->flags = ev->flags; 84135c4bbdfSmrg barrier->eventid = ev->event_id; 84235c4bbdfSmrg barrier->barrier = ev->barrierid; 84335c4bbdfSmrg barrier->root_x = double_to_fp1616(ev->root_x); 84435c4bbdfSmrg barrier->root_y = double_to_fp1616(ev->root_y); 84535c4bbdfSmrg 84635c4bbdfSmrg return Success; 84735c4bbdfSmrg} 84835c4bbdfSmrg 849ed6184dfSmrgint 850ed6184dfSmrgeventToGesturePinchEvent(GestureEvent *ev, xEvent **xi) 851ed6184dfSmrg{ 852ed6184dfSmrg int len = sizeof(xXIGesturePinchEvent); 853ed6184dfSmrg xXIGesturePinchEvent *xpe; 854ed6184dfSmrg 855ed6184dfSmrg *xi = calloc(1, len); 85658cf2af7Smrg if (*xi == NULL) 85758cf2af7Smrg return BadAlloc; 858ed6184dfSmrg xpe = (xXIGesturePinchEvent *) * xi; 859ed6184dfSmrg xpe->type = GenericEvent; 860ed6184dfSmrg xpe->extension = IReqCode; 861ed6184dfSmrg xpe->evtype = GetXI2Type(ev->type); 862ed6184dfSmrg xpe->time = ev->time; 863ed6184dfSmrg xpe->length = bytes_to_int32(len - sizeof(xEvent)); 864ed6184dfSmrg xpe->detail = ev->num_touches; 865ed6184dfSmrg 866ed6184dfSmrg xpe->root = ev->root; 867ed6184dfSmrg xpe->deviceid = ev->deviceid; 868ed6184dfSmrg xpe->sourceid = ev->sourceid; 869ed6184dfSmrg xpe->root_x = double_to_fp1616(ev->root_x); 870ed6184dfSmrg xpe->root_y = double_to_fp1616(ev->root_y); 871ed6184dfSmrg xpe->flags |= (ev->flags & GESTURE_CANCELLED) ? XIGesturePinchEventCancelled : 0; 872ed6184dfSmrg 873ed6184dfSmrg xpe->delta_x = double_to_fp1616(ev->delta_x); 874ed6184dfSmrg xpe->delta_y = double_to_fp1616(ev->delta_y); 875ed6184dfSmrg xpe->delta_unaccel_x = double_to_fp1616(ev->delta_unaccel_x); 876ed6184dfSmrg xpe->delta_unaccel_y = double_to_fp1616(ev->delta_unaccel_y); 877ed6184dfSmrg xpe->scale = double_to_fp1616(ev->scale); 878ed6184dfSmrg xpe->delta_angle = double_to_fp1616(ev->delta_angle); 879ed6184dfSmrg 880ed6184dfSmrg xpe->mods.base_mods = ev->mods.base; 881ed6184dfSmrg xpe->mods.latched_mods = ev->mods.latched; 882ed6184dfSmrg xpe->mods.locked_mods = ev->mods.locked; 883ed6184dfSmrg xpe->mods.effective_mods = ev->mods.effective; 884ed6184dfSmrg 885ed6184dfSmrg xpe->group.base_group = ev->group.base; 886ed6184dfSmrg xpe->group.latched_group = ev->group.latched; 887ed6184dfSmrg xpe->group.locked_group = ev->group.locked; 888ed6184dfSmrg xpe->group.effective_group = ev->group.effective; 889ed6184dfSmrg 890ed6184dfSmrg return Success; 891ed6184dfSmrg} 892ed6184dfSmrg 893ed6184dfSmrgint 894ed6184dfSmrgeventToGestureSwipeEvent(GestureEvent *ev, xEvent **xi) 895ed6184dfSmrg{ 896ed6184dfSmrg int len = sizeof(xXIGestureSwipeEvent); 897ed6184dfSmrg xXIGestureSwipeEvent *xde; 898ed6184dfSmrg 899ed6184dfSmrg *xi = calloc(1, len); 90058cf2af7Smrg if (*xi == NULL) 90158cf2af7Smrg return BadAlloc; 902ed6184dfSmrg xde = (xXIGestureSwipeEvent *) * xi; 903ed6184dfSmrg xde->type = GenericEvent; 904ed6184dfSmrg xde->extension = IReqCode; 905ed6184dfSmrg xde->evtype = GetXI2Type(ev->type); 906ed6184dfSmrg xde->time = ev->time; 907ed6184dfSmrg xde->length = bytes_to_int32(len - sizeof(xEvent)); 908ed6184dfSmrg xde->detail = ev->num_touches; 909ed6184dfSmrg 910ed6184dfSmrg xde->root = ev->root; 911ed6184dfSmrg xde->deviceid = ev->deviceid; 912ed6184dfSmrg xde->sourceid = ev->sourceid; 913ed6184dfSmrg xde->root_x = double_to_fp1616(ev->root_x); 914ed6184dfSmrg xde->root_y = double_to_fp1616(ev->root_y); 915ed6184dfSmrg xde->flags |= (ev->flags & GESTURE_CANCELLED) ? XIGestureSwipeEventCancelled : 0; 916ed6184dfSmrg 917ed6184dfSmrg xde->delta_x = double_to_fp1616(ev->delta_x); 918ed6184dfSmrg xde->delta_y = double_to_fp1616(ev->delta_y); 919ed6184dfSmrg xde->delta_unaccel_x = double_to_fp1616(ev->delta_unaccel_x); 920ed6184dfSmrg xde->delta_unaccel_y = double_to_fp1616(ev->delta_unaccel_y); 921ed6184dfSmrg 922ed6184dfSmrg xde->mods.base_mods = ev->mods.base; 923ed6184dfSmrg xde->mods.latched_mods = ev->mods.latched; 924ed6184dfSmrg xde->mods.locked_mods = ev->mods.locked; 925ed6184dfSmrg xde->mods.effective_mods = ev->mods.effective; 926ed6184dfSmrg 927ed6184dfSmrg xde->group.base_group = ev->group.base; 928ed6184dfSmrg xde->group.latched_group = ev->group.latched; 929ed6184dfSmrg xde->group.locked_group = ev->group.locked; 930ed6184dfSmrg xde->group.effective_group = ev->group.effective; 931ed6184dfSmrg 932ed6184dfSmrg return Success; 933ed6184dfSmrg} 934ed6184dfSmrg 9356747b715Smrg/** 9366747b715Smrg * Return the corresponding core type for the given event or 0 if no core 9376747b715Smrg * equivalent exists. 9386747b715Smrg */ 9396747b715Smrgint 94035c4bbdfSmrgGetCoreType(enum EventType type) 9416747b715Smrg{ 9426747b715Smrg int coretype = 0; 94335c4bbdfSmrg 94435c4bbdfSmrg switch (type) { 94535c4bbdfSmrg case ET_Motion: 94635c4bbdfSmrg coretype = MotionNotify; 94735c4bbdfSmrg break; 94835c4bbdfSmrg case ET_ButtonPress: 94935c4bbdfSmrg coretype = ButtonPress; 95035c4bbdfSmrg break; 95135c4bbdfSmrg case ET_ButtonRelease: 95235c4bbdfSmrg coretype = ButtonRelease; 95335c4bbdfSmrg break; 95435c4bbdfSmrg case ET_KeyPress: 95535c4bbdfSmrg coretype = KeyPress; 95635c4bbdfSmrg break; 95735c4bbdfSmrg case ET_KeyRelease: 95835c4bbdfSmrg coretype = KeyRelease; 95935c4bbdfSmrg break; 96035c4bbdfSmrg default: 96135c4bbdfSmrg break; 9626747b715Smrg } 9636747b715Smrg return coretype; 9646747b715Smrg} 9656747b715Smrg 9666747b715Smrg/** 9676747b715Smrg * Return the corresponding XI 1.x type for the given event or 0 if no 9686747b715Smrg * equivalent exists. 9696747b715Smrg */ 9706747b715Smrgint 97135c4bbdfSmrgGetXIType(enum EventType type) 9726747b715Smrg{ 9736747b715Smrg int xitype = 0; 97435c4bbdfSmrg 97535c4bbdfSmrg switch (type) { 97635c4bbdfSmrg case ET_Motion: 97735c4bbdfSmrg xitype = DeviceMotionNotify; 97835c4bbdfSmrg break; 97935c4bbdfSmrg case ET_ButtonPress: 98035c4bbdfSmrg xitype = DeviceButtonPress; 98135c4bbdfSmrg break; 98235c4bbdfSmrg case ET_ButtonRelease: 98335c4bbdfSmrg xitype = DeviceButtonRelease; 98435c4bbdfSmrg break; 98535c4bbdfSmrg case ET_KeyPress: 98635c4bbdfSmrg xitype = DeviceKeyPress; 98735c4bbdfSmrg break; 98835c4bbdfSmrg case ET_KeyRelease: 98935c4bbdfSmrg xitype = DeviceKeyRelease; 99035c4bbdfSmrg break; 99135c4bbdfSmrg case ET_ProximityIn: 99235c4bbdfSmrg xitype = ProximityIn; 99335c4bbdfSmrg break; 99435c4bbdfSmrg case ET_ProximityOut: 99535c4bbdfSmrg xitype = ProximityOut; 99635c4bbdfSmrg break; 99735c4bbdfSmrg default: 99835c4bbdfSmrg break; 9996747b715Smrg } 10006747b715Smrg return xitype; 10016747b715Smrg} 10026747b715Smrg 10036747b715Smrg/** 10046747b715Smrg * Return the corresponding XI 2.x type for the given event or 0 if no 10056747b715Smrg * equivalent exists. 10066747b715Smrg */ 10076747b715Smrgint 100835c4bbdfSmrgGetXI2Type(enum EventType type) 10096747b715Smrg{ 10106747b715Smrg int xi2type = 0; 10116747b715Smrg 101235c4bbdfSmrg switch (type) { 101335c4bbdfSmrg case ET_Motion: 101435c4bbdfSmrg xi2type = XI_Motion; 101535c4bbdfSmrg break; 101635c4bbdfSmrg case ET_ButtonPress: 101735c4bbdfSmrg xi2type = XI_ButtonPress; 101835c4bbdfSmrg break; 101935c4bbdfSmrg case ET_ButtonRelease: 102035c4bbdfSmrg xi2type = XI_ButtonRelease; 102135c4bbdfSmrg break; 102235c4bbdfSmrg case ET_KeyPress: 102335c4bbdfSmrg xi2type = XI_KeyPress; 102435c4bbdfSmrg break; 102535c4bbdfSmrg case ET_KeyRelease: 102635c4bbdfSmrg xi2type = XI_KeyRelease; 102735c4bbdfSmrg break; 102835c4bbdfSmrg case ET_Enter: 102935c4bbdfSmrg xi2type = XI_Enter; 103035c4bbdfSmrg break; 103135c4bbdfSmrg case ET_Leave: 103235c4bbdfSmrg xi2type = XI_Leave; 103335c4bbdfSmrg break; 103435c4bbdfSmrg case ET_Hierarchy: 103535c4bbdfSmrg xi2type = XI_HierarchyChanged; 103635c4bbdfSmrg break; 103735c4bbdfSmrg case ET_DeviceChanged: 103835c4bbdfSmrg xi2type = XI_DeviceChanged; 103935c4bbdfSmrg break; 104035c4bbdfSmrg case ET_RawKeyPress: 104135c4bbdfSmrg xi2type = XI_RawKeyPress; 104235c4bbdfSmrg break; 104335c4bbdfSmrg case ET_RawKeyRelease: 104435c4bbdfSmrg xi2type = XI_RawKeyRelease; 104535c4bbdfSmrg break; 104635c4bbdfSmrg case ET_RawButtonPress: 104735c4bbdfSmrg xi2type = XI_RawButtonPress; 104835c4bbdfSmrg break; 104935c4bbdfSmrg case ET_RawButtonRelease: 105035c4bbdfSmrg xi2type = XI_RawButtonRelease; 105135c4bbdfSmrg break; 105235c4bbdfSmrg case ET_RawMotion: 105335c4bbdfSmrg xi2type = XI_RawMotion; 105435c4bbdfSmrg break; 105535c4bbdfSmrg case ET_RawTouchBegin: 105635c4bbdfSmrg xi2type = XI_RawTouchBegin; 105735c4bbdfSmrg break; 105835c4bbdfSmrg case ET_RawTouchUpdate: 105935c4bbdfSmrg xi2type = XI_RawTouchUpdate; 106035c4bbdfSmrg break; 106135c4bbdfSmrg case ET_RawTouchEnd: 106235c4bbdfSmrg xi2type = XI_RawTouchEnd; 106335c4bbdfSmrg break; 106435c4bbdfSmrg case ET_FocusIn: 106535c4bbdfSmrg xi2type = XI_FocusIn; 106635c4bbdfSmrg break; 106735c4bbdfSmrg case ET_FocusOut: 106835c4bbdfSmrg xi2type = XI_FocusOut; 106935c4bbdfSmrg break; 107035c4bbdfSmrg case ET_TouchBegin: 107135c4bbdfSmrg xi2type = XI_TouchBegin; 107235c4bbdfSmrg break; 107335c4bbdfSmrg case ET_TouchEnd: 107435c4bbdfSmrg xi2type = XI_TouchEnd; 107535c4bbdfSmrg break; 107635c4bbdfSmrg case ET_TouchUpdate: 107735c4bbdfSmrg xi2type = XI_TouchUpdate; 107835c4bbdfSmrg break; 107935c4bbdfSmrg case ET_TouchOwnership: 108035c4bbdfSmrg xi2type = XI_TouchOwnership; 108135c4bbdfSmrg break; 108235c4bbdfSmrg case ET_BarrierHit: 108335c4bbdfSmrg xi2type = XI_BarrierHit; 108435c4bbdfSmrg break; 108535c4bbdfSmrg case ET_BarrierLeave: 108635c4bbdfSmrg xi2type = XI_BarrierLeave; 108735c4bbdfSmrg break; 1088ed6184dfSmrg case ET_GesturePinchBegin: 1089ed6184dfSmrg xi2type = XI_GesturePinchBegin; 1090ed6184dfSmrg break; 1091ed6184dfSmrg case ET_GesturePinchUpdate: 1092ed6184dfSmrg xi2type = XI_GesturePinchUpdate; 1093ed6184dfSmrg break; 1094ed6184dfSmrg case ET_GesturePinchEnd: 1095ed6184dfSmrg xi2type = XI_GesturePinchEnd; 1096ed6184dfSmrg break; 1097ed6184dfSmrg case ET_GestureSwipeBegin: 1098ed6184dfSmrg xi2type = XI_GestureSwipeBegin; 1099ed6184dfSmrg break; 1100ed6184dfSmrg case ET_GestureSwipeUpdate: 1101ed6184dfSmrg xi2type = XI_GestureSwipeUpdate; 1102ed6184dfSmrg break; 1103ed6184dfSmrg case ET_GestureSwipeEnd: 1104ed6184dfSmrg xi2type = XI_GestureSwipeEnd; 1105ed6184dfSmrg break; 110635c4bbdfSmrg default: 110735c4bbdfSmrg break; 11086747b715Smrg } 11096747b715Smrg return xi2type; 11106747b715Smrg} 1111ed6184dfSmrg 1112ed6184dfSmrg/** 1113ed6184dfSmrg * Converts a gesture type to corresponding Gesture{Pinch,Swipe}Begin. 1114ed6184dfSmrg * Returns 0 if the input type is not a gesture. 1115ed6184dfSmrg */ 1116ed6184dfSmrgenum EventType 1117ed6184dfSmrgGestureTypeToBegin(enum EventType type) 1118ed6184dfSmrg{ 1119ed6184dfSmrg switch (type) { 1120ed6184dfSmrg case ET_GesturePinchBegin: 1121ed6184dfSmrg case ET_GesturePinchUpdate: 1122ed6184dfSmrg case ET_GesturePinchEnd: 1123ed6184dfSmrg return ET_GesturePinchBegin; 1124ed6184dfSmrg case ET_GestureSwipeBegin: 1125ed6184dfSmrg case ET_GestureSwipeUpdate: 1126ed6184dfSmrg case ET_GestureSwipeEnd: 1127ed6184dfSmrg return ET_GestureSwipeBegin; 1128ed6184dfSmrg default: 1129ed6184dfSmrg return 0; 1130ed6184dfSmrg } 1131ed6184dfSmrg} 1132ed6184dfSmrg 1133ed6184dfSmrg/** 1134ed6184dfSmrg * Converts a gesture type to corresponding Gesture{Pinch,Swipe}End. 1135ed6184dfSmrg * Returns 0 if the input type is not a gesture. 1136ed6184dfSmrg */ 1137ed6184dfSmrgenum EventType 1138ed6184dfSmrgGestureTypeToEnd(enum EventType type) 1139ed6184dfSmrg{ 1140ed6184dfSmrg switch (type) { 1141ed6184dfSmrg case ET_GesturePinchBegin: 1142ed6184dfSmrg case ET_GesturePinchUpdate: 1143ed6184dfSmrg case ET_GesturePinchEnd: 1144ed6184dfSmrg return ET_GesturePinchEnd; 1145ed6184dfSmrg case ET_GestureSwipeBegin: 1146ed6184dfSmrg case ET_GestureSwipeUpdate: 1147ed6184dfSmrg case ET_GestureSwipeEnd: 1148ed6184dfSmrg return ET_GestureSwipeEnd; 1149ed6184dfSmrg default: 1150ed6184dfSmrg return 0; 1151ed6184dfSmrg } 1152ed6184dfSmrg} 1153