[PATCH weston v3 13/36] libweston: add heads_changed hook
Pekka Paalanen
ppaalanen at gmail.com
Tue Oct 31 11:48:23 UTC 2017
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.
Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
libweston/compositor.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-
libweston/compositor.h | 8 +++++
2 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/libweston/compositor.c b/libweston/compositor.c
index c8b1ef6d..d9143a02 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -4416,12 +4416,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
@@ -4435,6 +4470,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
+ * checking their status 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
@@ -4658,13 +4717,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?
@@ -5280,6 +5349,11 @@ 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);
+
+ if (compositor->heads_changed_source) {
+ wl_event_source_remove(compositor->heads_changed_source);
+ weston_compositor_call_heads_changed(compositor);
+ }
}
/** Uninitialize an output
@@ -5992,6 +6066,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 80fd66a2..8dd0f231 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -874,6 +874,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;
@@ -969,6 +971,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 {
@@ -1972,6 +1976,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