[PATCH libinput 4/7] evdev: add an interface hook to suspend a device

Peter Hutterer peter.hutterer at who-t.net
Tue May 19 15:52:35 PDT 2015


The touchpad carries enough state around that calling release_all_keys() isn't
enough to properly suspend it. e.g. a button down after tapping won't be
released by trying to release the physical button for it.

We need to clear the state properly, but that's interface-specific so add a
new hook for it.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c | 10 ++++++++++
 src/evdev.c             | 14 ++++++++++++--
 src/evdev.h             |  4 ++++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index c85986e..026f9ee 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -854,6 +854,15 @@ tp_suspend(struct tp_dispatch *tp, struct evdev_device *device)
 }
 
 static void
+tp_interface_suspend(struct evdev_dispatch *dispatch,
+		     struct evdev_device *device)
+{
+	struct tp_dispatch *tp = (struct tp_dispatch *)dispatch;
+
+	tp_clear_state(tp);
+}
+
+static void
 tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
 {
 	if (tp->buttons.has_topbuttons) {
@@ -1060,6 +1069,7 @@ tp_interface_tag_device(struct evdev_device *device,
 
 static struct evdev_dispatch_interface tp_interface = {
 	tp_interface_process,
+	tp_interface_suspend,
 	tp_interface_remove,
 	tp_interface_destroy,
 	tp_interface_device_added,
diff --git a/src/evdev.c b/src/evdev.c
index 87c59dc..d45264b 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -813,6 +813,13 @@ release_pressed_keys(struct evdev_device *device)
 }
 
 static void
+fallback_suspend(struct evdev_dispatch *dispatch,
+		 struct evdev_device *device)
+{
+	release_pressed_keys(device);
+}
+
+static void
 fallback_destroy(struct evdev_dispatch *dispatch)
 {
 	free(dispatch);
@@ -869,6 +876,7 @@ evdev_calibration_get_default_matrix(struct libinput_device *libinput_device,
 
 struct evdev_dispatch_interface fallback_interface = {
 	fallback_process,
+	fallback_suspend,
 	NULL, /* remove */
 	fallback_destroy,
 	NULL, /* device_added */
@@ -2414,14 +2422,16 @@ evdev_device_suspend(struct evdev_device *device)
 {
 	evdev_notify_suspended_device(device);
 
+	if (device->dispatch->interface->suspend)
+		device->dispatch->interface->suspend(device->dispatch,
+						     device);
+
 	if (device->source) {
 		libinput_remove_source(device->base.seat->libinput,
 				       device->source);
 		device->source = NULL;
 	}
 
-	release_pressed_keys(device);
-
 	if (device->mtdev) {
 		mtdev_close_delete(device->mtdev);
 		device->mtdev = NULL;
diff --git a/src/evdev.h b/src/evdev.h
index 20c0b55..086e3b7 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -227,6 +227,10 @@ struct evdev_dispatch_interface {
 			struct input_event *event,
 			uint64_t time);
 
+	/* Device is being suspended */
+	void (*suspend)(struct evdev_dispatch *dispatch,
+			struct evdev_device *device);
+
 	/* Device is being removed (may be NULL) */
 	void (*remove)(struct evdev_dispatch *dispatch);
 
-- 
2.3.5



More information about the wayland-devel mailing list