diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 1393c308..291b6322 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -2660,6 +2660,8 @@ tp_init_accel(struct tp_dispatch *tp) struct evdev_device *device = tp->device; int res_x, res_y; struct motion_filter *filter; + int dpi = device->dpi; + bool use_v_avg = device->use_velocity_averaging; res_x = tp->device->abs.absinfo_x->resolution; res_y = tp->device->abs.absinfo_y->resolution; @@ -2677,11 +2679,14 @@ tp_init_accel(struct tp_dispatch *tp) if (tp->device->model_flags & EVDEV_MODEL_LENOVO_X230 || tp->device->model_flags & EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81) - filter = create_pointer_accelerator_filter_lenovo_x230(tp->device->dpi); + filter = create_pointer_accelerator_filter_lenovo_x230(dpi, use_v_avg); else if (libevdev_get_id_bustype(device->evdev) == BUS_BLUETOOTH) - filter = create_pointer_accelerator_filter_touchpad(device->dpi, ms2us(50), ms2us(10)); + filter = create_pointer_accelerator_filter_touchpad(dpi, + ms2us(50), + ms2us(10), + use_v_avg); else - filter = create_pointer_accelerator_filter_touchpad(device->dpi, 0, 0); + filter = create_pointer_accelerator_filter_touchpad(dpi, 0, 0, use_v_avg); if (!filter) return false; diff --git a/src/evdev.c b/src/evdev.c index 806b9a46..93955786 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -956,11 +956,14 @@ 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_multiplier); + filter = create_pointer_accelerator_filter_trackpoint(device->trackpoint_multiplier, + device->use_velocity_averaging); else if (device->dpi < DEFAULT_MOUSE_DPI) - filter = create_pointer_accelerator_filter_linear_low_dpi(device->dpi); + filter = create_pointer_accelerator_filter_linear_low_dpi(device->dpi, + device->use_velocity_averaging); else - filter = create_pointer_accelerator_filter_linear(device->dpi); + filter = create_pointer_accelerator_filter_linear(device->dpi, + device->use_velocity_averaging); if (!filter) return false; @@ -1208,6 +1211,29 @@ evdev_get_trackpoint_multiplier(struct evdev_device *device) return multiplier; } +static inline bool +evdev_need_velocity_averaging(struct evdev_device *device) +{ + struct quirks_context *quirks; + struct quirks *q; + bool use_velocity_averaging = false; /* default off unless we have quirk */ + + quirks = evdev_libinput_context(device)->quirks; + q = quirks_fetch_for_device(quirks, device->udev_device); + if (q) { + quirks_get_bool(q, + QUIRK_ATTR_USE_VELOCITY_AVERAGING, + &use_velocity_averaging); + quirks_unref(q); + } + + if (use_velocity_averaging) + evdev_log_info(device, + "velocity averaging is turned on\n"); + + return use_velocity_averaging; +} + static inline int evdev_read_dpi_prop(struct evdev_device *device) { @@ -1716,6 +1742,8 @@ evdev_configure_device(struct evdev_device *device) if (udev_tags & EVDEV_UDEV_TAG_TOUCHPAD) { if (udev_tags & EVDEV_UDEV_TAG_TABLET) evdev_tag_tablet_touchpad(device); + /* whether velocity should be averaged, false by default */ + device->use_velocity_averaging = evdev_need_velocity_averaging(device); dispatch = evdev_mt_touchpad_create(device); evdev_log_info(device, "device is a touchpad\n"); return dispatch; @@ -1727,6 +1755,8 @@ evdev_configure_device(struct evdev_device *device) evdev_tag_trackpoint(device, device->udev_device); device->dpi = evdev_read_dpi_prop(device); device->trackpoint_multiplier = evdev_get_trackpoint_multiplier(device); + /* whether velocity should be averaged, false by default */ + device->use_velocity_averaging = evdev_need_velocity_averaging(device); device->seat_caps |= EVDEV_DEVICE_POINTER; diff --git a/src/evdev.h b/src/evdev.h index 347086a1..81d9a5f0 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -175,6 +175,7 @@ struct evdev_device { bool is_suspended; int dpi; /* HW resolution */ double trackpoint_multiplier; /* trackpoint constant multiplier */ + bool use_velocity_averaging; /* whether averaging should be applied on velocity calculation */ 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-low-dpi.c b/src/filter-low-dpi.c index 6b017afb..9a39f525 100644 --- a/src/filter-low-dpi.c +++ b/src/filter-low-dpi.c @@ -236,14 +236,14 @@ struct motion_filter_interface accelerator_interface_low_dpi = { }; static struct pointer_accelerator_low_dpi * -create_default_filter(int dpi) +create_default_filter(int dpi, bool use_velocity_averaging) { struct pointer_accelerator_low_dpi *filter; filter = zalloc(sizeof *filter); filter->last_velocity = 0.0; - trackers_init(&filter->trackers); + trackers_init(&filter->trackers, use_velocity_averaging ? 16 : 2); filter->threshold = DEFAULT_THRESHOLD; filter->accel = DEFAULT_ACCELERATION; @@ -254,11 +254,11 @@ create_default_filter(int dpi) } struct motion_filter * -create_pointer_accelerator_filter_linear_low_dpi(int dpi) +create_pointer_accelerator_filter_linear_low_dpi(int dpi, bool use_velocity_averaging) { struct pointer_accelerator_low_dpi *filter; - filter = create_default_filter(dpi); + filter = create_default_filter(dpi, use_velocity_averaging); if (!filter) return NULL; diff --git a/src/filter-mouse.c b/src/filter-mouse.c index 37444869..89c3919b 100644 --- a/src/filter-mouse.c +++ b/src/filter-mouse.c @@ -310,14 +310,14 @@ struct motion_filter_interface accelerator_interface = { }; static struct pointer_accelerator * -create_default_filter(int dpi) +create_default_filter(int dpi, bool use_velocity_averaging) { struct pointer_accelerator *filter; filter = zalloc(sizeof *filter); filter->last_velocity = 0.0; - trackers_init(&filter->trackers); + trackers_init(&filter->trackers, use_velocity_averaging ? 16 : 2); filter->threshold = DEFAULT_THRESHOLD; filter->accel = DEFAULT_ACCELERATION; @@ -328,11 +328,11 @@ create_default_filter(int dpi) } struct motion_filter * -create_pointer_accelerator_filter_linear(int dpi) +create_pointer_accelerator_filter_linear(int dpi, bool use_velocity_averaging) { struct pointer_accelerator *filter; - filter = create_default_filter(dpi); + filter = create_default_filter(dpi, use_velocity_averaging); if (!filter) return NULL; diff --git a/src/filter-private.h b/src/filter-private.h index fa2fea40..b24a5c9a 100644 --- a/src/filter-private.h +++ b/src/filter-private.h @@ -71,7 +71,7 @@ struct pointer_trackers { struct pointer_delta_smoothener *smoothener; }; -void trackers_init(struct pointer_trackers *trackers); +void trackers_init(struct pointer_trackers *trackers, int ntrackers); void trackers_free(struct pointer_trackers *trackers); void diff --git a/src/filter-touchpad-x230.c b/src/filter-touchpad-x230.c index 10bdc1bb..65fae37b 100644 --- a/src/filter-touchpad-x230.c +++ b/src/filter-touchpad-x230.c @@ -331,7 +331,7 @@ struct motion_filter_interface accelerator_interface_x230 = { * Don't touch this. */ struct motion_filter * -create_pointer_accelerator_filter_lenovo_x230(int dpi) +create_pointer_accelerator_filter_lenovo_x230(int dpi, bool use_velocity_averaging) { struct pointer_accelerator_x230 *filter; @@ -340,7 +340,7 @@ create_pointer_accelerator_filter_lenovo_x230(int dpi) filter->profile = touchpad_lenovo_x230_accel_profile; filter->last_velocity = 0.0; - trackers_init(&filter->trackers); + trackers_init(&filter->trackers, use_velocity_averaging ? 16 : 2); filter->threshold = X230_THRESHOLD; filter->accel = X230_ACCELERATION; /* unitless factor */ diff --git a/src/filter-touchpad.c b/src/filter-touchpad.c index cfad1968..9c19527b 100644 --- a/src/filter-touchpad.c +++ b/src/filter-touchpad.c @@ -318,7 +318,8 @@ struct motion_filter_interface accelerator_interface_touchpad = { struct motion_filter * create_pointer_accelerator_filter_touchpad(int dpi, uint64_t event_delta_smooth_threshold, - uint64_t event_delta_smooth_value) + uint64_t event_delta_smooth_value, + bool use_velocity_averaging) { struct touchpad_accelerator *filter; struct pointer_delta_smoothener *smoothener; @@ -326,7 +327,7 @@ create_pointer_accelerator_filter_touchpad(int dpi, filter = zalloc(sizeof *filter); filter->last_velocity = 0.0; - trackers_init(&filter->trackers); + trackers_init(&filter->trackers, use_velocity_averaging ? 16 : 2); filter->threshold = 130; filter->dpi = dpi; diff --git a/src/filter-trackpoint.c b/src/filter-trackpoint.c index a401a712..c85a082a 100644 --- a/src/filter-trackpoint.c +++ b/src/filter-trackpoint.c @@ -182,7 +182,7 @@ struct motion_filter_interface accelerator_interface_trackpoint = { }; struct motion_filter * -create_pointer_accelerator_filter_trackpoint(double multiplier) +create_pointer_accelerator_filter_trackpoint(double multiplier, bool use_velocity_averaging) { struct trackpoint_accelerator *filter; struct pointer_delta_smoothener *smoothener; @@ -207,7 +207,7 @@ create_pointer_accelerator_filter_trackpoint(double multiplier) filter->multiplier = multiplier; - trackers_init(&filter->trackers); + trackers_init(&filter->trackers, use_velocity_averaging ? 16 : 2); filter->base.interface = &accelerator_interface_trackpoint; diff --git a/src/filter.c b/src/filter.c index fe60c62a..ef081dde 100644 --- a/src/filter.c +++ b/src/filter.c @@ -91,10 +91,8 @@ filter_get_type(struct motion_filter *filter) } void -trackers_init(struct pointer_trackers *trackers) +trackers_init(struct pointer_trackers *trackers, int ntrackers) { - const int ntrackers = 16; - trackers->trackers = zalloc(ntrackers * sizeof(*trackers->trackers)); trackers->ntrackers = ntrackers; diff --git a/src/filter.h b/src/filter.h index 7e001d2f..177acbdb 100644 --- a/src/filter.h +++ b/src/filter.h @@ -108,21 +108,22 @@ struct motion_filter * create_pointer_accelerator_filter_flat(int dpi); struct motion_filter * -create_pointer_accelerator_filter_linear(int dpi); +create_pointer_accelerator_filter_linear(int dpi, bool use_velocity_averaging); struct motion_filter * -create_pointer_accelerator_filter_linear_low_dpi(int dpi); +create_pointer_accelerator_filter_linear_low_dpi(int dpi, bool use_velocity_averaging); struct motion_filter * create_pointer_accelerator_filter_touchpad(int dpi, uint64_t event_delta_smooth_threshold, - uint64_t event_delta_smooth_value); + uint64_t event_delta_smooth_value, + bool use_velocity_averaging); struct motion_filter * -create_pointer_accelerator_filter_lenovo_x230(int dpi); +create_pointer_accelerator_filter_lenovo_x230(int dpi, bool use_velocity_averaging); struct motion_filter * -create_pointer_accelerator_filter_trackpoint(double multiplier); +create_pointer_accelerator_filter_trackpoint(double multiplier, bool use_velocity_averaging); struct motion_filter * create_pointer_accelerator_filter_tablet(int xres, int yres); diff --git a/src/quirks.c b/src/quirks.c index 0525e81a..54b207d1 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -267,6 +267,7 @@ quirk_get_name(enum quirk q) case QUIRK_ATTR_RESOLUTION_HINT: return "AttrResolutionHint"; case QUIRK_ATTR_TRACKPOINT_MULTIPLIER: return "AttrTrackpointMultiplier"; case QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD: return "AttrThumbPressureThreshold"; + case QUIRK_ATTR_USE_VELOCITY_AVERAGING: return "AttrUseVelocityAveraging"; default: abort(); } @@ -643,6 +644,7 @@ parse_attr(struct quirks_context *ctx, struct quirk_dimensions dim; struct quirk_range range; unsigned int v; + bool b; double d; if (streq(key, quirk_get_name(QUIRK_ATTR_SIZE_HINT))) { @@ -716,6 +718,17 @@ parse_attr(struct quirks_context *ctx, p->type = PT_DOUBLE; p->value.d = d; rc = true; + } else if (streq(key, quirk_get_name(QUIRK_ATTR_USE_VELOCITY_AVERAGING))) { + p->id = QUIRK_ATTR_USE_VELOCITY_AVERAGING; + if (streq(value, "1")) + b = true; + else if (streq(value, "0")) + b = false; + else + goto out; + p->type = PT_BOOL; + p->value.b = b; + 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 c5d38b24..051ce7b6 100644 --- a/src/quirks.h +++ b/src/quirks.h @@ -95,6 +95,7 @@ enum quirk { QUIRK_ATTR_RESOLUTION_HINT, QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, + QUIRK_ATTR_USE_VELOCITY_AVERAGING, }; /** diff --git a/tools/ptraccel-debug.c b/tools/ptraccel-debug.c index 9a84688a..5e403b66 100644 --- a/tools/ptraccel-debug.c +++ b/tools/ptraccel-debug.c @@ -222,6 +222,7 @@ main(int argc, char **argv) double custom_deltas[1024]; double speed = 0.0; int dpi = 1000; + bool use_averaging = false; const char *filter_type = "linear"; accel_profile_func_t profile = NULL; double tp_multiplier = 1.0; @@ -314,19 +315,25 @@ main(int argc, char **argv) } if (streq(filter_type, "linear")) { - filter = create_pointer_accelerator_filter_linear(dpi); + filter = create_pointer_accelerator_filter_linear(dpi, + use_averaging); profile = pointer_accel_profile_linear; } else if (streq(filter_type, "low-dpi")) { - filter = create_pointer_accelerator_filter_linear_low_dpi(dpi); + filter = create_pointer_accelerator_filter_linear_low_dpi(dpi, + use_averaging); profile = pointer_accel_profile_linear_low_dpi; } else if (streq(filter_type, "touchpad")) { - filter = create_pointer_accelerator_filter_touchpad(dpi, 0, 0); + filter = create_pointer_accelerator_filter_touchpad(dpi, + 0, 0, + use_averaging); profile = touchpad_accel_profile_linear; } else if (streq(filter_type, "x230")) { - filter = create_pointer_accelerator_filter_lenovo_x230(dpi); + filter = create_pointer_accelerator_filter_lenovo_x230(dpi, + use_averaging); profile = touchpad_lenovo_x230_accel_profile; } else if (streq(filter_type, "trackpoint")) { - filter = create_pointer_accelerator_filter_trackpoint(tp_multiplier); + filter = create_pointer_accelerator_filter_trackpoint(tp_multiplier, + use_averaging); profile = trackpoint_accel_profile; } else { fprintf(stderr, "Invalid filter type %s\n", filter_type); diff --git a/tools/shared.c b/tools/shared.c index f68ffead..7b3b8de2 100644 --- a/tools/shared.c +++ b/tools/shared.c @@ -639,6 +639,7 @@ tools_list_device_quirks(struct quirks_context *ctx, QUIRK_ATTR_RESOLUTION_HINT, QUIRK_ATTR_TRACKPOINT_MULTIPLIER, QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD, + QUIRK_ATTR_USE_VELOCITY_AVERAGING, }; enum quirk *q; @@ -722,6 +723,10 @@ tools_list_device_quirks(struct quirks_context *ctx, snprintf(buf, sizeof(buf), "%s=%0.2f\n", name, d); callback(userdata, buf); break; + case QUIRK_ATTR_USE_VELOCITY_AVERAGING: + snprintf(buf, sizeof(buf), "%s=1", name); + callback(userdata, buf); + break; } }