[PATCH libinput v5] evdev: use a different filter for low resolution touchpad on the Lenovo X230

Peter Hutterer peter.hutterer at who-t.net
Sun Apr 26 17:11:50 PDT 2015


On Thu, Apr 23, 2015 at 02:32:40PM -0400, Benjamin Tissoires wrote:
> Those touchpads presents an actual lower resolution that what is
> advertised.
> 
> We see some jumps from the cursor due to the big steps in X and Y
> when we are receiving data.
> 
> For instance, we receive:
> 
> E: 13.471932 0003 0000 16366    # EV_ABS / ABS_X                16366
> E: 13.471932 0003 0001 9591     # EV_ABS / ABS_Y                9591
> E: 13.471932 0000 0000 0000     # ------------ SYN_REPORT (0) ----------
> E: 13.479924 0003 0000 16316    # EV_ABS / ABS_X                16316
> E: 13.479924 0003 0001 9491     # EV_ABS / ABS_Y                9491
> E: 13.479924 0000 0000 0000     # ------------ SYN_REPORT (0) ----------
> E: 13.487939 0003 0000 16271    # EV_ABS / ABS_X                16271
> E: 13.487939 0003 0001 9403     # EV_ABS / ABS_Y                9403
> E: 13.487939 0000 0000 0000     # ------------ SYN_REPORT (0) ----------
> 
> -> jumps of ~50 in X in each report, and ~100 for Y.
> 
> Apply a factor to minimize those jumps at low speed, and try
> keeping the same feeling as regular touchpads at high speed.
> It still feels slower but it is usable at least
> 
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
> ---
> 
> Hi,
> 
> So this will hopefully be validated and pulled upstream.
> This patch needs the one Peter sent out yesterday (evdev: add support for
> LIBINPUT_MODEL_* udev tags). It is thus much smaller given that the generic
> bits are in the other patch.
> 
> The final choice for the acceleration profile is the one I sent in the v1 of
> the series. A nice drawing of the acceleration profile is available here:
> http://people.freedesktop.org/~tissoire/x230-v5.png
> 
> If anybody wants to polish it, I am all for it.
> 
> Some special notes if you want to use the patch without rebooting:
> - do not forget to update the hwdb (sudo udevadm hwdb --update)
> - reload the udev rules (sudo udevadm control --reload)
> - and trigger the input nodes (sudo udevadm trigger /dev/input/event*)
> - the udev database should still show LIBINPUT_MODEL_LENOVO_X230 attached to the
>   touchpad node (udevadm info --export-db | less)
> 
> Then kill X (or restart gdm), and you are good.

pushed, thanks
   06b4d83..26ceea3  master -> master

Cheers,
   Peter


