summaryrefslogtreecommitdiff
path: root/dix
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2010-02-26 14:02:09 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2010-03-10 09:30:19 +1000
commit9f462ff9082634719e64d2d8d4dbd09ec7deaf2e (patch)
tree81d4de20311ed08e6f1dda1e68f0b137449768e1 /dix
parentbbae92795c7eab062e6722c42fa7915e0cee5d69 (diff)
dix: Clip only into axis ranges if we're in absolute mode. (#26543)
An absolute device in relative mode may provide valuators outside of the axis range. Clipping back into the range prevents screen crossings in a multi-screen (Xinerama) setup as the required screen edge for crossing is never met: miPointerSetPosition crosses the screen conditional to the X coordinate being equal to the screen width or _less than_ 0. While the former can be met when clipping into the coordinate range and scaling, the latter cannot, resulting in a mouse pointer that gets stuck on the rightmost screen. This patch only applies axis clipping for valuators in mode Absolute. If relative, we allow the values to get above/below the axis ranges. Doesn't matter, miPointerSetPosition will reset the values to the allowed range even if no screen was crossed. This leads to interesting values provided to clients, the valuator range of the device resets once a screen is crossed and essentially reflects the position of the cursor on the screen - scaled into the valuator range. The values themselves are valid given the range though. In theory, the XI1 specs require that a relative device has a min/max range of 0/0. This doesn't really go well with devices that actually can switch mode between relative and absolute since they would have to reset their axis range when switching. If multiple XI clients are in use, we have no method of notifying them about the changes, so other clients may continue to use the wrong axis ranges (note: XI1 wasn't really designed to have multiple clients use a device). Expecting all relative devices to have this min/max of 0 is unrealistic at this point. So pick what is possibly the lesser of all evils, pass the beer and despair. X.Org Bug 26543 <http://bugs.freedesktop.org/show_bug.cgi?id=26543> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Daniel Stone <daniel@fooishbar.org>
Diffstat (limited to 'dix')
-rw-r--r--dix/getevents.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/dix/getevents.c b/dix/getevents.c
index 82bb77b4b..197deb4fb 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -710,7 +710,7 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
/* if attached, clip both x and y to the defined limits (usually
* co-ord space limit). If it is attached, we need x/y to go over the
* limits to be able to change screens. */
- if(dev->u.master) {
+ if(dev->u.master && dev->valuator->mode == Absolute) {
clipAxis(dev, 0, x);
clipAxis(dev, 1, y);
}
@@ -720,7 +720,8 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
for (; i < num; i++)
{
dev->last.valuators[i + first] += valuators[i];
- clipAxis(dev, i, &dev->last.valuators[i + first]);
+ if (dev->valuator->mode == Absolute)
+ clipAxis(dev, i, &dev->last.valuators[i + first]);
valuators[i] = dev->last.valuators[i + first];
}
}