On Fri, Mar 23, 2018 at 02:01:00PM +0200, Pekka Paalanen wrote:
> From: Louis-Francis Ratté-Boulianne <l...@collabora.com>
> 
> In addition to the normal touch event processing mode, introduce a new
> mode for calibrating a touchscreen input device.
> 
> In the calibration mode, normal touch event processing is skipped, and
> the raw events are forwarded to the calibrator instead. The calibrator
> is not yet implemented, so the calls will be added in a following patch.
> 
> To switch between modes, two functions are added, one for entering each
> mode. The mode switch happens only when no touches are down on any touch
> device, to avoid confusing touch grabs and clients. To realise this, the
> state machine has four states: prepare and actual state for both normal
> and calibrator modes.
> 
> At this point nothing will attempt to change the touch event mode.
> 
> The new calibrator mode is necessary, because when calibrating a
> touchscreen, the touch events must be routed to the calibration client
> directly. The touch coordinates are expected to be wrong, so they cannot
> go through the normal focus surface picking. The calibrator code also
> cannot use the normal touch grab interface, because it needs to be able
> to distinguish between different physical touch input devices, even if
> they are part of the same weston_seat. This requirement makes
> calibration special enough to warrant the new mode, a sort of "super
> grab".
> 
> Co-developed by Louis-Francis and Pekka.
> 
> Signed-off-by: Louis-Francis Ratté-Boulianne <l...@collabora.com>
> Signed-off-by: Pekka Paalanen <pekka.paala...@collabora.co.uk>

series 13-20 Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net>, pls see
my comments in the emails though.

Cheers,
   Peter

