[PATCH evdev] Fix absolute events with swapped axes

przanoni at gmail.com przanoni at gmail.com
Wed Dec 14 09:23:36 PST 2011


From: Paulo Zanoni <paulo.r.zanoni at intel.com>

We were correctly swapping the valuator values, but we were not
calling valuator_mask_unset() when needed, so the cursor kept jumping
to the edges.

This patch does the swapping before the main "for", so we don't need to
store unswapped_{x,y} and unswapped_isset_{x,y} even when we don't need
to swap.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
---
 src/evdev.c |   31 ++++++++++++++++++++++---------
 1 files changed, 22 insertions(+), 9 deletions(-)

Another solution to the problem would involve keeping the unswapped_x
and unswapped_y variables, and also adding unswapped_isset_{x,y}, but I
believe this one looks better because it just computes these values if
swap_axes is actually set.

How I tested:
 - disabled synaptics
 - configured my touchpad to report absolute events with evdev
   - Option "Mode" "Absolute"
 - xinput --set-prop "SynPS/2 Synaptics TouchPad" "Evdev Axes Swap" 1

If you move your finger across the touchpad when the axes are inverted
the cursor keeps jumping to the edges (because we set the valuators to 0
when what we really wanted was to call valuator_mask_unset). After the
patch, the cursor acts as we expect. Also, the edges of the touchpad
match the edges of the screen (the values are scaled correctly).

diff --git a/src/evdev.c b/src/evdev.c
index 428d3c1..b1f9b2e 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -436,10 +436,30 @@ EvdevProcessValuators(InputInfoPtr pInfo)
      * just works.
      */
     else if (pEvdev->abs_queued && pEvdev->in_proximity) {
-        int unswapped_x = valuator_mask_get(pEvdev->vals, 0);
-        int unswapped_y = valuator_mask_get(pEvdev->vals, 1);
         int i;
 
+        if (pEvdev->swap_axes) {
+            int swapped_isset[2] = {0, 0};
+            int swapped_values[2];
+
+            for(i = 0; i <= 1; i++)
+                if (valuator_mask_isset(pEvdev->vals, i)) {
+                    swapped_isset[1 - i] = 1;
+                    swapped_values[1 - i] =
+                        xf86ScaleAxis(valuator_mask_get(pEvdev->vals, i),
+                                      pEvdev->absinfo[1 - i].maximum,
+                                      pEvdev->absinfo[1 - i].minimum,
+                                      pEvdev->absinfo[i].maximum,
+                                      pEvdev->absinfo[i].minimum);
+                }
+
+            for (i = 0; i <= 1; i++)
+                if (swapped_isset[i])
+                    valuator_mask_set(pEvdev->vals, i, swapped_values[i]);
+                else
+                    valuator_mask_unset(pEvdev->vals, i);
+        }
+
         for (i = 0; i <= 1; i++) {
             int val;
             int calib_min;
@@ -458,13 +478,6 @@ EvdevProcessValuators(InputInfoPtr pInfo)
                 calib_max = pEvdev->calibration.max_y;
             }
 
-            if (pEvdev->swap_axes)
-                val = xf86ScaleAxis((i == 0 ? unswapped_y : unswapped_x),
-                                    pEvdev->absinfo[i].maximum,
-                                    pEvdev->absinfo[i].minimum,
-                                    pEvdev->absinfo[1 - i].maximum,
-                                    pEvdev->absinfo[1 - i].minimum);
-
             if (pEvdev->flags & EVDEV_CALIBRATED)
                 val = xf86ScaleAxis(val, pEvdev->absinfo[i].maximum,
                                     pEvdev->absinfo[i].minimum, calib_max,
-- 
1.7.7.3



More information about the xorg-devel mailing list