[PATCH evdev] Only use mtdev for multitouch devices

Peter Hutterer peter.hutterer at who-t.net
Tue Jul 24 20:52:16 PDT 2012


mtdev uses a chunk of memory per device (~41kB), mainly for for its
internal event buffers. The average box these days can easily have 10
devices, but only few of those are multitouch. So check if we have
ABS_MT_POSITION axes and only create an mtdev instance if we do.

If a device has multitouch axes but not x/y, we will ignore events from this
device now.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev.c |   81 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 71 insertions(+), 10 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index f33b201..ee98a4a 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -774,6 +774,9 @@ EvdevProcessTouchEvent(InputInfoPtr pInfo, struct input_event *ev)
     EvdevPtr pEvdev = pInfo->private;
     int map;
 
+    if (!pEvdev->mtdev)
+        return;
+
     if (ev->code == ABS_MT_SLOT) {
         EvdevProcessTouch(pInfo);
         pEvdev->cur_slot = ev->value;
@@ -1385,7 +1388,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device)
     }
 
 #ifdef MULTITOUCH
-    if (num_mt_axes_total > 0)
+    if (pEvdev->mtdev && num_mt_axes_total > 0)
     {
         int num_touches = 0;
         int mode = pEvdev->flags & EVDEV_TOUCHPAD ?
@@ -2326,6 +2329,68 @@ EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4])
     }
 }
 
+#ifdef MULTITOUCH
+/**
+ * Open an mtdev device for this device. mtdev is a bit too generous with
+ * memory usage, so only do so for devices with multitouch bits set.
+ *
+ * @return FALSE on error, TRUE if mtdev was initiated or the device doesn't
+ * need it
+ */
+static Bool
+EvdevOpenMTDev(InputInfoPtr pInfo)
+{
+    EvdevPtr pEvdev = pInfo->private;
+    unsigned long bitmask[NLONGS(EV_CNT)]      = {0};
+    unsigned long abs_bitmask[NLONGS(ABS_CNT)] = {0};
+    int len;
+
+    if (pEvdev->mtdev) {
+        pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
+        return TRUE;
+    }
+
+    if (pInfo->fd < 0) {
+        xf86Msg(X_ERROR, "%s: Bug. fd < 0\n", pInfo->name);
+        return FALSE;
+    }
+
+    /* Use ioctl here, this may be called before EvdevCache */
+    len = ioctl(pInfo->fd, EVIOCGBIT(0, sizeof(bitmask)), bitmask);
+    if (len < 0) {
+        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
+                    strerror(errno));
+        return FALSE;
+    }
+
+    if (!EvdevBitIsSet(bitmask, EV_ABS))
+        return TRUE;
+
+    len = ioctl(pInfo->fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
+    if (len < 0) {
+        xf86IDrvMsg(pInfo, X_ERROR, "ioctl EVIOCGBIT failed: %s\n",
+                    strerror(errno));
+        return FALSE;
+    }
+
+    if (!EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_X) ||
+        !EvdevBitIsSet(abs_bitmask, ABS_MT_POSITION_Y))
+        return TRUE;
+
+    xf86IDrvMsg(pInfo, X_INFO, "Using mtdev for this device\n");
+    pEvdev->mtdev = mtdev_new_open(pInfo->fd);
+    if (pEvdev->mtdev)
+        pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
+    else {
+        xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
+        EvdevCloseDevice(pInfo);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+#endif
+
 static int
 EvdevOpenDevice(InputInfoPtr pInfo)
 {
@@ -2366,18 +2431,14 @@ EvdevOpenDevice(InputInfoPtr pInfo)
     }
 
 #ifdef MULTITOUCH
-    if (!pEvdev->mtdev) { /* after PreInit mtdev is still valid */
-        pEvdev->mtdev = mtdev_new_open(pInfo->fd);
-        if (!pEvdev->mtdev) {
-            xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
-            EvdevCloseDevice(pInfo);
-            return FALSE;
-        }
+    if (!EvdevOpenMTDev(pInfo)) {
+        xf86Msg(X_ERROR, "%s: Couldn't open mtdev device\n", pInfo->name);
+        EvdevCloseDevice(pInfo);
+        return FALSE;
     }
-    if (pEvdev->mtdev)
-        pEvdev->cur_slot = pEvdev->mtdev->caps.slot.value;
 #endif
 
+
     return Success;
 }
 
-- 
1.7.10.4



More information about the xorg-devel mailing list