--- 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