[PATCH evdev 8/8] handle multitouch events whithin proximity
Peter Hutterer
peter.hutterer at who-t.net
Wed Jan 9 16:09:57 PST 2013
On Wed, Jan 09, 2013 at 07:21:22PM +0100, Benjamin Tissoires wrote:
> 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>
Series looks good minus the comment in 7/8 which goes over to this patch
too.
We need a bunch of testcases for XIT before we can merge this though, I'd
rather avoid breaking existing devices :)
Cheers,
Peter
> ---
> 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