From 831ce3c0d3b8b5521c0f504c204ae6d11453780a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 5 Jun 2018 14:54:50 +1000 Subject: [PATCH 01/12] filter: replace the trackpoint accel with a velocity-based one This gets rid of the trackpoint range propery that we've been parsing until now and instead just opts for a basic curve with some deceleration for low pressure. The speed range is taken from the touchpad and should be wide enough for most trackpoints that fall within the expected range. Trackpoints like the new ALPS ones need to be configured through a hwdb (this part is currently missing). Signed-off-by: Peter Hutterer --- doc/pointer-acceleration.dox | 30 ++--- src/filter-trackpoint.c | 250 ++++++++++------------------------- 2 files changed, 79 insertions(+), 201 deletions(-) diff --git a/doc/pointer-acceleration.dox b/doc/pointer-acceleration.dox index 6b2177c3..63b742ce 100644 --- a/doc/pointer-acceleration.dox +++ b/doc/pointer-acceleration.dox @@ -114,31 +114,21 @@ that trackpoint speed is a function of pressure rather than moving speed. But trackpoint hardware is quite varied in how it reacts to user pressure and unlike other devices it cannot easily be normalized for physical properties. Measuring pressure objectively across a variety of hardware is -nontrivial. +nontrivial. See @ref trackpoints for more details. -libinput's pointer acceleration is a function of the total available -pressure range on a device. See @ref trackpoint_range for details. +The deltas for trackpoints are converted units/ms but there is no common +physical reference point for a unit. Thus, the same pressure on different +trackpoints will generate different speeds and thus different acceleration +behaviors. Additionally, some trackpoints provide the ability to adjust the +sensitivity in hardware by modifying a sysfs file on the serio node. A +higher sensitivity results in higher deltas, thus changing the definition of +what is a unit again. -libinput relies on some system-wide configured properties, specifically the -@ref udev_config. The property that influences trackpoint acceleration is -`LIBINPUT_ATTR_TRACKPOINT_RANGE` which specifies the total delta range for -the trackpoint. See @ref trackpoint_range for details. - -Additionally, some trackpoints provide the ability to adjust the sensitivity in -hardware by modifying a sysfs file on the serio node. The udev property -`POINTINGSTICK_SENSITIVITY` indicates the desired value, a udev -builtin is expected to apply this to the device, i.e. libinput does not -handle this property. Once applied, the sensitivity adjusts the deltas -coming out of the hardware. When the sensitivity changes, the trackpoint -range changes and thus the `LIBINPUT_ATTR_TRACKPOINT_RANGE` property -becomes invalid. - -As of version 1.9, libinput does not parse the `POINTINGSTICK_CONST_ACCEL` property anymore. @image html ptraccel-trackpoint.svg "Pointer acceleration curves for trackpoints" -The image above shows the trackpoint acceleration profile for each input -delta. +The image above shows the trackpoint acceleration profile for the speed in +units/ms. @section ptraccel-profile-flat The flat pointer acceleration profile diff --git a/src/filter-trackpoint.c b/src/filter-trackpoint.c index 760f0e6e..5e07851d 100644 --- a/src/filter-trackpoint.c +++ b/src/filter-trackpoint.c @@ -1,7 +1,7 @@ /* * Copyright © 2006-2009 Simon Thum * Copyright © 2012 Jonas Ådahl - * Copyright © 2014-2015 Red Hat, Inc. + * Copyright © 2014-2018 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,121 +36,38 @@ #include "libinput-util.h" #include "filter-private.h" -/* Trackpoint acceleration */ -#define TRACKPOINT_DEFAULT_MAX_ACCEL 2.0 /* in units/us */ -#define TRACKPOINT_DEFAULT_MAX_DELTA 120 -/* As measured on a Lenovo T440 at kernel-default sensitivity 128 */ -#define TRACKPOINT_DEFAULT_RANGE 20 /* max value */ - -struct tablet_accelerator_flat { - struct motion_filter base; - - double factor; - int xres, yres; - double xres_scale, /* 1000dpi : tablet res */ - yres_scale; /* 1000dpi : tablet res */ -}; - struct trackpoint_accelerator { struct motion_filter base; - struct device_float_coords history[4]; - size_t history_size; - - double scale_factor; - double max_accel; - double max_delta; - - double incline; /* incline of the function */ - double offset; /* offset of the function */ + struct pointer_trackers trackers; + double speed_factor; }; double trackpoint_accel_profile(struct motion_filter *filter, void *data, - double delta) + double velocity) { struct trackpoint_accelerator *accel_filter = (struct trackpoint_accelerator *)filter; - const double max_accel = accel_filter->max_accel; double factor; - delta = fabs(delta); + velocity = v_us2ms(velocity); /* make it units/ms */ - /* This is almost the equivalent of the xserver acceleration - at sensitivity 128 and speed 0.0 */ - factor = delta * accel_filter->incline + accel_filter->offset; - factor = min(factor, max_accel); + /* Just a nice-enough curve that provides fluid factor conversion + * from the minimum speed up to the real maximum. Generated by + * https://www.mycurvefit.com/ with input data + * 0 0.3 + * 0.1 1 + * 0.4 3 + * 0.6 4 + */ + factor = 10.06254 + (0.3 - 10.06254)/(1 + pow(velocity/0.9205459, 1.15363)); + factor *= accel_filter->speed_factor; return factor; } -/** - * Average the deltas, they are messy and can provide sequences like 7, 7, - * 9, 8, 14, 7, 9, 8 ... The outliers cause unpredictable jumps, so average - * them out. - */ -static inline struct device_float_coords -trackpoint_average_delta(struct trackpoint_accelerator *filter, - const struct device_float_coords *unaccelerated) -{ - size_t i; - struct device_float_coords avg = {0}; - - memmove(&filter->history[1], - &filter->history[0], - sizeof(*filter->history) * (filter->history_size - 1)); - filter->history[0] = *unaccelerated; - - for (i = 0; i < filter->history_size; i++) { - avg.x += filter->history[i].x; - avg.y += filter->history[i].y; - } - avg.x /= filter->history_size; - avg.y /= filter->history_size; - - return avg; -} - -/** - * Undo any system-wide magic scaling, so we're behaving the same regardless - * of the trackpoint hardware. This way we can apply our profile independent - * of any other configuration that messes with things. - */ -static inline struct device_float_coords -trackpoint_normalize_deltas(const struct trackpoint_accelerator *accel_filter, - const struct device_float_coords *delta) -{ - struct device_float_coords scaled = *delta; - - scaled.x *= accel_filter->scale_factor; - scaled.y *= accel_filter->scale_factor; - - return scaled; -} - -/** - * We set a max delta per event, to avoid extreme jumps once we exceed the - * expected pressure. Trackpoint hardware is inconsistent once the pressure - * gets high, so we can expect sequences like 30, 40, 35, 55, etc. This may - * be caused by difficulty keeping up high consistent pressures or just - * measuring errors in the hardware. Either way, we cap to a max delta so - * once we hit the high pressures, movement is capped and consistent. - */ -static inline struct normalized_coords -trackpoint_clip_to_max_delta(const struct trackpoint_accelerator *accel_filter, - struct normalized_coords coords) -{ - const double max_delta = accel_filter->max_delta; - - if (abs(coords.x) > max_delta) - coords.x = copysign(max_delta, coords.x); - if (abs(coords.y) > max_delta) - coords.y = copysign(max_delta, coords.y); - - return coords; -} - static struct normalized_coords trackpoint_accelerator_filter(struct motion_filter *filter, const struct device_float_coords *unaccelerated, @@ -158,23 +75,16 @@ trackpoint_accelerator_filter(struct motion_filter *filter, { struct trackpoint_accelerator *accel_filter = (struct trackpoint_accelerator *)filter; - struct device_float_coords scaled; - struct device_float_coords avg; struct normalized_coords coords; double f; - double delta; + double velocity; - scaled = trackpoint_normalize_deltas(accel_filter, unaccelerated); - avg = trackpoint_average_delta(accel_filter, &scaled); + trackers_feed(&accel_filter->trackers, unaccelerated, time); + velocity = trackers_velocity(&accel_filter->trackers, time); - delta = hypot(avg.x, avg.y); - - f = trackpoint_accel_profile(filter, data, delta); - - coords.x = avg.x * f; - coords.y = avg.y * f; - - coords = trackpoint_clip_to_max_delta(accel_filter, coords); + f = trackpoint_accel_profile(filter, data, velocity); + coords.x = unaccelerated->x * f; + coords.y = unaccelerated->y * f; return coords; } @@ -185,89 +95,72 @@ trackpoint_accelerator_filter_noop(struct motion_filter *filter, void *data, uint64_t time) { - struct trackpoint_accelerator *accel_filter = - (struct trackpoint_accelerator *)filter; - struct device_float_coords scaled; - struct device_float_coords avg; struct normalized_coords coords; - scaled = trackpoint_normalize_deltas(accel_filter, unaccelerated); - avg = trackpoint_average_delta(accel_filter, &scaled); - - coords.x = avg.x; - coords.y = avg.y; - - coords = trackpoint_clip_to_max_delta(accel_filter, coords); + coords.x = unaccelerated->x; + coords.y = unaccelerated->y; return coords; } +/* Maps the [-1, 1] speed setting into a constant acceleration + * range. This isn't a linear scale, we keep 0 as the 'optimized' + * mid-point and scale down to 0 for setting -1 and up to 5 for + * setting 1. On the premise that if you want a faster cursor, it + * doesn't matter as much whether you have 0.56789 or 0.56790, + * but for lower settings it does because you may lose movements. + * *shrug*. + * + * Magic numbers calculated by MyCurveFit.com, data points were + * 0.0 0.0 + * 0.1 0.1 (because we need 4 points) + * 1 1 + * 2 5 + * + * This curve fits nicely into the range necessary. + */ +static inline double +speed_factor(double s) +{ + s += 1; /* map to [0, 2] */ + return 435837.2 + (0.04762636 - 435837.2)/(1 + pow(s/240.4549, + 2.377168)); +} + static bool trackpoint_accelerator_set_speed(struct motion_filter *filter, double speed_adjustment) { struct trackpoint_accelerator *accel_filter = (struct trackpoint_accelerator*)filter; - double incline, offset, max; assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0); - /* Helloooo, magic numbers. - - These numbers were obtained by finding an acceleration curve that - provides precision at slow speeds but still provides a good - acceleration at higher pressure - and a quick ramp-up to that - acceleration. - - Trackpoints have built-in acceleration curves already, so we - don't put a new function on top, we merely scale the output from - those curves (re-calculating the pressure values from the - firmware-defined curve and applying a new curve is unreliable). - - For that basic scaling, we assume a constant factor f based on - the speed setting together with a maximum factor m (for this - speed setting). Delta acceleration is thus: - factor = max(m, f) - accelerated_delta = delta * factor; - - Trial and error showed a couple of pairs that work well for the - various speed settings (Lenovo T440, sensitivity 128): - - -1.0: f = 0.3, m = 1 - -0.5: f = 0.6, m = 2 - 0.0: f = 1.0, m = 6 - 0.5: f = 1.4, m = 8 - 1.0: f = 1.9, m = 15 - - Note: if f >= 2.0, some pixels are unaddressable - - Those pairs were fed into the linear/exponential regression tool - at http://www.xuru.org/rt/LR.asp and show two functions that map - speed settings to the respective f and m. - Given a speed setting s in [-1.0, 1.0] - f(s) = 0.8 * s + 1.04 - m(s) = 4.6 * e**(1.2 * s) - These are close enough to the tested pairs. - */ - - max = 4.6 * pow(M_E, 1.2 * speed_adjustment); - incline = 0.8 * speed_adjustment + 1.04; - offset = 0; - - accel_filter->max_accel = max; - accel_filter->incline = incline; - accel_filter->offset = offset; filter->speed_adjustment = speed_adjustment; + accel_filter->speed_factor = speed_factor(speed_adjustment); + return true; } +static void +trackpoint_accelerator_restart(struct motion_filter *filter, + void *data, + uint64_t time) +{ + struct trackpoint_accelerator *accel = + (struct trackpoint_accelerator *) filter; + + trackers_reset(&accel->trackers, time); +} + static void trackpoint_accelerator_destroy(struct motion_filter *filter) { struct trackpoint_accelerator *accel_filter = (struct trackpoint_accelerator *)filter; + trackers_free(&accel_filter->trackers); free(accel_filter); } @@ -275,7 +168,7 @@ struct motion_filter_interface accelerator_interface_trackpoint = { .type = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE, .filter = trackpoint_accelerator_filter, .filter_constant = trackpoint_accelerator_filter_noop, - .restart = NULL, + .restart = trackpoint_accelerator_restart, .destroy = trackpoint_accelerator_destroy, .set_speed = trackpoint_accelerator_set_speed, }; @@ -286,8 +179,8 @@ create_pointer_accelerator_filter_trackpoint(int max_hw_delta) struct trackpoint_accelerator *filter; /* Trackpoints are special. They don't have a movement speed like a - * mouse or a finger, instead they send a constant stream of events - * based on the pressure applied. + * mouse or a finger, instead they send a stream of events based on + * the pressure applied. * * Physical ranges on a trackpoint are the max values for relative * deltas, but these are highly device-specific. @@ -298,17 +191,12 @@ create_pointer_accelerator_filter_trackpoint(int max_hw_delta) if (!filter) return NULL; - filter->history_size = ARRAY_LENGTH(filter->history); - filter->max_accel = TRACKPOINT_DEFAULT_MAX_ACCEL; - filter->max_delta = TRACKPOINT_DEFAULT_MAX_DELTA; - - filter->scale_factor = 1.0 * TRACKPOINT_DEFAULT_RANGE / max_hw_delta; - - /* Crop to a maximum 1.0 for the scale factor, otherwise we scale up - * events from low-res trackpoints when really we should just take - * those as-is. + /* FIXME: should figure out something here to deal with the + * trackpoint range/max hw delta. Or we just make it a literal + * "magic" number and live with it. */ - filter->scale_factor = min(1.0, filter->scale_factor); + + trackers_init(&filter->trackers); filter->base.interface = &accelerator_interface_trackpoint; From 6dca5df80645c5d98640f4e2c04e06f4ba5d5fd3 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 27 Jun 2018 15:53:23 +1000 Subject: [PATCH 02/12] filter: make the trackpoint accel profile func the same prototype as the others Signed-off-by: Peter Hutterer --- src/filter-trackpoint.c | 5 +++-- src/filter.h | 3 ++- tools/ptraccel-debug.c | 25 ++----------------------- 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/src/filter-trackpoint.c b/src/filter-trackpoint.c index 5e07851d..ebc7ee12 100644 --- a/src/filter-trackpoint.c +++ b/src/filter-trackpoint.c @@ -46,7 +46,8 @@ struct trackpoint_accelerator { double trackpoint_accel_profile(struct motion_filter *filter, void *data, - double velocity) + double velocity, + uint64_t time) { struct trackpoint_accelerator *accel_filter = (struct trackpoint_accelerator *)filter; @@ -82,7 +83,7 @@ trackpoint_accelerator_filter(struct motion_filter *filter, trackers_feed(&accel_filter->trackers, unaccelerated, time); velocity = trackers_velocity(&accel_filter->trackers, time); - f = trackpoint_accel_profile(filter, data, velocity); + f = trackpoint_accel_profile(filter, data, velocity, time); coords.x = unaccelerated->x * f; coords.y = unaccelerated->y * f; diff --git a/src/filter.h b/src/filter.h index 506ab123..3865b819 100644 --- a/src/filter.h +++ b/src/filter.h @@ -154,5 +154,6 @@ touchpad_lenovo_x230_accel_profile(struct motion_filter *filter, double trackpoint_accel_profile(struct motion_filter *filter, void *data, - double delta); + double delta, + uint64_t time); #endif /* FILTER_H */ diff --git a/tools/ptraccel-debug.c b/tools/ptraccel-debug.c index 670f0457..fbb06755 100644 --- a/tools/ptraccel-debug.c +++ b/tools/ptraccel-debug.c @@ -169,24 +169,6 @@ print_accel_func(struct motion_filter *filter, } } -static void -print_accel_func_trackpoint(struct motion_filter *filter, - int max) -{ - printf("# gnuplot:\n"); - printf("# set xlabel \"deltas (units)\"\n"); - printf("# set ylabel \"raw accel factor\"\n"); - printf("# set style data lines\n"); - printf("# plot \"gnuplot.data\" using 1:2 title 'accel factor'\n"); - printf("#\n"); - printf("# data: delta(units) factor\n"); - for (double delta = 0; delta < max; delta += 0.2) { - double factor = trackpoint_accel_profile(filter, NULL, delta); - - printf("%.2f %f\n", delta, factor); - } -} - static void usage(void) { @@ -350,7 +332,7 @@ main(int argc, char **argv) profile = touchpad_lenovo_x230_accel_profile; } else if (streq(filter_type, "trackpoint")) { filter = create_pointer_accelerator_filter_trackpoint(tp_range_max); - profile = NULL; /* trackpoint is special */ + profile = trackpoint_accel_profile; } else { fprintf(stderr, "Invalid filter type %s\n", filter_type); return 1; @@ -381,10 +363,7 @@ main(int argc, char **argv) switch (mode) { case ACCEL: - if (!profile) /* trackpoint */ - print_accel_func_trackpoint(filter, tp_range_max); - else - print_accel_func(filter, profile, dpi); + print_accel_func(filter, profile, dpi); break; case DELTA: print_ptraccel_deltas(filter, step); From 5f9c9856613e2a03473bf8756775a9eff0c7c35a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 27 Jun 2018 15:54:04 +1000 Subject: [PATCH 03/12] tools: fix units for trackpoint accel graph We use speed now and trackpoints are in units/ms Signed-off-by: Peter Hutterer --- tools/make-ptraccel-graphs.sh | 4 ++-- tools/ptraccel-debug.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/make-ptraccel-graphs.sh b/tools/make-ptraccel-graphs.sh index 2e6c73af..a98d79c7 100755 --- a/tools/make-ptraccel-graphs.sh +++ b/tools/make-ptraccel-graphs.sh @@ -76,13 +76,13 @@ done $gnuplot < Date: Fri, 29 Jun 2018 15:15:20 +1000 Subject: [PATCH 04/12] tools: reduce the trackpoint gnuplot range to 0..1 units/ms Anything above 1 unit/ms is high pressure. Though that depends on the trackpoint range, so... Signed-off-by: Peter Hutterer --- tools/make-ptraccel-graphs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/make-ptraccel-graphs.sh b/tools/make-ptraccel-graphs.sh index a98d79c7..049527db 100755 --- a/tools/make-ptraccel-graphs.sh +++ b/tools/make-ptraccel-graphs.sh @@ -80,7 +80,7 @@ set xlabel "delta (units/ms)" set ylabel "accel factor" set style data lines set yrange [0:5] -set xrange [0:20] +set xrange [0:1] speeds="$speeds" fname(s)=sprintf("$outfile-%s.gnuplot", s) plot for [s in speeds] fname(s) using 4:2 title s, \ From 6480bfe14dab5a974d9943a175121cae500462fc Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 27 Jun 2018 15:54:55 +1000 Subject: [PATCH 05/12] tools: drop the special handling for trackpoint accel, not needed anymore Signed-off-by: Peter Hutterer --- tools/ptraccel-debug.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/ptraccel-debug.c b/tools/ptraccel-debug.c index 150a3b3b..5ee88c30 100644 --- a/tools/ptraccel-debug.c +++ b/tools/ptraccel-debug.c @@ -185,7 +185,6 @@ usage(void) "--steps= ... in motion and delta modes only. Increase dx by step each round\n" "--speed= ... accel speed [-1, 1], default 0\n" "--dpi= ... device resolution in DPI (default: 1000)\n" - "--trackpoint-range= ... range of the trackpoint deltas (default: 20)\n" "--filter= \n" " linear ... the default motion filter\n" " low-dpi ... low-dpi filter, use --dpi with this argument\n" @@ -236,7 +235,6 @@ main(int argc, char **argv) OPT_SPEED, OPT_DPI, OPT_FILTER, - OPT_TRACKPOINT_RANGE, }; while (1) { @@ -251,7 +249,6 @@ main(int argc, char **argv) {"speed", 1, 0, OPT_SPEED }, {"dpi", 1, 0, OPT_DPI }, {"filter", 1, 0, OPT_FILTER }, - {"trackpoint-range", 1, 0, OPT_TRACKPOINT_RANGE }, {0, 0, 0, 0} }; @@ -309,9 +306,6 @@ main(int argc, char **argv) case OPT_FILTER: filter_type = optarg; break; - case OPT_TRACKPOINT_RANGE: - tp_range_max = strtod(optarg, NULL); - break; default: usage(); exit(1); From 0021f9e7a8b0cd086f6d564ff13dff7fcd644790 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 29 Jun 2018 15:09:47 +1000 Subject: [PATCH 06/12] tools: make-ptraccel-graphs: drop an unnecessary outfile Signed-off-by: Peter Hutterer --- tools/make-ptraccel-graphs.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/make-ptraccel-graphs.sh b/tools/make-ptraccel-graphs.sh index 049527db..bfb3f917 100755 --- a/tools/make-ptraccel-graphs.sh +++ b/tools/make-ptraccel-graphs.sh @@ -69,7 +69,6 @@ plot for [s in speeds] fname(s) using 1:2 title s, \ EOF outfile="ptraccel-trackpoint" -$tool --mode=accel --dpi=1000 --filter=linear > $outfile-mouse.gnuplot for speed in $speeds; do $tool --mode=accel --speed=$speed --filter=trackpoint > $outfile-$speed.gnuplot done From 1cc9f44e93ca1c3e25a6f937f36d99c3f9c8a209 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 9 Jul 2018 16:00:45 +1000 Subject: [PATCH 07/12] quirks: add quirks_get_double() Signed-off-by: Peter Hutterer --- src/quirks.c | 20 ++++++++++++++++++++ src/quirks.h | 13 +++++++++++++ tools/shared.c | 1 + 3 files changed, 34 insertions(+) diff --git a/src/quirks.c b/src/quirks.c index c74ecbb4..8d0d6847 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -54,6 +54,7 @@ enum property_type { PT_BOOL, PT_DIMENSION, PT_RANGE, + PT_DOUBLE, }; /** @@ -74,6 +75,7 @@ struct property { char *s; struct quirk_dimensions dim; struct quirk_range range; + double d; } value; }; @@ -1434,6 +1436,24 @@ quirks_get_uint32(struct quirks *q, enum quirk which, uint32_t *val) return true; } +bool +quirks_get_double(struct quirks *q, enum quirk which, double *val) +{ + struct property *p; + + if (!q) + return false; + + p = quirk_find_prop(q, which); + if (!p) + return false; + + assert(p->type == PT_DOUBLE); + *val = p->value.d; + + return true; +} + bool quirks_get_string(struct quirks *q, enum quirk which, char **val) { diff --git a/src/quirks.h b/src/quirks.h index 36e1e14b..df8b7dd3 100644 --- a/src/quirks.h +++ b/src/quirks.h @@ -216,6 +216,19 @@ quirks_get_int32(struct quirks *q, enum quirk which, int32_t *val); +/** + * Get the value of the given quirk, as double. + * This function will assert if the quirk type does not match the + * requested type. If the quirk is not set for this device, val is + * unchanged. + * + * @return true if the quirk value is valid, false otherwise. + */ +bool +quirks_get_double(struct quirks *q, + enum quirk which, + double *val); + /** * Get the value of the given quirk, as string. * This function will assert if the quirk type does not match the diff --git a/tools/shared.c b/tools/shared.c index 3cda4573..fa03cc75 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -630,6 +630,7 @@ tools_list_device_quirks(struct quirks_context *ctx, struct quirk_range r; uint32_t v; char *s; + double d; if (!quirks_has_quirk(quirks, *q)) continue; From 27f7a66de4e705b2cd00d2d8ba499c9a5829fee0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 9 Jul 2018 16:04:50 +1000 Subject: [PATCH 08/12] filter: add a trackpoint multiplier factor Measuring the trackpoint range has not shown to be sufficient or precise enough to be used as an ingredient for trackpoint acceleration. So let's just switch back to a generic multiplier that we can apply to the input deltas do undo any device-specific lack of scaling. Signed-off-by: Peter Hutterer --- doc/pointer-acceleration.dox | 3 + doc/svg/trackpoint-delta-illustration.svg | 126 +++++++++++ doc/trackpoints.dox | 248 ++++++++++++---------- meson.build | 1 + src/evdev.c | 61 ++---- src/evdev.h | 2 +- src/filter-trackpoint.c | 33 +-- src/filter.h | 2 +- src/libinput-util.h | 1 - src/quirks.c | 9 + src/quirks.h | 1 + tools/shared.c | 6 + 12 files changed, 320 insertions(+), 173 deletions(-) create mode 100644 doc/svg/trackpoint-delta-illustration.svg diff --git a/doc/pointer-acceleration.dox b/doc/pointer-acceleration.dox index 63b742ce..1d93dbdc 100644 --- a/doc/pointer-acceleration.dox +++ b/doc/pointer-acceleration.dox @@ -124,6 +124,9 @@ sensitivity in hardware by modifying a sysfs file on the serio node. A higher sensitivity results in higher deltas, thus changing the definition of what is a unit again. +libinput attempts to normalize unit data to the best of its abilities, see +@ref trackpoint_multiplier. Beyond this, it is not possible to have +consistent behavior across different touchpad devices. @image html ptraccel-trackpoint.svg "Pointer acceleration curves for trackpoints" diff --git a/doc/svg/trackpoint-delta-illustration.svg b/doc/svg/trackpoint-delta-illustration.svg new file mode 100644 index 00000000..8423dfa2 --- /dev/null +++ b/doc/svg/trackpoint-delta-illustration.svg @@ -0,0 +1,126 @@ + + + +Gnuplot +Produced by GNUPLOT 5.0 patchlevel 6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + minimum possible interval + + + delta is 1 + + + + + + + + + + + physical pressure + + + + + time between events + + + + + time between events + + + + + + (x, y) delta values + + + (x, y) delta values + + + + + + + + + + + + + + + + + diff --git a/doc/trackpoints.dox b/doc/trackpoints.dox index 5cdc64d2..8bd6c680 100644 --- a/doc/trackpoints.dox +++ b/doc/trackpoints.dox @@ -26,128 +26,144 @@ multiple laptops. The values provided by a trackpoint are motion deltas, usually corresponding to the pressure applied to the trackstick. For example, pressure towards the -screen on a laptop provides negative y deltas at a fixed rate (e.g. every -10ms). As the pressure increases, the delta increases too. As the pressure -decreases, the delta decreases until it hits the neutral state. +screen on a laptop provides negative y deltas. The reporting rate increases +as the pressure increases and once events are reported at the maximum rate, +the delta values increase. The figure below shows a rough illustration of +this concept. As the pressure +decreases, the delta decrease first, then the reporting rate until the +trackpoint is in a neutral state and no events are reported. Trackpoint data +is hart to generalize, see + +Observations on trackpoint input data for more details. + +@image html trackpoint-delta-illustration.svg Illustration of the relationship between reporting rate and delta values on a trackpoint The delta range itself can vary greatly between laptops, some devices send a -maximum delta value of 30, others can go beyond 100. To normalize the motion -trackpoint, libinput uses the available delta range and fits its -acceleration curve into this range. This requires calibration by the user, -see @ref trackpoint_range_measure. +maximum delta value of 30, others can go beyond 100. However, the useful +delta range is a fraction of the maximum range. It is uncomfortable to exert +sufficient pressure to even get close to the maximum ranges. + +@section trackpoint_multiplier The magic trackpoint multiplier + +To accomodate for the wildly different input data on trackpoint, libinput +uses a multiplier that is applied to input deltas. Trackpoints that send +comparatively high deltas can be "slowed down", trackpoints that send low +deltas can be "sped up" to match the expected range. The actual acceleration +profile is applied to these pre-multiplied deltas. + +Given a trackpoint delta (dx, dy), a multiplier M and a pointer acceleration +function f(dx, dy) → (dx', dy'), the algorithm is effectively: +@verbatim +f(M * dx, M * dy) → (dx', dy') +@endverbatim + +The magic trackpoint multiplier **is not user visible configuration**. It is +part of the @ref device-quirks system and provided once per device. +User-specific preferences can be adjusted with the pointer acceleration speed +setting libinput_device_config_accel_set_speed(). + +@subsection trackpoint_multiplier_adjustment Adjusting the magic trackpoint multiplier + +This section only applies if: +- the trackpoint default speed (speed setting 0) is unusably slow or + unusably fast, **and** +- the lowest speed setting (-1) is still too fast **or** the highest speed + setting is still too slow, **and** +- the @ref device-quirks for this device do not list a trackpoint multiplier + (see @ref device-quirks-debugging) + +If the only satisfactory speed settings are less than -0.75 or greater than +0.75, a multiplier *may* be required. + +A specific multiplier will apply to **all users with the same laptop +model**, so proceed with caution. You must be capable/willing to adjust +device quirks, build libinput from source and restart the session frequently +to adjust the multiplier. If this does not apply, wait for someone else with +the same hardware to do this. + +Finding the correct multiplier is difficult and requires some trial and +error. The default multiplier is always 1.0. A value between 0.0 and 1.0 +slows the trackpoint down, a value above 1.0 speeds the trackpoint up. +Values below zero are invalid. + +@note The multiplier is not a configuration to adjust to personal +preferences. The multiplier normalizes the input data into a range that can +then be configured with the speed setting. + +To adjust the local multiplier, first @ref building_libinput +"build libinput from git master". It is not required to install libinput +from git. The below assumes that all @ref building_dependencies are already +installed. + +@verbatim +$ cd path/to/libinput.git + +# Use an approximate multiplier in the quirks file +$ cat > data/99-trackpont-override.quirks <estimate the appropriate trackpoint range. For example, let's look at -the histogram below: - -@verbatim -Histogram for x axis deltas, in counts of 5 - -30: - -29: - -28: + - -27: + - -26: ++ - -25: ++++ - -24: +++++ - -23: ++ - -22: ++++++ - -21: +++ - -20: ++++ - -19: +++++++ - -18: ++++++++++++ - -17: ++++++++++++ - -16: ++++++++++++ - -15: ++++ - -14: +++++ - -13: +++++ - -12: ++++++ - -11: +++++ - -10: +++ - -9: ++++ - -8: +++++++ - -7: +++++++ - -6: ++++++++++++ - -5: ++++++++++++ - -4: ++++++++++++ - -3: +++++++++ - -2: +++++++++ - -1: ++++++++ - 0: +++++++ - 1: +++++ - 2: +++++ - 3: ++++++ - 4: ++++++ - 5: +++++++ - 6: ++++ - 7: ++ - 8: +++ - 9: +++ - 10: +++ - 11: +++ - 12: +++ - 13: ++++ - 14: ++++++ - 15: ++++ - 16: ++++ - 17: ++++ - 18: ++++++ - 19: +++++++ - 20: ++++ - 21: ++++++ - 22: ++++++ - 23: ++++++ - 24: ++++++ - 25: +++++++++ - 26: +++++++ - 27: ++++++++ - 28: +++++ - 29: ++ - 30: ++ - 31: + - 32: - 33: - 34: -@endverbatim - -The 0 delta is the neutral state, each + represents 5 events with that -delta value. Note how the curve is distributed, it's not a classic bell -curve. That can be a factor of the input provided or the firmware-based -pointer acceleration. - -Overall, the majority of events appear to be in the 0-25 range with a few -outliers. So the trackpoint range libinput should use for this particular -device would be 25. Note how there is a fair bit of guesswork involved, a -trackpoint's data is never clean enough to get a definitive value. It is -generally better to take a (slightly) smaller range than one too large. - -The device quirk set is `AttrTrackpointRange=25`. See @ref -device-quirks for details on how to apply device quirks. +If using libinput version 1.11.x or earlier, please see + +the 1.11.0 documentation */ diff --git a/meson.build b/meson.build index 7d21f364..5d146a62 100644 --- a/meson.build +++ b/meson.build @@ -421,6 +421,7 @@ if get_option('documentation') 'doc/svg/thumb-detection.svg', 'doc/svg/top-software-buttons.svg', 'doc/svg/touchscreen-gestures.svg', + 'doc/svg/trackpoint-delta-illustration.svg', 'doc/svg/twofinger-scrolling.svg', # style files 'doc/style/header.html', diff --git a/src/evdev.c b/src/evdev.c index 9fb11d83..2b729342 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -956,7 +956,7 @@ evdev_init_accel(struct evdev_device *device, if (which == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) filter = create_pointer_accelerator_filter_flat(device->dpi); else if (device->tags & EVDEV_TAG_TRACKPOINT) - filter = create_pointer_accelerator_filter_trackpoint(device->trackpoint_range); + filter = create_pointer_accelerator_filter_trackpoint(device->trackpoint_multiplier); else if (device->dpi < DEFAULT_MOUSE_DPI) filter = create_pointer_accelerator_filter_linear_low_dpi(device->dpi); else @@ -1176,59 +1176,36 @@ evdev_read_wheel_tilt_props(struct evdev_device *device) return flags; } -static inline int -evdev_get_trackpoint_range(struct evdev_device *device) +static inline double +evdev_get_trackpoint_multiplier(struct evdev_device *device) { struct quirks_context *quirks; struct quirks *q; - const char *prop; - uint32_t range = DEFAULT_TRACKPOINT_RANGE; + double multiplier = 1.0; if (!(device->tags & EVDEV_TAG_TRACKPOINT)) - return DEFAULT_TRACKPOINT_RANGE; + return 1.0; quirks = evdev_libinput_context(device)->quirks; q = quirks_fetch_for_device(quirks, device->udev_device); - if (q && quirks_get_uint32(q, QUIRK_ATTR_TRACKPOINT_RANGE, &range)) { - goto out; + if (q) { + quirks_get_double(q, QUIRK_ATTR_TRACKPOINT_MULTIPLIER, &multiplier); + quirks_unref(q); } - evdev_log_info(device, - "trackpoint does not have a specified range, " - "guessing... see %strackpoints.html\n", - HTTP_DOC_LINK); - - prop = udev_device_get_property_value(device->udev_device, - "POINTINGSTICK_SENSITIVITY"); - if (prop) { - int sensitivity; - - if (!safe_atoi(prop, &sensitivity) || - (sensitivity < 0.0 || sensitivity > 255)) { - evdev_log_error(device, - "trackpoint sensitivity property is present but invalid, " - "using %d instead\n", - DEFAULT_TRACKPOINT_SENSITIVITY); - sensitivity = DEFAULT_TRACKPOINT_SENSITIVITY; - } - range = 1.0 * DEFAULT_TRACKPOINT_RANGE * - sensitivity/DEFAULT_TRACKPOINT_SENSITIVITY; - - evdev_log_debug(device, - "trackpoint udev sensitivity is %d\n", - sensitivity); + if (multiplier <= 0.0) { + evdev_log_bug_libinput(device, + "trackpoint multiplier %.2f is invalid\n", + multiplier); + multiplier = 1.0; } -out: - quirks_unref(q); + if (multiplier != 1.0) + evdev_log_info(device, + "trackpoint device set to range %.2f\n", + multiplier); - if (range == 0) { - evdev_log_bug_libinput(device, "trackpoint range is zero\n"); - range = DEFAULT_TRACKPOINT_RANGE; - } - - evdev_log_info(device, "trackpoint device set to range %d\n", range); - return range; + return multiplier; } static inline int @@ -1749,7 +1726,7 @@ evdev_configure_device(struct evdev_device *device) evdev_tag_external_mouse(device, device->udev_device); evdev_tag_trackpoint(device, device->udev_device); device->dpi = evdev_read_dpi_prop(device); - device->trackpoint_range = evdev_get_trackpoint_range(device); + device->trackpoint_multiplier = evdev_get_trackpoint_multiplier(device); device->seat_caps |= EVDEV_DEVICE_POINTER; diff --git a/src/evdev.h b/src/evdev.h index 82094824..3757dff3 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -189,7 +189,7 @@ struct evdev_device { bool is_mt; bool is_suspended; int dpi; /* HW resolution */ - int trackpoint_range; /* trackpoint max delta */ + double trackpoint_multiplier; /* trackpoint constant multiplier */ struct ratelimit syn_drop_limit; /* ratelimit for SYN_DROPPED logging */ struct ratelimit nonpointer_rel_limit; /* ratelimit for REL_* events from non-pointer devices */ uint32_t model_flags; diff --git a/src/filter-trackpoint.c b/src/filter-trackpoint.c index ebc7ee12..1b926268 100644 --- a/src/filter-trackpoint.c +++ b/src/filter-trackpoint.c @@ -41,6 +41,8 @@ struct trackpoint_accelerator { struct pointer_trackers trackers; double speed_factor; + + double multiplier; }; double @@ -76,16 +78,20 @@ trackpoint_accelerator_filter(struct motion_filter *filter, { struct trackpoint_accelerator *accel_filter = (struct trackpoint_accelerator *)filter; + struct device_float_coords multiplied; struct normalized_coords coords; double f; double velocity; - trackers_feed(&accel_filter->trackers, unaccelerated, time); + multiplied.x = unaccelerated->x * accel_filter->multiplier; + multiplied.y = unaccelerated->y * accel_filter->multiplier; + + trackers_feed(&accel_filter->trackers, &multiplied, time); velocity = trackers_velocity(&accel_filter->trackers, time); f = trackpoint_accel_profile(filter, data, velocity, time); - coords.x = unaccelerated->x * f; - coords.y = unaccelerated->y * f; + coords.x = multiplied.x * f; + coords.y = multiplied.y * f; return coords; } @@ -95,11 +101,12 @@ trackpoint_accelerator_filter_noop(struct motion_filter *filter, const struct device_float_coords *unaccelerated, void *data, uint64_t time) { - + struct trackpoint_accelerator *accel_filter = + (struct trackpoint_accelerator *)filter; struct normalized_coords coords; - coords.x = unaccelerated->x; - coords.y = unaccelerated->y; + coords.x = unaccelerated->x * accel_filter->multiplier; + coords.y = unaccelerated->y * accel_filter->multiplier; return coords; } @@ -175,27 +182,29 @@ struct motion_filter_interface accelerator_interface_trackpoint = { }; struct motion_filter * -create_pointer_accelerator_filter_trackpoint(int max_hw_delta) +create_pointer_accelerator_filter_trackpoint(double multiplier) { struct trackpoint_accelerator *filter; + assert(multiplier > 0.0); + /* Trackpoints are special. They don't have a movement speed like a * mouse or a finger, instead they send a stream of events based on * the pressure applied. * * Physical ranges on a trackpoint are the max values for relative - * deltas, but these are highly device-specific. + * deltas, but these are highly device-specific and unreliable to + * measure. * + * Instead, we just have a constant multiplier we have in the quirks + * system. */ filter = zalloc(sizeof *filter); if (!filter) return NULL; - /* FIXME: should figure out something here to deal with the - * trackpoint range/max hw delta. Or we just make it a literal - * "magic" number and live with it. - */ + filter->multiplier = multiplier; trackers_init(&filter->trackers); diff --git a/src/filter.h b/src/filter.h index 3865b819..7e001d2f 100644 --- a/src/filter.h +++ b/src/filter.h @@ -122,7 +122,7 @@ struct motion_filter * create_pointer_accelerator_filter_lenovo_x230(int dpi); struct motion_filter * -create_pointer_accelerator_filter_trackpoint(int max_delta); +create_pointer_accelerator_filter_trackpoint(double multiplier); struct motion_filter * create_pointer_accelerator_filter_tablet(int xres, int yres); diff --git a/src/libinput-util.h b/src/libinput-util.h index fadf11c2..c68b888a 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -54,7 +54,6 @@ /* The HW DPI rate we normalize to before calculating pointer acceleration */ #define DEFAULT_MOUSE_DPI 1000 -#define DEFAULT_TRACKPOINT_RANGE 20 #define DEFAULT_TRACKPOINT_SENSITIVITY 128 #define ANSI_HIGHLIGHT "\x1B[0;1;39m" diff --git a/src/quirks.c b/src/quirks.c index 8d0d6847..76639f05 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -265,6 +265,7 @@ quirk_get_name(enum quirk q) case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD: return "AttrPalmPressureThreshold"; case QUIRK_ATTR_RESOLUTION_HINT: return "AttrResolutionHint"; case QUIRK_ATTR_TRACKPOINT_RANGE: return "AttrTrackpointRange"; + case QUIRK_ATTR_TRACKPOINT_MULTIPLIER: return "AttrTrackpointMultiplier"; case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD: return "AttrThumbPressureThreshold"; default: abort(); @@ -642,6 +643,7 @@ parse_attr(struct quirks_context *ctx, struct quirk_dimensions dim; struct quirk_range range; unsigned int v; + double d; if (streq(key, quirk_get_name(QUIRK_ATTR_SIZE_HINT))) { p->id = QUIRK_ATTR_SIZE_HINT; @@ -714,6 +716,13 @@ parse_attr(struct quirks_context *ctx, p->type = PT_UINT; p->value.u = v; rc = true; + } else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_MULTIPLIER))) { + p->id = QUIRK_ATTR_TRACKPOINT_MULTIPLIER; + if (!safe_atod(value, &d)) + goto out; + p->type = PT_DOUBLE; + p->value.d = d; + rc = true; } else if (streq(key, quirk_get_name(QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD))) { p->id = QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD; if (!safe_atou(value, &v)) diff --git a/src/quirks.h b/src/quirks.h index df8b7dd3..e10c3ed1 100644 --- a/src/quirks.h +++ b/src/quirks.h @@ -94,6 +94,7 @@ enum quirk { QUIRK_ATTR_PALM_PRESSURE_THRESHOLD, QUIRK_ATTR_RESOLUTION_HINT, QUIRK_ATTR_TRACKPOINT_RANGE, + QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, }; diff --git a/tools/shared.c b/tools/shared.c index fa03cc75..92c362b8 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -616,6 +616,7 @@ tools_list_device_quirks(struct quirks_context *ctx, QUIRK_ATTR_PALM_PRESSURE_THRESHOLD, QUIRK_ATTR_RESOLUTION_HINT, QUIRK_ATTR_TRACKPOINT_RANGE, + QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, }; enum quirk *q; @@ -696,6 +697,11 @@ tools_list_device_quirks(struct quirks_context *ctx, snprintf(buf, sizeof(buf), "%s=%s", name, s); callback(userdata, buf); break; + case QUIRK_ATTR_TRACKPOINT_MULTIPLIER: + quirks_get_double(quirks, *q, &d); + snprintf(buf, sizeof(buf), "%s=%0.2f\n", name, d); + callback(userdata, buf); + break; } } From a857b399f2ce38060a4d0acf753738908b3b3203 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 Jul 2018 15:01:18 +1000 Subject: [PATCH 09/12] quirks: remove the trackpoint range quirks entries The only trackpoint where I have a rough idea what we need is the ALPS v8 one. All other ones we'll have to re-do. Signed-off-by: Peter Hutterer --- data/30-vendor-alps.quirks | 2 +- data/50-system-lenovo.quirks | 20 -------------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/data/30-vendor-alps.quirks b/data/30-vendor-alps.quirks index 2f020d1e..e4e5d47e 100644 --- a/data/30-vendor-alps.quirks +++ b/data/30-vendor-alps.quirks @@ -33,4 +33,4 @@ MatchBus=ps2 MatchVendor=0x0002 MatchProduct=0x0008 MatchVersion=0x0800 -AttrTrackpointRange=160 +AttrTrackpointMultiplier=0.125 diff --git a/data/50-system-lenovo.quirks b/data/50-system-lenovo.quirks index 18a1adee..7f50d167 100644 --- a/data/50-system-lenovo.quirks +++ b/data/50-system-lenovo.quirks @@ -20,21 +20,6 @@ MatchName=Synaptics tm2964-001 MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p* ModelLenovoT450Touchpad=1 -[Lenovo T440s Trackpoint] -MatchName=TPPS/2 IBM TrackPoint -MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440s* -AttrTrackpointRange=30 - -[Lenovo T440s Trackpoint] -MatchName=TPPS/2 IBM TrackPoint -MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT450s* -AttrTrackpointRange=50 - -[Lenovo X270 Trackpoint] -MatchName=TPPS/2 IBM TrackPoint -MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX270* -AttrTrackpointRange=40 - [Lenovo P50 Touchpad] MatchName=SynPS/2 Synaptics TouchPad MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadP50*: @@ -66,11 +51,6 @@ MatchVendor=0x17EF MatchProduct=0x6047 AttrKeyboardIntegration=external -[Lenovo X280 Trackpoint] -MatchName=*ALPS TrackPoint* -MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadX280:* -AttrTrackpointRange=70 - # Lenovo Thinkpad Yoga (not the consumer versions) disables the keyboard # mechanically. We must not disable the keyboard because some keys are # still accessible on the screen and volume rocker. From f4dc296247f887414c6fa3b6e2c353c02001cea4 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 Jul 2018 15:04:25 +1000 Subject: [PATCH 10/12] quirks: remove the leftovers of the trackpoint range attribute Signed-off-by: Peter Hutterer --- src/quirks.c | 8 -------- src/quirks.h | 1 - tools/shared.c | 2 -- 3 files changed, 11 deletions(-) diff --git a/src/quirks.c b/src/quirks.c index 76639f05..951c76bc 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -264,7 +264,6 @@ quirk_get_name(enum quirk q) case QUIRK_ATTR_PRESSURE_RANGE: return "AttrPressureRange"; case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD: return "AttrPalmPressureThreshold"; case QUIRK_ATTR_RESOLUTION_HINT: return "AttrResolutionHint"; - case QUIRK_ATTR_TRACKPOINT_RANGE: return "AttrTrackpointRange"; case QUIRK_ATTR_TRACKPOINT_MULTIPLIER: return "AttrTrackpointMultiplier"; case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD: return "AttrThumbPressureThreshold"; default: @@ -709,13 +708,6 @@ parse_attr(struct quirks_context *ctx, p->type = PT_DIMENSION; p->value.dim = dim; rc = true; - } else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_RANGE))) { - p->id = QUIRK_ATTR_TRACKPOINT_RANGE; - if (!safe_atou(value, &v)) - goto out; - p->type = PT_UINT; - p->value.u = v; - rc = true; } else if (streq(key, quirk_get_name(QUIRK_ATTR_TRACKPOINT_MULTIPLIER))) { p->id = QUIRK_ATTR_TRACKPOINT_MULTIPLIER; if (!safe_atod(value, &d)) diff --git a/src/quirks.h b/src/quirks.h index e10c3ed1..c5d38b24 100644 --- a/src/quirks.h +++ b/src/quirks.h @@ -93,7 +93,6 @@ enum quirk { QUIRK_ATTR_PRESSURE_RANGE, QUIRK_ATTR_PALM_PRESSURE_THRESHOLD, QUIRK_ATTR_RESOLUTION_HINT, - QUIRK_ATTR_TRACKPOINT_RANGE, QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, }; diff --git a/tools/shared.c b/tools/shared.c index 92c362b8..b2f895cb 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -615,7 +615,6 @@ tools_list_device_quirks(struct quirks_context *ctx, QUIRK_ATTR_PRESSURE_RANGE, QUIRK_ATTR_PALM_PRESSURE_THRESHOLD, QUIRK_ATTR_RESOLUTION_HINT, - QUIRK_ATTR_TRACKPOINT_RANGE, QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, }; @@ -684,7 +683,6 @@ tools_list_device_quirks(struct quirks_context *ctx, break; case QUIRK_ATTR_PALM_SIZE_THRESHOLD: case QUIRK_ATTR_PALM_PRESSURE_THRESHOLD: - case QUIRK_ATTR_TRACKPOINT_RANGE: case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD: quirks_get_uint32(quirks, *q, &v); snprintf(buf, sizeof(buf), "%s=%u", name, v); From 210813f3a8bb04482b16414da9d592795c5aa12f Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 Jul 2018 16:34:22 +1000 Subject: [PATCH 11/12] quirks: append "Touchpad" to the various dell touchpad quirks Signed-off-by: Peter Hutterer --- data/50-system-dell.quirks | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/50-system-dell.quirks b/data/50-system-dell.quirks index c3026495..2457c943 100644 --- a/data/50-system-dell.quirks +++ b/data/50-system-dell.quirks @@ -5,18 +5,18 @@ MatchName=* Touchpad MatchDMIModalias=dmi:*svnDellInc.:* ModelTouchpadVisibleMarker=1 -[Dell Lattitude E6220] +[Dell Lattitude E6220 Touchpad] MatchName=*AlpsPS/2 ALPS GlidePoint MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6220:* AttrPressureRange=100:90 -[Dell XPS L322X] +[Dell XPS L322X Touchpad] MatchName=*CyPS/2 Cypress Trackpad MatchDMIModalias=dmi:*svnDell*:XPSL322X* AttrPressureRange=32:20 AttrPalmPressureThreshold=254 -[Dell XPS13 9333] +[Dell XPS13 9333 Touchpad] MatchName=*Synaptics s3203 MatchDMIModalias=dmi:*svnDellInc.:*pnXPS139333* AttrPressureRange=15:10 From 43cd2cbf83e0f94c8a087300987d1e187890accf Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 11 Jul 2018 16:34:57 +1000 Subject: [PATCH 12/12] data: add the dell trackpoint multipliers From systemd's hwdb/70-pointingstick.hwdb Signed-off-by: Peter Hutterer --- data/50-system-dell.quirks | 25 +++++++++++++++++++++++++ data/50-system-lenovo.quirks | 16 ++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/data/50-system-dell.quirks b/data/50-system-dell.quirks index 2457c943..7e873edf 100644 --- a/data/50-system-dell.quirks +++ b/data/50-system-dell.quirks @@ -21,3 +21,28 @@ MatchName=*Synaptics s3203 MatchDMIModalias=dmi:*svnDellInc.:*pnXPS139333* AttrPressureRange=15:10 AttrPalmPressureThreshold=150 + +[Dell Latitude D620 Trackpoint] +MatchName=*DualPoint Stick +MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeD620* +AttrTrackpointMultiplier=0.5 + +[Latitude E5570 Trackpoint] +MatchName=*DualPoint Stick +MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE5570* +AttrTrackpointMultiplier=0.1 + +[Latitude E6320 Trackpoint] +MatchName=*DualPoint Stick +MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6320* +AttrTrackpointMultiplier=2.0 + +[Latitude E6400 Trackpoint] +MatchName=*DualPoint Stick +MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE6400* +AttrTrackpointMultiplier=1.5 + +[Latitude E7470 Trackpoint] +MatchName=*DualPoint Stick +MatchDMIModalias=dmi:*svnDellInc.:pnLatitudeE7470* +AttrTrackpointMultiplier=0.6 diff --git a/data/50-system-lenovo.quirks b/data/50-system-lenovo.quirks index 7f50d167..0969869a 100644 --- a/data/50-system-lenovo.quirks +++ b/data/50-system-lenovo.quirks @@ -20,6 +20,16 @@ MatchName=Synaptics tm2964-001 MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadT440p* ModelLenovoT450Touchpad=1 +[Lenovo X200 Trackpoint] +MatchName=*TPPS/2 IBM TrackPoint +MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX20?:* +AttrTrackpointMultiplier=1.25 + +[Lenovo X200x Trackpoint] +MatchName=*TPPS/2 IBM TrackPoint +MatchDMIModalias=dmi:*svnLENOVO:*pvrThinkPadX20??:* +AttrTrackpointMultiplier=1.25 + [Lenovo P50 Touchpad] MatchName=SynPS/2 Synaptics TouchPad MatchDMIModalias=dmi:*svnLENOVO:*:pvrThinkPadP50*: @@ -70,3 +80,9 @@ ModelLenovoCarbonX16th=1 MatchName=AT Translated Set 2 keyboard MatchDMIModalias=dmi:*svnIBM:*pvrThinkPadX41Tablet:* ModelTabletModeNoSuspend=1 + +[Lenovo UltraNav SK-8845 (USB keyboard) Trackpoint] +MatchBus=usb +MatchVendor=0x06CB +MatchProduct=0x0009 +AttrTrackpointMultiplier=2.5