From 37b7c6ebb5418fb5048edaaad1e9e5f617613c8d Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 7 Nov 2017 10:15:01 +0200 Subject: [PATCH] libweston: support user data on weston_output Support attaching custom data to a weston_output by the traditional destroy listener / wl_signal_get approach. Needs a new destroy signal, because user data lifetime should be the lifetime of the weston_output regradless of its enabled status. The old destroy signal is for output consumers that only care about enabled outputs in the system and gets emitted on disable, not on destroy. Signed-off-by: Pekka Paalanen Reviewed-by: Daniel Stone Acked-by: Derek Foreman --- libweston/compositor.c | 46 ++++++++++++++++++++++++++++++++++++++++++ libweston/compositor.h | 11 +++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index 4e15c2e8..c4410e68 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -5445,6 +5445,7 @@ weston_output_init(struct weston_output *output, output->destroying = 0; output->name = strdup(name); wl_list_init(&output->link); + wl_signal_init(&output->user_destroy_signal); output->enabled = false; wl_list_init(&output->head_list); @@ -5685,6 +5686,49 @@ weston_compositor_flush_heads_changed(struct weston_compositor *compositor) } } +/** Add destroy callback for an output + * + * \param output The output to watch. + * \param listener The listener to add. The \c notify member must be set. + * + * The listener callback will be called when user destroys an output. This + * may be delayed by a backend in some cases. The main purpose of the + * listener is to allow hooking up custom data to the output. The custom data + * can be fetched via weston_output_get_destroy_listener() followed by + * container_of(). + * + * The \c data argument to the notify callback is the weston_output being + * destroyed. + * + * @note This is for the final destruction of an output, not when it gets + * disabled. If you want to keep track of enabled outputs, this is not it. + */ +WL_EXPORT void +weston_output_add_destroy_listener(struct weston_output *output, + struct wl_listener *listener) +{ + wl_signal_add(&output->user_destroy_signal, listener); +} + +/** Look up destroy listener for an output + * + * \param output The output 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() weston_output_add_destroy_listener() + */ +WL_EXPORT struct wl_listener * +weston_output_get_destroy_listener(struct weston_output *output, + wl_notify_func_t notify) +{ + return wl_signal_get(&output->user_destroy_signal, notify); +} + /** Uninitialize an output * * Removes the output from the list of enabled outputs if necessary, but @@ -5704,6 +5748,8 @@ weston_output_release(struct weston_output *output) output->destroying = 1; + wl_signal_emit(&output->user_destroy_signal, output); + if (output->idle_repaint_source) wl_event_source_remove(output->idle_repaint_source); diff --git a/libweston/compositor.h b/libweston/compositor.h index c6083c7c..f3137dea 100644 --- a/libweston/compositor.h +++ b/libweston/compositor.h @@ -180,6 +180,9 @@ struct weston_output { uint32_t id; char *name; + /** Matches the lifetime from the user perspective */ + struct wl_signal user_destroy_signal; + void *renderer_state; struct wl_list link; @@ -220,7 +223,7 @@ struct weston_output { struct weston_output_zoom zoom; int dirty; struct wl_signal frame_signal; - struct wl_signal destroy_signal; + struct wl_signal destroy_signal; /**< sent when disabled */ int move_x, move_y; struct timespec frame_time; /* presentation timestamp */ uint64_t msc; /* media stream counter */ @@ -1808,6 +1811,12 @@ weston_output_activate_zoom(struct weston_output *output, void weston_output_move(struct weston_output *output, int x, int y); +void +weston_output_add_destroy_listener(struct weston_output *output, + struct wl_listener *listener); +struct wl_listener * +weston_output_get_destroy_listener(struct weston_output *output, + wl_notify_func_t notify); void weston_output_release(struct weston_output *output); void