summaryrefslogtreecommitdiff
path: root/udev
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2018-03-05 13:17:43 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2018-03-09 09:49:54 +1000
commit1523d8bb2e066bec297f7a03ce4a0d8cada8f383 (patch)
tree8e837b19507ab821159e9e2b64ba33a1eafd12af /udev
parent1b64888a2248af2a287365598cf520e4e2be33fd (diff)
downloadlibinput-1523d8bb2e066bec297f7a03ce4a0d8cada8f383.tar.gz
Extract and reset the abs fuzz value for the x/y axes
The kernel fuzz handling is buggy, especially when we want to rely on the fuzz value for our hysteresis. But since this is a hw property and (at least sometimes) set by the driver, we can't make this a pure libinput hwdb set either. So our workaround is: * extract the (non-zero) fuzz into a udev property so we don't lose it * set the fuzz to 0 to disable the in-kernel hysteresis * overwrite our internal absinfo with the property fuzz This way we get to use the hw-specified fuzz without having the kernel muck around with it. We also get to use the EVDEV_ABS_ values in 60-evdev.hwdb to override a driver-set fuzz. Two drawbacks: - we're resetting the kernel fuzz to 0, this affects any other users of the device node. That's probably a minor impact only. - we can only save this in a udev property there's a risk of this information getting lost when playing around with udev rules. That too should be a minor issue. https://bugs.freedesktop.org/show_bug.cgi?id=105303 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'udev')
-rw-r--r--udev/90-libinput-model-quirks.rules.in1
-rw-r--r--udev/libinput-model-quirks.c58
2 files changed, 58 insertions, 1 deletions
diff --git a/udev/90-libinput-model-quirks.rules.in b/udev/90-libinput-model-quirks.rules.in
index e7d56bbe..5ddc0ba4 100644
--- a/udev/90-libinput-model-quirks.rules.in
+++ b/udev/90-libinput-model-quirks.rules.in
@@ -15,7 +15,6 @@ KERNEL!="event*", GOTO="libinput_model_quirks_end"
# First, run the program and import the LIBINPUT_MODEL_FIRMWARE_VERSION
# environment (if any)
KERNELS=="*input*", \
- ENV{ID_INPUT_TOUCHPAD}=="1", \
IMPORT{program}="@UDEV_TEST_PATH@libinput-model-quirks %S%p"
# Second, match on anything with that env set and import from the hwdb
diff --git a/udev/libinput-model-quirks.c b/udev/libinput-model-quirks.c
index 2dc917d5..d1d5a68a 100644
--- a/udev/libinput-model-quirks.c
+++ b/udev/libinput-model-quirks.c
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <libudev.h>
#include <linux/input.h>
+#include <libevdev/libevdev.h>
#include "libinput-util.h"
@@ -107,6 +108,61 @@ handle_touchpad(struct udev_device *device)
handle_touchpad_synaptics(device);
}
+/**
+ * For a non-zero fuzz on the x/y axes, print that fuzz as property and
+ * reset the kernel's fuzz to 0.
+ * https://bugs.freedesktop.org/show_bug.cgi?id=105202
+ */
+static void
+handle_absfuzz(struct udev_device *device)
+{
+ const char *devnode;
+ struct libevdev *evdev = NULL;
+ int fd = -1;
+ int rc;
+ unsigned int *code;
+ unsigned int axes[] = {ABS_X,
+ ABS_Y,
+ ABS_MT_POSITION_X,
+ ABS_MT_POSITION_Y};
+
+ devnode = udev_device_get_devnode(device);
+ if (!devnode)
+ goto out;
+
+ fd = open(devnode, O_RDWR);
+ if (fd == -1 && errno == EACCES)
+ fd = open(devnode, O_RDONLY);
+ if (fd < 0)
+ goto out;
+
+ rc = libevdev_new_from_fd(fd, &evdev);
+ if (rc != 0)
+ goto out;
+
+ if (!libevdev_has_event_type(evdev, EV_ABS))
+ goto out;
+
+ ARRAY_FOR_EACH(axes, code) {
+ struct input_absinfo abs;
+ int fuzz;
+
+ fuzz = libevdev_get_abs_fuzz(evdev, *code);
+ if (!fuzz)
+ continue;
+
+ abs = *libevdev_get_abs_info(evdev, *code);
+ abs.fuzz = 0;
+ libevdev_kernel_set_abs_info(evdev, *code, &abs);
+
+ printf("LIBINPUT_FUZZ_%02x=%d\n", *code, fuzz);
+ }
+
+out:
+ close(fd);
+ libevdev_free(evdev);
+}
+
int main(int argc, char **argv)
{
int rc = 1;
@@ -127,6 +183,8 @@ int main(int argc, char **argv)
if (!device)
goto out;
+ handle_absfuzz(device);
+
if (prop_value(device, "ID_INPUT_TOUCHPAD"))
handle_touchpad(device);