diff options
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | src/evdev-mt-touchpad.c | 76 | ||||
-rw-r--r-- | src/filter-touchpad-flat.c | 125 | ||||
-rw-r--r-- | src/filter.h | 3 | ||||
-rw-r--r-- | test/test-pointer.c | 35 |
5 files changed, 175 insertions, 65 deletions
diff --git a/meson.build b/meson.build index c13052d5..27581b81 100644 --- a/meson.build +++ b/meson.build @@ -289,6 +289,7 @@ src_libfilter = [ 'src/filter-low-dpi.c', 'src/filter-mouse.c', 'src/filter-touchpad.c', + 'src/filter-touchpad-flat.c', 'src/filter-touchpad-x230.c', 'src/filter-tablet.c', 'src/filter-trackpoint.c', diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index f84102fe..cc53a434 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -2917,33 +2917,12 @@ tp_init_slots(struct tp_dispatch *tp, return true; } -static uint32_t -tp_accel_config_get_profiles(struct libinput_device *libinput_device) -{ - return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; -} - static enum libinput_config_status tp_accel_config_set_profile(struct libinput_device *libinput_device, - enum libinput_config_accel_profile profile) -{ - return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; -} - -static enum libinput_config_accel_profile -tp_accel_config_get_profile(struct libinput_device *libinput_device) -{ - return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; -} - -static enum libinput_config_accel_profile -tp_accel_config_get_default_profile(struct libinput_device *libinput_device) -{ - return LIBINPUT_CONFIG_ACCEL_PROFILE_NONE; -} + enum libinput_config_accel_profile profile); static bool -tp_init_accel(struct tp_dispatch *tp) +tp_init_accel(struct tp_dispatch *tp, enum libinput_config_accel_profile which) { struct evdev_device *device = tp->device; int res_x, res_y; @@ -2965,8 +2944,10 @@ tp_init_accel(struct tp_dispatch *tp) tp->accel.y_scale_coeff = (DEFAULT_MOUSE_DPI/25.4) / res_y; tp->accel.xy_scale_coeff = 1.0 * res_x/res_y; - if (evdev_device_has_model_quirk(device, QUIRK_MODEL_LENOVO_X230) || - tp->device->model_flags & EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81) + if (which == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT) + filter = create_pointer_accelerator_filter_touchpad_flat(dpi); + else if (evdev_device_has_model_quirk(device, QUIRK_MODEL_LENOVO_X230) || + tp->device->model_flags & EVDEV_MODEL_LENOVO_X220_TOUCHPAD_FW81) 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(dpi, @@ -2981,16 +2962,49 @@ tp_init_accel(struct tp_dispatch *tp) evdev_device_init_pointer_acceleration(tp->device, filter); - /* we override the profile hooks for accel configuration with hooks - * that don't allow selection of profiles */ - device->pointer.config.get_profiles = tp_accel_config_get_profiles; device->pointer.config.set_profile = tp_accel_config_set_profile; - device->pointer.config.get_profile = tp_accel_config_get_profile; - device->pointer.config.get_default_profile = tp_accel_config_get_default_profile; return true; } +static enum libinput_config_status +tp_accel_config_set_speed(struct libinput_device *device, double speed) +{ + struct evdev_device *dev = evdev_device(device); + + if (!filter_set_speed(dev->pointer.filter, speed)) + return LIBINPUT_CONFIG_STATUS_INVALID; + + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + +static enum libinput_config_status +tp_accel_config_set_profile(struct libinput_device *libinput_device, + enum libinput_config_accel_profile profile) +{ + struct evdev_device *device = evdev_device(libinput_device); + struct tp_dispatch *tp = tp_dispatch(device->dispatch); + struct motion_filter *filter; + double speed; + + filter = device->pointer.filter; + if (filter_get_type(filter) == profile) + return LIBINPUT_CONFIG_STATUS_SUCCESS; + + speed = filter_get_speed(filter); + device->pointer.filter = NULL; + + if (tp_init_accel(tp, profile)) { + tp_accel_config_set_speed(libinput_device, speed); + filter_destroy(filter); + } else { + device->pointer.filter = filter; + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; + } + + return LIBINPUT_CONFIG_STATUS_SUCCESS; +} + static uint32_t tp_scroll_get_methods(struct tp_dispatch *tp) { @@ -3597,7 +3611,7 @@ tp_init(struct tp_dispatch *tp, tp_init_hysteresis(tp); - if (!tp_init_accel(tp)) + if (!tp_init_accel(tp, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE)) return false; tp_init_tap(tp); diff --git a/src/filter-touchpad-flat.c b/src/filter-touchpad-flat.c new file mode 100644 index 00000000..658d5b5d --- /dev/null +++ b/src/filter-touchpad-flat.c @@ -0,0 +1,125 @@ +/* + * Copyright © 2006-2009 Simon Thum + * Copyright © 2012 Jonas Ådahl + * Copyright © 2014-2015 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "filter.h" +#include "libinput-util.h" +#include "filter-private.h" + + +#define TP_MAGIC_SLOWDOWN_FLAT 0.2968 + +struct touchpad_accelerator_flat { + struct motion_filter base; + + double factor; + int dpi; +}; + +static struct normalized_coords +accelerator_filter_touchpad_flat(struct motion_filter *filter, + const struct device_float_coords *unaccelerated, + void *data, uint64_t time) +{ + struct touchpad_accelerator_flat *accel_filter = + (struct touchpad_accelerator_flat *)filter; + double factor; /* unitless factor */ + struct normalized_coords accelerated; + + /* You want flat acceleration, you get flat acceleration for the + * device */ + factor = accel_filter->factor; + accelerated.x = TP_MAGIC_SLOWDOWN_FLAT * factor * unaccelerated->x; + accelerated.y = TP_MAGIC_SLOWDOWN_FLAT * factor * unaccelerated->y; + + return accelerated; +} + +static struct normalized_coords +accelerator_filter_noop_touchpad_flat(struct motion_filter *filter, + const struct device_float_coords *unaccelerated, + void *data, uint64_t time) +{ + struct touchpad_accelerator_flat *accel = + (struct touchpad_accelerator_flat *) filter; + struct normalized_coords normalized; + + normalized = normalize_for_dpi(unaccelerated, accel->dpi); + normalized.x = TP_MAGIC_SLOWDOWN_FLAT * normalized.x; + normalized.y = TP_MAGIC_SLOWDOWN_FLAT * normalized.y; + + return normalized; +} + +static bool +accelerator_set_speed_touchpad_flat(struct motion_filter *filter, + double speed_adjustment) +{ + struct touchpad_accelerator_flat *accel_filter = + (struct touchpad_accelerator_flat *)filter; + + assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0); + + accel_filter->factor = max(0.005, 1 + speed_adjustment); + filter->speed_adjustment = speed_adjustment; + + return true; +} + +static void +accelerator_destroy_touchpad_flat(struct motion_filter *filter) +{ + struct touchpad_accelerator_flat *accel = + (struct touchpad_accelerator_flat *) filter; + + free(accel); +} + +struct motion_filter_interface accelerator_interface_touchpad_flat = { + .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT, + .filter = accelerator_filter_touchpad_flat, + .filter_constant = accelerator_filter_noop_touchpad_flat, + .restart = NULL, + .destroy = accelerator_destroy_touchpad_flat, + .set_speed = accelerator_set_speed_touchpad_flat, +}; + +struct motion_filter * +create_pointer_accelerator_filter_touchpad_flat(int dpi) +{ + struct touchpad_accelerator_flat *filter; + + filter = zalloc(sizeof *filter); + filter->base.interface = &accelerator_interface_touchpad_flat; + filter->dpi = dpi; + + return &filter->base; +} diff --git a/src/filter.h b/src/filter.h index 177acbdb..5c1bdcc8 100644 --- a/src/filter.h +++ b/src/filter.h @@ -120,6 +120,9 @@ create_pointer_accelerator_filter_touchpad(int dpi, bool use_velocity_averaging); struct motion_filter * +create_pointer_accelerator_filter_touchpad_flat(int dpi); + +struct motion_filter * create_pointer_accelerator_filter_lenovo_x230(int dpi, bool use_velocity_averaging); struct motion_filter * diff --git a/test/test-pointer.c b/test/test-pointer.c index 22a8bfb7..aca68446 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -1917,39 +1917,6 @@ START_TEST(pointer_accel_profile_defaults) } END_TEST -START_TEST(pointer_accel_profile_defaults_noprofile) -{ - struct litest_device *dev = litest_current_device(); - struct libinput_device *device = dev->libinput_device; - enum libinput_config_status status; - enum libinput_config_accel_profile profile; - uint32_t profiles; - - ck_assert(libinput_device_config_accel_is_available(device)); - - profile = libinput_device_config_accel_get_default_profile(device); - ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); - - profile = libinput_device_config_accel_get_profile(device); - ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); - - profiles = libinput_device_config_accel_get_profiles(device); - ck_assert_int_eq(profiles, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); - - status = libinput_device_config_accel_set_profile(device, - LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT); - ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); - profile = libinput_device_config_accel_get_profile(device); - ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); - - status = libinput_device_config_accel_set_profile(device, - LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE); - ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED); - profile = libinput_device_config_accel_get_profile(device); - ck_assert_int_eq(profile, LIBINPUT_CONFIG_ACCEL_PROFILE_NONE); -} -END_TEST - START_TEST(pointer_accel_profile_invalid) { struct litest_device *dev = litest_current_device(); @@ -3213,7 +3180,7 @@ TEST_COLLECTION(pointer) litest_add("pointer:accel", pointer_accel_defaults_absolute_relative, LITEST_ABSOLUTE|LITEST_RELATIVE, LITEST_ANY); litest_add("pointer:accel", pointer_accel_direction_change, LITEST_RELATIVE, LITEST_POINTINGSTICK); litest_add("pointer:accel", pointer_accel_profile_defaults, LITEST_RELATIVE, LITEST_TOUCHPAD); - litest_add("pointer:accel", pointer_accel_profile_defaults_noprofile, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("pointer:accel", pointer_accel_profile_defaults, LITEST_TOUCHPAD, LITEST_ANY); litest_add("pointer:accel", pointer_accel_profile_invalid, LITEST_RELATIVE, LITEST_ANY); litest_add("pointer:accel", pointer_accel_profile_noaccel, LITEST_ANY, LITEST_TOUCHPAD|LITEST_RELATIVE|LITEST_TABLET); litest_add("pointer:accel", pointer_accel_profile_flat_motion_relative, LITEST_RELATIVE, LITEST_TOUCHPAD); |