---
 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

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to