> ---
>  libweston/compositor.c |   2 +
>  libweston/compositor.h |  39 +++++++++++++
>  libweston/input.c      | 146 
> +++++++++++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 182 insertions(+), 5 deletions(-)
> 
> diff --git a/libweston/compositor.c b/libweston/compositor.c
> index 8452c5d2..d7922799 100644
> --- a/libweston/compositor.c
> +++ b/libweston/compositor.c
> @@ -6289,6 +6289,8 @@ weston_compositor_create(struct wl_display *display, 
> void *user_data)
>  
>       ec->activate_serial = 1;
>  
> +     ec->touch_mode = WESTON_TOUCH_MODE_NORMAL;
> +
>       if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 4,
>                             ec, compositor_bind))
>               goto fail;
> diff --git a/libweston/compositor.h b/libweston/compositor.h
> index 129e15b8..48a9af55 100644
> --- a/libweston/compositor.h
> +++ b/libweston/compositor.h
> @@ -482,6 +482,34 @@ struct weston_touch_device_ops {
>                               const struct weston_touch_device_matrix 
> *matrix);
>  };
>  
> +enum weston_touch_mode {
> +     /** Normal touch event handling */
> +     WESTON_TOUCH_MODE_NORMAL,
> +
> +     /** Prepare moving to WESTON_TOUCH_MODE_CALIB.
> +      *
> +      * Move to WESTON_TOUCH_MODE_CALIB as soon as no touches are down on
> +      * any seat. Until then, all touch events are routed normally.
> +      */
> +     WESTON_TOUCH_MODE_PREP_CALIB,
> +
> +     /** Calibration mode
> +      *
> +      * Only a single weston_touch_device forwards events to the calibrator
> +      * all other touch device cause a calibrator "wrong device" event to
> +      * be sent.
> +      */
> +     WESTON_TOUCH_MODE_CALIB,
> +
> +     /** Prepare moving to WESTON_TOUCH_MODE_NORMAL.
> +      *
> +      * Move to WESTON_TOUCH_MODE_NORMAL as soon as no touches are down on
> +      * any seat. Until then, touch events are routed as in
> +      * WESTON_TOUCH_MODE_CALIB except "wrong device" events are not sent.
> +      */
> +     WESTON_TOUCH_MODE_PREP_NORMAL
> +};
> +
>  /** Represents a physical touchscreen input device */
>  struct weston_touch_device {
>       char *devpath;                  /**< unique name */
> @@ -1080,6 +1108,8 @@ struct weston_compositor {
>  
>       weston_heads_changed_func_t heads_changed;
>       struct wl_event_source *heads_changed_source;
> +
> +     enum weston_touch_mode touch_mode;
>  };
>  
>  struct weston_buffer {
> @@ -1560,6 +1590,15 @@ notify_touch_frame(struct weston_touch_device *device);
>  void
>  notify_touch_cancel(struct weston_touch_device *device);
>  
> +void
> +weston_compositor_set_touch_mode_normal(struct weston_compositor 
> *compositor);
> +
> +void
> +weston_compositor_set_touch_mode_calib(struct weston_compositor *compositor);
> +
> +static inline void
> +touch_calibrator_mode_changed(struct weston_compositor *compositor) { /* 
> stub */ }
> +
>  void
>  weston_layer_entry_insert(struct weston_layer_entry *list,
>                         struct weston_layer_entry *entry);
> diff --git a/libweston/input.c b/libweston/input.c
> index 7e4677e6..4a82203c 100644
> --- a/libweston/input.c
> +++ b/libweston/input.c
> @@ -185,6 +185,12 @@ weston_touch_device_can_calibrate(struct 
> weston_touch_device *device)
>       return !!device->ops;
>  }
>  
> +static enum weston_touch_mode
> +weston_touch_device_get_mode(struct weston_touch_device *device)
> +{
> +     return device->aggregate->seat->compositor->touch_mode;
> +}
> +
>  static struct weston_pointer_client *
>  weston_pointer_client_create(struct wl_client *client)
>  {
> @@ -2401,6 +2407,105 @@ process_touch_normal(struct weston_touch_device 
> *device,
>       }
>  }
>  
> +static enum weston_touch_mode
> +get_next_touch_mode(enum weston_touch_mode from)
> +{
> +     switch (from) {
> +     case WESTON_TOUCH_MODE_PREP_NORMAL:
> +             return WESTON_TOUCH_MODE_NORMAL;
> +
> +     case WESTON_TOUCH_MODE_PREP_CALIB:
> +             return WESTON_TOUCH_MODE_CALIB;
> +
> +     case WESTON_TOUCH_MODE_NORMAL:
> +     case WESTON_TOUCH_MODE_CALIB:
> +             return from;
> +     }
> +
> +     return WESTON_TOUCH_MODE_NORMAL;
> +}
> +
> +/** Global touch mode update
> + *
> + * If no seat has a touch down and the compositor is in a PREP touch mode,
> + * set the compositor to the goal touch mode.
> + *
> + * Calls calibrator if touch mode changed.
> + */
> +static void
> +weston_compositor_update_touch_mode(struct weston_compositor *compositor)
> +{
> +     struct weston_seat *seat;
> +     struct weston_touch *touch;
> +     enum weston_touch_mode goal;
> +
> +     wl_list_for_each(seat, &compositor->seat_list, link) {
> +             touch = weston_seat_get_touch(seat);
> +             if (!touch)
> +                     continue;
> +
> +             if (touch->num_tp > 0)
> +                     return;
> +     }
> +
> +     goal = get_next_touch_mode(compositor->touch_mode);
> +     if (compositor->touch_mode != goal) {
> +             compositor->touch_mode = goal;
> +             touch_calibrator_mode_changed(compositor);
> +     }
> +}
> +
> +/** Start transition to normal touch event handling
> + *
> + * The touch event mode changes when all touches on all touch devices have
> + * been lifted. If no touches are currently down, the transition is 
> immediate.
> + *
> + * \sa weston_touch_mode
> + */
> +void
> +weston_compositor_set_touch_mode_normal(struct weston_compositor *compositor)
> +{
> +     switch (compositor->touch_mode) {
> +     case WESTON_TOUCH_MODE_PREP_NORMAL:
> +     case WESTON_TOUCH_MODE_NORMAL:
> +             return;
> +     case WESTON_TOUCH_MODE_PREP_CALIB:
> +             compositor->touch_mode = WESTON_TOUCH_MODE_NORMAL;
> +             touch_calibrator_mode_changed(compositor);
> +             return;
> +     case WESTON_TOUCH_MODE_CALIB:
> +             compositor->touch_mode = WESTON_TOUCH_MODE_PREP_NORMAL;
> +     }
> +
> +     weston_compositor_update_touch_mode(compositor);
> +}
> +
> +/** Start transition to calibrator touch event handling
> + *
> + * The touch event mode changes when all touches on all touch devices have
> + * been lifted. If no touches are currently down, the transition is 
> immediate.
> + *
> + * \sa weston_touch_mode
> + */
> +void
> +weston_compositor_set_touch_mode_calib(struct weston_compositor *compositor)
> +{
> +     switch (compositor->touch_mode) {
> +     case WESTON_TOUCH_MODE_PREP_CALIB:
> +     case WESTON_TOUCH_MODE_CALIB:
> +             assert(0);
> +             return;
> +     case WESTON_TOUCH_MODE_PREP_NORMAL:
> +             compositor->touch_mode = WESTON_TOUCH_MODE_CALIB;
> +             touch_calibrator_mode_changed(compositor);
> +             return;
> +     case WESTON_TOUCH_MODE_NORMAL:
> +             compositor->touch_mode = WESTON_TOUCH_MODE_PREP_CALIB;
> +     }
> +
> +     weston_compositor_update_touch_mode(compositor);
> +}
> +
>  /** Feed in touch down, motion, and up events, calibratable device.
>   *
>   * It assumes always the correct cycle sequence until it gets here: 
> touch_down
> @@ -2471,23 +2576,54 @@ notify_touch_cal(struct weston_touch_device *device,
>               break;
>       }
>  
> -     process_touch_normal(device, time, touch_id, x, y, touch_type);
> +     /* Properly forward the touch event */
> +     switch (weston_touch_device_get_mode(device)) {
> +     case WESTON_TOUCH_MODE_NORMAL:
> +     case WESTON_TOUCH_MODE_PREP_CALIB:
> +             process_touch_normal(device, time, touch_id, x, y, touch_type);
> +             break;
> +     case WESTON_TOUCH_MODE_CALIB:
> +     case WESTON_TOUCH_MODE_PREP_NORMAL:
> +             break;
> +     }
>  }
>  
>  WL_EXPORT void
>  notify_touch_frame(struct weston_touch_device *device)
>  {
> -     struct weston_touch_grab *grab = device->aggregate->grab;
> +     struct weston_touch_grab *grab;
>  
> -     grab->interface->frame(grab);
> +     switch (weston_touch_device_get_mode(device)) {
> +     case WESTON_TOUCH_MODE_NORMAL:
> +     case WESTON_TOUCH_MODE_PREP_CALIB:
> +             grab = device->aggregate->grab;
> +             grab->interface->frame(grab);
> +             break;
> +     case WESTON_TOUCH_MODE_CALIB:
> +     case WESTON_TOUCH_MODE_PREP_NORMAL:
> +             break;
> +     }
> +
> +     
> weston_compositor_update_touch_mode(device->aggregate->seat->compositor);
>  }
>  
>  WL_EXPORT void
>  notify_touch_cancel(struct weston_touch_device *device)
>  {
> -     struct weston_touch_grab *grab = device->aggregate->grab;
> +     struct weston_touch_grab *grab;
> +
> +     switch (weston_touch_device_get_mode(device)) {
> +     case WESTON_TOUCH_MODE_NORMAL:
> +     case WESTON_TOUCH_MODE_PREP_CALIB:
> +             grab = device->aggregate->grab;
> +             grab->interface->cancel(grab);
> +             break;
> +     case WESTON_TOUCH_MODE_CALIB:
> +     case WESTON_TOUCH_MODE_PREP_NORMAL:
> +             break;
> +     }
>  
> -     grab->interface->cancel(grab);
> +     
> weston_compositor_update_touch_mode(device->aggregate->seat->compositor);
>  }
>  
>  static int
> -- 
> 2.16.1
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
> 
_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to