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);