compositor: introduce internal shell_interface
authorTiago Vignatti <tiago.vignatti@intel.com>
Thu, 19 Apr 2012 13:18:18 +0000 (16:18 +0300)
committerKristian Høgsberg <krh@bitplanet.net>
Sun, 22 Apr 2012 03:21:08 +0000 (23:21 -0400)
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>
src/compositor.h
src/shell.c
src/xserver-launcher.c

index 59494ad..5cf4285 100644 (file)
@@ -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;
index 42c980c..ed5ca80 100644 (file)
@@ -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;
 
@@ -676,16 +674,22 @@ reset_shell_surface_type(struct shell_surface *surface)
 }
 
 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)
 
 {
        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);
 
@@ -1083,13 +1085,25 @@ destroy_shell_surface(struct wl_resource *resource)
 }
 
 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)
 {
        struct shell_surface *shsurf = container_of(listener,
                                                    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);
index c5ca326..7ae7776 100644 (file)
@@ -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 = {