diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2013-04-26 15:10:08 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2013-05-23 15:35:05 +1000 |
commit | 756ab88d93542f0589c9bf46f40ccc57df64f0fd (patch) | |
tree | 0bb2f6bfee8550cbff495577b81cee32ac607bd9 | |
parent | 5cc2c96f824dbb28b9f8da61efc41596f8bd0561 (diff) |
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>
-rw-r--r-- | dix/devices.c | 4 | ||||
-rw-r--r-- | dix/getevents.c | 14 |
2 files changed, 12 insertions, 6 deletions
diff --git a/dix/devices.c b/dix/devices.c index 9b6faee23..291b76773 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 ac0ccb28f..51d4fd4da 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. */ |