From 2fb3d14aa1b81daee98632f4b30c0006d90363be Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Tue, 4 Aug 2009 03:11:49 -0500 Subject: [PATCH] evdev.c: Fix/improve discrimination of rel/abs axes The relevant comment from evdev.c: We don't allow relative and absolute axes on the same device. The reason is that some devices (MS Optical Desktop 2000) register both rel and abs axes for x/y. The abs axes register min/max; this min/max then also applies to the relative device (the mouse) and caps it at 0..255 for both axes. So, unless you have a small screen, you won't be enjoying it much; consequently, absolute axes are generally ignored. However, currenly only a device with absolute axes can be registered as a touch{pad,screen}. Thus, given such a device, absolute axes are used and relative axes are ignored. Signed-off-by: Michael Witten --- src/evdev.c | 65 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index e4e6d72..086fb0c 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1427,28 +1427,57 @@ EvdevInit(DeviceIntPtr device) EvdevAddKeyClass(device); if (pEvdev->flags & EVDEV_BUTTON_EVENTS) EvdevAddButtonClass(device); - /* We don't allow relative and absolute axes on the same device. Reason - Reason being that some devices (MS Optical Desktop 2000) register both - rel and abs axes for x/y. - The abs axes register min/max, this min/max then also applies to the - relative device (the mouse) and caps it at 0..255 for both axis. - So unless you have a small screen, you won't be enjoying it much. - - FIXME: somebody volunteer to fix this. + + /* We don't allow relative and absolute axes on the same device. The + * reason is that some devices (MS Optical Desktop 2000) register both + * rel and abs axes for x/y. + * + * The abs axes register min/max; this min/max then also applies to the + * relative device (the mouse) and caps it at 0..255 for both axes. + * So, unless you have a small screen, you won't be enjoying it much; + * consequently, absolute axes are generally ignored. + * + * However, currenly only a device with absolute axes can be registered + * as a touch{pad,screen}. Thus, given such a device, absolute axes are + * used and relative axes are ignored. */ - if (pEvdev->flags & EVDEV_RELATIVE_EVENTS) { - if (EvdevAddRelClass(device) == Success) - { - if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) + + if (pEvdev->flags & (EVDEV_TOUCHPAD | EVDEV_TOUCHSCREEN)) + { + xf86Msg(X_INFO,"%s: touchpads and touchscreens ignore relative " + "axes.\n", device->name); + + if (EvdevAddAbsClass(device) != Success) + return !Success; + + pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS; + + } else if (pEvdev->flags & EVDEV_RELATIVE_EVENTS) { + + int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS; + + if (EvdevAddRelClass(device) == Success) { + + if (has_abs_axes) { + + pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS; + xf86Msg(X_INFO,"%s: relative axes found, ignoring absolute " "axes.\n", device->name); - pEvdev->flags &= ~EVDEV_ABSOLUTE_EVENTS; - } else - pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS; - } + } - if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) - EvdevAddAbsClass(device); + } else { + + if (has_abs_axes && EvdevAddAbsClass(device) == Success) + pEvdev->flags &= ~EVDEV_RELATIVE_EVENTS; + else + return !Success; + + } + + } else if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS) + if (EvdevAddAbsClass(device) != Success) + return !Success; #ifdef HAVE_PROPERTIES /* We drop the return value, the only time we ever want the handlers to -- 1.6.2.2.479.g2aec