The Xen Virtual Pointer device has ABS_X, ABS_Y and REL_WHEEL. If smooth
scrolling is detected, the current code would first initialize relative axes
for scrolling and immediately overwrite those axes when the abs valuators are
written out.

This patch fixes the default case only, in the case of a device setting the
two Ignore*Axis options both to "off", the axes are still overwritten. The
wheels will work, other axes only if the same number of abs axes exists. And
it keeps the current memory leak too, but it's marked with a FIXME now.

Signed-off-by: Peter Hutterer <[email protected]>
---
 src/evdev.c | 82 +++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 44 insertions(+), 38 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index 5a39d8b..045d780 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1221,7 +1221,7 @@ is_blacklisted_axis(int axis)
 
 
 static int
-EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes)
+EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes)
 {
     InputInfoPtr pInfo;
     EvdevPtr pEvdev;
@@ -1283,16 +1283,9 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int 
want_scroll_axes)
 
 #endif
 
+
 #ifdef HAVE_SMOOTH_SCROLLING
-    if (want_scroll_axes && libevdev_has_event_type(pEvdev->dev, EV_REL))
-    {
-        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
-            num_axes++;
-        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
-            num_axes++;
-        if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
-            num_axes++;
-    }
+    num_axes += num_scroll_axes;
 #endif
 
     if (num_axes + num_mt_axes > MAX_VALUATORS) {
@@ -1397,7 +1390,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int 
want_scroll_axes)
     }
 
 #ifdef HAVE_SMOOTH_SCROLLING
-    if (want_scroll_axes)
+    if (num_scroll_axes > 0)
     {
         mapping++; /* continue from abs axis mapping */
 
@@ -1507,7 +1500,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int 
want_scroll_axes)
 #endif
 
 #ifdef HAVE_SMOOTH_SCROLLING
-    if (want_scroll_axes)
+    if (num_scroll_axes)
     {
         int idx;
         if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
@@ -1642,7 +1635,7 @@ EvdevSetScrollValuators(DeviceIntPtr device)
 }
 
 static int
-EvdevAddRelValuatorClass(DeviceIntPtr device)
+EvdevAddRelValuatorClass(DeviceIntPtr device, int num_scroll_axes)
 {
     InputInfoPtr pInfo;
     EvdevPtr pEvdev;
@@ -1655,24 +1648,22 @@ EvdevAddRelValuatorClass(DeviceIntPtr device)
     if (!libevdev_has_event_type(pEvdev->dev, EV_REL))
         goto out;
 
-    for (i = 0; i < REL_MAX; i++)
+    for (i = 0; i < REL_MAX; i++) {
+        if (i == REL_WHEEL || i == REL_HWHEEL || i == REL_DIAL)
+            continue;
+
         if (libevdev_has_event_code(pEvdev->dev, EV_REL, i))
             num_axes++;
-    if (num_axes < 1)
-        goto out;
+    }
 
-#ifndef HAVE_SMOOTH_SCROLLING
-    /* Wheels are special, we post them as button events. So let's ignore them
-     * in the axes list too */
-    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
-        num_axes--;
-    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
-        num_axes--;
-    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
-        num_axes--;
+    /* If we have only relative scroll axes, then we punt axis init to
+       EvdevInitAbsValuators if possible */
+    if (num_axes < 1 &&
+        (num_scroll_axes == 0 || pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
+            goto out;
 
-    if (num_axes <= 0)
-        goto out;
+#ifdef HAVE_SMOOTH_SCROLLING
+    num_axes += num_scroll_axes;
 #endif
 
     if (num_axes > MAX_VALUATORS) {
@@ -1811,20 +1802,36 @@ EvdevInitButtonMapping(InputInfoPtr pInfo)
 
 }
 
+static int
+EvdevCountScrollAxes(EvdevPtr pEvdev)
+{
+    int num_scroll_axes = 0;
+
+#ifdef HAVE_SMOOTH_SCROLLING
+    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL))
+        num_scroll_axes++;
+    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL))
+        num_scroll_axes++;
+    if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL))
+        num_scroll_axes++;
+#endif
+
+    return num_scroll_axes;
+}
+
 static void
 EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev)
 {
     InputInfoPtr pInfo = device->public.devicePrivate;
-    int rel_success = FALSE;
+    int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
 
     if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
-        EvdevAddRelValuatorClass(device) == Success)
-    {
-        rel_success = TRUE;
+        EvdevAddRelValuatorClass(device, num_scroll_axes) == Success)
         xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n");
-    }
+    /* FIXME: EvdevAddAbsValuatorClass overwrites the valuators initialized
+       in EvdevAddRelValuatorClass and leaks the latter's memory */
     if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
-        EvdevAddAbsValuatorClass(device, !rel_success) == Success)
+        EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success)
         xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n");
 }
 
@@ -1832,8 +1839,9 @@ static void
 EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev)
 {
     InputInfoPtr pInfo = device->public.devicePrivate;
+    int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
 
-    if (EvdevAddAbsValuatorClass(device, TRUE) == Success) {
+    if (EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success) {
         xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n");
     } else {
         xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute 
axes.\n");
@@ -1846,8 +1854,9 @@ EvdevInitRelValuators(DeviceIntPtr device, EvdevPtr 
pEvdev)
 {
     InputInfoPtr pInfo = device->public.devicePrivate;
     int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS;
+    int num_scroll_axes = EvdevCountScrollAxes(pEvdev);
 
-    if (EvdevAddRelValuatorClass(device) == Success) {
+    if (EvdevAddRelValuatorClass(device, num_scroll_axes) == Success) {
 
         xf86IDrvMsg(pInfo, X_INFO,"initialized for relative axes.\n");
 
@@ -2274,9 +2283,6 @@ EvdevProbe(InputInfoPtr pInfo)
 #endif
                 EvdevForceXY(pInfo, Absolute);
         }
-
-
-
     }
 
     for (i = 0; i < BTN_MISC; i++) {
-- 
1.9.3

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to