From 5159af060795dda215a26f93b9c6cfd7b5764db1 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 11 Mar 2021 11:31:14 +0100 Subject: [PATCH] backend-headless: check that outputs and heads are in fact ours As a first step towards heterogeneous outputs, ignore other backends' heads and outputs. This is done by checking the destroy callbacks for heads and outputs. See: https://gitlab.freedesktop.org/wayland/weston/-/issues/268 Signed-off-by: Philipp Zabel --- libweston/backend-headless/headless.c | 48 +++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/libweston/backend-headless/headless.c b/libweston/backend-headless/headless.c index 7165ce40..bf8309f6 100644 --- a/libweston/backend-headless/headless.c +++ b/libweston/backend-headless/headless.c @@ -79,15 +79,25 @@ static const uint32_t headless_formats[] = { DRM_FORMAT_ARGB8888, }; +static void +headless_head_destroy(struct weston_head *base); + static inline struct headless_head * to_headless_head(struct weston_head *base) { + if (base->backend_id != headless_head_destroy) + return NULL; return container_of(base, struct headless_head, base); } +static void +headless_output_destroy(struct weston_output *base); + static inline struct headless_output * to_headless_output(struct weston_output *base) { + if (base->destroy != headless_output_destroy) + return NULL; return container_of(base, struct headless_output, base); } @@ -125,7 +135,11 @@ headless_output_repaint(struct weston_output *output_base, pixman_region32_t *damage) { struct headless_output *output = to_headless_output(output_base); - struct weston_compositor *ec = output->base.compositor; + struct weston_compositor *ec; + + assert(output); + + ec = output->base.compositor; ec->renderer->repaint_output(&output->base, damage); @@ -158,11 +172,15 @@ static int headless_output_disable(struct weston_output *base) { struct headless_output *output = to_headless_output(base); - struct headless_backend *b = to_headless_backend(base->compositor); + struct headless_backend *b; + + assert(output); if (!output->base.enabled) return 0; + b = to_headless_backend(base->compositor); + wl_event_source_remove(output->finish_frame_timer); switch (b->renderer_type) { @@ -184,6 +202,8 @@ headless_output_destroy(struct weston_output *base) { struct headless_output *output = to_headless_output(base); + assert(output); + headless_output_disable(&output->base); weston_output_release(&output->base); @@ -246,10 +266,14 @@ static int headless_output_enable(struct weston_output *base) { struct headless_output *output = to_headless_output(base); - struct headless_backend *b = to_headless_backend(base->compositor); + struct headless_backend *b; struct wl_event_loop *loop; int ret = 0; + assert(output); + + b = to_headless_backend(base->compositor); + loop = wl_display_get_event_loop(b->compositor->wl_display); output->finish_frame_timer = wl_event_loop_add_timer(loop, finish_frame_handler, output); @@ -286,6 +310,9 @@ headless_output_set_size(struct weston_output *base, struct weston_head *head; int output_width, output_height; + if (!output) + return -1; + /* We can only be called once. */ assert(!output->base.current_mode); @@ -360,6 +387,9 @@ headless_head_create(struct weston_compositor *compositor, return -1; weston_head_init(&head->base, name); + + head->base.backend_id = headless_head_destroy; + weston_head_set_connection_status(&head->base, true); weston_head_set_supported_eotf_mask(&head->base, WESTON_EOTF_MODE_ALL_MASK); @@ -375,8 +405,12 @@ headless_head_create(struct weston_compositor *compositor, } static void -headless_head_destroy(struct headless_head *head) +headless_head_destroy(struct weston_head *base) { + struct headless_head *head = to_headless_head(base); + + assert(head); + weston_head_release(&head->base); free(head); } @@ -389,8 +423,10 @@ headless_destroy(struct weston_compositor *ec) weston_compositor_shutdown(ec); - wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) - headless_head_destroy(to_headless_head(base)); + wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) { + if (to_headless_head(base)) + headless_head_destroy(base); + } free(b); }