input: introduce touch event mode for calibrator
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@collabora.com> Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> v1 Tested-by: Matt Hoosier <matt.hoosier@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
332a45e096
commit
c4689ff1d0
|
@ -6334,6 +6334,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;
|
||||
|
|
|
@ -489,6 +489,34 @@ struct weston_touch_device_ops {
|
|||
const struct weston_touch_device_matrix *cal);
|
||||
};
|
||||
|
||||
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 *syspath; /**< unique name */
|
||||
|
@ -1092,6 +1120,8 @@ struct weston_compositor {
|
|||
*/
|
||||
struct wl_signal heads_changed_signal;
|
||||
struct wl_event_source *heads_changed_source;
|
||||
|
||||
enum weston_touch_mode touch_mode;
|
||||
};
|
||||
|
||||
struct weston_buffer {
|
||||
|
@ -1573,6 +1603,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);
|
||||
|
|
|
@ -187,6 +187,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)
|
||||
{
|
||||
|
@ -2403,6 +2409,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
|
||||
|
@ -2470,23 +2575,54 @@ notify_touch_normalized(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;
|
||||
|
||||
grab->interface->cancel(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;
|
||||
}
|
||||
|
||||
weston_compositor_update_touch_mode(device->aggregate->seat->compositor);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
Loading…
Reference in New Issue