configure.ac | 8 - debian/changelog | 7 + debian/upstream/signing-key.asc | 24 +++ debian/watch | 2 doc/Makefile.am | 1 doc/contributing.dox | 18 ++ doc/libinput.doxygen.in | 1 doc/page-hierarchy.dox | 4 doc/pointer-acceleration.dox | 25 +++ doc/reporting-bugs.dox | 113 +++++++++++++++-- src/evdev-mt-touchpad.c | 36 +++-- src/evdev.c | 62 +++++++-- src/evdev.h | 1 src/libinput-private.h | 10 - src/libinput-util.c | 32 ++++ src/libinput-util.h | 1 src/libinput.c | 11 + test/Makefile.am | 1 test/device.c | 34 +++++ test/litest-device-mouse-wheel-click-angle.c | 2 test/litest-device-mouse-wheel-click-count.c | 77 +++++++++++ test/litest.c | 4 test/litest.h | 1 test/misc.c | 31 ++++ test/pointer.c | 49 ++++++- test/touchpad.c | 4 tools/event-debug.c | 2 tools/event-gui.c | 2 tools/shared.c | 1 udev/90-libinput-model-quirks.hwdb | 6 udev/Makefile.am | 7 + udev/parse_hwdb.py | 178 +++++++++++++++++++++++++++ 32 files changed, 695 insertions(+), 60 deletions(-)
New commits: commit 3f84174fce9421ca5ea8893f4bb7d05a72bc5fc8 Author: Timo Aaltonen <tjaal...@debian.org> Date: Fri Nov 18 15:58:30 2016 +0200 release to sid diff --git a/debian/changelog b/debian/changelog index 4273e94..56b32ab 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,9 @@ -libinput (1.5.1-1) UNRELEASED; urgency=medium +libinput (1.5.1-1) unstable; urgency=medium * New upstream release. * watch: Let uscan verify tarball signatures. - -- Timo Aaltonen <tjaal...@debian.org> Fri, 18 Nov 2016 15:32:58 +0200 + -- Timo Aaltonen <tjaal...@debian.org> Fri, 18 Nov 2016 15:58:09 +0200 libinput (1.5.0-1) unstable; urgency=medium commit 859fb9a5c5e91f8d01eb3d8f095bb52b2350b80c Author: Timo Aaltonen <tjaal...@debian.org> Date: Fri Nov 18 15:36:29 2016 +0200 watch: Let uscan verify tarball signatures. diff --git a/debian/changelog b/debian/changelog index 5ccb4fb..4273e94 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ libinput (1.5.1-1) UNRELEASED; urgency=medium * New upstream release. + * watch: Let uscan verify tarball signatures. -- Timo Aaltonen <tjaal...@debian.org> Fri, 18 Nov 2016 15:32:58 +0200 diff --git a/debian/upstream/signing-key.asc b/debian/upstream/signing-key.asc new file mode 100644 index 0000000..a141a05 --- /dev/null +++ b/debian/upstream/signing-key.asc @@ -0,0 +1,24 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1 + +mQGiBD8b0wYRBACph9kRJmP+4+JGsCgFlFoy4vFO0DCG+jmkQN0n1wdInt/N/UtA +sZToO72AUmfmYizA+IEbzBrx0UnUo3w3BDmHxUWf/akZiPUz9AA/YFY4xC3MY2OK +VN2Jz6YSce4zJ5jd2ZRobHm4HuIf/8yqSCcsv7FNfrLaTNIFRs5gYYsqZwCgwmkp +RSLRc8WAnHrTWNQDaEFM2rUEAKTjrTjMN8+KGd0BxNX7HiTSqQP++nXNwAYs1oWB +Yt82YHj9SvRCqCzD1pzJQivYnlNoWDza1VeMnfdAvkdia8z4lYbO/RunXZJvra3Z +VDm+izq+uwUAyvFuEYnNz09VSqwXKT6+XW0Xtz2vHq52r6DS6mK8cGJHZ5OhrRjq +UEYxA/9STh+QfA98xtNoRcf52E/46r7IpCj440oRVc9lMfxQZrLGQNqp7sPdIhGQ +CCo2NUII5hkhdAG71kpbfSXU4Sh32p1cU1KYCAkDFfb49bKuAs+Pff8v6FGZxTdd +AinPZr4BbsYJatk818aTCnu0+s7L8jL5GPfeyuyEMKwzVBx2mLQpUGV0ZXIgSHV0 +dGVyZXIgKFdoby1UKSA8b2ZmaWNlQHdoby10Lm5ldD6IWQQTEQIAGQUCPxvTBgQL +BwMCAxUCAwMWAgECHgECF4AACgkQ4jt+cLRn8L/0RACfWo3KTMUg+uPRqA6RXxk0 +4CWjXaMAoJeIxOpZLB3RBltPnSi7PyVQIkHFuQENBD8b0wgQBACTnqOYOWYVR8O1 +D73J6nbdAeZCbXrUkyXIuyqBOdKmX/0QJmSs7Wfsa+hPfDhj6ai0Gs2C8Qg/0Pzk +86b4p9DLkf0M6RaYjUtCJBpS59xrsV6nz6xZzQa4RRdf1YJmw2tia1MMXzxbwQU2 +bKpYEm8NsGaBURMGd02EvsMN2wI2uwADBQP/e9MjVr/85XDzAlUBN8HwYW5szTyP +8ZVcQOqOmNebkTWGLvkPrBdXmxpzrWjxPolO1WcWQjUL0bN/rbdqefT65iVHJHJZ +/cpTtgGlCPhL5JTA50ltd0I13CABYWLFmswonXES/6tcglf4rr3Nri2sOrY5HggP +ipEzOo5vdKOow/qIRgQYEQIABgUCPxvTCAAKCRDiO35wtGfwv68jAKCDvL2gkrg1 +4NfV7rNc057K1nL2GgCeKApWRgGVzaOkAp0P5tQulaDD6zM= +=7uBX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/debian/watch b/debian/watch index 7a6dd67..2992083 100644 --- a/debian/watch +++ b/debian/watch @@ -1,4 +1,4 @@ #git=git://anongit.freedesktop.org/wayland/libinput version=3 -opts=dversionmangle=s/\+dfsg\d*$// \ +opts=pgpsigurlmangle=s/$/.sig/,dversionmangle=s/\+dfsg\d*$// \ http://www.freedesktop.org/software/libinput/libinput-(.*)\.tar\.xz commit ae4329e420b7a2c55613b440c541f3a516488ce0 Author: Timo Aaltonen <tjaal...@debian.org> Date: Fri Nov 18 15:33:21 2016 +0200 update changelog diff --git a/debian/changelog b/debian/changelog index 2377954..5ccb4fb 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libinput (1.5.1-1) UNRELEASED; urgency=medium + + * New upstream release. + + -- Timo Aaltonen <tjaal...@debian.org> Fri, 18 Nov 2016 15:32:58 +0200 + libinput (1.5.0-1) unstable; urgency=medium * New upstream release. commit 8616cc0bb9d483a8ef5955e1880e78f00a8f4746 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Fri Nov 11 13:49:27 2016 +1000 configure.ac: libinput 1.5.1 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/configure.ac b/configure.ac index 0ae9b76..43db9bb 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.64]) m4_define([libinput_major_version], [1]) m4_define([libinput_minor_version], [5]) -m4_define([libinput_micro_version], [0]) +m4_define([libinput_micro_version], [1]) m4_define([libinput_version], [libinput_major_version.libinput_minor_version.libinput_micro_version]) @@ -35,7 +35,7 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) # b) If interfaces have been changed or added, but binary compatibility has # been preserved, change to C+1:0:A+1 # c) If the interface is the same as the previous version, change to C:R+1:A -LIBINPUT_LT_VERSION=20:1:10 +LIBINPUT_LT_VERSION=20:2:10 AC_SUBST(LIBINPUT_LT_VERSION) AM_SILENT_RULES([yes]) commit 92c30b5a7188e5ec94eb4ebbc7b9a1523c67d341 Author: Hermann Gausterer <git-libinput-2...@mrq1.org> Date: Wed Nov 9 16:58:07 2016 +0100 evdev: fix typo / bugzilla url Signed-off-by: Hermann Gausterer <git-libinput-2...@mrq1.org> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/src/evdev.c b/src/evdev.c index d04636f..fac8fcb 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -2749,7 +2749,7 @@ evdev_pre_configure_model_quirks(struct evdev_device *device) /* Claims to have double/tripletap but doesn't actually send it * https://bugzilla.redhat.com/show_bug.cgi?id=1351285 and - * https://bugzilla.redhat.com/show_bug.cgi?id=98538 + * https://bugs.freedesktop.org/show_bug.cgi?id=98538 */ if (device->model_flags & (EVDEV_MODEL_HP8510_TOUCHPAD|EVDEV_MODEL_HP6910_TOUCHPAD)) { commit 58c7a9cbf0aaa49b4802f2460acee20e4807dc28 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Fri Oct 28 15:08:32 2016 +1000 evdev: implement support for the MOUSE_WHEEL_CLICK_COUNT property Not all mice have a click angle with integer degrees. The new MOUSE_WHEEL_CLICK_COUNT property specifies how many clicks per full rotation, the angle can be calculated from that. See https://github.com/systemd/systemd/pull/4440 for more information CLICK_COUNT overrides CLICK_ANGLE, so we check for the former first and then fall back to the angle if need be. No changes to the user-facing API. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/src/evdev.c b/src/evdev.c index 2412751..d04636f 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -2008,7 +2008,7 @@ evdev_device_init_pointer_acceleration(struct evdev_device *device, static inline bool evdev_read_wheel_click_prop(struct evdev_device *device, const char *prop, - int *angle) + double *angle) { int val; @@ -2032,18 +2032,53 @@ evdev_read_wheel_click_prop(struct evdev_device *device, return false; } +static inline bool +evdev_read_wheel_click_count_prop(struct evdev_device *device, + const char *prop, + double *angle) +{ + int val; + + prop = udev_device_get_property_value(device->udev_device, prop); + if (!prop) + return false; + + val = parse_mouse_wheel_click_angle_property(prop); + if (val) { + *angle = 360.0/val; + return true; + } + + log_error(evdev_libinput_context(device), + "Mouse wheel click count '%s' is present but invalid, " + "using %d degrees for angle instead instead\n", + device->devname, + DEFAULT_WHEEL_CLICK_ANGLE); + *angle = DEFAULT_WHEEL_CLICK_ANGLE; + + return false; +} + static inline struct wheel_angle evdev_read_wheel_click_props(struct evdev_device *device) { struct wheel_angle angles; - evdev_read_wheel_click_prop(device, - "MOUSE_WHEEL_CLICK_ANGLE", - &angles.x); - if (!evdev_read_wheel_click_prop(device, - "MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL", - &angles.y)) - angles.y = angles.x; + /* CLICK_COUNT overrides CLICK_ANGLE */ + if (!evdev_read_wheel_click_count_prop(device, + "MOUSE_WHEEL_CLICK_COUNT", + &angles.x)) + evdev_read_wheel_click_prop(device, + "MOUSE_WHEEL_CLICK_ANGLE", + &angles.x); + if (!evdev_read_wheel_click_count_prop(device, + "MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL", + &angles.y)) { + if (!evdev_read_wheel_click_prop(device, + "MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL", + &angles.y)) + angles.y = angles.x; + } return angles; } diff --git a/src/libinput-private.h b/src/libinput-private.h index 5b46da7..52f129a 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -73,7 +73,7 @@ struct normalized_range_coords { /* A pair of angles in degrees */ struct wheel_angle { - int x, y; + double x, y; }; /* A pair of angles in degrees */ diff --git a/src/libinput-util.c b/src/libinput-util.c index 4b90fbb..6c051c3 100644 --- a/src/libinput-util.c +++ b/src/libinput-util.c @@ -176,6 +176,38 @@ parse_mouse_dpi_property(const char *prop) } /** + * Helper function to parse the MOUSE_WHEEL_CLICK_COUNT property from udev. + * Property is of the form: + * MOUSE_WHEEL_CLICK_COUNT=<integer> + * Where the number indicates the number of wheel clicks per 360 deg + * rotation. + * + * We skip preceding whitespaces and parse the first number seen. If + * multiple numbers are specified, we ignore those. + * + * @param prop The value of the udev property (without the MOUSE_WHEEL_CLICK_COUNT=) + * @return The click count of the wheel (may be negative) or 0 on error. + */ +int +parse_mouse_wheel_click_count_property(const char *prop) +{ + int count = 0, + nread = 0; + + while(*prop != 0 && *prop == ' ') + prop++; + + sscanf(prop, "%d%n", &count, &nread); + if (nread == 0 || count == 0 || abs(count) > 360) + return 0; + if (prop[nread] != ' ' && prop[nread] != '\0') + return 0; + + return count; +} + +/** + * * Helper function to parse the MOUSE_WHEEL_CLICK_ANGLE property from udev. * Property is of the form: * MOUSE_WHEEL_CLICK_ANGLE=<integer> diff --git a/src/libinput-util.h b/src/libinput-util.h index e31860d..b7bef80 100644 --- a/src/libinput-util.h +++ b/src/libinput-util.h @@ -370,6 +370,7 @@ enum ratelimit_state ratelimit_test(struct ratelimit *r); int parse_mouse_dpi_property(const char *prop); int parse_mouse_wheel_click_angle_property(const char *prop); +int parse_mouse_wheel_click_count_property(const char *prop); double parse_trackpoint_accel_property(const char *prop); bool parse_dimension_property(const char *prop, size_t *width, size_t *height); diff --git a/test/Makefile.am b/test/Makefile.am index 7ff12e4..f4a9252 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -35,6 +35,7 @@ liblitest_la_SOURCES = \ litest-device-mouse-roccat.c \ litest-device-mouse-low-dpi.c \ litest-device-mouse-wheel-click-angle.c \ + litest-device-mouse-wheel-click-count.c \ litest-device-ms-surface-cover.c \ litest-device-protocol-a-touch-screen.c \ litest-device-qemu-usb-tablet.c \ diff --git a/test/litest-device-mouse-wheel-click-count.c b/test/litest-device-mouse-wheel-click-count.c new file mode 100644 index 0000000..419b702 --- /dev/null +++ b/test/litest-device-mouse-wheel-click-count.c @@ -0,0 +1,77 @@ +/* + * Copyright © 2016 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "litest.h" +#include "litest-int.h" + +static void litest_mouse_setup(void) +{ + struct litest_device *d = litest_create_device(LITEST_MOUSE_WHEEL_CLICK_COUNT); + litest_set_current_device(d); +} + +static struct input_id input_id = { + .bustype = 0x3, + .vendor = 0x1234, + .product = 0x5678, +}; + +static int events[] = { + EV_KEY, BTN_LEFT, + EV_KEY, BTN_RIGHT, + EV_KEY, BTN_MIDDLE, + EV_REL, REL_X, + EV_REL, REL_Y, + EV_REL, REL_WHEEL, + -1 , -1, +}; + +static const char udev_rule[] = +"ACTION==\"remove\", GOTO=\"wheel_click_count_end\"\n" +"KERNEL!=\"event*\", GOTO=\"wheel_click_count_end\"\n" +"\n" +"ATTRS{name}==\"litest Wheel Click Count Mouse*\",\\\n" +" ENV{MOUSE_WHEEL_CLICK_ANGLE}=\"-15\",\n" +" ENV{MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL}=\"13\",\n\\" +" ENV{MOUSE_WHEEL_CLICK_COUNT}=\"-14\",\n" +" ENV{MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL}=\"27\"\\\n" +"\n" +"LABEL=\"wheel_click_count_end\""; + +struct litest_test_device litest_mouse_wheel_click_count_device = { + .type = LITEST_MOUSE_WHEEL_CLICK_COUNT, + .features = LITEST_RELATIVE | LITEST_BUTTON | LITEST_WHEEL, + .shortname = "mouse-wheelclickcount", + .setup = litest_mouse_setup, + .interface = NULL, + + .name = "Wheel Click Count Mouse", + .id = &input_id, + .absinfo = NULL, + .events = events, + .udev_rule = udev_rule, +}; diff --git a/test/litest.c b/test/litest.c index fd62d21..515eb18 100644 --- a/test/litest.c +++ b/test/litest.c @@ -402,6 +402,7 @@ extern struct litest_test_device litest_wacom_cintiq_13hdt_finger_device; extern struct litest_test_device litest_wacom_cintiq_13hdt_pen_device; extern struct litest_test_device litest_wacom_cintiq_13hdt_pad_device; extern struct litest_test_device litest_wacom_hid4800_tablet_device; +extern struct litest_test_device litest_mouse_wheel_click_count_device; struct litest_test_device* devices[] = { &litest_synaptics_clickpad_device, @@ -458,6 +459,7 @@ struct litest_test_device* devices[] = { &litest_wacom_cintiq_13hdt_pen_device, &litest_wacom_cintiq_13hdt_pad_device, &litest_wacom_hid4800_tablet_device, + &litest_mouse_wheel_click_count_device, NULL, }; diff --git a/test/litest.h b/test/litest.h index 4602355..d52ebd2 100644 --- a/test/litest.h +++ b/test/litest.h @@ -224,6 +224,7 @@ enum litest_device_type { LITEST_WACOM_CINTIQ_13HDT_PAD, LITEST_WACOM_CINTIQ_13HDT_FINGER, LITEST_WACOM_HID4800_PEN, + LITEST_MOUSE_WHEEL_CLICK_COUNT, }; enum litest_device_feature { diff --git a/test/misc.c b/test/misc.c index 582d4fc..4afd4d0 100644 --- a/test/misc.c +++ b/test/misc.c @@ -750,6 +750,35 @@ START_TEST(wheel_click_parser) } END_TEST +START_TEST(wheel_click_count_parser) +{ + struct parser_test tests[] = { + { "1", 1 }, + { "10", 10 }, + { "-12", -12 }, + { "360", 360 }, + { "66 ", 66 }, + { " 100 ", 100 }, + + { "0", 0 }, + { "-0", 0 }, + { "a", 0 }, + { "10a", 0 }, + { "10-", 0 }, + { "sadfasfd", 0 }, + { "361", 0 }, + { NULL, 0 } + }; + + int i, angle; + + for (i = 0; tests[i].tag != NULL; i++) { + angle = parse_mouse_wheel_click_count_property(tests[i].tag); + ck_assert_int_eq(angle, tests[i].expected_value); + } +} +END_TEST + struct parser_test_float { char *tag; double expected_value; @@ -956,6 +985,7 @@ litest_setup_tests_misc(void) litest_add_no_device("misc:ratelimit", ratelimit_helpers); litest_add_no_device("misc:parser", dpi_parser); litest_add_no_device("misc:parser", wheel_click_parser); + litest_add_no_device("misc:parser", wheel_click_count_parser); litest_add_no_device("misc:parser", trackpoint_accel_parser); litest_add_no_device("misc:parser", dimension_prop_parser); litest_add_no_device("misc:time", time_conversion); diff --git a/test/pointer.c b/test/pointer.c index 175cb3b..4f33de5 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -473,14 +473,45 @@ START_TEST(pointer_button_auto_release) } END_TEST -static inline int +static inline double +wheel_click_count(struct litest_device *dev, int which) +{ + struct udev_device *d; + const char *prop = NULL; + int count; + double angle = 0.0; + + d = libinput_device_get_udev_device(dev->libinput_device); + litest_assert_ptr_notnull(d); + + if (which == REL_HWHEEL) + prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_COUNT_HORIZONTAL"); + if(!prop) + prop = udev_device_get_property_value(d, "MOUSE_WHEEL_CLICK_COUNT"); + if (!prop) + goto out; + + count = parse_mouse_wheel_click_count_property(prop); + angle = 360.0/count; + +out: + udev_device_unref(d); + return angle; +} + +static inline double wheel_click_angle(struct litest_device *dev, int which) { struct udev_device *d; const char *prop = NULL; const int default_angle = 15; - int angle = default_angle; + double angle; + + angle = wheel_click_count(dev, which); + if (angle != 0.0) + return angle; + angle = default_angle; d = libinput_device_get_udev_device(dev->libinput_device); litest_assert_ptr_notnull(d); @@ -492,7 +523,7 @@ wheel_click_angle(struct litest_device *dev, int which) goto out; angle = parse_mouse_wheel_click_angle_property(prop); - if (angle == 0) + if (angle == 0.0) angle = default_angle; out: @@ -508,7 +539,7 @@ test_wheel_event(struct litest_device *dev, int which, int amount) struct libinput_event_pointer *ptrev; enum libinput_pointer_axis axis; - int scroll_step, expected, discrete;; + double scroll_step, expected, discrete; scroll_step = wheel_click_angle(dev, which); expected = amount * scroll_step; @@ -535,10 +566,12 @@ test_wheel_event(struct litest_device *dev, int which, int amount) axis, LIBINPUT_POINTER_AXIS_SOURCE_WHEEL); - litest_assert_int_eq(libinput_event_pointer_get_axis_value(ptrev, axis), - expected); - litest_assert_int_eq(libinput_event_pointer_get_axis_value_discrete(ptrev, axis), - discrete); + litest_assert_double_eq( + libinput_event_pointer_get_axis_value(ptrev, axis), + expected); + litest_assert_double_eq( + libinput_event_pointer_get_axis_value_discrete(ptrev, axis), + discrete); libinput_event_destroy(event); } commit e0ccfc87f047ff3c5595e268869c071c0b48428d Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Thu Nov 3 14:01:17 2016 +1000 doc: expand trackpoint pointer acceleration documentation a bit Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/doc/pointer-acceleration.dox b/doc/pointer-acceleration.dox index 2fbb4cc..502bc7b 100644 --- a/doc/pointer-acceleration.dox +++ b/doc/pointer-acceleration.dox @@ -108,14 +108,33 @@ The image above shows the touchpad acceleration profile in comparison to the @section ptraccel-trackpoint Pointer acceleration on trackpoints +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. +libinput relies on some sytem-wide configured properties, specifically the +@ref udev_config. The two properties that influence trackpoint acceleration +````POINTINGSTICK_CONST_ACCEL```` which is a constant factor applied to the +trackpoint's motion data. For example, a factor of 3 will see all input data +multipled by 3. This multiplication is done by libinput. + +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. + Trackpoint pointer acceleration uses the @ref ptraccel-low-dpi profile, with a -constant deceleration factor taking the place of the DPI settings. +constant acceleration factor taking the place of the DPI settings. @image html ptraccel-trackpoint.svg "Pointer acceleration curves for trackpoints" The image above shows the trackpoint acceleration profile in comparison to the -@ref ptraccel-linear. The constant acceleration factor, usually applied by -udev, shapes the acceleration profile. +@ref ptraccel-linear. + +The constant acceleration factor, usually applied in +@ref udev_config, shapes the acceleration profile and is pre-applied before +any user-specific acceleration adjustments. @section ptraccel-profile-flat The flat pointer acceleration profile commit 76008034ca04e8bf235f9be001c50176ade24479 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Wed Nov 2 21:11:00 2016 +1000 evdev: add hwdb quirk for HP Compaq 6910 Same as the HP Compat 8510, it doesn't send BTN_TOOL_DOUBLETAP/TRIPLETAP. This may be a general issue with those series but they're 6 years old now, so it's questionable to spend extra effort detecting them. https://bugs.freedesktop.org/show_bug.cgi?id=98538 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Reviewed-by: Hans de Goede <hdego...@redhat.com> diff --git a/src/evdev.c b/src/evdev.c index f423251..2412751 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -2143,6 +2143,7 @@ evdev_read_model_flags(struct evdev_device *device) MODEL(TRACKBALL), MODEL(APPLE_MAGICMOUSE), MODEL(HP8510_TOUCHPAD), + MODEL(HP6910_TOUCHPAD), #undef MODEL { "ID_INPUT_TRACKBALL", EVDEV_MODEL_TRACKBALL }, { NULL, EVDEV_MODEL_DEFAULT }, @@ -2712,9 +2713,11 @@ evdev_pre_configure_model_quirks(struct evdev_device *device) libevdev_disable_event_type(device->evdev, EV_ABS); /* Claims to have double/tripletap but doesn't actually send it - * https://bugzilla.redhat.com/show_bug.cgi?id=1351285 + * https://bugzilla.redhat.com/show_bug.cgi?id=1351285 and + * https://bugzilla.redhat.com/show_bug.cgi?id=98538 */ - if (device->model_flags & EVDEV_MODEL_HP8510_TOUCHPAD) { + if (device->model_flags & + (EVDEV_MODEL_HP8510_TOUCHPAD|EVDEV_MODEL_HP6910_TOUCHPAD)) { libevdev_disable_event_code(device->evdev, EV_KEY, BTN_TOOL_DOUBLETAP); libevdev_disable_event_code(device->evdev, EV_KEY, BTN_TOOL_TRIPLETAP); } diff --git a/src/evdev.h b/src/evdev.h index 4e28e05..b811f51 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -120,6 +120,7 @@ enum evdev_device_model { EVDEV_MODEL_TRACKBALL = (1 << 19), EVDEV_MODEL_APPLE_MAGICMOUSE = (1 << 20), EVDEV_MODEL_HP8510_TOUCHPAD = (1 << 21), + EVDEV_MODEL_HP6910_TOUCHPAD = (1 << 22), }; struct mt_slot { diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb index fed28e2..4bfc0f9 100644 --- a/udev/90-libinput-model-quirks.hwdb +++ b/udev/90-libinput-model-quirks.hwdb @@ -91,7 +91,11 @@ libinput:name:Cypress APA Trackpad ?cyapa?:dmi:* # HP ########################################## -# HP 8510w +# HP Compaq6910p +libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPCompaq6910p* + LIBINPUT_MODEL_HP6910_TOUCHPAD=1 + +# HP Compaq 8510w libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnHewlett-Packard:*pnHPCompaq8510w* LIBINPUT_MODEL_HP8510_TOUCHPAD=1 commit a58a9de70d7bc963006ba9ded049a2b97f0cdadd Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Wed Nov 2 10:45:39 2016 +1000 evdev: actually ignore joysticks A joystick has ID_INPUT_JOYSTICK *and* ID_INPUT set, so we need to check for both. https://bugs.freedesktop.org/show_bug.cgi?id=98009 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Reviewed-by: Hans de Goede <hdego...@redhat.com> diff --git a/src/evdev.c b/src/evdev.c index d49b391..f423251 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -2468,7 +2468,7 @@ evdev_configure_device(struct evdev_device *device) /* libwacom *adds* TABLET, TOUCHPAD but leaves JOYSTICK in place, so make sure we only ignore real joystick devices */ - if ((udev_tags & EVDEV_UDEV_TAG_JOYSTICK) == udev_tags) { + if (udev_tags == (EVDEV_UDEV_TAG_INPUT|EVDEV_UDEV_TAG_JOYSTICK)) { log_info(libinput, "input device '%s', %s is a joystick, ignoring\n", device->devname, devnode); diff --git a/test/device.c b/test/device.c index 4ed12d9..f44a988 100644 --- a/test/device.c +++ b/test/device.c @@ -1058,6 +1058,39 @@ START_TEST(abs_mt_device_missing_res) } END_TEST +START_TEST(ignore_joystick) +{ + struct libinput *li; + struct libevdev_uinput *uinput; + struct libinput_device *device; + struct input_absinfo absinfo[] = { + { ABS_X, 0, 10, 0, 0, 10 }, + { ABS_Y, 0, 10, 0, 0, 10 }, + { ABS_RX, 0, 10, 0, 0, 10 }, + { ABS_RY, 0, 10, 0, 0, 10 }, + { ABS_THROTTLE, 0, 2, 0, 0, 0 }, + { ABS_RUDDER, 0, 255, 0, 0, 0 }, + { -1, -1, -1, -1, -1, -1 } + }; + + li = litest_create_context(); + litest_disable_log_handler(li); + litest_drain_events(li); + + uinput = litest_create_uinput_abs_device("joystick test device", NULL, + absinfo, + EV_KEY, BTN_TRIGGER, + EV_KEY, BTN_A, + -1); + device = libinput_path_add_device(li, + libevdev_uinput_get_devnode(uinput)); + litest_assert_ptr_null(device); + libevdev_uinput_destroy(uinput); + litest_restore_log_handler(li); + libinput_unref(li); +} +END_TEST + START_TEST(device_wheel_only) { struct litest_device *dev = litest_current_device(); @@ -1464,6 +1497,7 @@ litest_setup_tests_device(void) litest_add_ranged_no_device("device:invalid devices", abs_mt_device_no_range, &abs_mt_range); litest_add_no_device("device:invalid devices", abs_device_missing_res); litest_add_no_device("device:invalid devices", abs_mt_device_missing_res); + litest_add_no_device("device:invalid devices", ignore_joystick); litest_add("device:wheel", device_wheel_only, LITEST_WHEEL, LITEST_RELATIVE|LITEST_ABSOLUTE|LITEST_TABLET); litest_add_no_device("device:accelerometer", device_accelerometer); commit e09705522a69d2de94d147f3482089275a8109df Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Tue Sep 13 16:57:25 2016 +1000 udev: add the hwdb_parser.py test from systemd upstream for this file lives in systemd, any changes to the actual parser should flow back there. libinput's matches are fairly simple. We have the various LIBINPUT_MODEL_ tags that just take a "1" and the two attributes that are dimensions. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Reviewed-by: Hans de Goede <hdego...@redhat.com> diff --git a/configure.ac b/configure.ac index 47e1594..0ae9b76 100644 --- a/configure.ac +++ b/configure.ac @@ -46,6 +46,10 @@ AC_PROG_CC_C99 AC_PROG_CXX # Only used by build C++ test AC_PROG_GREP +# Only used for testing the hwdb +AM_PATH_PYTHON([3.0],, [:]) +AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) + # Initialize libtool LT_PREREQ([2.2]) LT_INIT diff --git a/udev/Makefile.am b/udev/Makefile.am index f06dc56..17ae0b8 100644 --- a/udev/Makefile.am +++ b/udev/Makefile.am @@ -41,3 +41,10 @@ DISTCLEANFILES = \ 80-libinput-device-groups.rules \ 90-libinput-model-quirks.rules EXTRA_DIST = 80-libinput-test-device.rules + +if HAVE_PYTHON +TESTS = parse_hwdb.py +TEST_EXTENSIONS = .py +PY_LOG_COMPILER = $(PYTHON) +endif +EXTRA_DIST += parse_hwdb.py diff --git a/udev/parse_hwdb.py b/udev/parse_hwdb.py new file mode 100755 index 0000000..99e9c59 --- /dev/null +++ b/udev/parse_hwdb.py @@ -0,0 +1,178 @@ +#!/usr/bin/python3 +# vim: set expandtab shiftwidth=4: +# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ +# +# ANY MODIFICATIONS TO THIS FILE SHOULD BE MERGED INTO THE SYSTEMD UPSTREAM +# +# This file is part of systemd. It is distributed under the MIT license, see +# below. +# +# Copyright 2016 Zbigniew Jędrzejewski-Szmek +# +# The MIT License (MIT) +# +# 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 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. + +import functools +import glob +import string +import sys +import os + +try: + from pyparsing import (Word, White, Literal, ParserElement, Regex, + LineStart, LineEnd, + ZeroOrMore, OneOrMore, Combine, Or, Optional, Suppress, Group, + nums, alphanums, printables, + stringEnd, pythonStyleComment, + ParseBaseException) +except ImportError: + print('pyparsing is not available') + sys.exit(77) + +try: + from evdev.ecodes import ecodes +except ImportError: + ecodes = None + print('WARNING: evdev is not available') + +EOL = LineEnd().suppress() +EMPTYLINE = LineStart() + LineEnd() +COMMENTLINE = pythonStyleComment + EOL +INTEGER = Word(nums) +REAL = Combine((INTEGER + Optional('.' + Optional(INTEGER))) ^ ('.' + INTEGER)) +UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_') + +TYPES = { + 'libinput': ('name', 'touchpad', 'mouse'), + } + +@functools.lru_cache() +def hwdb_grammar(): + ParserElement.setDefaultWhitespaceChars('') + + prefix = Or(category + ':' + Or(conn) + ':' + for category, conn in TYPES.items()) + matchline = Combine(prefix + Word(printables + ' ' + '®')) + EOL + propertyline = (White(' ', exact=1).suppress() + + Combine(UDEV_TAG - '=' - Word(alphanums + '_=:@*.! ') - Optional(pythonStyleComment)) + + EOL) + propertycomment = White(' ', exact=1) + pythonStyleComment + EOL + + group = (OneOrMore(matchline('MATCHES*') ^ COMMENTLINE.suppress()) - + OneOrMore(propertyline('PROPERTIES*') ^ propertycomment.suppress()) - + (EMPTYLINE ^ stringEnd()).suppress() ) + commentgroup = OneOrMore(COMMENTLINE).suppress() - EMPTYLINE.suppress() + + grammar = OneOrMore(group('GROUPS*') ^ commentgroup) + stringEnd() + + return grammar + +@functools.lru_cache() +def property_grammar(): + ParserElement.setDefaultWhitespaceChars(' ') + + model_props = [Regex(r'LIBINPUT_MODEL_[_0-9A-Z]+')('NAME') + - Suppress('=') - + (Literal('1'))('VALUE') + ] + + dimension = INTEGER('X') + Suppress('x') + INTEGER('Y') + sz_props = ( + ('LIBINPUT_ATTR_SIZE_HINT', Group(dimension('SETTINGS*'))), + ('LIBINPUT_ATTR_RESOLUTION_HINT', Group(dimension('SETTINGS*'))), + ) + size_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE') + for name, val in sz_props] + + grammar = Or(model_props + size_props); + + return grammar + +ERROR = False +def error(fmt, *args, **kwargs): + global ERROR + ERROR = True + print(fmt.format(*args, **kwargs)) + +def convert_properties(group): + matches = [m[0] for m in group.MATCHES] + props = [p[0] for p in group.PROPERTIES] + return matches, props + +def parse(fname): + grammar = hwdb_grammar() + try: + parsed = grammar.parseFile(fname) + except ParseBaseException as e: + error('Cannot parse {}: {}', fname, e) + return [] + return [convert_properties(g) for g in parsed.GROUPS] + +def check_match_uniqueness(groups): + matches = sum((group[0] for group in groups), []) + matches.sort() + prev = None + for match in matches: + if match == prev: + error('Match {!r} is duplicated', match)