diff options
-rw-r--r-- | desktop-shell/shell.c | 38 | ||||
-rw-r--r-- | src/compositor.c | 33 | ||||
-rw-r--r-- | src/compositor.h | 15 | ||||
-rw-r--r-- | src/data-device.c | 11 | ||||
-rw-r--r-- | src/input.c | 11 | ||||
-rw-r--r-- | xwayland/window-manager.c | 7 |
6 files changed, 69 insertions, 46 deletions
diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c index 810961f8..9fafb39a 100644 --- a/desktop-shell/shell.c +++ b/desktop-shell/shell.c @@ -3463,10 +3463,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) { @@ -3579,18 +3576,13 @@ 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_shell_surface", + resource, WL_SHELL_ERROR_ROLE) < 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_resource_post_no_memory(surface_resource); return; } @@ -3899,18 +3891,13 @@ 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", + resource, XDG_SHELL_ERROR_ROLE) < 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_resource_post_no_memory(surface_resource); return; } @@ -3997,12 +3984,9 @@ 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", + resource, XDG_SHELL_ERROR_ROLE) < 0) return; - } if (!parent_resource) { wl_resource_post_error(surface_resource, @@ -4017,9 +4001,7 @@ xdg_get_xdg_popup(struct wl_client *client, shsurf = create_xdg_popup(sc, shell, surface, &xdg_popup_client, parent, seat, serial, x, y); if (!shsurf) { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "surface->configure already set"); + wl_resource_post_no_memory(surface_resource); return; } diff --git a/src/compositor.c b/src/compositor.c index 29731c74..45409114 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -2764,6 +2764,31 @@ weston_surface_get_main_surface(struct weston_surface *surface) return surface; } +WL_EXPORT int +weston_surface_set_role(struct weston_surface *surface, + const char *role_name, + struct wl_resource *error_resource, + uint32_t error_code) +{ + assert(role_name); + + if (surface->role_name == NULL || + surface->role_name == role_name || + strcmp(surface->role_name, role_name) == 0) { + surface->role_name = role_name; + + return 0; + } + + wl_resource_post_error(error_resource, error_code, + "Cannot assign role %s to wl_surface@%d," + " already has role %s\n", + role_name, + wl_resource_get_id(surface->resource), + surface->role_name); + return -1; +} + static void subsurface_set_position(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y) @@ -3099,13 +3124,9 @@ 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", resource, + WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 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 44379fe2..0fbca331 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -908,6 +908,15 @@ struct weston_surface { */ struct wl_list subsurface_list; /* weston_subsurface::parent_link */ struct wl_list subsurface_list_pending; /* ...::parent_link_pending */ + + /* + * For tracking protocol role assignments. Different roles may + * have the same configure hook, e.g. in shell.c. Configure hook + * may get reset, this will not. + * XXX: map configure functions 1:1 to roles, and never reset it, + * and replace role_name with configure. + */ + const char *role_name; }; struct weston_subsurface { @@ -1231,6 +1240,12 @@ 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 char *role_name, + struct wl_resource *error_resource, + uint32_t error_code); + struct weston_buffer * weston_buffer_from_resource(struct wl_resource *resource); diff --git a/src/data-device.c b/src/data-device.c index 75fc60cb..a8ab4e8c 100644 --- a/src/data-device.c +++ b/src/data-device.c @@ -666,11 +666,12 @@ 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-icon", + resource, + WL_DATA_DEVICE_ERROR_ROLE) < 0) + return; } if (is_pointer_grab) diff --git a/src/input.c b/src/input.c index 530904d6..1c71b2c3 100644 --- a/src/input.c +++ b/src/input.c @@ -1640,14 +1640,11 @@ 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-cursor", + resource, + WL_POINTER_ERROR_ROLE) < 0) return; - } } if (pointer->sprite) diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c index 4e91f9dc..29023733 100644 --- a/xwayland/window-manager.c +++ b/xwayland/window-manager.c @@ -2303,6 +2303,13 @@ xserver_map_shell_surface(struct weston_wm_window *window, if (!shell_interface->get_primary_view) return; + if (window->surface->configure) { + weston_log("warning, unexpected in %s: " + "surface's configure hook is already set.\n", + __func__); + return; + } + window->shsurf = shell_interface->create_shell_surface(shell_interface->shell, window->surface, |