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.
0a3657d2ee 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>
This commit is contained in:
Peter Hutterer
2009-10-15 11:13:47 +10:00
parent fbd86e2530
commit 1d86f5dec1
2 changed files with 49 additions and 11 deletions

View File

@@ -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

View File

@@ -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
@@ -1422,6 +1424,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)
{
@@ -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));