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>
This commit is contained in:
parent
5cc2c96f82
commit
756ab88d93
|
@ -112,8 +112,8 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
|
||||||
* Transform is the user supplied (affine) transform
|
* Transform is the user supplied (affine) transform
|
||||||
* InvScale scales coordinates back up into their native range
|
* InvScale scales coordinates back up into their native range
|
||||||
*/
|
*/
|
||||||
sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].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;
|
sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1;
|
||||||
|
|
||||||
/* invscale */
|
/* invscale */
|
||||||
pixman_f_transform_init_scale(&scale, sx, sy);
|
pixman_f_transform_init_scale(&scale, sx, sy);
|
||||||
|
|
|
@ -298,11 +298,11 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
|
||||||
|
|
||||||
if (from && from->min_value < from->max_value) {
|
if (from && from->min_value < from->max_value) {
|
||||||
fmin = from->min_value;
|
fmin = from->min_value;
|
||||||
fmax = from->max_value;
|
fmax = from->max_value + 1;
|
||||||
}
|
}
|
||||||
if (to && to->min_value < to->max_value) {
|
if (to && to->min_value < to->max_value) {
|
||||||
tmin = to->min_value;
|
tmin = to->min_value;
|
||||||
tmax = to->max_value;
|
tmax = to->max_value + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fmin == tmin && fmax == tmax)
|
if (fmin == tmin && fmax == tmax)
|
||||||
|
@ -924,9 +924,9 @@ scale_to_desktop(DeviceIntPtr dev, ValuatorMask *mask,
|
||||||
|
|
||||||
/* scale x&y to desktop coordinates */
|
/* scale x&y to desktop coordinates */
|
||||||
*screenx = rescaleValuatorAxis(x, dev->valuator->axes + 0, NULL,
|
*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,
|
*screeny = rescaleValuatorAxis(y, dev->valuator->axes + 1, NULL,
|
||||||
screenInfo.y, screenInfo.height - 1);
|
screenInfo.y, screenInfo.height);
|
||||||
|
|
||||||
*devx = x;
|
*devx = x;
|
||||||
*devy = y;
|
*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
|
* 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
|
* event to be m. XI2 clients that do their own coordinate mapping would
|
||||||
* otherwise interpret the position of the device elsewere to the cursor.
|
* 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.
|
* @return the number of events written into events.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue