From d3595908e508a4e18611ce208952add4264c555e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 19 Sep 2018 12:02:51 +1000 Subject: [PATCH] evdev: introduce a touch arbitration enum This enables us to change the types of touch arbitration, with the focus on allowing location-based touch arbitration as well as the more generic "disable everything". Signed-off-by: Peter Hutterer --- src/evdev-fallback.c | 20 +++++++++++--------- src/evdev-fallback.h | 6 +++--- src/evdev-mt-touchpad.c | 22 ++++++++++++---------- src/evdev-mt-touchpad.h | 2 +- src/evdev-tablet.c | 8 +++++++- src/evdev.h | 7 ++++++- 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c index c584e09..4f607d2 100644 --- a/src/evdev-fallback.c +++ b/src/evdev-fallback.c @@ -1196,20 +1196,16 @@ fallback_interface_sync_initial_state(struct evdev_device *device, static void fallback_interface_toggle_touch(struct evdev_dispatch *evdev_dispatch, struct evdev_device *device, - bool enable, + enum evdev_arbitration_state which, uint64_t time) { struct fallback_dispatch *dispatch = fallback_dispatch(evdev_dispatch); - bool ignore_events = !enable; - if (ignore_events == dispatch->arbitration.ignore_events) + if (which == dispatch->arbitration.state) return; - if (ignore_events) { - libinput_timer_cancel(&dispatch->arbitration.arbitration_timer); - fallback_return_to_neutral_state(dispatch, device); - dispatch->arbitration.in_arbitration = true; - } else { + switch (which) { + case ARBITRATION_NOT_ACTIVE: /* if in-kernel arbitration is in use and there is a touch * and a pen in proximity, lifting the pen out of proximity * causes a touch begin for the touch. On a hand-lift the @@ -1219,9 +1215,15 @@ fallback_interface_toggle_touch(struct evdev_dispatch *evdev_dispatch, * event is caught as palm touch. */ libinput_timer_set(&dispatch->arbitration.arbitration_timer, time + ms2us(90)); + break; + case ARBITRATION_IGNORE_ALL: + libinput_timer_cancel(&dispatch->arbitration.arbitration_timer); + fallback_return_to_neutral_state(dispatch, device); + dispatch->arbitration.in_arbitration = true; + break; } - dispatch->arbitration.ignore_events = ignore_events; + dispatch->arbitration.state = which; } static void diff --git a/src/evdev-fallback.h b/src/evdev-fallback.h index 47f9f5e..58694dc 100644 --- a/src/evdev-fallback.h +++ b/src/evdev-fallback.h @@ -141,11 +141,11 @@ struct fallback_dispatch { struct list paired_keyboard_list; } lid; - /* pen/touch arbitration has a delayed state, if ignore_events is - * true we want to ignore events, in_arbitration actually filters. + /* pen/touch arbitration has a delayed state, + * in_arbitration is what decides when to filter. */ struct { - bool ignore_events; + enum evdev_arbitration_state state; bool in_arbitration; struct libinput_timer arbitration_timer; } arbitration; diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 650a193..7385ab5 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1028,7 +1028,7 @@ tp_palm_detect_arbitration_triggered(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) { - if (!tp->arbitration.in_arbitration) + if (tp->arbitration.state == ARBITRATION_NOT_ACTIVE) return false; t->palm.state = PALM_ARBITRATION; @@ -2685,27 +2685,28 @@ tp_arbitration_timeout(uint64_t now, void *data) { struct tp_dispatch *tp = data; - if (tp->arbitration.in_arbitration) - tp->arbitration.in_arbitration = false; + if (tp->arbitration.state != ARBITRATION_NOT_ACTIVE) + tp->arbitration.state = ARBITRATION_NOT_ACTIVE; } static void tp_interface_toggle_touch(struct evdev_dispatch *dispatch, struct evdev_device *device, - bool enable, + enum evdev_arbitration_state which, uint64_t time) { struct tp_dispatch *tp = tp_dispatch(dispatch); - bool arbitrate = !enable; - if (arbitrate == tp->arbitration.in_arbitration) + if (which == tp->arbitration.state) return; - if (arbitrate) { + switch (which) { + case ARBITRATION_IGNORE_ALL: libinput_timer_cancel(&tp->arbitration.arbitration_timer); tp_clear_state(tp); - tp->arbitration.in_arbitration = true; - } else { + tp->arbitration.state = which; + break; + case ARBITRATION_NOT_ACTIVE: /* if in-kernel arbitration is in use and there is a touch * and a pen in proximity, lifting the pen out of proximity * causes a touch begin for the touch. On a hand-lift the @@ -2715,6 +2716,7 @@ tp_interface_toggle_touch(struct evdev_dispatch *dispatch, * event is caught as palm touch. */ libinput_timer_set(&tp->arbitration.arbitration_timer, time + ms2us(90)); + break; } } @@ -3231,7 +3233,7 @@ tp_init_palmdetect_arbitration(struct tp_dispatch *tp, tp_libinput_context(tp), timer_name, tp_arbitration_timeout, tp); - tp->arbitration.in_arbitration = false; + tp->arbitration.state = ARBITRATION_NOT_ACTIVE; } static void diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 93857ae..61db33a 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -270,7 +270,7 @@ struct tp_dispatch { /* pen/touch arbitration */ struct { - bool in_arbitration; + enum evdev_arbitration_state state; struct libinput_timer arbitration_timer; } arbitration; diff --git a/src/evdev-tablet.c b/src/evdev-tablet.c index 899a3f9..6d177e1 100644 --- a/src/evdev-tablet.c +++ b/src/evdev-tablet.c @@ -1623,15 +1623,21 @@ tablet_set_touch_device_enabled(struct evdev_device *touch_device, uint64_t time) { struct evdev_dispatch *dispatch; + enum evdev_arbitration_state which; if (touch_device == NULL) return; + if (enable) + which = ARBITRATION_NOT_ACTIVE; + else + which = ARBITRATION_IGNORE_ALL; + dispatch = touch_device->dispatch; if (dispatch->interface->toggle_touch) dispatch->interface->toggle_touch(dispatch, touch_device, - enable, + which, time); } diff --git a/src/evdev.h b/src/evdev.h index 3a613eb..e983fb1 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -144,6 +144,11 @@ enum evdev_debounce_state { DEBOUNCE_ACTIVE, }; +enum evdev_arbitration_state { + ARBITRATION_NOT_ACTIVE, + ARBITRATION_IGNORE_ALL, +}; + struct evdev_device { struct libinput_device base; @@ -301,7 +306,7 @@ struct evdev_dispatch_interface { * enable/disable touch capabilities */ void (*toggle_touch)(struct evdev_dispatch *dispatch, struct evdev_device *device, - bool enable, + enum evdev_arbitration_state which, uint64_t now); /* Return the state of the given switch */ -- 2.7.4