From 69c4cec4f171dd8d1bcce43ec94ce10a94f1eae3 Mon Sep 17 00:00:00 2001
From: Philipp Zabel
Date: Tue, 16 Feb 2021 10:16:11 +0100
Subject: [PATCH] backend-wayland: 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-wayland/wayland.c | 80 ++++++++++++++++++++++++-----
1 file changed, 67 insertions(+), 13 deletions(-)
diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c
index 825faed3..e98d7d87 100644
--- a/libweston/backend-wayland/wayland.c
+++ b/libweston/backend-wayland/wayland.c
@@ -231,15 +231,25 @@ struct wayland_input {
struct gl_renderer_interface *gl_renderer;
+static void
+wayland_head_destroy(struct weston_head *base);
+
static inline struct wayland_head *
to_wayland_head(struct weston_head *base)
{
+ if (base->backend_id != wayland_head_destroy)
+ return NULL;
return container_of(base, struct wayland_head, base);
}
+static void
+wayland_output_destroy(struct weston_output *base);
+
static inline struct wayland_output *
to_wayland_output(struct weston_output *base)
{
+ if (base->destroy != wayland_output_destroy)
+ return NULL;
return container_of(base, struct wayland_output, base);
}
@@ -499,8 +509,11 @@ static int
wayland_output_start_repaint_loop(struct weston_output *output_base)
{
struct wayland_output *output = to_wayland_output(output_base);
- struct wayland_backend *wb =
- to_wayland_backend(output->base.compositor);
+ struct wayland_backend *wb;
+
+ assert(output);
+
+ wb = to_wayland_backend(output->base.compositor);
/* If this is the initial frame, we need to attach a buffer so that
* the compositor can map the surface and include it in its render
@@ -527,7 +540,11 @@ wayland_output_repaint_gl(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct wayland_output *output = to_wayland_output(output_base);
- struct weston_compositor *ec = output->base.compositor;
+ struct weston_compositor *ec;
+
+ assert(output);
+
+ ec = output->base.compositor;
output->frame_cb = wl_surface_frame(output->parent.surface);
wl_callback_add_listener(output->frame_cb, &frame_listener, output);
@@ -638,10 +655,13 @@ wayland_output_repaint_pixman(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct wayland_output *output = to_wayland_output(output_base);
- struct wayland_backend *b =
- to_wayland_backend(output->base.compositor);
+ struct wayland_backend *b;
struct wayland_shm_buffer *sb;
+ assert(output);
+
+ b = to_wayland_backend(output->base.compositor);
+
if (output->frame) {
if (frame_status(output->frame) & FRAME_STATUS_REPAINT)
wl_list_for_each(sb, &output->shm.buffers, link)
@@ -709,7 +729,11 @@ static int
wayland_output_disable(struct weston_output *base)
{
struct wayland_output *output = to_wayland_output(base);
- struct wayland_backend *b = to_wayland_backend(base->compositor);
+ struct wayland_backend *b;
+
+ assert(output);
+
+ b = to_wayland_backend(base->compositor);
if (!output->base.enabled)
return 0;
@@ -743,6 +767,8 @@ wayland_output_destroy(struct weston_output *base)
{
struct wayland_output *output = to_wayland_output(base);
+ assert(output);
+
wayland_output_disable(&output->base);
weston_output_release(&output->base);
@@ -1045,7 +1071,7 @@ static int
wayland_output_switch_mode(struct weston_output *output_base,
struct weston_mode *mode)
{
- struct wayland_output *output = to_wayland_output(output_base);
+ struct wayland_output *output;
struct wayland_backend *b;
struct wl_surface *old_surface;
struct weston_mode *old_mode;
@@ -1056,6 +1082,9 @@ wayland_output_switch_mode(struct weston_output *output_base,
return -1;
}
+ output = to_wayland_output(output_base);
+ assert(output);
+
if (mode == NULL) {
weston_log("mode is NULL.\n");
return -1;
@@ -1212,10 +1241,14 @@ static int
wayland_output_enable(struct weston_output *base)
{
struct wayland_output *output = to_wayland_output(base);
- struct wayland_backend *b = to_wayland_backend(base->compositor);
+ struct wayland_backend *b;
enum mode_status mode_status;
int ret = 0;
+ assert(output);
+
+ b = to_wayland_backend(base->compositor);
+
wl_list_init(&output->shm.buffers);
wl_list_init(&output->shm.free_buffers);
@@ -1291,9 +1324,16 @@ static int
wayland_output_attach_head(struct weston_output *output_base,
struct weston_head *head_base)
{
- struct wayland_backend *b = to_wayland_backend(output_base->compositor);
struct wayland_output *output = to_wayland_output(output_base);
struct wayland_head *head = to_wayland_head(head_base);
+ struct wayland_backend *b;
+
+ assert(output);
+
+ if (!head)
+ return -1;
+
+ b = to_wayland_backend(output_base->compositor);
if (!wl_list_empty(&output->base.head_list))
return -1;
@@ -1318,6 +1358,8 @@ wayland_output_detach_head(struct weston_output *output_base,
{
struct wayland_output *output = to_wayland_output(output_base);
+ assert(output);
+
/* Rely on the disable hook if the output was enabled. We do not
* support cloned heads, so detaching is guaranteed to disable the
* output.
@@ -1376,6 +1418,9 @@ wayland_head_create(struct weston_compositor *compositor, const char *name)
return NULL;
weston_head_init(&head->base, name);
+
+ head->base.backend_id = wayland_head_destroy;
+
weston_head_set_connection_status(&head->base, true);
weston_compositor_add_head(compositor, &head->base);
@@ -1423,8 +1468,12 @@ wayland_head_create_for_parent_output(struct weston_compositor *compositor,
}
static void
-wayland_head_destroy(struct wayland_head *head)
+wayland_head_destroy(struct weston_head *base)
{
+ struct wayland_head *head = to_wayland_head(base);
+
+ assert(head);
+
if (head->parent_output)
head->parent_output->head = NULL;
@@ -1439,6 +1488,9 @@ wayland_output_set_size(struct weston_output *base, int width, int height)
struct weston_head *head;
int output_width, output_height;
+ if (!output)
+ return -1;
+
/* We can only be called once. */
assert(!output->base.current_mode);
@@ -2555,7 +2607,7 @@ wayland_parent_output_destroy(struct wayland_parent_output *output)
wl_callback_destroy(output->sync_cb);
if (output->head)
- wayland_head_destroy(output->head);
+ wayland_head_destroy(&output->head->base);
wl_output_destroy(output->global);
free(output->physical.make);
@@ -2670,8 +2722,10 @@ wayland_destroy(struct weston_compositor *ec)
weston_compositor_shutdown(ec);
- wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
- wayland_head_destroy(to_wayland_head(base));
+ wl_list_for_each_safe(base, next, &ec->head_list, compositor_link) {
+ if (to_wayland_head(base))
+ wayland_head_destroy(base);
+ }
wl_list_for_each_safe(input, next_input, &b->input_list, link)
wayland_input_destroy(input);