[PATCH weston] Send errors if a surface is reusing surface roles

Jasper St. Pierre jstpierre at mecheye.net
Fri Aug 22 10:37:34 PDT 2014


---
 desktop-shell/shell.c | 35 ++++++++++-------------------------
 src/compositor.c      | 25 +++++++++++++++++++------
 src/compositor.h      |  6 ++++++
 src/data-device.c     |  9 ++++-----
 src/input.c           |  9 ++-------
 5 files changed, 41 insertions(+), 43 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 7bfc0d3..66fb9b0 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -3315,10 +3315,7 @@ create_common_surface(struct shell_client *owner, void *shell,
 {
 	struct shell_surface *shsurf;
 
-	if (surface->configure) {
-		weston_log("surface->configure already set\n");
-		return NULL;
-	}
+	assert(surface->configure == NULL);
 
 	shsurf = calloc(1, sizeof *shsurf);
 	if (!shsurf) {
@@ -3405,18 +3402,14 @@ shell_get_shell_surface(struct wl_client *client,
 	struct desktop_shell *shell = sc->shell;
 	struct shell_surface *shsurf;
 
-	if (get_shell_surface(surface)) {
-		wl_resource_post_error(surface_resource,
-				       WL_DISPLAY_ERROR_INVALID_OBJECT,
-				       "desktop_shell::get_shell_surface already requested");
+	if (weston_surface_set_role(surface, &wl_surface_interface) < 0)
 		return;
-	}
 
 	shsurf = create_common_surface(sc, shell, surface, &shell_client);
 	if (!shsurf) {
 		wl_resource_post_error(surface_resource,
-				       WL_DISPLAY_ERROR_INVALID_OBJECT,
-				       "surface->configure already set");
+				       WL_DISPLAY_ERROR_NO_MEMORY,
+				       "No memory");
 		return;
 	}
 
@@ -3707,18 +3700,14 @@ xdg_get_xdg_surface(struct wl_client *client,
 	struct desktop_shell *shell = sc->shell;
 	struct shell_surface *shsurf;
 
-	if (get_shell_surface(surface)) {
-		wl_resource_post_error(surface_resource,
-				       WL_DISPLAY_ERROR_INVALID_OBJECT,
-				       "xdg_shell::get_xdg_surface already requested");
+	if (weston_surface_set_role(surface, &xdg_surface_interface) < 0)
 		return;
-	}
 
 	shsurf = create_xdg_surface(sc, shell, surface, &xdg_client);
 	if (!shsurf) {
 		wl_resource_post_error(surface_resource,
-				       WL_DISPLAY_ERROR_INVALID_OBJECT,
-				       "surface->configure already set");
+				       WL_DISPLAY_ERROR_NO_MEMORY,
+				       "No memory");
 		return;
 	}
 
@@ -3802,12 +3791,8 @@ xdg_get_xdg_popup(struct wl_client *client,
 	struct weston_surface *parent;
 	struct shell_seat *seat;
 
-	if (get_shell_surface(surface)) {
-		wl_resource_post_error(surface_resource,
-				       WL_DISPLAY_ERROR_INVALID_OBJECT,
-				       "xdg_shell::get_xdg_popup already requested");
+	if (weston_surface_set_role(surface, &xdg_popup_interface) < 0)
 		return;
-	}
 
 	if (!parent_resource) {
 		wl_resource_post_error(surface_resource,
@@ -3823,8 +3808,8 @@ xdg_get_xdg_popup(struct wl_client *client,
 				  parent, seat, serial, x, y);
 	if (!shsurf) {
 		wl_resource_post_error(surface_resource,
-				       WL_DISPLAY_ERROR_INVALID_OBJECT,
-				       "surface->configure already set");
+				       WL_DISPLAY_ERROR_NO_MEMORY,
+				       "No memory");
 		return;
 	}
 
diff --git a/src/compositor.c b/src/compositor.c
index 53740ae..ab60fbb 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2599,6 +2599,24 @@ weston_surface_get_main_surface(struct weston_surface *surface)
 	return surface;
 }
 
+WL_EXPORT int
+weston_surface_set_role(struct weston_surface *surface,
+			const struct wl_interface *role_interface)
+{
+	if (surface->role_interface != NULL &&
+	    surface->role_interface != role_interface) {
+		wl_resource_post_error(surface->resource,
+				       WL_SURFACE_ERROR_SURFACE_HAS_EXISTING_ROLE,
+				       "Cannot assign role %s, already has role %s\n",
+				       role_interface->name,
+				       surface->role_interface->name);
+		return -1;
+	}
+
+	surface->role_interface = role_interface;
+	return 0;
+}
+
 static void
 subsurface_set_position(struct wl_client *client,
 			struct wl_resource *resource, int32_t x, int32_t y)
@@ -2934,13 +2952,8 @@ subcompositor_get_subsurface(struct wl_client *client,
 		return;
 	}
 
-	if (surface->configure) {
-		wl_resource_post_error(resource,
-			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
-			"%s%d: wl_surface@%d already has a role",
-			where, id, wl_resource_get_id(surface_resource));
+	if (weston_surface_set_role(surface, &wl_subsurface_interface) < 0)
 		return;
-	}
 
 	if (weston_surface_get_main_surface(parent) == surface) {
 		wl_resource_post_error(resource,
diff --git a/src/compositor.h b/src/compositor.h
index c0fc0a6..d060265 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -888,6 +888,8 @@ struct weston_surface {
 	 */
 	struct wl_list subsurface_list; /* weston_subsurface::parent_link */
 	struct wl_list subsurface_list_pending; /* ...::parent_link_pending */
+
+	const struct wl_interface *role_interface;
 };
 
 struct weston_subsurface {
@@ -1210,6 +1212,10 @@ weston_surface_unmap(struct weston_surface *surface);
 struct weston_surface *
 weston_surface_get_main_surface(struct weston_surface *surface);
 
+int
+weston_surface_set_role(struct weston_surface *surface,
+			const struct wl_interface *role_interface);
+
 struct weston_buffer *
 weston_buffer_from_resource(struct wl_resource *resource);
 
diff --git a/src/data-device.c b/src/data-device.c
index 9953196..ab397ab 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -666,11 +666,10 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
 		source = wl_resource_get_user_data(source_resource);
 	if (icon_resource)
 		icon = wl_resource_get_user_data(icon_resource);
-	if (icon && icon->configure) {
-		wl_resource_post_error(icon_resource,
-				       WL_DISPLAY_ERROR_INVALID_OBJECT,
-				       "surface->configure already set");
-		return;
+
+	if (icon) {
+		if (weston_surface_set_role(icon, &wl_data_device_interface) < 0)
+			return;
 	}
 
 	if (is_pointer_grab)
diff --git a/src/input.c b/src/input.c
index b80fd6d..05ffb89 100644
--- a/src/input.c
+++ b/src/input.c
@@ -1582,14 +1582,9 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
 	if (pointer->focus_serial - serial > UINT32_MAX / 2)
 		return;
 
-	if (surface && pointer->sprite && surface != pointer->sprite->surface) {
-		if (surface->configure) {
-			wl_resource_post_error(surface->resource,
-					       WL_DISPLAY_ERROR_INVALID_OBJECT,
-					       "surface->configure already "
-					       "set");
+	if (surface) {
+		if (weston_surface_set_role(surface, &wl_pointer_interface) < 0)
 			return;
-		}
 	}
 
 	if (pointer->sprite)
-- 
2.1.0



More information about the wayland-devel mailing list