circle.yml | 151 +++++++++++++++++++++++++++ configure.ac | 2 doc/building.dox | 20 +++ meson.build | 48 +++++--- src/evdev-lid.c | 8 + src/evdev-mt-touchpad-gestures.c | 7 + src/evdev-mt-touchpad.c | 7 - src/evdev.c | 20 +-- src/timer.c | 18 ++- test/Makefile.am | 1 test/litest-device-gpio-keys.c | 75 +++++++++++++ test/litest.c | 2 test/litest.h | 1 test/test-gestures.c | 211 --------------------------------------- test/test-lid.c | 20 +++ test/test-pointer.c | 35 ++++++ test/test-touchpad.c | 42 +++++++ test/valgrind.suppressions | 7 + tools/Makefile.am | 2 19 files changed, 425 insertions(+), 252 deletions(-)
New commits: commit 0df61c76fe08040f90bb8f916944e938d07975de Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Thu Sep 7 10:43:30 2017 +1000 configure.ac: libinput 1.8.2 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/configure.ac b/configure.ac index 37b6f42..b66a61f 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], [8]) -m4_define([libinput_micro_version], [1]) +m4_define([libinput_micro_version], [2]) m4_define([libinput_version], [libinput_major_version.libinput_minor_version.libinput_micro_version]) diff --git a/meson.build b/meson.build index 93a20d5..4cb83dd 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('libinput', 'c', 'cpp', - version : '1.8.1', + version : '1.8.2', license : 'MIT/Expat', default_options : [ 'c_std=gnu99', 'warning_level=2' ], meson_version : '>= 0.40.0') commit 05c287c16cee05be7713c060d65c5e004f1b8f19 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Thu Sep 7 16:54:22 2017 +1000 test: add the gpio-keys device to the Makefile Fixes distcheck Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/test/Makefile.am b/test/Makefile.am index 5cb89a6..700ae69 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -29,6 +29,7 @@ liblitest_la_SOURCES = \ litest-device-cyborg-rat-5.c \ litest-device-elantech-touchpad.c \ litest-device-generic-singletouch.c \ + litest-device-gpio-keys.c \ litest-device-huion-pentablet.c \ litest-device-keyboard.c \ litest-device-keyboard-all-codes.c \ commit 3d83026c37a9c87582725c14eea2b2183c279db4 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Sat Jul 29 13:59:40 2017 +0100 gestures: don't try to pinch for nfingers > slots We don't know the position of the third finger on 2-slot touchpads, differing between swipe and pinch is reliable. Simply disable 3-finger pinch and always use swipe; 3fg pinch is uncommon anyway and it's better to have one of the gestures working reliably than both unreliably. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Reviewed-by: Hans de Goede <hdego...@redhat.com> (cherry picked from commit 6d435cda0679a271ba8e174c3cd0ca41ffe4f03c) diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c index a20b26d..26bdef5 100644 --- a/src/evdev-mt-touchpad-gestures.c +++ b/src/evdev-mt-touchpad-gestures.c @@ -334,6 +334,10 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time) if (tp->gesture.finger_count == 2) { tp_gesture_set_scroll_buildup(tp); return GESTURE_STATE_SCROLL; + /* more fingers than slots, don't bother with pinch, always + * assume swipe */ + } else if (tp->gesture.finger_count > tp->num_slots) { + return GESTURE_STATE_SWIPE; } /* for 3+ finger gestures, check if one finger is > 20mm @@ -356,7 +360,8 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time) /* If both touches are moving in the same direction assume * scroll or swipe */ - if (tp_gesture_same_directions(dir1, dir2)) { + if (tp->gesture.finger_count > tp->num_slots || + tp_gesture_same_directions(dir1, dir2)) { if (tp->gesture.finger_count == 2) { tp_gesture_set_scroll_buildup(tp); return GESTURE_STATE_SCROLL; diff --git a/test/test-gestures.c b/test/test-gestures.c index ce1012d..e95d1a0 100644 --- a/test/test-gestures.c +++ b/test/test-gestures.c @@ -754,110 +754,6 @@ START_TEST(gestures_pinch_3fg) } END_TEST -START_TEST(gestures_pinch_3fg_btntool) -{ - struct litest_device *dev = litest_current_device(); - struct libinput *li = dev->libinput; - struct libinput_event *event; - struct libinput_event_gesture *gevent; - double dx, dy; - int cardinal = _i; /* ranged test */ - double dir_x, dir_y; - int i; - double scale, oldscale; - double angle; - int cardinals[8][2] = { - { 0, 30 }, - { 30, 30 }, - { 30, 0 }, - { 30, -30 }, - { 0, -30 }, - { -30, -30 }, - { -30, 0 }, - { -30, 30 }, - }; - - if (libevdev_get_num_slots(dev->evdev) > 2 || - !libinput_device_has_capability(dev->libinput_device, - LIBINPUT_DEVICE_CAP_GESTURE)) - return; - - dir_x = cardinals[cardinal][0]; - dir_y = cardinals[cardinal][1]; - - litest_drain_events(li); - - litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y); - litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y); - litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0); - litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1); - litest_event(dev, EV_SYN, SYN_REPORT, 0); - libinput_dispatch(li); - - for (i = 0; i < 8; i++) { - litest_push_event_frame(dev); - if (dir_x > 0.0) - dir_x -= 2; - else if (dir_x < 0.0) - dir_x += 2; - if (dir_y > 0.0) - dir_y -= 2; - else if (dir_y < 0.0) - dir_y += 2; - litest_touch_move(dev, - 0, - 50 + dir_x, - 50 + dir_y); - litest_touch_move(dev, - 1, - 50 - dir_x, - 50 - dir_y); - litest_pop_event_frame(dev); - libinput_dispatch(li); - } - - event = libinput_get_event(li); - gevent = litest_is_gesture_event(event, - LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, - 3); - dx = libinput_event_gesture_get_dx(gevent); - dy = libinput_event_gesture_get_dy(gevent); - scale = libinput_event_gesture_get_scale(gevent); - ck_assert(dx == 0.0); - ck_assert(dy == 0.0); - ck_assert(scale == 1.0); - - libinput_event_destroy(event); - - while ((event = libinput_get_event(li)) != NULL) { - gevent = litest_is_gesture_event(event, - LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, - 3); - - oldscale = scale; - scale = libinput_event_gesture_get_scale(gevent); - - ck_assert(scale < oldscale); - - angle = libinput_event_gesture_get_angle_delta(gevent); - ck_assert_double_le(fabs(angle), 1.0); - - libinput_event_destroy(event); - libinput_dispatch(li); - } - - litest_touch_up(dev, 0); - litest_touch_up(dev, 1); - libinput_dispatch(li); - event = libinput_get_event(li); - gevent = litest_is_gesture_event(event, - LIBINPUT_EVENT_GESTURE_PINCH_END, - 3); - ck_assert(!libinput_event_gesture_get_cancelled(gevent)); - libinput_event_destroy(event); -} -END_TEST - START_TEST(gestures_pinch_4fg) { struct litest_device *dev = litest_current_device(); @@ -969,111 +865,6 @@ START_TEST(gestures_pinch_4fg) } END_TEST -START_TEST(gestures_pinch_4fg_btntool) -{ - struct litest_device *dev = litest_current_device(); - struct libinput *li = dev->libinput; - struct libinput_event *event; - struct libinput_event_gesture *gevent; - double dx, dy; - int cardinal = _i; /* ranged test */ - double dir_x, dir_y; - int i; - double scale, oldscale; - double angle; - int cardinals[8][2] = { - { 0, 30 }, - { 30, 30 }, - { 30, 0 }, - { 30, -30 }, - { 0, -30 }, - { -30, -30 }, - { -30, 0 }, - { -30, 30 }, - }; - - if (libevdev_get_num_slots(dev->evdev) > 2 || - !libevdev_has_event_code(dev->evdev, EV_KEY, BTN_TOOL_QUADTAP) || - !libinput_device_has_capability(dev->libinput_device, - LIBINPUT_DEVICE_CAP_GESTURE)) - return; - - dir_x = cardinals[cardinal][0]; - dir_y = cardinals[cardinal][1]; - - litest_drain_events(li); - - litest_touch_down(dev, 0, 50 + dir_x, 50 + dir_y); - litest_touch_down(dev, 1, 50 - dir_x, 50 - dir_y); - litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0); - litest_event(dev, EV_KEY, BTN_TOOL_QUADTAP, 1); - litest_event(dev, EV_SYN, SYN_REPORT, 0); - libinput_dispatch(li); - - for (i = 0; i < 8; i++) { - litest_push_event_frame(dev); - if (dir_x > 0.0) - dir_x -= 3; - else if (dir_x < 0.0) - dir_x += 3; - if (dir_y > 0.0) - dir_y -= 3; - else if (dir_y < 0.0) - dir_y += 3; - litest_touch_move(dev, - 0, - 50 + dir_x, - 50 + dir_y); - litest_touch_move(dev, - 1, - 50 - dir_x, - 50 - dir_y); - litest_pop_event_frame(dev); - libinput_dispatch(li); - } - - event = libinput_get_event(li); - gevent = litest_is_gesture_event(event, - LIBINPUT_EVENT_GESTURE_PINCH_BEGIN, - 4); - dx = libinput_event_gesture_get_dx(gevent); - dy = libinput_event_gesture_get_dy(gevent); - scale = libinput_event_gesture_get_scale(gevent); - ck_assert(dx == 0.0); - ck_assert(dy == 0.0); - ck_assert(scale == 1.0); - - libinput_event_destroy(event); - - while ((event = libinput_get_event(li)) != NULL) { - gevent = litest_is_gesture_event(event, - LIBINPUT_EVENT_GESTURE_PINCH_UPDATE, - 4); - - oldscale = scale; - scale = libinput_event_gesture_get_scale(gevent); - - ck_assert(scale < oldscale); - - angle = libinput_event_gesture_get_angle_delta(gevent); - ck_assert_double_le(fabs(angle), 1.5); - - libinput_event_destroy(event); - libinput_dispatch(li); - } - - litest_touch_up(dev, 0); - litest_touch_up(dev, 1); - libinput_dispatch(li); - event = libinput_get_event(li); - gevent = litest_is_gesture_event(event, - LIBINPUT_EVENT_GESTURE_PINCH_END, - 4); - ck_assert(!libinput_event_gesture_get_cancelled(gevent)); - libinput_event_destroy(event); -} -END_TEST - START_TEST(gestures_spread) { struct litest_device *dev = litest_current_device(); @@ -1282,9 +1073,7 @@ litest_setup_tests_gestures(void) litest_add_ranged("gestures:swipe", gestures_swipe_4fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals); litest_add_ranged("gestures:pinch", gestures_pinch, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals); litest_add_ranged("gestures:pinch", gestures_pinch_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals); - litest_add_ranged("gestures:pinch", gestures_pinch_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals); litest_add_ranged("gestures:pinch", gestures_pinch_4fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals); - litest_add_ranged("gestures:pinch", gestures_pinch_4fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals); litest_add_ranged("gestures:pinch", gestures_spread, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &cardinals); litest_add_ranged("gestures:pinch", gestures_pinch_vertical_positon, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &fingers); commit a57d0d458f5a3aab5a7a7a41ca438042347824ab Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Tue Jul 25 09:38:46 2017 +1000 lid: disable all types but EV_SYN and EV_SW The lid dispatch interface is a one-trick pony and can only handle SW_LID. It ignores other switches but crashes on any event type other than EV_SW and EV_SYN. Disable those types so we just ignore the event instead of asserting. https://bugs.freedesktop.org/show_bug.cgi?id=101853 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> Reviewed-by: Jason Gerecke <jason.gere...@wacom.com> (cherry picked from commit 6bb05c594a73cee2ed9cf62af88fdcab4011f57a) diff --git a/meson.build b/meson.build index fbb1c4e..93a20d5 100644 --- a/meson.build +++ b/meson.build @@ -512,6 +512,7 @@ if get_option('tests') 'test/litest-device-cyborg-rat-5.c', 'test/litest-device-elantech-touchpad.c', 'test/litest-device-generic-singletouch.c', + 'test/litest-device-gpio-keys.c', 'test/litest-device-huion-pentablet.c', 'test/litest-device-keyboard.c', 'test/litest-device-keyboard-all-codes.c', diff --git a/src/evdev-lid.c b/src/evdev-lid.c index fe98e6e..3de5fe4 100644 --- a/src/evdev-lid.c +++ b/src/evdev-lid.c @@ -298,6 +298,7 @@ struct evdev_dispatch * evdev_lid_switch_dispatch_create(struct evdev_device *lid_device) { struct lid_switch_dispatch *dispatch = zalloc(sizeof *dispatch); + int type; if (dispatch == NULL) return NULL; @@ -311,5 +312,12 @@ evdev_lid_switch_dispatch_create(struct evdev_device *lid_device) dispatch->lid_is_closed = false; + for (type = EV_KEY; type < EV_CNT; type++) { + if (type == EV_SW) + continue; + + libevdev_disable_event_type(lid_device->evdev, type); + } + return &dispatch->base; } diff --git a/test/litest-device-gpio-keys.c b/test/litest-device-gpio-keys.c new file mode 100644 index 0000000..37b058c --- /dev/null +++ b/test/litest-device-gpio-keys.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2017 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 "litest.h" +#include "litest-int.h" + +static void +litest_gpio_keys_setup(void) +{ + struct litest_device *d = litest_create_device(LITEST_GPIO_KEYS); + litest_set_current_device(d); +} + +static struct input_id input_id = { + .bustype = 0x19, + .vendor = 0x1, + .product = 0x1, +}; + +static int events[] = { + EV_SW, SW_LID, + EV_SW, SW_TABLET_MODE, + EV_KEY, KEY_POWER, + EV_KEY, KEY_VOLUMEUP, + EV_KEY, KEY_VOLUMEDOWN, + EV_KEY, KEY_POWER, + -1, -1, +}; + +static const char udev_rule[] = +"ACTION==\"remove\", GOTO=\"switch_end\"\n" +"KERNEL!=\"event*\", GOTO=\"switch_end\"\n" +"\n" +"ATTRS{name}==\"litest gpio-keys*\",\\\n" +" ENV{ID_INPUT_SWITCH}=\"1\",\\\n" +" ENV{LIBINPUT_ATTR_gpio_keys_RELIABILITY}=\"reliable\"\n" +"\n" +"LABEL=\"switch_end\""; + +struct litest_test_device litest_gpio_keys_device = { + .type = LITEST_GPIO_KEYS, + .features = LITEST_SWITCH, + .shortname = "gpio keys", + .setup = litest_gpio_keys_setup, + .interface = NULL, + + .name = "gpio-keys", + .id = &input_id, + .events = events, + .absinfo = NULL, + + .udev_rule = udev_rule, +}; diff --git a/test/litest.c b/test/litest.c index 3cb3f38..db14806 100644 --- a/test/litest.c +++ b/test/litest.c @@ -416,6 +416,7 @@ extern struct litest_test_device litest_mouse_wheel_tilt_device; extern struct litest_test_device litest_lid_switch_device; extern struct litest_test_device litest_lid_switch_surface3_device; extern struct litest_test_device litest_appletouch_device; +extern struct litest_test_device litest_gpio_keys_device; struct litest_test_device* devices[] = { &litest_synaptics_clickpad_device, @@ -481,6 +482,7 @@ struct litest_test_device* devices[] = { &litest_lid_switch_device, &litest_lid_switch_surface3_device, &litest_appletouch_device, + &litest_gpio_keys_device, NULL, }; diff --git a/test/litest.h b/test/litest.h index a2cb6ee..8625d34 100644 --- a/test/litest.h +++ b/test/litest.h @@ -232,6 +232,7 @@ enum litest_device_type { LITEST_LID_SWITCH, LITEST_LID_SWITCH_SURFACE3, LITEST_APPLETOUCH, + LITEST_GPIO_KEYS, }; enum litest_device_feature { diff --git a/test/test-lid.c b/test/test-lid.c index 4bf4c05..b5d3d58 100644 --- a/test/test-lid.c +++ b/test/test-lid.c @@ -555,6 +555,24 @@ START_TEST(lid_update_hw_on_key_closed_on_init) } END_TEST +START_TEST(lid_key_press) +{ + struct litest_device *sw = litest_current_device(); + struct libinput *li = sw->libinput; + + litest_drain_events(li); + + litest_keyboard_key(sw, KEY_POWER, true); + litest_keyboard_key(sw, KEY_POWER, false); + libinput_dispatch(li); + + /* We should route the key events correctly, but for now we just + * ignore them. This test will fail once the key events are handled + * correctly. */ + litest_assert_empty_queue(li); +} +END_TEST + void litest_setup_tests_lid(void) { @@ -576,4 +594,6 @@ litest_setup_tests_lid(void) litest_add_for_device("lid:buggy", lid_update_hw_on_key, LITEST_LID_SWITCH_SURFACE3); litest_add_for_device("lid:buggy", lid_update_hw_on_key_closed_on_init, LITEST_LID_SWITCH_SURFACE3); + + litest_add_for_device("lid:keypress", lid_key_press, LITEST_GPIO_KEYS); } commit 582ce30d27599f8a4b1f26108aaecf0bd894b482 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Mon Jul 17 12:30:25 2017 +1000 timer: always restart the timer loop when we called one of them If a timer_func causes the removal or addition of a different timer, our tmp pointer from the list_for_each_safe may not be valid anymore. This was triggered by having the debounce code trigger a middle button state change, which caused that timer to be cancelled. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> (cherry picked from commit 6d0edf9d07379082d9a2c66c71e929ad510b29d2) diff --git a/src/timer.c b/src/timer.c index 7a0a8eb..d7e04ba 100644 --- a/src/timer.c +++ b/src/timer.c @@ -116,7 +116,7 @@ static void libinput_timer_handler(void *data) { struct libinput *libinput = data; - struct libinput_timer *timer, *tmp; + struct libinput_timer *timer; uint64_t now; uint64_t discard; int r; @@ -132,7 +132,8 @@ libinput_timer_handler(void *data) if (now == 0) return; - list_for_each_safe(timer, tmp, &libinput->timer.list, link) { +restart: + list_for_each(timer, &libinput->timer.list, link) { if (timer->expire == 0) continue; @@ -141,6 +142,16 @@ libinput_timer_handler(void *data) as timer_func may re-arm it */ libinput_timer_cancel(timer); timer->timer_func(now, timer->timer_func_data); + + /* + * Restart the loop. We can't use + * list_for_each_safe() here because that only + * allows removing one (our) timer per timer_func. + * But the timer func may trigger another unrelated + * timer to be cancelled and removed, causing a + * segfault. + */ + goto restart; } } } commit cfb0a39aba03e3053f9135c59765b2367b8780e0 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Mon Jul 17 11:58:11 2017 +1000 timer: if a timer is inactive, do not call the timer func Race conditions may happen where code that cancels a timer is called just as that timer triggers. If we cancel a timer, we assume that we've put the code into a state where the timer firing will trigger a bug. This could be observed with the middle button code if the release event was held back just long enough. The button release code cancelled the timer, set the state back to idle and then complained when the timeout handling sent a 'timeout' event while being in idle. Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> (cherry picked from commit 696fdff247453e60e259349d0125f67856361b54) diff --git a/src/timer.c b/src/timer.c index 4a7b43a..7a0a8eb 100644 --- a/src/timer.c +++ b/src/timer.c @@ -133,6 +133,9 @@ libinput_timer_handler(void *data) return; list_for_each_safe(timer, tmp, &libinput->timer.list, link) { + if (timer->expire == 0) + continue; + if (timer->expire <= now) { /* Clear the timer before calling timer_func, as timer_func may re-arm it */ commit 1e89ceb93c90ab1a3d5e3a9a9bbfb8bc3e0bde34 Author: Peter Hutterer <peter.hutte...@who-t.net> Date: Tue Jul 18 16:12:27 2017 +1000 evdev: recover from a lost button count If the kernel sends us a button press for a button that is thought to be down we have lost track of the state of the button. Ignore the button press event, in the hope that the next release makes things right again. A release event may be masked if another process grabs the device for some period of time, e.g. libinput debug-events --grab. https://bugs.freedesktop.org/show_bug.cgi?id=101796 Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> (cherry picked from commit 399c50dbeb9dd96ee959dc270bcb9f4be7ab6710) diff --git a/src/evdev.c b/src/evdev.c index a680414..ea0ed7a 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -836,16 +836,16 @@ fallback_process_key(struct fallback_dispatch *dispatch, type = get_key_type(e->code); /* Ignore key release events from the kernel for keys that libinput - * never got a pressed event for. */ - if (e->value == 0) { - switch (type) { - case EVDEV_KEY_TYPE_NONE: - break; - case EVDEV_KEY_TYPE_KEY: - case EVDEV_KEY_TYPE_BUTTON: - if (!hw_is_key_down(dispatch, e->code)) - return; - } + * never got a pressed event for or key presses for keys that we + * think are still down */ + switch (type) { + case EVDEV_KEY_TYPE_NONE: + break; + case EVDEV_KEY_TYPE_KEY: + case EVDEV_KEY_TYPE_BUTTON: + if ((e->value && hw_is_key_down(dispatch, e->code)) || + (e->value == 0 && !hw_is_key_down(dispatch, e->code))) + return; } hw_set_key_down(dispatch, e->code, e->value); diff --git a/test/test-pointer.c b/test/test-pointer.c index e09f8f8..2f03195 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -490,6 +490,40 @@ START_TEST(pointer_button_has_no_button) } END_TEST +START_TEST(pointer_recover_from_lost_button_count) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libevdev *evdev = dev->evdev; + + disable_button_scrolling(dev); + + litest_drain_events(dev->libinput); + + litest_button_click(dev, BTN_LEFT, 1); + + litest_assert_button_event(li, + BTN_LEFT, + LIBINPUT_BUTTON_STATE_PRESSED); + + /* Grab for the release to make libinput lose count */ + libevdev_grab(evdev, LIBEVDEV_GRAB); + litest_button_click(dev, BTN_LEFT, 0); + libevdev_grab(evdev, LIBEVDEV_UNGRAB); + + litest_assert_empty_queue(li); + + litest_button_click(dev, BTN_LEFT, 1); + litest_assert_empty_queue(li); + + litest_button_click(dev, BTN_LEFT, 0); + litest_assert_button_event(li, + BTN_LEFT, + LIBINPUT_BUTTON_STATE_RELEASED); + litest_assert_empty_queue(li); +} +END_TEST + static inline double wheel_click_count(struct litest_device *dev, int which) { @@ -2088,6 +2122,7 @@ litest_setup_tests_pointer(void) litest_add_no_device("pointer:button", pointer_button_auto_release); litest_add_no_device("pointer:button", pointer_seat_button_count); litest_add_for_device("pointer:button", pointer_button_has_no_button, LITEST_KEYBOARD); + litest_add("pointer:button", pointer_recover_from_lost_button_count, LITEST_BUTTON, LITEST_CLICKPAD); litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET); litest_add("pointer:scroll", pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add("pointer:scroll", pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE); diff --git a/test/valgrind.suppressions b/test/valgrind.suppressions index e3ad874..dd573f5 100644 --- a/test/valgrind.suppressions +++ b/test/valgrind.suppressions @@ -45,3 +45,10 @@ ... obj:/usr/lib*/libpython3*.so* } +{ + libevdev:grab + Memcheck:Param + ioctl(generic) + fun:ioctl + fun:libevdev_grab +} commit 2d8b79877fa3b61aca52e59068e58d8980907164 Author: Philip Withnall <withn...@endlessm.com> Date: Fri Aug 18 09:13:33 2017 +0100 build: Add -Iinclude to unit tests It seems the unit tests rely on another part of <linux/input.h> which I missed in the previous commit (5cf4b35b). Signed-off-by: Philip Withnall <withn...@endlessm.com> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/meson.build b/meson.build index f66584a..fbb1c4e 100644 --- a/meson.build +++ b/meson.build @@ -642,7 +642,7 @@ if get_option('tests') def_LT_VERSION = '-DLIBINPUT_LT_VERSION="@0@:@1@:@2@"'.format(libinput_lt_c, libinput_lt_r, libinput_lt_a) libinput_test_runner = executable('libinput-test-suite-runner', libinput_test_runner_sources, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], dependencies : dep_litest, c_args : [ def_LT_VERSION ], install : false) @@ -653,25 +653,25 @@ if get_option('tests') # build-test only executable('test-build-pedantic', 'test/build-pedantic.c', - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], c_args : ['-std=c99', '-pedantic', '-Werror'], install : false) # build-test only executable('test-build-std-gnuc90', 'test/build-pedantic.c', - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], c_args : ['-std=gnu90', '-Werror'], install : false) # test for linking with the minimal linker flags executable('test-build-linker', 'test/build-pedantic.c', - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], dependencies : [ dep_libinput, dep_libinput_util ], install : false) # test including from C++ executable('test-build-cxx', 'test/build-cxx.cc', - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install : false) valgrind_env = environment() commit 1cfae5a4a5f1829109e7b59c75a66e901dea0804 Author: Philip Withnall <withn...@endlessm.com> Date: Tue Aug 15 15:42:48 2017 +0100 build: Add -Iinclude to libinput and its tools Various files use #include <linux/input.h> and, if the system input.h is too old, will fail to compile. Use the internal copy by adding -Iinclude to the build command lines. This was the case in the old autotools build system. Signed-off-by: Philip Withnall <withn...@endlessm.com> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/meson.build b/meson.build index 81f8dc8..f66584a 100644 --- a/meson.build +++ b/meson.build @@ -47,6 +47,10 @@ dep_libevdev = dependency('libevdev', version : '>= 0.4') dep_lm = cc.find_library('m', required : false) dep_rt = cc.find_library('rt', required : false) +# Include directories +includes_include = include_directories('include') +includes_src = include_directories('src') + ############ libwacom configuration ############ have_libwacom = get_option('libwacom') @@ -78,13 +82,13 @@ udev_hwdb_dir = join_paths(udev_dir, 'hwdb.d') executable('libinput-device-group', 'udev/libinput-device-group.c', dependencies : [dep_udev, dep_libwacom], - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install : true, install_dir : udev_dir) executable('libinput-model-quirks', 'udev/libinput-model-quirks.c', dependencies : dep_udev, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install : true, install_dir : udev_dir) @@ -131,7 +135,8 @@ src_libinput_util = [ ] libinput_util = static_library('libinput-util', src_libinput_util, - dependencies : dep_udev) + dependencies : dep_udev, + include_directories : includes_include) dep_libinput_util = declare_dependency(link_with : libinput_util) ############ libfilter.a ############ @@ -202,7 +207,7 @@ mapfile = join_paths(meson.source_root(), 'src', 'libinput.sym') version_flag = '-Wl,--version-script,@0@'.format(mapfile) lib_libinput = shared_library('input', src_libinput, - include_directories : include_directories('.'), + include_directories : [include_directories('.'), includes_include], dependencies : deps_libinput, version : libinput_so_version, link_args : version_flag, @@ -354,7 +359,7 @@ tools_shared_sources = [ 'tools/shared.c', deps_tools_shared = [ dep_libinput, dep_libevdev ] lib_tools_shared = static_library('tools_shared', tools_shared_sources, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], dependencies : deps_tools_shared) dep_tools_shared = declare_dependency(link_with : lib_tools_shared, dependencies : deps_tools_shared) @@ -367,7 +372,7 @@ libinput_debug_events_sources = [ 'tools/libinput-debug-events.c' ] executable('libinput-debug-events', libinput_debug_events_sources, dependencies : deps_tools, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install_dir : libinput_tool_path, install : true ) @@ -382,7 +387,7 @@ libinput_list_devices_sources = [ 'tools/libinput-list-devices.c' ] executable('libinput-list-devices', libinput_list_devices_sources, dependencies : deps_tools, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install_dir : libinput_tool_path, install : true, ) @@ -397,7 +402,7 @@ libinput_measure_sources = [ 'tools/libinput-measure.c' ] executable('libinput-measure', libinput_measure_sources, dependencies : deps_tools, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install_dir : libinput_tool_path, install : true, ) @@ -412,7 +417,7 @@ libinput_measure_touchpad_tap_sources = [ 'tools/libinput-measure-touchpad-tap.c executable('libinput-measure-touchpad-tap', libinput_measure_touchpad_tap_sources, dependencies : deps_tools, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install_dir : libinput_tool_path, install : true, ) @@ -437,7 +442,7 @@ if get_option('debug-gui') executable('libinput-debug-gui', debug_gui_sources, dependencies : deps_debug_gui, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install_dir : libinput_tool_path, install : true ) @@ -454,7 +459,7 @@ libinput_sources = [ 'tools/libinput-tool.c' ] executable('libinput', libinput_sources, dependencies : deps_tools, - include_directories : include_directories ('src'), + include_directories : [includes_src, includes_include], install : true ) configure_file(input : 'tools/libinput.man', @@ -470,7 +475,7 @@ ptraccel_debug_sources = [ 'tools/ptraccel-debug.c' ] executable('ptraccel-debug', ptraccel_debug_sources, dependencies : [ dep_libfilter, dep_libinput ], - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], install : false ) @@ -584,7 +589,7 @@ if get_option('tests') join_paths(meson.build_root(), '80-libinput-device-groups.rules')) lib_litest = static_library('litest', lib_litest_sources, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], dependencies : deps_litest) dep_litest = declare_dependency(link_with : lib_litest, dependencies : deps_litest) @@ -604,7 +609,7 @@ if get_option('tests') deps_litest_selftest = [dep_litest] test_litest_selftest = executable('test-litest-selftest', test_litest_selftest_sources, - include_directories : include_directories('src'), + include_directories : [includes_src, includes_include], dependencies : deps_litest_selftest, c_args : defs_litest_selftest, install : false) commit 3dffe368544e6b6d357bab78c94cd972f955bce5 Author: Jussi Kukkonen <jussi.kukko...@intel.com> Date: Wed Aug 9 10:05:14 2017 +0300 tools: Fix race in (autotools) install exec/data distinction is done based on install dir so compat scripts must be moved in exec hook. This should fix this occasional failure: | install: cannot change permissions of | ‘/usr/bin/libinput-debug-events.compat’: No such file or directory Signed-off-by: Jussi Kukkonen <jussi.kukko...@intel.com> Signed-off-by: Peter Hutterer <peter.hutte...@who-t.net> diff --git a/tools/Makefile.am b/tools/Makefile.am index 2c8660b..7ee8b90 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -63,7 +63,7 @@ endif EXTRA_DIST = make-ptraccel-graphs.sh install-compat-scripts.sh $(bin_SCRIPTS)