[PATCH weston 20/25] input: introduce touch event mode for calibrator
Peter Hutterer
peter.hutterer at who-t.net
Mon Apr 9 04:24:59 UTC 2018
On Fri, Mar 23, 2018 at 02:01:00PM +0200, Pekka Paalanen wrote:
> From: Louis-Francis Ratté-Boulianne <lfrb at 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 <lfrb at collabora.com>
> Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
series 13-20 Reviewed-by: Peter Hutterer <peter.hutterer at 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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
More information about the wayland-devel
mailing list