[PATCH libinput v2] evdev: Add support for POINTINGSTICK_CONST_ACCEL udev property

Peter Hutterer peter.hutterer at who-t.net
Mon Apr 6 21:47:27 PDT 2015


On Fri, Apr 03, 2015 at 04:15:18PM +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 v2:
> -Use POINTINGSTICK_CONST_ACCEL instead of TRACKPOINT_CONST_ACCEL to match
>  changes to the udev patchset
> ---
>  src/evdev.c         | 33 +++++++++++++++++++++++++++++++++
>  src/evdev.h         |  7 +++++++
>  src/libinput-util.c | 31 +++++++++++++++++++++++++++++++
>  src/libinput-util.h |  1 +
>  4 files changed, 72 insertions(+)
> 
> diff --git a/src/evdev.c b/src/evdev.c
> index 2808c30..e54d559 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;
> +		}
> +	}

needs an entry in the udev property list in doc/device-configuration-via-udev.dox

> +
> +	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 sensitity differences

sensitivity

> +	 * between different 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..5891012 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 seperator */

"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;
> +}

add a couple of basic tests for this please, should mostly be copy/paste
from the other tests anyway.

Cheers,
   Peter

> 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 */
> -- 
> 2.3.4


More information about the wayland-devel mailing list