[PATCH evdev 8/8] handle multitouch events whithin proximity
Benjamin Tissoires
benjamin.tissoires at gmail.com
Wed Jan 9 10:21:22 PST 2013
ABS_MT_DISTANCE controls whether the finger is touching the sensor or not.
When the slot is opened, if the device reports ABS_MT_DISTANCE, we should
rely on it to set the right value of touch. If not, then the creation of
the slot means that the touch began.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
---
src/evdev.c | 38 +++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/src/evdev.c b/src/evdev.c
index 256037c..c84b2ac 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -734,7 +734,7 @@ static void
EvdevProcessTouch(InputInfoPtr pInfo)
{
EvdevPtr pEvdev = pInfo->private;
- int type;
+ int type, map;
int slot_index = last_mt_vals_slot(pEvdev);
EvdevMTState *mt_state;
@@ -748,9 +748,21 @@ EvdevProcessTouch(InputInfoPtr pInfo)
return;
if (pEvdev->slot_state == SLOTSTATE_CLOSE)
+ /* in any cases, release the touch when closing the slot */
mt_state->touch = FALSE;
- else if (pEvdev->slot_state == SLOTSTATE_OPEN)
- mt_state->touch = TRUE;
+ else if (pEvdev->slot_state == SLOTSTATE_OPEN) {
+ map = pEvdev->axis_map[ABS_MT_DISTANCE];
+ if (!map)
+ /* The device does not support distance:
+ * getting a new slot means the begining of the touch */
+ mt_state->touch = TRUE;
+ else
+ mt_state->touch = !valuator_mask_get(mt_state->last_vals, map);
+ }
+
+ /* If there is no touch, ignore events within proximity */
+ if (!mt_state->touch && !mt_state->touch_state)
+ return;
type = XI_TouchUpdate;
@@ -830,14 +842,21 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
if (pEvdev->slot_state == SLOTSTATE_EMPTY)
pEvdev->slot_state = SLOTSTATE_UPDATE;
- if (ev->code == ABS_MT_TRACKING_ID) {
+
+ switch (ev->code) {
+ case ABS_MT_TRACKING_ID:
+ /* open/close the slot => finger getting in/out proximity */
if (ev->value >= 0) {
pEvdev->slot_state = SLOTSTATE_OPEN;
valuator_mask_copy(pEvdev->mt_mask,
mt_state->last_vals);
} else
pEvdev->slot_state = SLOTSTATE_CLOSE;
- } else {
+ break;
+ case ABS_MT_DISTANCE:
+ mt_state->touch = !ev->value;
+ /* intentional fallback */
+ default:
map = pEvdev->axis_map[ev->code];
valuator_mask_set(pEvdev->mt_mask, map, ev->value);
valuator_mask_set(mt_state->last_vals, map, ev->value);
@@ -1453,10 +1472,15 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGMTSLOTS failed: %s\n",
strerror(errno));
}
- for (i = 0; i < num_touches; i++)
- valuator_mask_set(pEvdev->mt_state[i].last_vals,
+ for (i = 0; i < num_touches; i++) {
+ EvdevMTState *mt_state = &pEvdev->mt_state[i];
+ valuator_mask_set(mt_state->last_vals,
pEvdev->axis_map[axis],
mt_request_data[i]);
+
+ if (axis == ABS_MT_DISTANCE)
+ mt_state->touch = !mt_request_data[i];
+ }
}
}
--
1.8.0.2
More information about the xorg-devel
mailing list