aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Crisci <tony@dubstepdish.com>2017-09-29 08:58:17 -0400
committerTony Crisci <tony@dubstepdish.com>2017-09-30 08:55:40 -0400
commit19e30aab9bd7a0d572e065374d52a4cb0b160d5f (patch)
tree885d5337a4f15e8c2e0313572d3fa404f47f8c6d
parent93f79378f7801d3d7fce0125bf0b43b89252e2b8 (diff)
subcompositor protocol errors
-rw-r--r--include/wlr/types/wlr_surface.h5
-rw-r--r--types/wlr_compositor.c29
-rw-r--r--types/wlr_surface.c11
3 files changed, 41 insertions, 4 deletions
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index b6d5f79f..38d6b453 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -114,4 +114,9 @@ int wlr_surface_set_role(struct wlr_surface *surface, const char *role,
void wlr_surface_make_subsurface(struct wlr_surface *surface,
struct wlr_surface *parent, uint32_t id);
+/**
+ * Get the top of the subsurface tree for this surface.
+ */
+struct wlr_surface *wlr_surface_get_main_surface(struct wlr_surface *surface);
+
#endif
diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c
index a142ddd4..12903cda 100644
--- a/types/wlr_compositor.c
+++ b/types/wlr_compositor.c
@@ -84,10 +84,31 @@ static void subcompositor_get_subsurface(struct wl_client *client,
struct wlr_surface *surface = wl_resource_get_user_data(surface_resource);
struct wlr_surface *parent = wl_resource_get_user_data(parent_resource);
- // TODO: errors
- // * cannot be its own parent
- // * cannot already a subsurface
- // * cannot be an ancestor of parent
+ static const char msg[] = "get_subsurface: wl_subsurface@";
+
+ if (surface == parent) {
+ wl_resource_post_error(resource,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
+ "%s%d: wl_surface@%d cannot be its own parent",
+ msg, id, wl_resource_get_id(surface_resource));
+ return;
+ }
+
+ if (surface->subsurface) {
+ wl_resource_post_error(resource,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
+ "%s%d: wl_surface@%d is already a sub-surface",
+ msg, id, wl_resource_get_id(surface_resource));
+ return;
+ }
+
+ if (wlr_surface_get_main_surface(parent) == surface) {
+ wl_resource_post_error(resource,
+ WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
+ "%s%d: wl_surface@%d is an ancestor of parent",
+ msg, id, wl_resource_get_id(surface_resource));
+ return;
+ }
if (wlr_surface_set_role(surface, "wl_subsurface", resource,
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0) {
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 6f6df226..8c084ceb 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -769,3 +769,14 @@ void wlr_surface_make_subsurface(struct wlr_surface *surface,
surface->subsurface = subsurface;
}
+
+
+struct wlr_surface *wlr_surface_get_main_surface(struct wlr_surface *surface) {
+ struct wlr_subsurface *sub;
+
+ while (surface && (sub = surface->subsurface)) {
+ surface = sub->parent;
+ }
+
+ return surface;
+}