Re: [PATCH v3 2/4] evdev: use a different filter for low resolution touchpad on the Lenovo X230

2015-04-16 Thread Vasily Khoruzhick
On Thu, Apr 16, 2015 at 9:41 PM, 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  16366# EV_ABS / ABS_X16366
> E: 13.471932 0003 0001 9591 # EV_ABS / ABS_Y9591
> E: 13.471932    #  SYN_REPORT (0) --
> E: 13.479924 0003  16316# EV_ABS / ABS_X16316
> E: 13.479924 0003 0001 9491 # EV_ABS / ABS_Y9491
> E: 13.479924    #  SYN_REPORT (0) --
> E: 13.487939 0003  16271# EV_ABS / ABS_X16271
> E: 13.487939 0003 0001 9403 # EV_ABS / ABS_Y9403
> E: 13.487939    #  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 
> Signed-off-by: Peter Hutterer 
> ---
> Changes to v1:
> - a bit more generic than the original, makes adding new models more
> straightforward.
>
> Changes to v2:
> - changed the incline parameter to have a touchpad which feels like the other.
>   Not sure these are the final parameters but they make the touchpad much
>   better.
>
>  doc/device-configuration-via-udev.dox |9 
>  src/evdev-mt-touchpad.c   |   14 ++--
>  src/evdev.c   |   23 ++
>  src/evdev.h   |7 ++
>  src/filter.c  |   34 
> +
>  src/filter.h  |5 
>  6 files changed, 89 insertions(+), 3 deletions(-)
>
> diff --git a/doc/device-configuration-via-udev.dox 
> b/doc/device-configuration-via-udev.dox
> index fc1c0af..c570913 100644
> --- a/doc/device-configuration-via-udev.dox
> +++ b/doc/device-configuration-via-udev.dox
> @@ -57,6 +57,15 @@ See @ref motion_normalization for details.
>  The angle in degrees for each click on a mouse wheel. See
>  libinput_pointer_get_axis_source() for details.
>  
> +LIBINPUT_MODEL_LENOVO_X230
> +Do not use for anything except a Lenovo X230 series (you have been
> +warned).
> +This flag allows libinput to apply a different acceleration profile for the
> +touchpads of this series of laptops to counter a hardware deficiency. It may
> +also be use to tune other parts of the inputs of these laptops, so the 
> effects
> +of this property may change anytime and will be only tested against the
> +mentioned laptop series.
> +
>  
>
>  Below is an example udev rule to assign "seat1" to a device from vendor
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index 4e5a558..f88e906 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 5b4b2b6..0b705e4 100644
> --- a/src/evdev.c
> +++ b/src/evdev.c
> @@ -1356,6 +1356,28 @@ evdev_read_dpi_prop(struct evdev_device *device)
> return dpi;
>  }
>
> +static inline enum evdev_device_model
> +evdev_read_model(struct evdev_device *device)
> +{
> +   const struct model_map {
> +   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;
> +
> +   while (m->property) {
> +   if (!!udev_device_get_property_value(device->udev_device,
> +m->property))
> +   br

[PATCH v3 2/4] evdev: use a different filter for low resolution touchpad on the Lenovo X230

2015-04-16 Thread Benjamin Tissoires
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  16366# EV_ABS / ABS_X16366
E: 13.471932 0003 0001 9591 # EV_ABS / ABS_Y9591
E: 13.471932    #  SYN_REPORT (0) --
E: 13.479924 0003  16316# EV_ABS / ABS_X16316
E: 13.479924 0003 0001 9491 # EV_ABS / ABS_Y9491
E: 13.479924    #  SYN_REPORT (0) --
E: 13.487939 0003  16271# EV_ABS / ABS_X16271
E: 13.487939 0003 0001 9403 # EV_ABS / ABS_Y9403
E: 13.487939    #  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 
Signed-off-by: Peter Hutterer 
---
Changes to v1:
- a bit more generic than the original, makes adding new models more
straightforward.

Changes to v2:
- changed the incline parameter to have a touchpad which feels like the other.
  Not sure these are the final parameters but they make the touchpad much
  better.

 doc/device-configuration-via-udev.dox |9 
 src/evdev-mt-touchpad.c   |   14 ++--
 src/evdev.c   |   23 ++
 src/evdev.h   |7 ++
 src/filter.c  |   34 +
 src/filter.h  |5 
 6 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/doc/device-configuration-via-udev.dox 
b/doc/device-configuration-via-udev.dox
index fc1c0af..c570913 100644
--- a/doc/device-configuration-via-udev.dox
+++ b/doc/device-configuration-via-udev.dox
@@ -57,6 +57,15 @@ See @ref motion_normalization for details.
 The angle in degrees for each click on a mouse wheel. See
 libinput_pointer_get_axis_source() for details.
 
+LIBINPUT_MODEL_LENOVO_X230
+Do not use for anything except a Lenovo X230 series (you have been
+warned).
+This flag allows libinput to apply a different acceleration profile for the
+touchpads of this series of laptops to counter a hardware deficiency. It may
+also be use to tune other parts of the inputs of these laptops, so the effects
+of this property may change anytime and will be only tested against the
+mentioned laptop series.
+
 
 
 Below is an example udev rule to assign "seat1" to a device from vendor
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 4e5a558..f88e906 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 5b4b2b6..0b705e4 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1356,6 +1356,28 @@ evdev_read_dpi_prop(struct evdev_device *device)
return dpi;
 }
 
+static inline enum evdev_device_model
+evdev_read_model(struct evdev_device *device)
+{
+   const struct model_map {
+   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;
+
+   while (m->property) {
+   if (!!udev_device_get_property_value(device->udev_device,
+m->property))
+   break;
+   m++;
+   }
+
+   return m->model;
+}
+
 /* Return 1 if the given resolutions have been set, or 0 otherwise */
 inline int
 evdev_fix_abs_resolution(struct evdev_device *device,
@@ -1868,6 +1890,7 @@ evdev_device_create(struct libinput_seat *seat,
devic