---
 src/shell.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 155 insertions(+), 4 deletions(-)

diff --git a/src/shell.c b/src/shell.c
index 98fb0fe..0daa136 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -247,6 +247,12 @@ struct ping_timer {
        uint32_t serial;
 };
 
+enum shell_surface_class_interface {
+       SHELL_CLASS_WL_SHELL_SURFACE,
+       SHELL_CLASS_XDG_SURFACE,
+       SHELL_CLASS_XDG_POPUP
+};
+
 struct shell_surface {
        struct wl_resource *resource;
        struct wl_signal destroy_signal;
@@ -257,6 +263,7 @@ struct shell_surface {
        struct weston_surface *parent;
        struct desktop_shell *shell;
 
+       enum shell_surface_class_interface shell_class;
        enum shell_surface_type type, next_type;
        char *title, *class;
        int32_t saved_x, saved_y;
@@ -1918,7 +1925,17 @@ ping_handler(struct weston_surface *surface, uint32_t 
serial)
                        wl_event_loop_add_timer(loop, ping_timeout_handler, 
shsurf);
                wl_event_source_timer_update(shsurf->ping_timer->source, 
ping_timeout);
 
-               wl_shell_surface_send_ping(shsurf->resource, serial);
+               switch (shsurf->shell_class) {
+                       case SHELL_CLASS_WL_SHELL_SURFACE:
+                               wl_shell_surface_send_ping(shsurf->resource, 
serial);
+                               break;
+                       case SHELL_CLASS_XDG_SURFACE:
+                               xdg_surface_send_ping(shsurf->resource, serial);
+                               break;
+                       case SHELL_CLASS_XDG_POPUP:
+                               xdg_popup_send_ping(shsurf->resource, serial);
+                               break;
+               }
        }
 }
 
@@ -2664,7 +2681,17 @@ popup_grab_end(struct weston_pointer *pointer)
                assert(!wl_list_empty(&shseat->popup_grab.surfaces_list));
                /* Send the popup_done event to all the popups open */
                wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, 
popup.grab_link) {
-                       wl_shell_surface_send_popup_done(shsurf->resource);
+                       switch (shsurf->shell_class) {
+                               case SHELL_CLASS_WL_SHELL_SURFACE:
+                                       
wl_shell_surface_send_popup_done(shsurf->resource);
+                                       break;
+                               case SHELL_CLASS_XDG_POPUP:
+                                       
xdg_popup_send_popup_done(shsurf->resource,
+                                                                 
shsurf->popup.serial);
+                                       break;
+                               default:
+                                       break;
+                       }
                        shsurf->popup.shseat = NULL;
                        if (prev) {
                                wl_list_init(&prev->popup.grab_link);
@@ -2726,7 +2753,17 @@ shell_map_popup(struct shell_surface *shsurf)
        if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
                add_popup_grab(shsurf, shseat);
        } else {
-               wl_shell_surface_send_popup_done(shsurf->resource);
+               switch (shsurf->shell_class) {
+                       case SHELL_CLASS_WL_SHELL_SURFACE:
+                               
wl_shell_surface_send_popup_done(shsurf->resource);
+                               break;
+                       case SHELL_CLASS_XDG_POPUP:
+                               xdg_popup_send_popup_done(shsurf->resource,
+                                                         shsurf->popup.serial);
+                               break;
+                       default:
+                               break;
+               }
                shseat->popup_grab.client = NULL;
        }
 }
@@ -2932,6 +2969,8 @@ shell_get_shell_surface(struct wl_client *client,
                return;
        }
 
+       shsurf->shell_class = SHELL_CLASS_WL_SHELL_SURFACE;
+
        shsurf->resource =
                wl_resource_create(client,
                                   &wl_shell_surface_interface, 1, id);
@@ -3169,6 +3208,8 @@ xdg_get_xdg_surface(struct wl_client *client,
                return;
        }
 
