mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-07-22 03:04:13 +00:00
compositor: introduce internal shell_interface
We're able now to create shell_surfaces inside Weston. This makes possible the glue needed between shell and xserver-launcher. On the desktop-shell, it was split the protocol part from shell_surface specific functions to make this possible. Signed-off-by: Tiago Vignatti <tiago.vignatti@intel.com>
This commit is contained in:
parent
b10f1e3ab0
commit
bc052c99f9
|
@ -43,6 +43,7 @@ struct weston_transform {
|
|||
};
|
||||
|
||||
struct weston_surface;
|
||||
struct shell_surface;
|
||||
struct weston_input_device;
|
||||
struct weston_output;
|
||||
|
||||
|
@ -53,6 +54,15 @@ struct weston_mode {
|
|||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct weston_shell_interface {
|
||||
void *shell; /* either desktop or tablet */
|
||||
|
||||
void (*create_shell_surface)(void *shell,
|
||||
struct weston_surface *surface,
|
||||
struct shell_surface **ret);
|
||||
void (*set_toplevel)(struct shell_surface *shsurf);
|
||||
};
|
||||
|
||||
struct weston_border {
|
||||
int32_t left, right, top, bottom;
|
||||
};
|
||||
|
@ -194,6 +204,7 @@ struct weston_compositor {
|
|||
struct weston_shader solid_shader;
|
||||
struct weston_shader *current_shader;
|
||||
struct wl_display *wl_display;
|
||||
struct weston_shell_interface shell_interface;
|
||||
|
||||
struct wl_signal activate_signal;
|
||||
struct wl_signal lock_signal;
|
||||
|
|
105
src/shell.c
105
src/shell.c
|
@ -36,8 +36,6 @@
|
|||
#include "desktop-shell-server-protocol.h"
|
||||
#include "../shared/config-parser.h"
|
||||
|
||||
struct shell_surface;
|
||||
|
||||
struct desktop_shell {
|
||||
struct weston_compositor *compositor;
|
||||
|
||||
|
@ -675,6 +673,15 @@ reset_shell_surface_type(struct shell_surface *surface)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_toplevel(struct shell_surface *shsurf)
|
||||
{
|
||||
if (reset_shell_surface_type(shsurf))
|
||||
return;
|
||||
|
||||
shsurf->type = SHELL_SURFACE_TOPLEVEL;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_surface_set_toplevel(struct wl_client *client,
|
||||
struct wl_resource *resource)
|
||||
|
@ -682,10 +689,7 @@ shell_surface_set_toplevel(struct wl_client *client,
|
|||
{
|
||||
struct shell_surface *surface = resource->data;
|
||||
|
||||
if (reset_shell_surface_type(surface))
|
||||
return;
|
||||
|
||||
surface->type = SHELL_SURFACE_TOPLEVEL;
|
||||
set_toplevel(surface);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1055,10 +1059,8 @@ static const struct wl_shell_surface_interface shell_surface_implementation = {
|
|||
};
|
||||
|
||||
static void
|
||||
destroy_shell_surface(struct wl_resource *resource)
|
||||
destroy_shell_surface(struct shell_surface *shsurf)
|
||||
{
|
||||
struct shell_surface *shsurf = resource->data;
|
||||
|
||||
if (shsurf->popup.grab.input_device)
|
||||
wl_input_device_end_pointer_grab(shsurf->popup.grab.input_device);
|
||||
|
||||
|
@ -1082,6 +1084,14 @@ destroy_shell_surface(struct wl_resource *resource)
|
|||
free(shsurf);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_destroy_shell_surface(struct wl_resource *resource)
|
||||
{
|
||||
struct shell_surface *shsurf = resource->data;
|
||||
|
||||
destroy_shell_surface(shsurf);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_handle_surface_destroy(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
@ -1089,7 +1099,11 @@ shell_handle_surface_destroy(struct wl_listener *listener, void *data)
|
|||
struct shell_surface,
|
||||
surface_destroy_listener);
|
||||
|
||||
wl_resource_destroy(&shsurf->resource);
|
||||
/* tricky way to check if resource was in fact created */
|
||||
if (shsurf->resource.object.implementation != 0)
|
||||
wl_resource_destroy(&shsurf->resource);
|
||||
else
|
||||
destroy_shell_surface(shsurf);
|
||||
}
|
||||
|
||||
static struct shell_surface *
|
||||
|
@ -1110,49 +1124,30 @@ static void
|
|||
shell_surface_configure(struct weston_surface *, int32_t, int32_t);
|
||||
|
||||
static void
|
||||
shell_get_shell_surface(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *surface_resource)
|
||||
create_shell_surface(void *shell, struct weston_surface *surface,
|
||||
struct shell_surface **ret)
|
||||
{
|
||||
struct weston_surface *surface = surface_resource->data;
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface->configure) {
|
||||
wl_resource_post_error(surface_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"surface->configure already set");
|
||||
fprintf(stderr, "surface->configure already set\n");
|
||||
return;
|
||||
}
|
||||
|
||||
shsurf = calloc(1, sizeof *shsurf);
|
||||
if (!shsurf) {
|
||||
wl_resource_post_no_memory(resource);
|
||||
fprintf(stderr, "no memory to allocate shell surface\n");
|
||||
return;
|
||||
}
|
||||
|
||||
surface->configure = shell_surface_configure;
|
||||
surface->compositor->shell_interface.shell = shell;
|
||||
|
||||
shsurf->shell = (struct desktop_shell *) shell;
|
||||
shsurf->unresponsive = 0;
|
||||
shsurf->unresponsive_animation.exists = 0;
|
||||
shsurf->unresponsive_animation.fading_in = 0;
|
||||
shsurf->unresponsive_animation.current.frame = unresponsive_fade_frame;
|
||||
|
||||
shsurf->resource.destroy = destroy_shell_surface;
|
||||
shsurf->resource.object.id = id;
|
||||
shsurf->resource.object.interface = &wl_shell_surface_interface;
|
||||
shsurf->resource.object.implementation =
|
||||
(void (**)(void)) &shell_surface_implementation;
|
||||
shsurf->resource.data = shsurf;
|
||||
|
||||
shsurf->shell = resource->data;
|
||||
shsurf->saved_position_valid = false;
|
||||
shsurf->surface = surface;
|
||||
shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT;
|
||||
|
@ -1161,6 +1156,7 @@ shell_get_shell_surface(struct wl_client *client,
|
|||
shsurf->ping_timer = NULL;
|
||||
wl_list_init(&shsurf->fullscreen.transform.link);
|
||||
|
||||
wl_signal_init(&shsurf->resource.destroy_signal);
|
||||
shsurf->surface_destroy_listener.notify = shell_handle_surface_destroy;
|
||||
wl_signal_add(&surface->surface.resource.destroy_signal,
|
||||
&shsurf->surface_destroy_listener);
|
||||
|
@ -1174,7 +1170,42 @@ shell_get_shell_surface(struct wl_client *client,
|
|||
|
||||
shsurf->type = SHELL_SURFACE_NONE;
|
||||
|
||||
wl_client_add_resource(client, &shsurf->resource);
|
||||
*ret = shsurf;
|
||||
}
|
||||
|
||||
static void
|
||||
shell_get_shell_surface(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *surface_resource)
|
||||
{
|
||||
struct weston_surface *surface = surface_resource->data;
|
||||
struct desktop_shell *shell = resource->data;
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
create_shell_surface(shell, surface, &shsurf);
|
||||
if (!shsurf) {
|
||||
wl_resource_post_error(surface_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"surface->configure already set");
|
||||
return;
|
||||
}
|
||||
|
||||
shsurf->resource.destroy = shell_destroy_shell_surface;
|
||||
shsurf->resource.object.id = id;
|
||||
shsurf->resource.object.interface = &wl_shell_surface_interface;
|
||||
shsurf->resource.object.implementation =
|
||||
(void (**)(void)) &shell_surface_implementation;
|
||||
shsurf->resource.data = shsurf;
|
||||
|
||||
wl_client_add_resource(client, &shsurf->resource);
|
||||
}
|
||||
|
||||
static const struct wl_shell_interface shell_implementation = {
|
||||
|
@ -2474,6 +2505,8 @@ shell_init(struct weston_compositor *ec)
|
|||
shell->unlock_listener.notify = unlock;
|
||||
wl_signal_add(&ec->unlock_signal, &shell->unlock_listener);
|
||||
ec->ping_handler = ping_handler;
|
||||
ec->shell_interface.create_shell_surface = create_shell_surface;
|
||||
ec->shell_interface.set_toplevel = set_toplevel;
|
||||
|
||||
wl_list_init(&shell->backgrounds);
|
||||
wl_list_init(&shell->panels);
|
||||
|
|
|
@ -118,6 +118,7 @@ struct weston_wm {
|
|||
struct weston_wm_window {
|
||||
xcb_window_t id;
|
||||
struct weston_surface *surface;
|
||||
struct shell_surface *shsurf;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
char *class;
|
||||
char *name;
|
||||
|
@ -1516,6 +1517,8 @@ xserver_set_window_id(struct wl_client *client, struct wl_resource *resource,
|
|||
struct weston_wm *wm = wxs->wm;
|
||||
struct wl_surface *surface = surface_resource->data;
|
||||
struct weston_wm_window *window;
|
||||
struct weston_shell_interface *shell_interface =
|
||||
&wm->server->compositor->shell_interface;
|
||||
|
||||
if (client != wxs->client)
|
||||
return;
|
||||
|
@ -1532,6 +1535,14 @@ xserver_set_window_id(struct wl_client *client, struct wl_resource *resource,
|
|||
window->surface_destroy_listener.notify = surface_destroy;
|
||||
wl_signal_add(&surface->resource.destroy_signal,
|
||||
&window->surface_destroy_listener);
|
||||
|
||||
if (shell_interface->create_shell_surface) {
|
||||
shell_interface->create_shell_surface(shell_interface->shell,
|
||||
window->surface,
|
||||
&window->shsurf);
|
||||
|
||||
shell_interface->set_toplevel(window->shsurf);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct xserver_interface xserver_implementation = {
|
||||
|
|
Loading…
Reference in a new issue