evdev: add an interface hook to suspend a device

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@who-t.net>
Tested-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
Peter Hutterer 2015-05-19 15:57:11 +10:00
parent 58174416ca
commit 736e292fc4
3 changed files with 26 additions and 2 deletions

View file

@ -853,6 +853,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)
{
@ -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,

View file

@ -812,6 +812,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)
{
@ -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;

View file

@ -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);