[PATCH libinput v3] evdev: Add support for POINTINGSTICK_CONST_ACCEL udev property
Peter Hutterer
peter.hutterer at who-t.net
Wed Apr 8 21:48:57 PDT 2015
On Wed, Apr 08, 2015 at 12:11:58PM +0200, Hans de Goede wrote:
> There is quite a wide spread in the delta events generated by trackpoints,
> some generate deltas of 1-2 under normal use, while others generate deltas
> from 1-20.
>
> It is desirable to normalize trackpoint deltas just like we are normalizing
> mouse deltas to 1000 dpi, so as to give different model laptops aprox.
> the same trackpoint cursor speed ootb.
>
> Recent versions of udev + hwdb set a POINTINGSTICK_CONST_ACCEL udev property
> which can be used to adjust trackpoints which are too slow / too fast
> ootb, this commit implements support for that property.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
> Changes in v3:
> -Fix a couple of typos
> -Document TRACKPOINT_CONST_ACCEL udev property in
> doc/device-configuration-via-udev.dox
> -Added a test for parse_trackpoint_accel_property
> Changes in v2:
> -Use POINTINGSTICK_CONST_ACCEL instead of TRACKPOINT_CONST_ACCEL to match
> changes to the udev patchset
>
> foo
> ---
> doc/device-configuration-via-udev.dox | 4 ++++
> src/evdev.c | 33 +++++++++++++++++++++++++++++++++
> src/evdev.h | 7 +++++++
> src/libinput-util.c | 31 +++++++++++++++++++++++++++++++
> src/libinput-util.h | 1 +
> test/misc.c | 27 +++++++++++++++++++++++++++
> 6 files changed, 103 insertions(+)
>
> diff --git a/doc/device-configuration-via-udev.dox b/doc/device-configuration-via-udev.dox
> index fc1c0af..6579041 100644
> --- a/doc/device-configuration-via-udev.dox
> +++ b/doc/device-configuration-via-udev.dox
> @@ -57,6 +57,10 @@ See @ref motion_normalization for details.
> <dd>The angle in degrees for each click on a mouse wheel. See
> libinput_pointer_get_axis_source() for details.
> </dd>
> +<dt>POINTINGSTICK_CONST_ACCEL</dt>
> +<dd>A constant (linear) acceleration factor to apply to pointingstick deltas
> +to normalize them. See evdev_get_trackpoint_dpi() for details.
You can drop the "see ... " sentence since doxygen won't resolve it anyway.
Anyone interested enough in the code will (have to) be able to git grep.
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
otherwise, feel free to push this once all the udev changes have landed.
Cheers,
Peter
> +</dd>
> </dl>
>
> Below is an example udev rule to assign "seat1" to a device from vendor
> diff --git a/src/evdev.c b/src/evdev.c
> index 4205c2d..1730dae 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1319,6 +1319,31 @@ evdev_read_wheel_click_prop(struct evdev_device *device)
>
> return angle;
> }
> +
> +static inline int
> +evdev_get_trackpoint_dpi(struct evdev_device *device)
> +{
> + struct libinput *libinput = device->base.seat->libinput;
> + const char *trackpoint_accel;
> + double accel = DEFAULT_TRACKPOINT_ACCEL;
> +
> + trackpoint_accel = udev_device_get_property_value(
> + device->udev_device, "POINTINGSTICK_CONST_ACCEL");
> + if (trackpoint_accel) {
> + accel = parse_trackpoint_accel_property(trackpoint_accel);
> + if (accel == 0.0) {
> + log_error(libinput, "Trackpoint accel property for "
> + "'%s' is present but invalid, "
> + "using %.2f instead\n",
> + device->devname,
> + DEFAULT_TRACKPOINT_ACCEL);
> + accel = DEFAULT_TRACKPOINT_ACCEL;
> + }
> + }
> +
> + return DEFAULT_MOUSE_DPI / accel;
> +}
> +
> static inline int
> evdev_read_dpi_prop(struct evdev_device *device)
> {
> @@ -1326,6 +1351,14 @@ evdev_read_dpi_prop(struct evdev_device *device)
> const char *mouse_dpi;
> int dpi = DEFAULT_MOUSE_DPI;
>
> + /*
> + * Trackpoints do not have dpi, instead hwdb may contain a
> + * POINTINGSTICK_CONST_ACCEL value to compensate for sensitivity
> + * differences between models, we translate this to a fake dpi.
> + */
> + if (libevdev_has_property(device->evdev, INPUT_PROP_POINTING_STICK))
> + return evdev_get_trackpoint_dpi(device);
> +
> mouse_dpi = udev_device_get_property_value(device->udev_device,
> "MOUSE_DPI");
> if (mouse_dpi) {
> diff --git a/src/evdev.h b/src/evdev.h
> index c7a9e75..b63ae86 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -36,6 +36,13 @@
>
> /* The HW DPI rate we normalize to before calculating pointer acceleration */
> #define DEFAULT_MOUSE_DPI 1000
> +
> +/*
> + * The constant (linear) acceleration factor we use to normalize trackpoint
> + * deltas before calculating pointer acceleration.
> + */
> +#define DEFAULT_TRACKPOINT_ACCEL 1.0
> +
> /* The fake resolution value for abs devices without resolution */
> #define EVDEV_FAKE_RESOLUTION 1
>
> diff --git a/src/libinput-util.c b/src/libinput-util.c
> index 49e297a..4857435 100644
> --- a/src/libinput-util.c
> +++ b/src/libinput-util.c
> @@ -29,6 +29,7 @@
> #include "config.h"
>
> #include <ctype.h>
> +#include <locale.h>
> #include <stdarg.h>
> #include <stdbool.h>
> #include <stdio.h>
> @@ -201,3 +202,33 @@ parse_mouse_wheel_click_angle_property(const char *prop)
>
> return angle;
> }
> +
> +/**
> + * Helper function to parse the TRACKPOINT_CONST_ACCEL property from udev.
> + * Property is of the form:
> + * TRACKPOINT_CONST_ACCEL=<float>
> + *
> + * @param prop The value of the udev property (without the TRACKPOINT_CONST_ACCEL=)
> + * @return The acceleration, or 0.0 on error.
> + */
> +double
> +parse_trackpoint_accel_property(const char *prop)
> +{
> + locale_t c_locale;
> + double accel;
> + char *endp;
> +
> + /* Create a "C" locale to force strtod to use '.' as separator */
> + c_locale = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0);
> + if (c_locale == (locale_t)0)
> + return 0.0;
> +
> + accel = strtod_l(prop, &endp, c_locale);
> +
> + freelocale(c_locale);
> +
> + if (*endp != '\0')
> + return 0.0;
> +
> + return accel;
> +}
> diff --git a/src/libinput-util.h b/src/libinput-util.h
> index 30f59ec..74226b9 100644
> --- a/src/libinput-util.h
> +++ b/src/libinput-util.h
> @@ -242,5 +242,6 @@ enum ratelimit_state ratelimit_test(struct ratelimit *r);
>
> int parse_mouse_dpi_property(const char *prop);
> int parse_mouse_wheel_click_angle_property(const char *prop);
> +double parse_trackpoint_accel_property(const char *prop);
>
> #endif /* LIBINPUT_UTIL_H */
> diff --git a/test/misc.c b/test/misc.c
> index db26d67..829da7d 100644
> --- a/test/misc.c
> +++ b/test/misc.c
> @@ -557,6 +557,32 @@ START_TEST(wheel_click_parser)
> }
> END_TEST
>
> +struct parser_test_float {
> + char *tag;
> + double expected_value;
> +};
> +
> +START_TEST(trackpoint_accel_parser)
> +{
> + struct parser_test_float tests[] = {
> + { "0.5", 0.5 },
> + { "1.0", 1.0 },
> + { "2.0", 2.0 },
> + { "fail1.0", 0.0 },
> + { "1.0fail", 0.0 },
> + { "0,5", 0.0 },
> + { NULL, 0.0 }
> + };
> + int i;
> + double accel;
> +
> + for (i = 0; tests[i].tag != NULL; i++) {
> + accel = parse_trackpoint_accel_property(tests[i].tag);
> + ck_assert(accel == tests[i].expected_value);
> + }
> +}
> +END_TEST
> +
> int main (int argc, char **argv) {
> litest_add_no_device("events:conversion", event_conversion_device_notify);
> litest_add_for_device("events:conversion", event_conversion_pointer, LITEST_MOUSE);
> @@ -572,6 +598,7 @@ int main (int argc, char **argv) {
> litest_add_no_device("misc:ratelimit", ratelimit_helpers);
> litest_add_no_device("misc:dpi parser", dpi_parser);
> litest_add_no_device("misc:wheel click parser", wheel_click_parser);
> + litest_add_no_device("misc:trackpoint accel parser", trackpoint_accel_parser);
>
> return litest_run(argc, argv);
> }
> --
> 2.3.4
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
More information about the wayland-devel
mailing list