[PATCH weston 08/25] libweston: require connected heads for input devices

Pekka Paalanen ppaalanen at gmail.com
Fri Mar 23 12:00:48 UTC 2018


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

The use case driving this change is a clone mode setup, where the user
is hotplugging or unplugging a cloned touchscreen. Even if the output
and head are force-enabled, the touch device should still follow the
connector connection status. If there is no video signal for the
touchscreen (disconnected connector), then the touch input should be
ignored as well.

When the output is force-enabled, we need to trigger
output_heads_changed from connector status changes. If the head or
output are not force-enabled, the compositor will likely attach and
detach the head as appropriate. In clone mode, the attach or detach
needs to trigger output_heads_changed directly. In other cases, it may
be handled through the output getting enabled or disabled which are
different signals.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 libweston/compositor.c    | 30 ++++++++++++++++++++++++++++++
 libweston/compositor.h    |  1 +
 libweston/libinput-seat.c | 39 ++++++++++++++++++++++++++++++++++-----
 libweston/libinput-seat.h |  1 +
 4 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/libweston/compositor.c b/libweston/compositor.c
index 362074b6..8452c5d2 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -4454,11 +4454,31 @@ weston_head_init(struct weston_head *head, const char *name)
 	head->name = strdup(name);
 }
 
+/** Send output heads changed signal
+ *
+ * \param output The output that changed.
+ *
+ * Notify that the enabled output gained and/or lost heads, or that the
+ * associated heads may have changed their connection status. This does not
+ * include cases where the output becomes enabled or disabled. The registered
+ * callbacks are called after the change has successfully happened.
+ *
+ * If connection status change causes the compositor to attach or detach a head
+ * to an enabled output, the registered callbacks may be called multiple times.
+ */
+static void
+weston_output_emit_heads_changed(struct weston_output *output)
+{
+	wl_signal_emit(&output->compositor->output_heads_changed_signal,
+		       output);
+}
+
 /** Idle task for calling heads_changed callback */
 static void
 weston_compositor_call_heads_changed(void *data)
 {
 	struct weston_compositor *compositor = data;
+	struct weston_head *head;
 
 	compositor->heads_changed_source = NULL;
 
@@ -4466,6 +4486,11 @@ weston_compositor_call_heads_changed(void *data)
 		return;
 
 	compositor->heads_changed(compositor);
+
+	wl_list_for_each(head, &compositor->head_list, compositor_link) {
+		if (head->output && head->output->enabled)
+			weston_output_emit_heads_changed(head->output);
+	}
 }
 
 /** Schedule a call on idle to heads_changed callback
@@ -4672,6 +4697,8 @@ weston_output_attach_head(struct weston_output *output,
 		weston_log("Output '%s' updated to have head(s) %s\n",
 			   output->name, head_names);
 		free(head_names);
+
+		weston_output_emit_heads_changed(output);
 	}
 
 	return 0;
@@ -4717,6 +4744,8 @@ weston_head_detach(struct weston_head *head)
 			weston_log("Output '%s' updated to have head(s) %s\n",
 				   output->name, head_names);
 			free(head_names);
+
+			weston_output_emit_heads_changed(output);
 		}
 	}
 }
@@ -6251,6 +6280,7 @@ weston_compositor_create(struct wl_display *display, void *user_data)
 	wl_signal_init(&ec->output_destroyed_signal);
 	wl_signal_init(&ec->output_moved_signal);
 	wl_signal_init(&ec->output_resized_signal);
+	wl_signal_init(&ec->output_heads_changed_signal);
 	wl_signal_init(&ec->session_signal);
 	ec->session_active = 1;
 
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 4e69f932..675ee68f 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -964,6 +964,7 @@ struct weston_compositor {
 	struct wl_signal output_destroyed_signal;
 	struct wl_signal output_moved_signal;
 	struct wl_signal output_resized_signal; /* callback argument: resized output */
+	struct wl_signal output_heads_changed_signal; /* arg: weston_output */
 
 	struct wl_signal session_signal;
 	int session_active;
diff --git a/libweston/libinput-seat.c b/libweston/libinput-seat.c
index 3cece3a1..ac1e8e99 100644
--- a/libweston/libinput-seat.c
+++ b/libweston/libinput-seat.c
@@ -68,9 +68,16 @@ output_find_by_head_name(struct weston_compositor *compositor,
 	if (!head_name)
 		return NULL;
 
-	/* only enabled outputs */
+	/* Only enabled outputs with connected heads.
+	 * This means force-enabled outputs but with disconnected heads
+	 * will be ignored; if the touchscreen doesn't have a video signal,
+	 * touching it is meaningless.
+	 */
 	wl_list_for_each(output, &compositor->output_list, link) {
 		wl_list_for_each(head, &output->head_list, output_link) {
+			if (!weston_head_is_connected(head))
+				continue;
+
 			if (strcmp(head_name, head->name) == 0)
 				return output;
 		}
@@ -377,12 +384,9 @@ udev_seat_led_update(struct weston_seat *seat_base, enum weston_led leds)
 }
 
 static void
-notify_output_create(struct wl_listener *listener, void *data)
+udev_seat_output_changed(struct udev_seat *seat, struct weston_output *output)
 {
-	struct udev_seat *seat = container_of(listener, struct udev_seat,
-					      output_create_listener);
 	struct evdev_device *device;
-	struct weston_output *output = data;
 	struct weston_output *found;
 
 	wl_list_for_each(device, &seat->devices_list, link) {
@@ -406,6 +410,26 @@ notify_output_create(struct wl_listener *listener, void *data)
 	}
 }
 
+static void
+notify_output_create(struct wl_listener *listener, void *data)
+{
+	struct udev_seat *seat = container_of(listener, struct udev_seat,
+					      output_create_listener);
+	struct weston_output *output = data;
+
+	udev_seat_output_changed(seat, output);
+}
+
+static void
+notify_output_heads_changed(struct wl_listener *listener, void *data)
+{
+	struct udev_seat *seat = container_of(listener, struct udev_seat,
+					      output_heads_listener);
+	struct weston_output *output = data;
+
+	udev_seat_output_changed(seat, output);
+}
+
 static struct udev_seat *
 udev_seat_create(struct udev_input *input, const char *seat_name)
 {
@@ -423,6 +447,10 @@ udev_seat_create(struct udev_input *input, const char *seat_name)
 	wl_signal_add(&c->output_created_signal,
 		      &seat->output_create_listener);
 
+	seat->output_heads_listener.notify = notify_output_heads_changed;
+	wl_signal_add(&c->output_heads_changed_signal,
+		      &seat->output_heads_listener);
+
 	wl_list_init(&seat->devices_list);
 
 	return seat;
@@ -440,6 +468,7 @@ udev_seat_destroy(struct udev_seat *seat)
 	udev_seat_remove_devices(seat);
 	weston_seat_release(&seat->base);
 	wl_list_remove(&seat->output_create_listener.link);
+	wl_list_remove(&seat->output_heads_listener.link);
 	free(seat);
 }
 
diff --git a/libweston/libinput-seat.h b/libweston/libinput-seat.h
index 65c9b64b..8c6a5bf7 100644
--- a/libweston/libinput-seat.h
+++ b/libweston/libinput-seat.h
@@ -39,6 +39,7 @@ struct udev_seat {
 	struct weston_seat base;
 	struct wl_list devices_list;
 	struct wl_listener output_create_listener;
+	struct wl_listener output_heads_listener;
 };
 
 typedef void (*udev_configure_device_t)(struct weston_compositor *compositor,
-- 
2.16.1



More information about the wayland-devel mailing list