From 2a1ed92c51843e5be3de5bea76522628505481aa Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 24 Jan 2017 15:04:39 +1000 Subject: [PATCH] switch: sync the initial state of the switch on startup This is the default behavior, based on the theory of hardware actually doing the right thing. That's not always the case, follow-up patches will change when we do the theoretically ideal thing. Signed-off-by: Peter Hutterer --- src/evdev.c | 23 ++++++++++++++++++++++- test/test-lid.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/evdev.c b/src/evdev.c index 216dcc27..2e0402b1 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1359,6 +1359,27 @@ lid_switch_destroy(struct evdev_dispatch *evdev_dispatch) free(dispatch); } +static void +lid_switch_sync_initial_state(struct evdev_device *device, + struct evdev_dispatch *evdev_dispatch) +{ + struct lid_switch_dispatch *dispatch = + (struct lid_switch_dispatch*)evdev_dispatch; + struct libevdev *evdev = device->evdev; + + dispatch->lid_is_closed = libevdev_get_event_value(evdev, + EV_SW, + SW_LID); + if (dispatch->lid_is_closed) { + uint64_t time; + time = libinput_now(evdev_libinput_context(device)); + switch_notify_toggle(&device->base, + time, + LIBINPUT_SWITCH_LID, + LIBINPUT_SWITCH_STATE_ON); + } +} + struct evdev_dispatch_interface lid_switch_interface = { lid_switch_process, NULL, /* suspend */ @@ -1368,7 +1389,7 @@ struct evdev_dispatch_interface lid_switch_interface = { NULL, /* device_removed */ NULL, /* device_suspended */ NULL, /* device_resumed */ - NULL, /* post_added */ + lid_switch_sync_initial_state, NULL, /* toggle_touch */ }; diff --git a/test/test-lid.c b/test/test-lid.c index e1a9088c..59c461dd 100644 --- a/test/test-lid.c +++ b/test/test-lid.c @@ -87,6 +87,47 @@ START_TEST(lid_switch_double) } END_TEST +START_TEST(lid_switch_down_on_init) +{ + struct litest_device *sw = litest_current_device(); + struct libinput *li; + struct libinput_event *event; + + litest_lid_action(sw, LIBINPUT_SWITCH_STATE_ON); + + /* need separate context to test */ + li = litest_create_context(); + libinput_path_add_device(li, + libevdev_uinput_get_devnode(sw->uinput)); + libinput_dispatch(li); + + litest_wait_for_event_of_type(li, LIBINPUT_EVENT_SWITCH_TOGGLE, -1); + event = libinput_get_event(li); + litest_is_switch_event(event, + LIBINPUT_SWITCH_LID, + LIBINPUT_SWITCH_STATE_ON); + libinput_event_destroy(event); + + while ((event = libinput_get_event(li))) { + ck_assert_int_ne(libinput_event_get_type(event), + LIBINPUT_EVENT_SWITCH_TOGGLE); + libinput_event_destroy(event); + } + + litest_lid_action(sw, LIBINPUT_SWITCH_STATE_OFF); + libinput_dispatch(li); + event = libinput_get_event(li); + litest_is_switch_event(event, + LIBINPUT_SWITCH_LID, + LIBINPUT_SWITCH_STATE_OFF); + libinput_event_destroy(event); + litest_assert_empty_queue(li); + + libinput_unref(li); + +} +END_TEST + static inline struct litest_device * lid_init_paired_touchpad(struct libinput *li) { @@ -257,6 +298,7 @@ litest_setup_tests_lid(void) { litest_add("lid:switch", lid_switch, LITEST_SWITCH, LITEST_ANY); litest_add("lid:switch", lid_switch_double, LITEST_SWITCH, LITEST_ANY); + litest_add("lid:switch", lid_switch_down_on_init, LITEST_SWITCH, LITEST_ANY); litest_add("lid:disable_touchpad", lid_disable_touchpad, LITEST_SWITCH, LITEST_ANY); litest_add("lid:disable_touchpad", lid_disable_touchpad_during_touch, LITEST_SWITCH, LITEST_ANY); litest_add("lid:disable_touchpad", lid_disable_touchpad_edge_scroll, LITEST_SWITCH, LITEST_ANY);