summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-10-15 11:13:47 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-10-15 11:36:49 +1000
commit1d86f5dec16beaf9391f320d7702cc59e9486bf4 (patch)
tree3c08d7a6e09207b9cc30aac3d2fbf190b1451e5f /src
parentfbd86e2530f3f69f397d3bae9ad87cf8e2d14221 (diff)
Convert IgnoreAbsolute/RelativeAxes options into trinary state.
The Xen Virtual Pointer device exports both absolute and relative axes from the kernel device. Which coordinates are used is a run-time decision and depends on the host-specific configuration. 0a3657d2ee62f4086e9687218cb33835ba61a0b3 broke these devices, and they are now unusable out-of-the-box as there is no configuration to cover them. This patch converts the IgnoreAbsoluteAxes and the IgnoreRelativeAxes configuration options into a trinary state. 1. If unset, configure the device as normal by trying to guess the right axis setup. 2. If set to true, ignore the specific axis type completely (except for wheel events). 3. If set to false, explicitly 'unignore' the axis type, alwas configuring it if it is present on the device. This setting introduces seemingly buggy behaviour (see Bug 21832) 1. and 2. replicate the current driver behaviour. The result of 3. is that is that if a device has absolute axes and the options set to false, both axes will be initialized (absolute last to get clipping right). This requires axis labelling priorty to switch from relative first to absolute first. Relative events are forwarded into the server through the absolute axes, the server scales this into the device absolute range and everyone is happy. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src')
-rw-r--r--src/evdev.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/src/evdev.c b/src/evdev.c
index 62d1bc7..0dff271 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -90,6 +90,8 @@
#define EVDEV_TOUCHSCREEN (1 << 6)
#define EVDEV_CALIBRATED (1 << 7) /* run-time calibrated? */
#define EVDEV_TABLET (1 << 8) /* device looks like a tablet? */
+#define EVDEV_UNIGNORE_ABSOLUTE (1 << 9) /* explicitly unignore abs axes */
+#define EVDEV_UNIGNORE_RELATIVE (1 << 10) /* explicitly unignore rel axes */
#define MIN_KEYCODE 8
#define GLYPHS_PER_KEY 2
@@ -1423,6 +1425,17 @@ EvdevInitButtonMapping(InputInfoPtr pInfo)
}
static void
+EvdevInitAnyClass(DeviceIntPtr device, EvdevPtr pEvdev)
+{
+ if (pEvdev->flags & EVDEV_RELATIVE_EVENTS &&
+ EvdevAddRelClass(device) == Success)
+ xf86Msg(X_INFO, "%s: initialized for relative axes.\n", device->name);
+ if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS &&
+ EvdevAddAbsClass(device) == Success)
+ xf86Msg(X_INFO, "%s: initialized for absolute axes.\n", device->name);
+}
+
+static void
EvdevInitAbsClass(DeviceIntPtr device, EvdevPtr pEvdev)
{
if (EvdevAddAbsClass(device) == Success) {
@@ -1513,7 +1526,9 @@ EvdevInit(DeviceIntPtr device)
* used and relative axes are ignored.
*/
- if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
+ if (pEvdev->flags & (EVDEV_UNIGNORE_RELATIVE | EVDEV_UNIGNORE_ABSOLUTE))
+ EvdevInitAnyClass(device, pEvdev);
+ else if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN | EVDEV_TABLET))
EvdevInitTouchDevice(device, pEvdev);
else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
EvdevInitRelClass(device, pEvdev);
@@ -1777,7 +1792,7 @@ EvdevProbe(InputInfoPtr pInfo)
{
int i, has_rel_axes, has_abs_axes, has_keys, num_buttons, has_scroll;
int kernel24 = 0;
- int ignore_rel, ignore_abs;
+ int ignore_abs = 0, ignore_rel = 0;
EvdevPtr pEvdev = pInfo->private;
if (pEvdev->grabDevice && ioctl(pInfo->fd, EVIOCGRAB, (void *)1)) {
@@ -1793,8 +1808,26 @@ EvdevProbe(InputInfoPtr pInfo)
ioctl(pInfo->fd, EVIOCGRAB, (void *)0);
}
- ignore_rel = xf86SetBoolOption(pInfo->options, "IgnoreRelativeAxes", FALSE);
- ignore_abs = xf86SetBoolOption(pInfo->options, "IgnoreAbsoluteAxes", FALSE);
+ /* Trinary state for ignoring axes:
+ - unset: do the normal thing.
+ - TRUE: explicitly ignore them.
+ - FALSE: unignore axes, use them at all cost if they're present.
+ */
+ if (xf86FindOption(pInfo->options, "IgnoreRelativeAxes"))
+ {
+ if (xf86SetBoolOption(pInfo->options, "IgnoreRelativeAxes", FALSE))
+ ignore_rel = TRUE;
+ else
+ pEvdev->flags |= EVDEV_UNIGNORE_RELATIVE;
+
+ }
+ if (xf86FindOption(pInfo->options, "IgnoreAbsoluteAxes"))
+ {
+ if (xf86SetBoolOption(pInfo->options, "IgnoreAbsoluteAxes", FALSE))
+ ignore_abs = TRUE;
+ else
+ pEvdev->flags |= EVDEV_UNIGNORE_ABSOLUTE;
+ }
has_rel_axes = FALSE;
has_abs_axes = FALSE;
@@ -2352,16 +2385,16 @@ static void EvdevInitAxesLabels(EvdevPtr pEvdev, int natoms, Atom *atoms)
int labels_len = 0;
char *misc_label;
- if (pEvdev->flags & EVDEV_RELATIVE_EVENTS)
- {
- labels = rel_labels;
- labels_len = ArrayLength(rel_labels);
- misc_label = AXIS_LABEL_PROP_REL_MISC;
- } else if ((pEvdev->flags & EVDEV_ABSOLUTE_EVENTS))
+ if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)
{
labels = abs_labels;
labels_len = ArrayLength(abs_labels);
misc_label = AXIS_LABEL_PROP_ABS_MISC;
+ } else if ((pEvdev->flags & EVDEV_RELATIVE_EVENTS))
+ {
+ labels = rel_labels;
+ labels_len = ArrayLength(rel_labels);
+ misc_label = AXIS_LABEL_PROP_REL_MISC;
}
memset(atoms, 0, natoms * sizeof(Atom));