Evdev is a 100% stateful protocol. The following is correct, and represents a double tap:
ABS_MT_SLOT 0 /* Set touch slot */ ABS_MT_TRACKING_ID 0 /* New touch with ID 0 in slot 0 */ ABS_MT_POSITION_X 500 /* Initial X position */ ABS_MT_POSITION_Y 500 /* Initial Y position */ SYNC /* End of frame */ ABS_MT_TRACKING_ID -1 /* Touch in last slot (0) ended */ SYNC /* End of frame */ ABS_MT_TRACKING_ID 1 /* New touch in last slot (0) with ID 1 */ SYNC /* End of frame */ ABS_MT_TRACKING_ID -1 /* Touch in last slot (0) ended */ SYNC /* End of frame */ Note that touch 1 has the same X and Y position as touch 0. This is implied because no new value was emitted. In fact, evdev will not emit an event with the same value as the previous event, even if the driver reports the event, so we can only assume that all the MT valuators have the same values as they were when they were last sent. This change adds a new valuator mask to hold all the last valuator values that came from evdev. When a new touch begins, all the last values are copied into it. Signed-off-by: Chase Douglas <[email protected]> --- src/evdev.c | 14 +++++++++----- src/evdev.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 82cdb00..0878716 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -760,13 +760,15 @@ 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) { - if (ev->value >= 0) - pEvdev->slot_state = SLOTSTATE_OPEN; - else - pEvdev->slot_state = SLOTSTATE_CLOSE; + if (ev->value >= 0) { + pEvdev->slot_state = SLOTSTATE_OPEN; + valuator_mask_copy(pEvdev->mt_mask, pEvdev->last_mt_vals); + } else + pEvdev->slot_state = SLOTSTATE_CLOSE; } else { map = pEvdev->axis_map[ev->code]; valuator_mask_set(pEvdev->mt_mask, map, ev->value); + valuator_mask_set(pEvdev->last_mt_vals, map, ev->value); } } } @@ -1250,7 +1252,8 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device) #ifdef MULTITOUCH if (num_mt_axes_total > 0) { pEvdev->mt_mask = valuator_mask_new(num_mt_axes_total); - if (!pEvdev->mt_mask) { + pEvdev->last_mt_vals = valuator_mask_new(num_mt_axes_total); + if (!pEvdev->mt_mask || !pEvdev->last_mt_vals) { xf86Msg(X_ERROR, "%s: failed to allocate MT valuator mask.\n", device->name); goto out; @@ -1428,6 +1431,7 @@ out: valuator_mask_free(&pEvdev->prox); #ifdef MULTITOUCH valuator_mask_free(&pEvdev->mt_mask); + valuator_mask_free(&pEvdev->last_mt_vals); for (i = 0; i < EVDEV_MAXQUEUE; i++) valuator_mask_free(&pEvdev->queue[i].touchMask); #endif diff --git a/src/evdev.h b/src/evdev.h index 1713b89..76043f9 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -158,6 +158,7 @@ typedef struct { ValuatorMask *old_vals; /* old values for calculating relative motion */ ValuatorMask *prox; /* last values set while not in proximity */ ValuatorMask *mt_mask; + ValuatorMask *last_mt_vals; int cur_slot; enum SlotState slot_state; #ifdef MULTITOUCH -- 1.7.7.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