+       shsurf->shell_class = SHELL_CLASS_XDG_SURFACE;
+
        shsurf->resource =
                wl_resource_create(client,
                                   &xdg_surface_interface, 1, id);
@@ -3177,12 +3218,122 @@ xdg_get_xdg_surface(struct wl_client *client,
                                       shsurf, shell_destroy_shell_surface);
 }
 
+/* xdg-popup implementation */
+
+static void
+xdg_popup_destroy(struct wl_client *client,
+                 struct wl_resource *resource)
+{
+       wl_resource_destroy(resource);
+}
+
+static void
+xdg_popup_pong(struct wl_client *client,
+              struct wl_resource *resource,
+              uint32_t serial)
+{
+       struct shell_surface *shsurf = wl_resource_get_user_data(resource);
+
+       surface_pong(shsurf, serial);
+}
+
+static const struct xdg_popup_interface xdg_popup_implementation = {
+       xdg_popup_destroy,
+       xdg_popup_pong
+};
+
+static void
+xdg_popup_send_configure(struct weston_surface *surface,
+                        uint32_t edges, int32_t width, int32_t height)
+{
+}
+
+static const struct weston_shell_client xdg_popup_client = {
+       xdg_popup_send_configure
+};
+
+static struct shell_surface *
+create_xdg_popup(void *shell, struct weston_surface *surface,
+                const struct weston_shell_client *client,
+                struct weston_surface *parent,
+                struct shell_seat *seat,
+                uint32_t serial,
+                int32_t x, int32_t y)
+{
+       struct shell_surface *shsurf;
+       shsurf = create_common_surface(shell, surface, client);
+
+       shsurf->type = SHELL_SURFACE_NONE;
+       shsurf->next_type = SHELL_SURFACE_POPUP;
+       shsurf->parent = parent;
+       shsurf->popup.shseat = seat;
+       shsurf->popup.serial = serial;
+       shsurf->popup.x = x;
+       shsurf->popup.y = y;
+
+       return shsurf;
+}
+
+static void
+xdg_get_xdg_popup(struct wl_client *client,
+                 struct wl_resource *resource,
+                 uint32_t id,
+                 struct wl_resource *surface_resource,
+                 struct wl_resource *parent_resource,
+                 struct wl_resource *seat_resource,
+                 uint32_t serial,
+                 int32_t x, int32_t y, uint32_t flags)
+{
+       struct weston_surface *surface =
+               wl_resource_get_user_data(surface_resource);
+       struct desktop_shell *shell = wl_resource_get_user_data(resource);
+       struct shell_surface *shsurf;
+       struct weston_surface *parent;
+       struct shell_seat *seat;
+
+       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 (!parent_resource) {
+               wl_resource_post_error(surface_resource,
+                                      WL_DISPLAY_ERROR_INVALID_OBJECT,
+                                      "xdg_shell::get_xdg_popup requires a 
parent shell surface");
+       }
+
+       parent = wl_resource_get_user_data(parent_resource);
+       seat = get_shell_seat(wl_resource_get_user_data(seat_resource));;
+
+       shsurf = create_xdg_popup(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");
+               return;
+       }
+
+       shsurf->shell_class = SHELL_CLASS_XDG_POPUP;
+
+       shsurf->resource =
+               wl_resource_create(client,
+                                  &xdg_popup_interface, 1, id);
+       wl_resource_set_implementation(shsurf->resource,
+                                      &xdg_popup_implementation,
+                                      shsurf, shell_destroy_shell_surface);
+}
+
 static const struct xdg_shell_interface xdg_implementation = {
        xdg_use_unstable_version,
        xdg_get_xdg_surface,
-       NULL // get_xdg_popup
+       xdg_get_xdg_popup
 };
 
+/* end of xdg-shell implementation */
+/***********************************/
 
 static void
 shell_fade(struct desktop_shell *shell, enum fade_type type);
-- 
1.8.3.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to