On Thu, Apr 16, 2015 at 9:41 PM, Benjamin Tissoires <benjamin.tissoi...@gmail.com> 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.tissoi...@gmail.com> > Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> > --- > 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. > <dd>The angle in degrees for each click on a mouse wheel. See > libinput_pointer_get_axis_source() for details. > </dd> > +<dt>LIBINPUT_MODEL_LENOVO_X230</dt> > +<dd><b>Do not use for anything except a Lenovo X230 series</b> (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. > +</dd> > </dl> > > 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, > device->scroll.wheel_click_angle = > evdev_read_wheel_click_prop(device); > device->dpi = evdev_read_dpi_prop(device); > + device->model = evdev_read_model(device); > /* at most 5 SYN_DROPPED log-messages per 30s */ > ratelimit_init(&device->syn_drop_limit, 30ULL * 1000, 5); > > diff --git a/src/evdev.h b/src/evdev.h > index af09baa..c4bfb79 100644 > --- a/src/evdev.h > +++ b/src/evdev.h > @@ -63,6 +63,11 @@ enum evdev_device_tags { > EVDEV_TAG_TOUCHPAD_TRACKPOINT = (1 << 3), > }; > > +enum evdev_device_model { > + EVDEV_MODEL_DEFAULT, > + EVDEV_MODEL_LENOVO_X230, > +}; > + > struct mt_slot { > int32_t seat_slot; > struct device_coords point; > @@ -160,6 +165,8 @@ struct evdev_device { > > int dpi; /* HW resolution */ > struct ratelimit syn_drop_limit; /* ratelimit for SYN_DROPPED logging > */ > + > + enum evdev_device_model model; > }; > > #define EVDEV_UNHANDLED_DEVICE ((struct evdev_device *) 1) > diff --git a/src/filter.c b/src/filter.c > index f7ff426..8c53f22 100644 > --- a/src/filter.c > +++ b/src/filter.c > @@ -355,3 +355,37 @@ 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; > + > + 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 * > + TP_MAGIC_LOW_RES_FACTOR; /* twice the > factor */
Not twice, square. > + > + speed_in *= TP_MAGIC_SLOWDOWN / TP_MAGIC_LOW_RES_FACTOR; > + > + speed_out = accel_profile_linear(speed_in, max_accel, threshold, > incline); > + > + 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 */ > -- > 1.7.1 > > _______________________________________________ > 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