[PATCH 3/3] dix: support the transformation matrix for relative devices.

Peter Hutterer peter.hutterer at who-t.net
Mon May 30 20:57:47 PDT 2011


The transformation matrix we previously stored was a scaled matrix based on
the axis ranges of the device. For relative movements, the scaling is not
required (or desired).

Store two separate matrices, one scaled, one unmodified. Depending on the
type of movement, apply the respective matrix.

This breaks the DeviceIntRec ABI

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 dix/devices.c      |    4 ++--
 dix/getevents.c    |   26 +++++++++++++++++++++++++-
 include/inputstr.h |    5 ++++-
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/dix/devices.c b/dix/devices.c
index 0ccf252..4e4b702 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -125,14 +125,14 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform)
         for (x=0; x<3; x++)
             dev->transform.m[y][x] = *transform++;
 
-    pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
+    pixman_f_transform_multiply(&dev->scale, &scale, &dev->transform);
 
     /* scale */
     pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
     scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
     scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
 
-    pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
+    pixman_f_transform_multiply(&dev->scale, &dev->scale, &scale);
 }
 
 /**
diff --git a/dix/getevents.c b/dix/getevents.c
index 1352a81..26c7f5d 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1066,6 +1066,28 @@ transform(struct pixman_f_transform *m, int *x, int *y)
     *y = lround(p.v[1]);
 }
 
+
+static void
+transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
+{
+    int x, y;
+
+    x = valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) : 0;
+    y = valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) : 0;
+
+    transform(&dev->transform, &x, &y);
+
+    if (x)
+        valuator_mask_set(mask, 0, x);
+    else
+        valuator_mask_unset(mask, 0);
+
+    if (y)
+        valuator_mask_set(mask, 1, y);
+    else
+        valuator_mask_unset(mask, 1);
+}
+
 static void
 transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
 {
@@ -1076,7 +1098,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
     oy = y = valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) :
                                             dev->last.valuators[1];
 
-    transform(&dev->transform, &x, &y);
+    transform(&dev->scale, &x, &y);
 
     if (valuator_mask_isset(mask, 0) || ox != x)
         valuator_mask_set(mask, 0, x);
@@ -1200,6 +1222,8 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
         transformAbsolute(pDev, &mask);
         moveAbsolute(pDev, &x, &y, &mask);
     } else {
+        transformRelative(pDev, &mask);
+
         if (flags & POINTER_ACCELERATE) {
             accelPointer(pDev, &mask, ms);
             /* The pointer acceleration code modifies the fractional part
diff --git a/include/inputstr.h b/include/inputstr.h
index 00f72c2..b917f6c 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -530,8 +530,11 @@ typedef struct _DeviceIntRec {
         XIPropertyHandlerPtr handlers; /* NULL-terminated */
     } properties;
 
-    /* coordinate transformation matrix for absolute input devices */
+    /* coordinate transformation matrix */
     struct pixman_f_transform transform;
+    /* scale matrix for absolute devices, this is the combined matrix of
+       [1/scale] . [transform] . [scale]. See DeviceSetTransform */
+    struct pixman_f_transform scale;
 
     /* XTest related master device id */
     int xtest_master_id;
-- 
1.7.5.1



More information about the xorg-devel mailing list