Hi, On 09/03/2014 04:03 AM, Peter Hutterer wrote: > We may be in the middle of a software button click or a tap, so make sure we > go back to the device-neutral state by unwinding. > > Signed-off-by: Peter Hutterer <[email protected]>
Looks good: Reviewed-by: Hans de Goede <[email protected]> Regards, Hans > --- > src/evdev-mt-touchpad-buttons.c | 10 +++++ > src/evdev-mt-touchpad-tap.c | 6 +++ > src/evdev-mt-touchpad.c | 91 > +++++++++++++++++++++++++++++++++++++++++ > src/evdev-mt-touchpad.h | 13 ++++++ > test/device.c | 10 ++--- > 5 files changed, 125 insertions(+), 5 deletions(-) > > diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c > index f6235a0..1dd8913 100644 > --- a/src/evdev-mt-touchpad-buttons.c > +++ b/src/evdev-mt-touchpad-buttons.c > @@ -484,6 +484,16 @@ tp_process_button(struct tp_dispatch *tp, > return 0; > } > > +void > +tp_release_all_buttons(struct tp_dispatch *tp, > + uint64_t time) > +{ > + if (tp->buttons.state) { > + tp->buttons.state = 0; > + tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE; > + } > +} > + > int > tp_init_buttons(struct tp_dispatch *tp, > struct evdev_device *device) > diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c > index a19d51e..8f055fc 100644 > --- a/src/evdev-mt-touchpad-tap.c > +++ b/src/evdev-mt-touchpad-tap.c > @@ -693,3 +693,9 @@ tp_destroy_tap(struct tp_dispatch *tp) > { > libinput_timer_cancel(&tp->tap.timer); > } > + > +void > +tp_release_all_taps(struct tp_dispatch *tp, uint64_t now) > +{ > + tp_tap_handle_timeout(now, tp); > +} > diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c > index cd31c48..51eced6 100644 > --- a/src/evdev-mt-touchpad.c > +++ b/src/evdev-mt-touchpad.c > @@ -641,6 +641,41 @@ tp_destroy(struct evdev_dispatch *dispatch) > free(tp); > } > > +static void > +tp_suspend(struct tp_dispatch *tp, struct evdev_device *device) > +{ > + uint64_t now = libinput_now(tp->device->base.seat->libinput); > + struct tp_touch *t; > + > + /* Unroll the touchpad state. > + * Release buttons first. If tp is a clickpad, the button event > + * must come before the touch up. If it isn't, the order doesn't > + * matter anyway > + * > + * Then cancel all timeouts on the taps, triggering the last set > + * of events. > + * > + * Then lift all touches so the touchpad is in a neutral state. > + * > + */ > + tp_release_all_buttons(tp, now); > + tp_release_all_taps(tp, now); > + > + tp_for_each_touch(tp, t) { > + tp_end_touch(tp, t, now); > + } > + > + tp_handle_state(tp, now); > + > + evdev_device_suspend(device); > +} > + > +static void > +tp_resume(struct tp_dispatch *tp, struct evdev_device *device) > +{ > + evdev_device_resume(device); > +} > + > static struct evdev_dispatch_interface tp_interface = { > tp_process, > tp_destroy > @@ -836,6 +871,54 @@ tp_init(struct tp_dispatch *tp, > return 0; > } > > +static uint32_t > +tp_sendevents_get_modes(struct libinput_device *device) > +{ > + return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED | > + LIBINPUT_CONFIG_SEND_EVENTS_DISABLED; > +} > + > +static enum libinput_config_status > +tp_sendevents_set_mode(struct libinput_device *device, > + enum libinput_config_send_events_mode mode) > +{ > + struct evdev_device *evdev = (struct evdev_device*)device; > + struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch; > + > + if (mode == tp->sendevents.current_mode) > + return LIBINPUT_CONFIG_STATUS_SUCCESS; > + > + switch(mode) { > + case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED: > + tp_resume(tp, evdev); > + break; > + case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED: > + tp_suspend(tp, evdev); > + break; > + default: > + return LIBINPUT_CONFIG_STATUS_UNSUPPORTED; > + } > + > + tp->sendevents.current_mode = mode; > + > + return LIBINPUT_CONFIG_STATUS_SUCCESS; > +} > + > +static enum libinput_config_send_events_mode > +tp_sendevents_get_mode(struct libinput_device *device) > +{ > + struct evdev_device *evdev = (struct evdev_device*)device; > + struct tp_dispatch *dispatch = (struct tp_dispatch*)evdev->dispatch; > + > + return dispatch->sendevents.current_mode; > +} > + > +static enum libinput_config_send_events_mode > +tp_sendevents_get_default_mode(struct libinput_device *device) > +{ > + return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; > +} > + > struct evdev_dispatch * > evdev_mt_touchpad_create(struct evdev_device *device) > { > @@ -850,5 +933,13 @@ evdev_mt_touchpad_create(struct evdev_device *device) > return NULL; > } > > + device->base.config.sendevents = &tp->sendevents.config; > + > + tp->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; > + tp->sendevents.config.get_modes = tp_sendevents_get_modes; > + tp->sendevents.config.set_mode = tp_sendevents_set_mode; > + tp->sendevents.config.get_mode = tp_sendevents_get_mode; > + tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode; > + > return &tp->base; > } > diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h > index 83edf4f..6988b79 100644 > --- a/src/evdev-mt-touchpad.h > +++ b/src/evdev-mt-touchpad.h > @@ -217,6 +217,11 @@ struct tp_dispatch { > int32_t right_edge; > int32_t left_edge; > } palm; > + > + struct { > + struct libinput_device_config_send_events config; > + enum libinput_config_send_events_mode current_mode; > + } sendevents; > }; > > #define tp_for_each_touch(_tp, _t) \ > @@ -248,6 +253,10 @@ tp_process_button(struct tp_dispatch *tp, > const struct input_event *e, > uint64_t time); > > +void > +tp_release_all_buttons(struct tp_dispatch *tp, > + uint64_t time); > + > int > tp_post_button_events(struct tp_dispatch *tp, uint64_t time); > > @@ -260,4 +269,8 @@ tp_button_touch_active(struct tp_dispatch *tp, struct > tp_touch *t); > bool > tp_button_is_inside_softbutton_area(struct tp_dispatch *tp, struct tp_touch > *t); > > +void > +tp_release_all_taps(struct tp_dispatch *tp, > + uint64_t time); > + > #endif > diff --git a/test/device.c b/test/device.c > index 1294740..8db69fd 100644 > --- a/test/device.c > +++ b/test/device.c > @@ -262,12 +262,12 @@ END_TEST > > int main (int argc, char **argv) > { > - litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, > LITEST_TOUCHPAD); > - litest_add("device:sendevents", device_sendevents_config_default, > LITEST_ANY, LITEST_TOUCHPAD); > - litest_add("device:sendevents", device_disable, LITEST_POINTER, > LITEST_TOUCHPAD); > + litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, > LITEST_ANY); > + litest_add("device:sendevents", device_sendevents_config_default, > LITEST_ANY, LITEST_ANY); > + litest_add("device:sendevents", device_disable, LITEST_POINTER, > LITEST_ANY); > litest_add("device:sendevents", device_disable_events_pending, > LITEST_POINTER, LITEST_TOUCHPAD); > - litest_add("device:sendevents", device_double_disable, LITEST_ANY, > LITEST_TOUCHPAD); > - litest_add("device:sendevents", device_double_enable, LITEST_ANY, > LITEST_TOUCHPAD); > + litest_add("device:sendevents", device_double_disable, LITEST_ANY, > LITEST_ANY); > + litest_add("device:sendevents", device_double_enable, LITEST_ANY, > LITEST_ANY); > litest_add_no_device("device:sendevents", > device_reenable_syspath_changed); > litest_add_no_device("device:sendevents", > device_reenable_device_removed); > > _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
