[PATCH 3/4] Implement MT Slots protocol support

Chase Douglas chase.douglas at canonical.com
Wed Jun 23 07:04:39 PDT 2010


From: Benjamin Tissoires <tissoire at cena.fr>

The MT Slots protocol sends only the ABS_MT_* values that have changed
from a previous set of events. We use the ABS_MT_SLOT value as an index
into an array of MT valuators.
(see kernel_src/Documentation/input/multi-touch-protocol.txt)

The "Abs Tracking ID" value can be used to figure out if a touch is down
or not. If it is != -1, then the touch is down. Otherwise, the touch is
up and the other values in the "slot" of valuators are invalid.

Signed-off-by: Benjamin Tissoires <tissoire at cena.fr>
Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
---
 src/evdev.c |   34 ++++++++++++++++++++++++++++++++--
 src/evdev.h |    1 +
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index 68d8946..777eebe 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -527,6 +527,12 @@ EvdevProcessRelativeMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
     }
 }
 
+static inline BOOL
+EvdevIsMTEvent(struct input_event *ev)
+{
+    return ev->code >= EVDEV_FIRST_MT_AXIS && ev->code <= EVDEV_LAST_MT_AXIS;
+}
+
 /**
  * Take the absolute motion input event and process it accordingly.
  */
@@ -549,7 +555,18 @@ EvdevProcessAbsoluteMotionEvent(InputInfoPtr pInfo, struct input_event *ev)
     if (EvdevWheelEmuFilterMotion(pInfo, ev))
         return;
 
-    pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
+    if (!EvdevIsMTEvent(ev) && ev->code != ABS_MT_SLOT)
+        pEvdev->vals[pEvdev->axis_map[ev->code]] = value;
+    else if (ev->code == ABS_MT_SLOT) {
+        pEvdev->mt_current_touchpoint = value;
+        return;
+    }
+    else if (pEvdev->mt_current_touchpoint < pEvdev->mt_max_touchpoints) {
+        pEvdev->vals[pEvdev->axis_map[ev->code] +
+            pEvdev->mt_current_touchpoint * pEvdev->mt_num_valuators] = value;
+    } else
+        return; /* mt-event, but not enough place to store it */
+
     if (ev->code == ABS_X)
         pEvdev->abs |= ABS_X_VALUE;
     else if (ev->code == ABS_Y)
@@ -1309,6 +1326,14 @@ EvdevMTInitValuators(DeviceIntPtr device, Atom *atoms)
             pEvdev->old_vals[real_axnum] = -1;
         }
     }
+
+    /* TRACKING_ID != -1 means touch is down */
+    for (j = 0; j < pEvdev->mt_max_touchpoints; j++) {
+        int axnum = pEvdev->axis_map[ABS_MT_TRACKING_ID];
+        int real_axnum = axnum + j * pEvdev->mt_num_valuators;
+
+        pEvdev->vals[real_axnum] = -1;
+    }
 }
 
 static int
@@ -1329,6 +1354,10 @@ EvdevAddAbsClass(DeviceIntPtr device)
     if (num_axes < 1)
         return !Success;
 
+    /* We use slots internally to arrange touches into valuators */
+    if (TestBit(ABS_MT_SLOT, pEvdev->abs_bitmask))
+        num_axes--;
+
     num_axes = EvdevMTAddExtraValuators(pEvdev, num_axes);
 
     pEvdev->num_vals = num_axes;
@@ -1338,7 +1367,8 @@ EvdevAddAbsClass(DeviceIntPtr device)
 
     for (axis = ABS_X; axis <= ABS_MAX; axis++) {
         pEvdev->axis_map[axis] = -1;
-        if (!TestBit(axis, pEvdev->abs_bitmask))
+        /* We use slots internally to arrange touches into valuators */
+        if (!TestBit(axis, pEvdev->abs_bitmask) || axis == ABS_MT_SLOT)
             continue;
         pEvdev->axis_map[axis] = i;
         i++;
diff --git a/src/evdev.h b/src/evdev.h
index 7f9fc47..25c63a7 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -197,6 +197,7 @@ typedef struct {
     unsigned int mt_num_valuators;
     unsigned int mt_max_touchpoints; /* the number of simultaneous touchpoints
                                       * the device can support */
+    unsigned int mt_current_touchpoint;
 } EvdevRec, *EvdevPtr;
 
 /* Event posting functions */
-- 
1.7.0.4



More information about the xorg-devel mailing list