[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