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

Reply via email to