summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2022-09-05 11:33:57 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2022-09-08 09:03:15 +1000
commitad71c74885081a0e9d88953d2237f2a26a6f0ffa (patch)
tree3811408138e7ade8e7c648a7761411ee530861c0
parent7ba0af575bee044145bda280ad2f5d7b1e7af479 (diff)
downloadlibinput-ad71c74885081a0e9d88953d2237f2a26a6f0ffa.tar.gz
filter: add a flat trackpoint accel
Previously, trackpoints got assigned the normal flat profile which does not accommodate for the trackpoint magic multiplier *and* had a config range that was too small if you take the multiplire indo account anyway. Fix this by adding a trackpoint-specific flat accel that has a wider configuration range and take sthe magic multiplier into account. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--meson.build1
-rw-r--r--src/evdev.c26
-rw-r--r--src/filter-trackpoint-flat.c148
-rw-r--r--src/filter.h3
4 files changed, 168 insertions, 10 deletions
diff --git a/meson.build b/meson.build
index 4accfa89..43a124b8 100644
--- a/meson.build
+++ b/meson.build
@@ -300,6 +300,7 @@ src_libfilter = [
'src/filter-touchpad-x230.c',
'src/filter-tablet.c',
'src/filter-trackpoint.c',
+ 'src/filter-trackpoint-flat.c',
]
libfilter = static_library('filter', src_libfilter,
dependencies : [dep_udev, dep_libwacom],
diff --git a/src/evdev.c b/src/evdev.c
index 31b37e5e..426933d1 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -1186,17 +1186,23 @@ static inline bool
evdev_init_accel(struct evdev_device *device,
enum libinput_config_accel_profile which)
{
- struct motion_filter *filter;
+ struct motion_filter *filter = NULL;
- 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,
- device->use_velocity_averaging);
- else if (device->dpi < DEFAULT_MOUSE_DPI)
- filter = create_pointer_accelerator_filter_linear_low_dpi(device->dpi,
- device->use_velocity_averaging);
- else
+ if (device->tags & EVDEV_TAG_TRACKPOINT) {
+ if (which == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT)
+ filter = create_pointer_accelerator_filter_trackpoint_flat(device->trackpoint_multiplier);
+ else
+ filter = create_pointer_accelerator_filter_trackpoint(device->trackpoint_multiplier,
+ device->use_velocity_averaging);
+ } else {
+ if (which == LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT)
+ filter = create_pointer_accelerator_filter_flat(device->dpi);
+ else if (device->dpi < DEFAULT_MOUSE_DPI)
+ filter = create_pointer_accelerator_filter_linear_low_dpi(device->dpi,
+ device->use_velocity_averaging);
+ }
+
+ if (!filter)
filter = create_pointer_accelerator_filter_linear(device->dpi,
device->use_velocity_averaging);
diff --git a/src/filter-trackpoint-flat.c b/src/filter-trackpoint-flat.c
new file mode 100644
index 00000000..d650a667
--- /dev/null
+++ b/src/filter-trackpoint-flat.c
@@ -0,0 +1,148 @@
+/*
+ * 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"
+
+struct trackpoint_flat_accelerator {
+ struct motion_filter base;
+
+ double speed_factor;
+ double multiplier;
+};
+
+static struct normalized_coords
+trackpoint_flat_filter(struct motion_filter *filter,
+ const struct device_float_coords *unaccelerated,
+ void *data, uint64_t time)
+{
+ struct trackpoint_flat_accelerator *accel_filter =
+ (struct trackpoint_flat_accelerator *) filter;
+ struct normalized_coords accelerated;
+
+ double factor = accel_filter->speed_factor;
+ double multiplier = accel_filter->multiplier;
+ accelerated.x = factor * multiplier * unaccelerated->x;
+ accelerated.y = factor * multiplier * unaccelerated->y;
+
+ return accelerated;
+}
+
+static struct normalized_coords
+trackpoint_flat_filter_noop(struct motion_filter *filter,
+ const struct device_float_coords *unaccelerated,
+ void *data, uint64_t time)
+{
+ /* We map the unaccelerated flat filter to have the same behavior as
+ * the "accelerated" flat filter.
+ * The filter by definition is flat, i.e. it does not actually
+ * apply any acceleration (merely a constant factor) and we can assume
+ * that a user wants all mouse movement to have the same speed, mapped
+ * 1:1 to the input speed.
+ *
+ * Thus we apply the same factor to our non-accelerated motion - this way
+ * things like button scrolling end up having the same movement as
+ * pointer motion.
+ */
+ return trackpoint_flat_filter(filter, unaccelerated, data, time);
+}
+
+/* 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_flat_set_speed(struct motion_filter *filter,
+ double speed_adjustment)
+{
+ struct trackpoint_flat_accelerator *accel_filter =
+ (struct trackpoint_flat_accelerator *) filter;
+
+ assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0);
+
+ filter->speed_adjustment = speed_adjustment;
+ accel_filter->speed_factor = speed_factor(speed_adjustment);
+
+
+ return true;
+}
+
+static void
+trackpoint_flat_destroy(struct motion_filter *filter)
+{
+ struct trackpoint_flat_accelerator *accel_filter =
+ (struct trackpoint_flat_accelerator *) filter;
+
+ free(accel_filter);
+}
+
+static struct motion_filter_interface accelerator_interface_flat = {
+ .type = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT,
+ .filter = trackpoint_flat_filter,
+ .filter_constant = trackpoint_flat_filter_noop,
+ .restart = NULL,
+ .destroy = trackpoint_flat_destroy,
+ .set_speed = trackpoint_flat_set_speed,
+};
+
+struct motion_filter *
+create_pointer_accelerator_filter_trackpoint_flat(double multiplier)
+{
+ struct trackpoint_flat_accelerator *filter;
+
+ filter = zalloc(sizeof *filter);
+ filter->base.interface = &accelerator_interface_flat;
+ filter->multiplier = multiplier;
+
+ return &filter->base;
+}
diff --git a/src/filter.h b/src/filter.h
index af987c40..7824fe9b 100644
--- a/src/filter.h
+++ b/src/filter.h
@@ -129,6 +129,9 @@ struct motion_filter *
create_pointer_accelerator_filter_trackpoint(double multiplier, bool use_velocity_averaging);
struct motion_filter *
+create_pointer_accelerator_filter_trackpoint_flat(double multiplier);
+
+struct motion_filter *
create_pointer_accelerator_filter_tablet(int xres, int yres);
/*