[PATCH weston v6 14/73] libweston: add heads_changed hook

Pekka Paalanen ppaalanen at gmail.com
Fri Feb 16 14:56:59 UTC 2018


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

Add a hook for compositors to get a callback when heads are added or
their connection status changes, to which compositors likely want to
react to by enabling or disabling outputs (API for that to be added
later).

As many head changes as possible should be coalesced into a single
heads_changed call. Therefore the callback is made from an idle task.
This anticipates a future atomic output configuration API, where the
global output configuration is tested and set atomically instead of one
by one.

weston_pending_output_coldplug() needs to manually execute the
heads_changed call so that initial outputs are created before any
plugins get their start-up idle tasks ran. This is especially important
for ivi-shell which does not support output hotplug, and for tests to
guarantee the expected outputs.

v6:
- fix a typo
- add comment in weston_pending_output_coldplug()

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Reviewed-by: Derek Foreman <derekf at osg.samsung.com>
---
 libweston/compositor.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++-
 libweston/compositor.h |  8 +++++
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/libweston/compositor.c b/libweston/compositor.c
index cc71a18e..8153540c 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -4439,12 +4439,47 @@ weston_head_init(struct weston_head *head, const char *name)
 	head->name = strdup(name);
 }
 
+/** Idle task for calling heads_changed callback */
+static void
+weston_compositor_call_heads_changed(void *data)
+{
+	struct weston_compositor *compositor = data;
+
+	compositor->heads_changed_source = NULL;
+
+	if (!compositor->heads_changed)
+		return;
+
+	compositor->heads_changed(compositor);
+}
+
+/** Schedule a call on idle to heads_changed callback
+ *
+ * \param compositor The Compositor.
+ *
+ * \memberof weston_compositor
+ * \internal
+ */
+static void
+weston_compositor_schedule_heads_changed(struct weston_compositor *compositor)
+{
+	struct wl_event_loop *loop;
+
+	if (compositor->heads_changed_source)
+		return;
+
+	loop = wl_display_get_event_loop(compositor->wl_display);
+	compositor->heads_changed_source = wl_event_loop_add_idle(loop,
+			weston_compositor_call_heads_changed, compositor);
+}
+
 /** Register a new head
  *
  * \param compositor The compositor.
  * \param head The head to register, must not be already registered.
  *
- * This signals the core that a new head has become available.
+ * This signals the core that a new head has become available, leading to
+ * heads_changed hook being called later.
  *
  * \memberof weston_compositor
  * \internal
@@ -4458,6 +4493,30 @@ weston_compositor_add_head(struct weston_compositor *compositor,
 
 	wl_list_insert(compositor->head_list.prev, &head->compositor_link);
 	head->compositor = compositor;
+	weston_compositor_schedule_heads_changed(compositor);
+}
+
+/** Set the function to be called when heads change
+ *
+ * \param compositor The compositor.
+ * \param cb The function to call, or NULL for none.
+ *
+ * Setting the function overrides any previous setting.
+ *
+ * The callback function will be called after heads are added or their
+ * connection status has changed. Several changes may be accumulated into a
+ * single call. The user is expected to iterate over the existing heads and
+ * check their statuses to find out what changed.
+ *
+ * \sa weston_compositor_iterate_heads, weston_head_is_connected,
+ * weston_head_is_enabled
+ * \memberof weston_compositor
+ */
+WL_EXPORT void
+weston_compositor_set_heads_changed_cb(struct weston_compositor *compositor,
+				       weston_heads_changed_func_t cb)
+{
+	compositor->heads_changed = cb;
 }
 
 /** Iterate over available heads
@@ -4681,13 +4740,23 @@ weston_head_set_internal(struct weston_head *head)
  * disconnected. For nested backends, the connection status should reflect the
  * connection to the parent display server.
  *
+ * When the connection status changes, it schedules a call to the heads_changed
+ * hook.
+ *
+ * \sa weston_compositor_set_heads_changed_cb
  * \memberof weston_head
  * \internal
  */
 WL_EXPORT void
 weston_head_set_connection_status(struct weston_head *head, bool connected)
 {
+	if (head->connected == connected)
+		return;
+
 	head->connected = connected;
+
+	if (head->compositor)
+		weston_compositor_schedule_heads_changed(head->compositor);
 }
 
 /** Is the head currently connected?
@@ -5348,6 +5417,15 @@ weston_pending_output_coldplug(struct weston_compositor *compositor)
 
 	wl_list_for_each_safe(output, next, &compositor->pending_output_list, link)
 		wl_signal_emit(&compositor->output_pending_signal, output);
+
+	/* Execute the heads changed callback manually to ensure it is
+	 * processed before any plugins get their start-up idle tasks ran.
+	 * This ensures the plugins see all the initial outputs.
+	 */
+	if (compositor->heads_changed_source) {
+		wl_event_source_remove(compositor->heads_changed_source);
+		weston_compositor_call_heads_changed(compositor);
+	}
 }
 
 /** Uninitialize an output
@@ -6059,6 +6137,9 @@ weston_compositor_destroy(struct weston_compositor *compositor)
 
 	weston_plugin_api_destroy_list(compositor);
 
+	if (compositor->heads_changed_source)
+		wl_event_source_remove(compositor->heads_changed_source);
+
 	free(compositor);
 }
 
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 7c95b454..4fb9d88f 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -882,6 +882,8 @@ struct weston_backend {
 struct weston_desktop_xwayland;
 struct weston_desktop_xwayland_interface;
 
+typedef void (*weston_heads_changed_func_t)(struct weston_compositor *compositor);
+
 struct weston_compositor {
 	struct wl_signal destroy_signal;
 
@@ -977,6 +979,8 @@ struct weston_compositor {
 	/* Whether to let the compositor run without any input device. */
 	bool require_input;
 
+	weston_heads_changed_func_t heads_changed;
+	struct wl_event_source *heads_changed_source;
 };
 
 struct weston_buffer {
@@ -1986,6 +1990,10 @@ weston_compositor_iterate_heads(struct weston_compositor *compositor,
 				struct weston_head *iter);
 
 void
+weston_compositor_set_heads_changed_cb(struct weston_compositor *compositor,
+				       weston_heads_changed_func_t cb);
+
+void
 weston_output_set_scale(struct weston_output *output,
 			int32_t scale);
 
-- 
2.13.6



More information about the wayland-devel mailing list