[PATCH evdev 3/5] Add the new valuators for multitouch

Benjamin Tissoires tissoire at cena.fr
Sun Mar 28 04:58:11 PDT 2010


The step one in implementing multitouch in evdev is to report all the
touches in different valuators.
This patch just creates the extra valuators required for multitouch.

Note that I currently assume that all definitions above ABS_MT_TOUCH_MAJOR
and below ABS_MAX are MT-related.

Signed-off-by: Benjamin Tissoires <tissoire at cena.fr>
---
 src/evdev.c |   51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/evdev.h |    5 +++++
 2 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index b84af7f..7e59601 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1156,7 +1156,7 @@ EvdevAddAbsClass(DeviceIntPtr device)
 {
     InputInfoPtr pInfo;
     EvdevPtr pEvdev;
-    int num_axes, axis, i = 0;
+    int num_axes, axis, mt_first_valuator, i = 0, j = 0;
     Atom *atoms;
     const char *mode;
 
@@ -1167,8 +1167,35 @@ EvdevAddAbsClass(DeviceIntPtr device)
             return !Success;
 
     num_axes = CountBits(pEvdev->abs_bitmask, NLONGS(ABS_MAX));
+    pEvdev->mt_num_valuators = 0;
     if (num_axes < 1)
         return !Success;
+
+    if (pEvdev->flags & EVDEV_MULTITOUCH) {
+        /* in case of multitouch devices, we force the axis Tracking ID if not reported by the kernel */
+        if (!TestBit(ABS_MT_TRACKING_ID, pEvdev->abs_bitmask)) {
+            num_axes++;
+            pEvdev->mt_num_valuators++;
+        }
+
+        /* count the number of valuators mt-related.
+         * assume that mt values are in the range
+         * ABS_MT_TOUCH_MAJOR..ABS_MAX */
+        mt_first_valuator = 0;
+        for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
+            if (!TestBit(axis, pEvdev->abs_bitmask))
+                continue;
+            if (!mt_first_valuator)
+                mt_first_valuator = axis;
+            pEvdev->mt_num_valuators++;
+        }
+
+        /* now add the extra axes to the count of reported axes
+         * the -1 is due to the already registered collection of
+         * multitouch events */
+        num_axes += (EVDEV_MAX_TOUCHPOINTS - 1) * pEvdev->mt_num_valuators;
+    }
+
     pEvdev->num_vals = num_axes;
     memset(pEvdev->vals, 0, num_axes * sizeof(int));
     memset(pEvdev->old_vals, -1, num_axes * sizeof(int));
@@ -1182,6 +1209,9 @@ EvdevAddAbsClass(DeviceIntPtr device)
         i++;
     }
 
+    if (pEvdev->flags & EVDEV_MULTITOUCH)
+        pEvdev->mt_first_axis = pEvdev->axis_map[mt_first_valuator];
+
     EvdevInitAxesLabels(pEvdev, pEvdev->num_vals, atoms);
 
     if (!InitValuatorClassDeviceStruct(device, num_axes,
@@ -1209,6 +1239,25 @@ EvdevAddAbsClass(DeviceIntPtr device)
         pEvdev->old_vals[axnum] = -1;
     }
 
+    /* initialize the extra mt-axes */
+    for (j = 1; j < EVDEV_MAX_TOUCHPOINTS; j++) {
+        for (axis = ABS_MT_TOUCH_MAJOR; axis <= ABS_MAX; axis++) {
+            int axnum = pEvdev->axis_map[axis];
+            int real_axnum = axnum + j * pEvdev->mt_num_valuators;
+            if (axnum == -1)
+                continue;
+            xf86InitValuatorAxisStruct(device, real_axnum,
+    #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7
+                                       atoms[axnum],
+    #endif
+                                       pEvdev->absinfo[axis].minimum,
+                                       pEvdev->absinfo[axis].maximum,
+                                       10000, 0, 10000);
+            xf86InitValuatorDefaults(device, real_axnum);
+            pEvdev->old_vals[real_axnum] = -1;
+        }
+    }
+
     xfree(atoms);
 
     if (!InitPtrFeedbackClassDeviceStruct(device, EvdevPtrCtrlProc))
diff --git a/src/evdev.h b/src/evdev.h
index 0e115f3..383a904 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -80,6 +80,8 @@
 #define MAX_VALUATORS 36
 #endif
 
+/* the number of simultaneous touchpoints the driver can support */
+#define EVDEV_MAX_TOUCHPOINTS 5 /* currently as MAX_VALUATORS == 36 */
 
 #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) < 5
 typedef struct {
@@ -193,6 +195,9 @@ typedef struct {
     /* Event queue used to defer keyboard/button events until EV_SYN time. */
     int                     num_queue;
     EventQueueRec           queue[EVDEV_MAXQUEUE];
+
+    unsigned int mt_first_axis;
+    unsigned int mt_num_valuators;
 } EvdevRec, *EvdevPtr;
 
 /* Event posting functions */
-- 
1.6.6.1



More information about the xorg-devel mailing list