From 2e1bedb4ed2042264cbbf0ffb4d65de2ba21efd1 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 10 Oct 2017 11:21:58 +0300 Subject: [PATCH] libweston: add weston_head destroy signal Add support for subscribing to weston_head destruction. The primary use case for heads being destroyed arbitrarily is the DRM-backend with MST connectors, which may disappear on unplug. It is not just the connector becoming disconnected, it is the connector actually disappearing. The compositor needs to know about disappearing heads so that it has a chance to clean up "orphaned" outputs which do get disabled but still need destroying at run time. Shutdown would destroy them as well. Signed-off-by: Pekka Paalanen Reviewed-by: Derek Foreman Reviewed-by: Ian Ray Reviewed-by: Daniel Stone Acked-by: Derek Foreman --- libweston/compositor.c | 45 ++++++++++++++++++++++++++++++++++++++++++ libweston/compositor.h | 9 +++++++++ 2 files changed, 54 insertions(+) diff --git a/libweston/compositor.c b/libweston/compositor.c index 23e5ef0e..652d27c2 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -4443,6 +4443,7 @@ weston_head_init(struct weston_head *head, const char *name) memset(head, 0, sizeof *head); wl_list_init(&head->compositor_link); + wl_signal_init(&head->destroy_signal); wl_list_init(&head->output_link); wl_list_init(&head->resource_list); head->name = strdup(name); @@ -4708,6 +4709,8 @@ weston_head_detach(struct weston_head *head) WL_EXPORT void weston_head_release(struct weston_head *head) { + wl_signal_emit(&head->destroy_signal, head); + weston_head_detach(head); free(head->make); @@ -4900,6 +4903,48 @@ weston_head_get_output(struct weston_head *head) return head->output; } +/** Add destroy callback for a head + * + * \param head The head to watch for. + * \param listener The listener to add. The \c notify member must be set. + * + * Heads may get destroyed for various reasons by the backends. If a head is + * attached to an output, the compositor should listen for head destruction + * and reconfigure or destroy the output if necessary. + * + * The destroy callbacks will be called on weston_head destruction before any + * automatic detaching from an associated weston_output and before any + * weston_head information is lost. + * + * The \c data argument to the notify callback is the weston_head being + * destroyed. + */ +WL_EXPORT void +weston_head_add_destroy_listener(struct weston_head *head, + struct wl_listener *listener) +{ + wl_signal_add(&head->destroy_signal, listener); +} + +/** Look up destroy listener for a head + * + * \param head The head to query. + * \param notify The notify function used used for the added destroy listener. + * \return The listener, or NULL if not found. + * + * This looks up the previously added destroy listener struct based on the + * notify function it has. The listener can be used to access user data + * through \c container_of(). + * + * \sa wl_signal_get() + */ +WL_EXPORT struct wl_listener * +weston_head_get_destroy_listener(struct weston_head *head, + wl_notify_func_t notify) +{ + return wl_signal_get(&head->destroy_signal, notify); +} + /* Move other outputs when one is resized so the space remains contiguous. */ static void weston_compositor_reflow_outputs(struct weston_compositor *compositor, diff --git a/libweston/compositor.h b/libweston/compositor.h index 8b20c8c9..b3b0edda 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -155,6 +155,7 @@ enum dpms_enum { struct weston_head { struct weston_compositor *compositor; /**< owning compositor */ struct wl_list compositor_link; /**< in weston_compositor::head_list */ + struct wl_signal destroy_signal; /**< destroy callbacks */ struct weston_output *output; /**< the output driving this head */ struct wl_list output_link; /**< in weston_output::head_list */ @@ -2052,6 +2053,14 @@ weston_head_get_output(struct weston_head *head); void weston_head_detach(struct weston_head *head); +void +weston_head_add_destroy_listener(struct weston_head *head, + struct wl_listener *listener); + +struct wl_listener * +weston_head_get_destroy_listener(struct weston_head *head, + wl_notify_func_t notify); + struct weston_head * weston_compositor_iterate_heads(struct weston_compositor *compositor, struct weston_head *iter);