xorg-x11-server/0005-dix-fix-device-scaling-to-use-a-min-max-range.patch

87 lines
3.7 KiB
Diff
Raw Normal View History

From 31e066546fd085725cc29e95867a04c70ce46ebc Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Fri, 26 Apr 2013 15:10:08 +1000
Subject: [PATCH 05/35] 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@who-t.net>
(cherry picked from commit 756ab88d93542f0589c9bf46f40ccc57df64f0fd)
---
dix/devices.c | 4 ++--
dix/getevents.c | 14 ++++++++++----
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/dix/devices.c b/dix/devices.c
index b2db4aa..a0d545a 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.
*/
--
1.8.2.1