[PATCH xf86-input-evdev] Copy last valuator values into new touch valuator masks

Chase Douglas chase.douglas at canonical.com
Tue Jan 3 17:52:13 PST 2012


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 <chase.douglas at canonical.com>
---
 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



More information about the xorg-devel mailing list