[PATCH libinput 08/14] switch: sync the initial state of the switch on startup

Peter Hutterer peter.hutterer at who-t.net
Wed Jan 25 23:44:18 UTC 2017


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 <peter.hutterer at who-t.net>
---
 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 216dcc2..2e0402b 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 e1a9088..59c461d 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);
-- 
2.9.3



More information about the wayland-devel mailing list