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.tissoi...@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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel