diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2011-12-14 16:33:05 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2011-12-21 12:38:35 +1000 |
commit | dbfd7b37a0ba21899d8ebb7e0b324301bd466c49 (patch) | |
tree | fe3c198b5adfff033b04cb123d5d6685f8cec90b /Xi | |
parent | 593c3e2eb3da5c5fb957b68c8025dfdbe1139639 (diff) |
Xi: make UpdateDeviceState aware of touch events
Update the logical button state for pointer-emulating events. Button state
must be kept separate from the ButtonClassRec to avoid clearing the button
state on a touch end if there is a physical button still down.
And obviously don't change the button state if we're currently replaying the
event history for some client.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
Diffstat (limited to 'Xi')
-rw-r--r-- | Xi/exevents.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/Xi/exevents.c b/Xi/exevents.c index b18157d30..5cf60f8f1 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -849,6 +849,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) KeyClassPtr k = NULL; ButtonClassPtr b = NULL; ValuatorClassPtr v = NULL; + TouchClassPtr t = NULL; /* This event is always the first we get, before the actual events with * the data. However, the way how the DDX is set up, "device" will @@ -866,6 +867,9 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) case ET_KeyRelease: case ET_ProximityIn: case ET_ProximityOut: + case ET_TouchBegin: + case ET_TouchUpdate: + case ET_TouchEnd: break; default: /* other events don't update the device */ @@ -875,6 +879,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) k = device->key; v = device->valuator; b = device->button; + t = device->touch; key = event->detail.key; @@ -976,6 +981,34 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) device->proximity->in_proximity = TRUE; else if (event->type == ET_ProximityOut) device->proximity->in_proximity = FALSE; + else if (event->type == ET_TouchBegin) { + BUG_WARN(!b || !v); + BUG_WARN(!t); + + if (!b || !t || !b->map[key]) + return DONT_PROCESS; + + if (!(event->flags & TOUCH_POINTER_EMULATED) || + (event->flags & TOUCH_REPLAYING)) + return DONT_PROCESS; + + IncreaseButtonCount(device, key, &t->buttonsDown, &t->motionMask, &t->state); + UpdateDeviceMotionMask(device, t->state, DeviceButtonMotionMask); + } else if (event->type == ET_TouchEnd) { + BUG_WARN(!b || !v); + BUG_WARN(!t); + + if (!b || !t || t->buttonsDown <= 0 || !b->map[key]) + return DONT_PROCESS; + + if (!(event->flags & TOUCH_POINTER_EMULATED)) + return DONT_PROCESS; + if (!(event->flags & TOUCH_END)) + return DONT_PROCESS; + + DecreaseButtonCount(device, key, &t->buttonsDown, &t->motionMask, &t->state); + UpdateDeviceMotionMask(device, t->state, DeviceButtonMotionMask); + } return DEFAULT; } |