diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2014-08-14 10:48:52 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2014-08-18 10:02:00 +1000 |
commit | 291b60172d25446d2cabe61ed93e56db6570baa3 (patch) | |
tree | 1404d6925ddbabbfe59ffcc7d9c19378db2da111 /src/evdev.c | |
parent | Make the slot-state per slot (diff) | |
download | xf86-input-evdev-291b60172d25446d2cabe61ed93e56db6570baa3.tar.gz xf86-input-evdev-291b60172d25446d2cabe61ed93e56db6570baa3.tar.bz2 xf86-input-evdev-291b60172d25446d2cabe61ed93e56db6570baa3.zip |
Fix axis initialization for devices with abs x/y and rel scrollwheels
The Xen Virtual Pointer device has ABS_X, ABS_Y and REL_WHEEL. If smooth
scrolling is detected, the current code would first initialize relative axes
for scrolling and immediately overwrite those axes when the abs valuators are
written out.
This patch fixes the default case only, in the case of a device setting the
two Ignore*Axis options both to "off", the axes are still overwritten. The
wheels will work, other axes only if the same number of abs axes exists. And
it keeps the current memory leak too, but it's marked with a FIXME now.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src/evdev.c')
-rw-r--r-- | src/evdev.c | 82 |
1 files changed, 44 insertions, 38 deletions
diff --git a/src/evdev.c b/src/evdev.c index 7aecf36..958d4f9 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1225,7 +1225,7 @@ is_blacklisted_axis(int axis) static int -EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes) +EvdevAddAbsValuatorClass(DeviceIntPtr device, int num_scroll_axes) { InputInfoPtr pInfo; EvdevPtr pEvdev; @@ -1287,16 +1287,9 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes) #endif + #ifdef HAVE_SMOOTH_SCROLLING - if (want_scroll_axes && libevdev_has_event_type(pEvdev->dev, EV_REL)) - { - if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL)) - num_axes++; - if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL)) - num_axes++; - if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL)) - num_axes++; - } + num_axes += num_scroll_axes; #endif if (num_axes + num_mt_axes > MAX_VALUATORS) { @@ -1401,7 +1394,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes) } #ifdef HAVE_SMOOTH_SCROLLING - if (want_scroll_axes) + if (num_scroll_axes > 0) { mapping++; /* continue from abs axis mapping */ @@ -1511,7 +1504,7 @@ EvdevAddAbsValuatorClass(DeviceIntPtr device, int want_scroll_axes) #endif #ifdef HAVE_SMOOTH_SCROLLING - if (want_scroll_axes) + if (num_scroll_axes) { int idx; if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL)) @@ -1646,7 +1639,7 @@ EvdevSetScrollValuators(DeviceIntPtr device) } static int -EvdevAddRelValuatorClass(DeviceIntPtr device) +EvdevAddRelValuatorClass(DeviceIntPtr device, int num_scroll_axes) { InputInfoPtr pInfo; EvdevPtr pEvdev; @@ -1659,24 +1652,22 @@ EvdevAddRelValuatorClass(DeviceIntPtr device) if (!libevdev_has_event_type(pEvdev->dev, EV_REL)) goto out; - for (i = 0; i < REL_MAX; i++) + for (i = 0; i < REL_MAX; i++) { + if (i == REL_WHEEL || i == REL_HWHEEL || i == REL_DIAL) + continue; + if (libevdev_has_event_code(pEvdev->dev, EV_REL, i)) num_axes++; - if (num_axes < 1) - goto out; + } -#ifndef HAVE_SMOOTH_SCROLLING - /* Wheels are special, we post them as button events. So let's ignore them - * in the axes list too */ - if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL)) - num_axes--; - if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL)) - num_axes--; - if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL)) - num_axes--; + /* If we have only relative scroll axes, then we punt axis init to + EvdevInitAbsValuators if possible */ + if (num_axes < 1 && + (num_scroll_axes == 0 || pEvdev->flags & EVDEV_ABSOLUTE_EVENTS)) + goto out; - if (num_axes <= 0) - goto out; +#ifdef HAVE_SMOOTH_SCROLLING + num_axes += num_scroll_axes; #endif if (num_axes > MAX_VALUATORS) { @@ -1815,20 +1806,36 @@ EvdevInitButtonMapping(InputInfoPtr pInfo) } +static int +EvdevCountScrollAxes(EvdevPtr pEvdev) +{ + int num_scroll_axes = 0; + +#ifdef HAVE_SMOOTH_SCROLLING + if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_WHEEL)) + num_scroll_axes++; + if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_HWHEEL)) + num_scroll_axes++; + if (libevdev_has_event_code(pEvdev->dev, EV_REL, REL_DIAL)) + num_scroll_axes++; +#endif + + return num_scroll_axes; +} + static void EvdevInitAnyValuators(DeviceIntPtr device, EvdevPtr pEvdev) { InputInfoPtr pInfo = device->public.devicePrivate; - int rel_success = FALSE; + int num_scroll_axes = EvdevCountScrollAxes(pEvdev); if (pEvdev->flags & EVDEV_RELATIVE_EVENTS && - EvdevAddRelValuatorClass(device) == Success) - { - rel_success = TRUE; + EvdevAddRelValuatorClass(device, num_scroll_axes) == Success) xf86IDrvMsg(pInfo, X_INFO, "initialized for relative axes.\n"); - } + /* FIXME: EvdevAddAbsValuatorClass overwrites the valuators initialized + in EvdevAddRelValuatorClass and leaks the latter's memory */ if (pEvdev->flags & EVDEV_ABSOLUTE_EVENTS && - EvdevAddAbsValuatorClass(device, !rel_success) == Success) + EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success) xf86IDrvMsg(pInfo, X_INFO, "initialized for absolute axes.\n"); } @@ -1836,8 +1843,9 @@ static void EvdevInitAbsValuators(DeviceIntPtr device, EvdevPtr pEvdev) { InputInfoPtr pInfo = device->public.devicePrivate; + int num_scroll_axes = EvdevCountScrollAxes(pEvdev); - if (EvdevAddAbsValuatorClass(device, TRUE) == Success) { + if (EvdevAddAbsValuatorClass(device, num_scroll_axes) == Success) { xf86IDrvMsg(pInfo, X_INFO,"initialized for absolute axes.\n"); } else { xf86IDrvMsg(pInfo, X_ERROR,"failed to initialize for absolute axes.\n"); @@ -1850,8 +1858,9 @@ EvdevInitRelValuators(DeviceIntPtr device, EvdevPtr pEvdev) { InputInfoPtr pInfo = device->public.devicePrivate; int has_abs_axes = pEvdev->flags & EVDEV_ABSOLUTE_EVENTS; + int num_scroll_axes = EvdevCountScrollAxes(pEvdev); - if (EvdevAddRelValuatorClass(device) == Success) { + if (EvdevAddRelValuatorClass(device, num_scroll_axes) == Success) { xf86IDrvMsg(pInfo, X_INFO,"initialized for relative axes.\n"); @@ -2278,9 +2287,6 @@ EvdevProbe(InputInfoPtr pInfo) #endif EvdevForceXY(pInfo, Absolute); } - - - } for (i = 0; i < BTN_MISC; i++) { |