libweston: support user data on weston_output
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>
Tue, 7 Nov 2017 08:15:01 +0000 (10:15 +0200)
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>
Tue, 17 Apr 2018 12:57:41 +0000 (15:57 +0300)
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 <pekka.paalanen@collabora.co.uk>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Derek Foreman <derekf@osg.samsung.com>
libweston/compositor.c
libweston/compositor.h

index 4e15c2e..c4410e6 100644 (file)
@@ -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);
 
index c6083c7..f3137de 100644 (file)
@@ -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 */
@@ -1809,6 +1812,12 @@ 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
 weston_output_transform_coordinate(struct weston_output *output,