[PATCH weston v5 13/36] libweston: add heads_changed hook

Derek Foreman derekf at osg.samsung.com
Fri Feb 2 20:31:59 UTC 2018


On 2017-12-14 05:40 AM, Pekka Paalanen wrote:
> 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.

Thanks for explaining this here, as I would've been wondering why 
otherwise - perhaps a brief comment in the code?

> 
> 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 99299c9f..1d436522 100644
> --- a/libweston/compositor.c
> +++ b/libweston/compositor.c
> @@ -4438,12 +4438,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
> @@ -4457,6 +4492,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.

check their statuses

Reviewed-by: Derek Foreman <derekf at osg.samsung.com>
as is patch 12

> + *
> + * \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
> @@ -4680,13 +4739,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?
> @@ -5296,6 +5365,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
> @@ -6009,6 +6083,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 c08c144c..f7b7050c 100644
> --- a/libweston/compositor.h
> +++ b/libweston/compositor.h
> @@ -883,6 +883,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;
>   
> @@ -978,6 +980,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 {
> @@ -1987,6 +1991,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);
>   
> 



More information about the wayland-devel mailing list