summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/evdev.man7
-rw-r--r--src/evdev.c53
2 files changed, 49 insertions, 11 deletions
diff --git a/man/evdev.man b/man/evdev.man
index e322eb6..9dd7a77 100644
--- a/man/evdev.man
+++ b/man/evdev.man
@@ -138,13 +138,18 @@ Invert the given axis. Default: off. Property: "Evdev Axis Inversion".
.BI "Option \*qIgnoreRelativeAxes\*q \*q" Bool \*q
.TP 7
.BI "Option \*qIgnoreAbsoluteAxes\*q \*q" Bool \*q
-Ignore the specified type of axis. Default: off. The X server cannot deal
+Ignore the specified type of axis. Default: unset. The X server cannot deal
with devices that have both relative and absolute axes. Evdev tries to guess
wich axes to ignore given the device type and disables absolute axes for
mice and relative axes for tablets, touchscreens and touchpad. These options
allow to forcibly disable an axis type. Mouse wheel axes are exempt and will
work even if relative axes are ignored. No property, this configuration must
be set in the configuration.
+.br
+If either option is set to False, the driver will not ignore the specified
+axes regardless of the presence of other axes. This may trigger buggy
+behavior and events from this axis are always forwarded. Users are
+discouraged from setting this option.
.TP 7
.BI "Option \*qReopenAttempts\*q \*q" integer \*q
Number of reopen attempts after a read error occurs on the device (e.g. after
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));