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 <hdego...@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.hutte...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel > _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel