summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2011-12-14 16:33:05 +1000
committerChase Douglas <chase.douglas@canonical.com>2011-12-21 10:34:12 -0800
commitd321abd2028e8221c6a108deca3939190392c241 (patch)
treeeea17f1f6b3cb93f15867da0f0dd23f38b172f18
parentcb91a878242debb3ba179381c9cb98b5f238f02e (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>
-rw-r--r--Xi/exevents.c33
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;
}