>  src/evdev-mt-touchpad.c            |   14 ++++++++++--
>  src/evdev.c                        |    1 +
>  src/evdev.h                        |    1 +
>  src/filter.c                       |   37 ++++++++++++++++++++++++++++++++++++
>  src/filter.h                       |    5 ++++
>  udev/90-libinput-model-quirks.hwdb |    8 +++++++
>  6 files changed, 63 insertions(+), 3 deletions(-)
> 
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index cccf033..d5ce880 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -998,6 +998,7 @@ static int
>  tp_init_accel(struct tp_dispatch *tp, double diagonal)
>  {
>  	int res_x, res_y;
> +	accel_profile_func_t profile;
>  
>  	res_x = tp->device->abs.absinfo_x->resolution;
>  	res_y = tp->device->abs.absinfo_y->resolution;
> @@ -1021,9 +1022,16 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal)
>  		tp->accel.y_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
>  	}
>  
> -	if (evdev_device_init_pointer_acceleration(
> -                                       tp->device,
> -                                       touchpad_accel_profile_linear) == -1)
> +	switch (tp->device->model) {
> +	case EVDEV_MODEL_LENOVO_X230:
> +		profile = touchpad_lenovo_x230_accel_profile;
> +		break;
> +	default:
> +		profile = touchpad_accel_profile_linear;
> +		break;
> +	}
> +
> +	if (evdev_device_init_pointer_acceleration(tp->device, profile) == -1)
>  		return -1;
>  
>  	return 0;
> diff --git a/src/evdev.c b/src/evdev.c
> index e3bba93..6a9df49 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1429,6 +1429,7 @@ evdev_read_model(struct evdev_device *device)
>  		const char *property;
>  		enum evdev_device_model model;
>  	} model_map[] = {
> +		{ "LIBINPUT_MODEL_LENOVO_X230", EVDEV_MODEL_LENOVO_X230 },
>  		{ NULL, EVDEV_MODEL_DEFAULT },
>  	};
>  	const struct model_map *m = model_map;
> diff --git a/src/evdev.h b/src/evdev.h
> index edd4011..151d103 100644
> --- a/src/evdev.h
> +++ b/src/evdev.h
> @@ -95,6 +95,7 @@ enum evdev_middlebutton_event {
>  
>  enum evdev_device_model {
>  	EVDEV_MODEL_DEFAULT,
> +	EVDEV_MODEL_LENOVO_X230,
>  };
>  
>  struct mt_slot {
> diff --git a/src/filter.c b/src/filter.c
> index 962d74d..b953bee 100644
> --- a/src/filter.c
> +++ b/src/filter.c
> @@ -345,3 +345,40 @@ touchpad_accel_profile_linear(struct motion_filter *filter,
>  
>  	return speed_out * TP_MAGIC_SLOWDOWN;
>  }
> +
> +double
> +touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
> +				      void *data,
> +				      double speed_in,
> +				      uint64_t time)
> +{
> +	/* Keep the magic factor from touchpad_accel_profile_linear.  */
> +	const double TP_MAGIC_SLOWDOWN = 0.4;
> +
> +	/* Those touchpads presents an actual lower resolution that what is
> +	 * advertised. We see some jumps from the cursor due to the big steps
> +	 * in X and Y when we are receiving data.
> +	 * Apply a factor to minimize those jumps at low speed, and try
> +	 * keeping the same feeling as regular touchpads at high speed.
> +	 * It still feels slower but it is usable at least */
> +	const double TP_MAGIC_LOW_RES_FACTOR = 4.0;
> +	double speed_out;
> +	struct pointer_accelerator *accel_filter =
> +		(struct pointer_accelerator *)filter;
> +
> +	double s1, s2;
> +	const double max_accel = accel_filter->accel *
> +				  TP_MAGIC_LOW_RES_FACTOR; /* unitless factor */
> +	const double threshold = accel_filter->threshold /
> +				  TP_MAGIC_LOW_RES_FACTOR; /* units/ms */
> +	const double incline = accel_filter->incline * TP_MAGIC_LOW_RES_FACTOR;
> +
> +	speed_in *= TP_MAGIC_SLOWDOWN / TP_MAGIC_LOW_RES_FACTOR;
> +
> +	s1 = min(1, speed_in * 5);
> +	s2 = 1 + (speed_in - threshold) * incline;
> +
> +	speed_out = min(max_accel, s2 > 1 ? s2 : s1);
> +
> +	return speed_out * TP_MAGIC_SLOWDOWN / TP_MAGIC_LOW_RES_FACTOR;
> +}
> diff --git a/src/filter.h b/src/filter.h
> index 70363a6..a053860 100644
> --- a/src/filter.h
> +++ b/src/filter.h
> @@ -67,4 +67,9 @@ touchpad_accel_profile_linear(struct motion_filter *filter,
>  			      void *data,
>  			      double speed_in,
>  			      uint64_t time);
> +double
> +touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
> +				      void *data,
> +				      double speed_in,
> +				      uint64_t time);
>  #endif /* FILTER_H */
> diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb
> index 02bb8f9..959be0f 100644
> --- a/udev/90-libinput-model-quirks.hwdb
> +++ b/udev/90-libinput-model-quirks.hwdb
> @@ -14,3 +14,11 @@
>  
>  #
>  # Sort by brand, model
> +
> +##########################################
> +# LENOVO
> +##########################################
> +
> +# X230 (Tablet)
> +libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX230*
> + LIBINPUT_MODEL_LENOVO_X230=1
> -- 
> 1.7.1
> 
> _______________________________________________
> 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