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