From 75840621534fc0159493a62d8fd479af9ce252c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 6 Sep 2011 13:48:16 -0400 Subject: [PATCH] Add a desktop_shell interface Mostly a toy-thing for now, to allow prototyping a desktop-shell client. --- compositor/Makefile.am | 8 ++- compositor/compositor.c | 3 +- compositor/compositor.h | 3 + compositor/shell.c | 137 ++++++++++++++++++++++++++++++++++++- protocol/desktop-shell.xml | 24 +++++++ 5 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 protocol/desktop-shell.xml diff --git a/compositor/Makefile.am b/compositor/Makefile.am index 46a32208..991e7539 100644 --- a/compositor/Makefile.am +++ b/compositor/Makefile.am @@ -75,7 +75,9 @@ desktop_shell_la_LIBADD = $(COMPOSITOR_LIBS) desktop_shell_la_CFLAGS = $(GCC_CFLAGS) desktop_shell_la_SOURCES = \ shell.c \ - switcher.c + switcher.c \ + desktop-shell-protocol.c \ + desktop-shell-server-protocol.h endif if ENABLE_MEEGO_TABLET_SHELL @@ -96,7 +98,9 @@ BUILT_SOURCES = \ meego-tablet-protocol.c \ meego-tablet-server-protocol.h \ xserver-protocol.c \ - xserver-server-protocol.h + xserver-server-protocol.h \ + desktop-shell-protocol.c \ + desktop-shell-server-protocol.h CLEANFILES = $(BUILT_SOURCES) diff --git a/compositor/compositor.c b/compositor/compositor.c index db8a94a0..005bba00 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -1391,7 +1391,8 @@ notify_button(struct wl_input_device *device, wlsc_compositor_idle_release(compositor); if (state && surface && device->grab == NULL) { - wlsc_surface_activate(surface, wd, time); + compositor->shell->activate(compositor->shell, + surface, wd, time); wl_input_device_start_grab(device, &device->motion_grab, button, time); diff --git a/compositor/compositor.h b/compositor/compositor.h index 0efc873a..be50a1f5 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -153,6 +153,9 @@ struct wlsc_spring { }; struct wlsc_shell { + void (*activate)(struct wlsc_shell *shell, + struct wlsc_surface *es, + struct wlsc_input_device *device, uint32_t time); void (*lock)(struct wlsc_shell *shell); void (*attach)(struct wlsc_shell *shell, struct wlsc_surface *surface); void (*set_selection_focus)(struct wlsc_shell *shell, diff --git a/compositor/shell.c b/compositor/shell.c index 4c959e66..393dfee4 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -21,15 +21,22 @@ */ #include +#include #include #include #include #include "wayland-server.h" #include "compositor.h" +#include "desktop-shell-server-protocol.h" struct wl_shell { + struct wlsc_compositor *compositor; struct wlsc_shell shell; + struct wlsc_surface *panel; + struct wl_listener panel_listener; + struct wlsc_surface *background; + struct wl_listener background_listener; }; struct wlsc_move_grab { @@ -733,7 +740,7 @@ shell_create_selection(struct wl_client *client, wl_client_add_resource(client, &selection->resource); } -const static struct wl_shell_interface shell_interface = { +static const struct wl_shell_interface shell_interface = { shell_move, shell_resize, shell_create_drag, @@ -743,15 +750,93 @@ const static struct wl_shell_interface shell_interface = { shell_set_fullscreen }; +static void +handle_background_surface_destroy(struct wl_listener *listener, + struct wl_resource *resource, uint32_t time) +{ + struct wl_shell *shell = + container_of(listener, struct wl_shell, background_listener); + + fprintf(stderr, "background surface gone\n"); + shell->background = NULL; +} + +static void +desktop_shell_set_background(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct wl_shell *shell = resource->data; + struct wlsc_surface *surface = surface_resource->data; + struct wlsc_output *output = + container_of(shell->compositor->output_list.next, + struct wlsc_output, link); + + shell->background = surface_resource->data; + shell->background_listener.func = handle_background_surface_destroy; + wl_list_insert(&surface_resource->destroy_listener_list, + &shell->background_listener.link); + + wl_resource_post_event(resource, + DESKTOP_SHELL_CONFIGURE, + wlsc_compositor_get_time(), 0, surface, + output->current->width, + output->current->height); +} + +static void +handle_panel_surface_destroy(struct wl_listener *listener, + struct wl_resource *resource, uint32_t time) +{ + struct wl_shell *shell = + container_of(listener, struct wl_shell, panel_listener); + + fprintf(stderr, "panel surface gone\n"); + shell->panel = NULL; +} + +static void +desktop_shell_set_panel(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct wl_shell *shell = resource->data; + struct wlsc_output *output = + container_of(shell->compositor->output_list.next, + struct wlsc_output, link); + + shell->panel = surface_resource->data; + + shell->panel_listener.func = handle_panel_surface_destroy; + wl_list_insert(&surface_resource->destroy_listener_list, + &shell->panel_listener.link); + + wl_resource_post_event(resource, + DESKTOP_SHELL_CONFIGURE, + wlsc_compositor_get_time(), 0, surface_resource, + output->current->width, + output->current->height); +} + +static const struct desktop_shell_interface desktop_shell_implementation = { + desktop_shell_set_background, + desktop_shell_set_panel +}; + static void move_binding(struct wl_input_device *device, uint32_t time, uint32_t key, uint32_t button, uint32_t state, void *data) { + struct wl_shell *shell = data; struct wlsc_surface *surface = (struct wlsc_surface *) device->pointer_focus; if (surface == NULL) return; + if (surface == shell->panel) + return; + if (surface == shell->background) + return; wlsc_surface_move(surface, (struct wlsc_input_device *) device, time); } @@ -760,6 +845,7 @@ static void resize_binding(struct wl_input_device *device, uint32_t time, uint32_t key, uint32_t button, uint32_t state, void *data) { + struct wl_shell *shell = data; struct wlsc_surface *surface = (struct wlsc_surface *) device->pointer_focus; struct wl_resource *resource; @@ -768,6 +854,10 @@ resize_binding(struct wl_input_device *device, uint32_t time, if (surface == NULL) return; + if (surface == shell->panel) + return; + if (surface == shell->background) + return; x = device->grab_x - surface->x; y = device->grab_y - surface->y; @@ -794,15 +884,39 @@ resize_binding(struct wl_input_device *device, uint32_t time, time, edges, resource); } +static void +activate(struct wlsc_shell *base, struct wlsc_surface *es, + struct wlsc_input_device *device, uint32_t time) +{ + struct wl_shell *shell = container_of(base, struct wl_shell, shell); + struct wlsc_compositor *compositor = shell->compositor; + + wlsc_surface_activate(es, device, time); + + if (es == shell->background) { + wl_list_remove(&es->link); + wl_list_insert(compositor->surface_list.prev, &es->link); + } else if (shell->panel) { + wl_list_remove(&shell->panel->link); + wl_list_insert(&compositor->surface_list, &shell->panel->link); + } +} + static void lock(struct wlsc_shell *shell) { } static void -attach(struct wlsc_shell *shell, struct wlsc_surface *es) +attach(struct wlsc_shell *base, struct wlsc_surface *es) { - if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN) { + struct wl_shell *shell = container_of(base, struct wl_shell, shell); + struct wlsc_compositor *compositor = shell->compositor; + + if (es == shell->background) { + wl_list_remove(&es->link); + wl_list_insert(compositor->surface_list.prev, &es->link); + } else if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN) { es->x = (es->fullscreen_output->current->width - es->width) / 2; es->y = (es->fullscreen_output->current->height - es->height) / 2; } @@ -817,6 +931,16 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id) &shell_interface, id, shell); } +static void +bind_desktop_shell(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + struct wl_shell *shell = data; + + wl_client_add_object(client, &desktop_shell_interface, + &desktop_shell_implementation, id, shell); +} + int shell_init(struct wlsc_compositor *ec); @@ -829,6 +953,8 @@ shell_init(struct wlsc_compositor *ec) if (shell == NULL) return -1; + shell->compositor = ec; + shell->shell.activate = activate; shell->shell.lock = lock; shell->shell.attach = attach; shell->shell.set_selection_focus = wlsc_selection_set_focus; @@ -837,6 +963,11 @@ shell_init(struct wlsc_compositor *ec) shell, bind_shell) == NULL) return -1; + if (wl_display_add_global(ec->wl_display, + &desktop_shell_interface, + shell, bind_desktop_shell) == NULL) + return -1; + wlsc_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER, move_binding, shell); wlsc_compositor_add_binding(ec, 0, BTN_MIDDLE, MODIFIER_SUPER, diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml new file mode 100644 index 00000000..438773dd --- /dev/null +++ b/protocol/desktop-shell.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + +