xserver: Branch 'master' - 4 commits

Keith Packard keithp at kemper.freedesktop.org
Thu May 23 09:42:58 PDT 2013


 dix/devices.c   |    5 ++--
 dix/getevents.c |   60 +++++++++++++++++++++++++++++++++++---------------------
 2 files changed, 41 insertions(+), 24 deletions(-)

New commits:
commit 7205888f9691403836e8c337e7095d91e5f63189
Merge: 2ccb9fb 6589f3b
Author: Keith Packard <keithp at keithp.com>
Date:   Thu May 23 10:41:54 2013 -0600

    Merge remote-tracking branch 'whot/unreviewed'

commit 6589f3b55e335eef6c658c8ba1fe15a062f7e31c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 14 08:31:19 2013 +1000

    dix: devices must have valuators before touch is initialized
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index 291b767..527eea0 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1647,6 +1647,7 @@ InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
 
     BUG_RETURN_VAL(device == NULL, FALSE);
     BUG_RETURN_VAL(device->touch != NULL, FALSE);
+    BUG_RETURN_VAL(device->valuator == NULL, FALSE);
 
     /* Check the mode is valid, and at least X and Y axes. */
     BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE);
commit 756ab88d93542f0589c9bf46f40ccc57df64f0fd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 26 15:10:08 2013 +1000

    dix: fix device scaling to use a [min,max[ range.
    
    defmin/defmax are screen coords and thus use a min-inclusive, max-exclusive
    range. device axes ranges are inclusive, so bump the max up by one to get the
    scaling right.
    
    This fixes off-by-one coordinate errors if the coordinate matrix is used to
    bind the device to a fraction of the screen. It introduces an off-by-one
    scaling error in the device coordinate range, but since most devices have a
    higher resolution than the screen (e.g. a Wacom I4 has 5080 dpi) the effect
    of this should be limited.
    
    This error manifests when we have numScreens > 1, as the scaling from
    desktop size back to screen size drops one device unit.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index 9b6faee..291b767 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -112,8 +112,8 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
      *  Transform is the user supplied (affine) transform
      *  InvScale scales coordinates back up into their native range
      */
-    sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
-    sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
+    sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1;
+    sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1;
 
     /* invscale */
     pixman_f_transform_init_scale(&scale, sx, sy);
diff --git a/dix/getevents.c b/dix/getevents.c
index ac0ccb2..51d4fd4 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -298,11 +298,11 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
 
     if (from && from->min_value < from->max_value) {
         fmin = from->min_value;
-        fmax = from->max_value;
+        fmax = from->max_value + 1;
     }
     if (to && to->min_value < to->max_value) {
         tmin = to->min_value;
-        tmax = to->max_value;
+        tmax = to->max_value + 1;
     }
 
     if (fmin == tmin && fmax == tmax)
@@ -924,9 +924,9 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
 
     /* scale x&y to desktop coordinates */
     *screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
-                                   screenInfo.x, screenInfo.width - 1);
+                                   screenInfo.x, screenInfo.width);
     *screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
-                                   screenInfo.y, screenInfo.height - 1);
+                                   screenInfo.y, screenInfo.height);
 
     *devx = x;
     *devy = y;
@@ -1366,6 +1366,12 @@ QueuePointerEvents(DeviceIntPtr device, int type,
  * is the last coordinate on the first screen and must be rescaled for the
  * event to be m. XI2 clients that do their own coordinate mapping would
  * otherwise interpret the position of the device elsewere to the cursor.
+ * However, this scaling leads to losses:
+ * if we have two ScreenRecs we scale from e.g. [0..44704]  (Wacom I4) to
+ * [0..2048[. that gives us 2047.954 as desktop coord, or the per-screen
+ * coordinate 1023.954. Scaling that back into the device coordinate range
+ * gives us 44703. So off by one device unit. It's a bug, but we'll have to
+ * live with it because with all this scaling, we just cannot win.
  *
  * @return the number of events written into events.
  */
commit 5cc2c96f824dbb28b9f8da61efc41596f8bd0561
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Mar 9 20:43:51 2013 +1000

    dix: pre-scale x by the screen:device:resolution ratio
    
    commit 61a99aff9d33728a0b67920254d2d4d79f80cf39
        dix: pre-scale relative events from abs devices to desktop ratio (#31636)
    
    added pre-scaling of relative coordinates coming from absolute devices to
    undo uneven scaling based on the screen dimensions.
    
    Devices have their own device width/height ratio as well (in a specific
    resolution) and this must be applied for relative devices as well to avoid
    scaling of the relative events into the device's ratio.
    
    e.g. a Wacom Intuos4 6x9 is in 16:10 format with equal horiz/vert
    resolution (dpi). A movement by 1000/1000 coordinates is a perfect diagonal
    on the tablet and must be reflected as such on the screen.
    
    However, we map the relative device-coordinate events to absolute screen
    coordinates based on the axis ranges. This results in an effective scaling
    of 1000/(1000 * 1.6) and thus an uneven x/y axis movement - the y
    axis is always faster.
    
    So we need to pre-scale not only by the desktop dimenstions but also by the
    device width/height ratio _and_ the resolution ratio.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 241c7ec..ac0ccb2 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -770,6 +770,29 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
 }
 
 
+static void
+scale_for_device_resolution(DeviceIntPtr dev, ValuatorMask *mask)
+{
+    double x;
+    ValuatorClassPtr v = dev->valuator;
+    int xrange = v->axes[0].max_value - v->axes[0].min_value + 1;
+    int yrange = v->axes[1].max_value - v->axes[1].min_value + 1;
+
+    double screen_ratio = 1.0 * screenInfo.width/screenInfo.height;
+    double device_ratio = 1.0 * xrange/yrange;
+    double resolution_ratio = 1.0;
+    double ratio;
+
+    if (!valuator_mask_fetch_double(mask, 0, &x))
+        return;
+
+    if (v->axes[0].resolution != 0 && v->axes[1].resolution != 0)
+        resolution_ratio = 1.0 * v->axes[0].resolution/v->axes[1].resolution;
+
+    ratio = device_ratio/resolution_ratio/screen_ratio;
+    valuator_mask_set_double(mask, 0, x * ratio);
+}
+
 /**
  * Move the device's pointer by the values given in @valuators.
  *
@@ -781,27 +804,14 @@ moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
 {
     int i;
     Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
+    ValuatorClassPtr v = dev->valuator;
 
     /* for abs devices in relative mode, we've just scaled wrong, since we
        mapped the device's shape into the screen shape. Undo this. */
-    if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
-        dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
-
-        double ratio = 1.0 * screenInfo.width/screenInfo.height;
-
-        if (ratio > 1.0) {
-            double y;
-            if (valuator_mask_fetch_double(mask, 1, &y)) {
-                y *= ratio;
-                valuator_mask_set_double(mask, 1, y);
-            }
-        } else {
-            double x;
-            if (valuator_mask_fetch_double(mask, 0, &x)) {
-                x *= ratio;
-                valuator_mask_set_double(mask, 0, x);
-            }
-        }
+    if ((flags & POINTER_ABSOLUTE) == 0 && v && v->numAxes > 1 &&
+        v->axes[0].min_value < v->axes[0].max_value &&
+        v->axes[1].min_value < v->axes[1].max_value) {
+        scale_for_device_resolution(dev, mask);
     }
 
     /* calc other axes, clip, drop back into valuators */


More information about the xorg-commit mailing list