summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derek.foreman@collabora.com>2022-07-27 10:34:37 -0500
committerDaniel Stone <daniels@collabora.com>2022-08-05 06:08:30 +0000
commit7e7198bd881859b20f74cbdae46b5700ff1cc5d4 (patch)
tree85fd1f6b7f3bdfb10308190a2e26995f40be294e
parent8409b74ec202aefba9e499ee8f87b07cbb0cf128 (diff)
downloadweston-7e7198bd881859b20f74cbdae46b5700ff1cc5d4.tar.gz
libweston: Check output placement
Make sure we don't enable an output that overlaps with other enabled outputs. We should probably do something similar when moving outputs, but we can't realistically do that right now, so at least leave a comment explaining why we're ignoring that case. Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
-rw-r--r--libweston/compositor.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 303f3aa9..e226f69c 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -6608,6 +6608,18 @@ weston_output_set_position(struct weston_output *output, int x, int y)
WL_EXPORT void
weston_output_move(struct weston_output *output, int x, int y)
{
+ /* XXX: we should probably perform some sanity checking here
+ * as we do for weston_output_enable, and allow moves to fail.
+ *
+ * However, while a front-end is rearranging outputs it may
+ * pass through indeterminate states where outputs overlap
+ * or are discontinuous, and this may be ok as long as no
+ * input processing or rendering occurs at that time.
+ *
+ * Ultimately, we probably need a way to pass complete output
+ * config atomically to libweston.
+ */
+
output->compositor->output_flow_dirty = true;
weston_output_set_position(output, x, y);
}
@@ -7230,6 +7242,45 @@ weston_output_create_heads_string(struct weston_output *output)
return str;
}
+static bool
+weston_outputs_overlap(struct weston_output *a, struct weston_output *b)
+{
+ bool overlap;
+ pixman_region32_t intersection;
+
+ pixman_region32_init(&intersection);
+ pixman_region32_intersect(&intersection, &a->region, &b->region);
+ overlap = pixman_region32_not_empty(&intersection);
+ pixman_region32_fini(&intersection);
+
+ return overlap;
+}
+
+/* This only works if the output region is current!
+ *
+ * That means we shouldn't expect it to return usable results unless
+ * the output is at least undergoing enabling.
+ */
+static bool
+weston_output_placement_ok(struct weston_output *output)
+{
+ struct weston_compositor *c = output->compositor;
+ struct weston_output *iter;
+
+ wl_list_for_each(iter, &c->output_list, link) {
+ if (!iter->enabled)
+ continue;
+
+ if (weston_outputs_overlap(iter, output)) {
+ weston_log("Error: output '%s' overlaps enabled output '%s'.\n",
+ output->name, iter->name);
+ return false;
+ }
+ }
+
+ return true;
+}
+
/** Constructs a weston_output object that can be used by the compositor.
*
* \param output The weston_output object that needs to be enabled. Must not
@@ -7309,6 +7360,11 @@ weston_output_enable(struct weston_output *output)
weston_output_transform_scale_init(output, output->transform, output->scale);
weston_output_init_geometry(output, output->x, output->y);
+
+ /* At this point we have a valid region so we can check placement. */
+ if (!weston_output_placement_ok(output))
+ return -1;
+
weston_output_damage(output);
wl_list_init(&output->animation_list);