[RFC weston 6/6] libweston-desktop: Implement xdg_shell_v6
Quentin Glidic
sardemff7+wayland at sardemff7.net
Sun Jul 17 08:59:23 UTC 2016
From: Quentin Glidic <sardemff7+git at sardemff7.net>
Signed-off-by: Quentin Glidic <sardemff7+git at sardemff7.net>
---
Makefile.am | 6 +-
libweston-desktop/libweston-desktop.c | 10 +
libweston-desktop/xdg-shell-v6.c | 884 ++++++++++++++++++++++++++++++++++
3 files changed, 899 insertions(+), 1 deletion(-)
create mode 100644 libweston-desktop/xdg-shell-v6.c
diff --git a/Makefile.am b/Makefile.am
index 59d22f5..9861d0f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -120,12 +120,16 @@ libweston_desktop_la_SOURCES = \
libweston-desktop/surface.c \
libweston-desktop/wl-shell.c \
libweston-desktop/xdg-shell-v5.c \
+ libweston-desktop/xdg-shell-v6.c \
libweston-desktop/xwayland.c
nodist_libweston_desktop_la_SOURCES = \
protocol/xdg-shell-unstable-v5-protocol.c \
- protocol/xdg-shell-unstable-v5-server-protocol.h
+ protocol/xdg-shell-unstable-v5-server-protocol.h \
+ protocol/xdg-shell-unstable-v6-protocol.c \
+ protocol/xdg-shell-unstable-v6-server-protocol.h
+libweston-desktop.la libweston-desktop/xdg-shell-v6.lo: protocol/xdg-shell-unstable-v6-server-protocol.h
libweston-desktop.la libweston-desktop/xdg-shell-v5.lo: protocol/xdg-shell-unstable-v5-server-protocol.h
if SYSTEMD_NOTIFY_SUPPORT
diff --git a/libweston-desktop/libweston-desktop.c b/libweston-desktop/libweston-desktop.c
index 5c6fcbb..9919701 100644
--- a/libweston-desktop/libweston-desktop.c
+++ b/libweston-desktop/libweston-desktop.c
@@ -40,6 +40,7 @@ struct weston_desktop {
struct weston_compositor *compositor;
struct weston_desktop_api api;
void *user_data;
+ struct wl_global *xdg_shell_v6;
struct wl_global *xdg_shell_v5;
struct wl_global *wl_shell;
};
@@ -66,6 +67,13 @@ weston_desktop_create(struct weston_compositor *compositor, const struct weston_
self->api.struct_size = api->struct_size;
memcpy(&self->api, api, self->api.struct_size);
+ self->xdg_shell_v6 = weston_desktop_xdg_shell_v6_create(self, self->compositor->wl_display);
+ if ( self->xdg_shell_v6 == NULL )
+ {
+ weston_desktop_destroy(self);
+ return NULL;
+ }
+
self->xdg_shell_v5 = weston_desktop_xdg_shell_v5_create(self, self->compositor->wl_display);
if ( self->xdg_shell_v5 == NULL )
{
@@ -96,6 +104,8 @@ weston_desktop_destroy(struct weston_desktop *self)
wl_global_destroy(self->wl_shell);
if ( self->xdg_shell_v5 != NULL )
wl_global_destroy(self->xdg_shell_v5);
+ if ( self->xdg_shell_v6 != NULL )
+ wl_global_destroy(self->xdg_shell_v6);
free(self);
}
diff --git a/libweston-desktop/xdg-shell-v6.c b/libweston-desktop/xdg-shell-v6.c
new file mode 100644
index 0000000..bc5bedf
--- /dev/null
+++ b/libweston-desktop/xdg-shell-v6.c
@@ -0,0 +1,884 @@
+/*
+ * Copyright © 2010-2012 Intel Corporation
+ * Copyright © 2011-2012 Collabora, Ltd.
+ * Copyright © 2013 Raspberry Pi Foundation
+ * Copyright © 2016 Quentin "Sardem FF7" Glidic
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include <stdbool.h>
+
+#include <wayland-server.h>
+
+#include "compositor.h"
+#include "zalloc.h"
+#include "protocol/xdg-shell-unstable-v6-server-protocol.h"
+
+#include "libweston-desktop.h"
+#include "internal.h"
+
+#define WD_XDG_SHELL_PROTOCOL_VERSION 1
+
+struct weston_desktop_xdg_positioner {
+ struct weston_desktop *desktop;
+ struct weston_desktop_client *client;
+ struct wl_resource *resource;
+
+ struct weston_desktop_surface_size size;
+ struct weston_desktop_surface_geometry anchor_rect;
+ enum zxdg_positioner_v6_anchor anchor;
+ enum zxdg_positioner_v6_gravity gravity;
+ enum zxdg_positioner_v6_constrain_adjustment constrain_adjustment;
+ struct weston_desktop_surface_position offset;
+};
+
+enum weston_desktop_xdg_surface_role {
+ WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE,
+ WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL,
+ WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP,
+};
+
+struct weston_desktop_xdg_surface {
+ struct wl_resource *resource;
+ struct weston_desktop *desktop;
+ struct weston_desktop_client *client;
+ struct weston_surface *surface;
+ struct weston_desktop_surface *desktop_surface;
+ bool configured;
+ struct wl_event_source *configure_idle;
+ uint32_t configure_serial;
+
+ bool has_geometry;
+ struct weston_desktop_surface_geometry next_geometry, geometry;
+
+ enum weston_desktop_xdg_surface_role role;
+};
+
+struct weston_desktop_xdg_toplevel {
+ struct weston_desktop_xdg_surface base;
+
+ struct wl_resource *resource;
+ struct weston_desktop_xdg_surface *surface;
+ struct weston_desktop_surface_size requested_size;
+ struct {
+ bool maximized;
+ bool fullscreen;
+ bool resizing;
+ bool activated;
+ } requested_state, next_state, state;
+ struct weston_desktop_surface_size next_max_size, max_size, next_min_size, min_size;
+};
+
+struct weston_desktop_xdg_popup {
+ struct weston_desktop_xdg_surface base;
+
+ struct wl_resource *resource;
+ struct weston_desktop_xdg_surface *surface;
+ struct weston_desktop_xdg_surface *parent;
+ struct weston_desktop_seat *seat;
+};
+
+#define weston_desktop_surface_role_biggest_size (sizeof(struct weston_desktop_xdg_toplevel))
+
+
+static struct weston_desktop_surface_position
+_weston_desktop_xdg_positioner_get_position(struct weston_desktop_xdg_positioner *self, struct weston_desktop_surface *surface, struct weston_desktop_surface *parent)
+{
+ struct weston_desktop_surface_position position = {
+ .x = self->anchor_rect.x + self->offset.x,
+ .y = self->anchor_rect.y + self->offset.y,
+ };
+
+ if ( self->constrain_adjustment == ZXDG_POSITIONER_V6_CONSTRAIN_ADJUSTMENT_NONE )
+ return position;
+
+ /* TODO: add compositor policy configuration and the code here */
+
+ return position;
+}
+
+static void
+_weston_desktop_xdg_positioner_protocol_set_size(struct wl_client *wl_client, struct wl_resource *resource, int32_t width, int32_t height)
+{
+ struct weston_desktop_xdg_positioner *self = wl_resource_get_user_data(resource);
+
+ self->size.width = width;
+ self->size.height = height;
+}
+
+static void
+_weston_desktop_xdg_positioner_protocol_set_anchor_rect(struct wl_client *wl_client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ struct weston_desktop_xdg_positioner *self = wl_resource_get_user_data(resource);
+
+ self->anchor_rect.x = x;
+ self->anchor_rect.y = y;
+ self->anchor_rect.width = width;
+ self->anchor_rect.height = height;
+}
+
+static void
+_weston_desktop_xdg_positioner_protocol_set_anchor(struct wl_client *wl_client, struct wl_resource *resource, enum zxdg_positioner_v6_anchor anchor)
+{
+ struct weston_desktop_xdg_positioner *self = wl_resource_get_user_data(resource);
+
+ self->anchor = anchor;
+}
+
+static void
+_weston_desktop_xdg_positioner_protocol_set_gravity(struct wl_client *wl_client, struct wl_resource *resource, enum zxdg_positioner_v6_gravity gravity)
+{
+ struct weston_desktop_xdg_positioner *self = wl_resource_get_user_data(resource);
+
+ self->gravity = gravity;
+}
+
+static void
+_weston_desktop_xdg_positioner_protocol_set_constrain_adjustment(struct wl_client *wl_client, struct wl_resource *resource, enum zxdg_positioner_v6_constrain_adjustment constrain_adjustment)
+{
+ struct weston_desktop_xdg_positioner *self = wl_resource_get_user_data(resource);
+
+ self->constrain_adjustment = constrain_adjustment;
+}
+
+static void
+_weston_desktop_xdg_positioner_protocol_set_offset(struct wl_client *wl_client, struct wl_resource *resource, int32_t x, int32_t y)
+{
+ struct weston_desktop_xdg_positioner *self = wl_resource_get_user_data(resource);
+
+ self->offset.x = x;
+ self->offset.y = y;
+}
+
+
+static void
+_weston_desktop_xdg_positioner_destroy(struct wl_resource *resource)
+{
+ struct weston_desktop_xdg_positioner *self = wl_resource_get_user_data(resource);
+
+ free(self);
+}
+
+static const struct zxdg_positioner_v6_interface _weston_desktop_xdg_positioner_implementation = {
+ .destroy = weston_desktop_destroy_request,
+ .set_size = _weston_desktop_xdg_positioner_protocol_set_size,
+ .set_anchor_rect = _weston_desktop_xdg_positioner_protocol_set_anchor_rect,
+ .set_anchor = _weston_desktop_xdg_positioner_protocol_set_anchor,
+ .set_gravity = _weston_desktop_xdg_positioner_protocol_set_gravity,
+ .set_constrain_adjustment = _weston_desktop_xdg_positioner_protocol_set_constrain_adjustment,
+ .set_offset = _weston_desktop_xdg_positioner_protocol_set_offset,
+};
+
+
+static void _weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *self);
+
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_parent(struct wl_client *wl_client, struct wl_resource *resource, struct wl_resource *parent_resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+ struct weston_desktop_surface *parent = wl_resource_get_user_data(parent_resource);
+
+ weston_desktop_api_set_parent(self->surface->desktop, surface, parent);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_title(struct wl_client *wl_client, struct wl_resource *resource, const char *title)
+{
+ struct weston_desktop_surface *self = wl_resource_get_user_data(resource);
+
+ weston_desktop_surface_set_title(self, title);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_app_id(struct wl_client *wl_client, struct wl_resource *resource, const char *app_id)
+{
+ struct weston_desktop_surface *self = wl_resource_get_user_data(resource);
+
+ weston_desktop_surface_set_app_id(self, app_id);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_show_window_menu(struct wl_client *wl_client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_show_window_menu(self->surface->desktop, surface, seat, x, y);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_move(struct wl_client *wl_client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_move(self->surface->desktop, surface, seat, serial);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_resize(struct wl_client *wl_client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial, enum zxdg_toplevel_v6_resize_edge edges)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_seat *seat = wl_resource_get_user_data(seat_resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_resize(self->surface->desktop, surface, seat, serial, edges);
+}
+
+static void
+_weston_desktop_xdg_toplevel_ack_configure(struct weston_desktop_xdg_toplevel *self)
+{
+ self->next_state = self->requested_state;
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_min_size(struct wl_client *wl_client, struct wl_resource *resource, int32_t width, int32_t height)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ self->next_min_size.width = width;
+ self->next_min_size.height = height;
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_max_size(struct wl_client *wl_client, struct wl_resource *resource, int32_t width, int32_t height)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ self->next_max_size.width = width;
+ self->next_max_size.height = height;
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_maximized(struct wl_client *wl_client, struct wl_resource *resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_ask_maximized(self->surface->desktop, surface, true);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_unset_maximized(struct wl_client *wl_client, struct wl_resource *resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_ask_maximized(self->surface->desktop, surface, false);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_fullscreen(struct wl_client *wl_client, struct wl_resource *resource, struct wl_resource *output_resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_ask_fullscreen(self->surface->desktop, surface, true);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_unset_fullscreen(struct wl_client *wl_client, struct wl_resource *resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_ask_fullscreen(self->surface->desktop, surface, false);
+}
+
+static void
+_weston_desktop_xdg_toplevel_protocol_set_minimized(struct wl_client *wl_client, struct wl_resource *resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ weston_desktop_api_ask_minimized(self->surface->desktop, surface);
+}
+
+
+static void
+_weston_desktop_xdg_toplevel_send_configure(struct weston_desktop_xdg_toplevel *self)
+{
+ uint32_t *s;
+ struct wl_array states;
+
+ wl_array_init(&states);
+ if ( self->requested_state.maximized )
+ {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED;
+ }
+ if ( self->requested_state.fullscreen )
+ {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN;
+ }
+ if ( self->requested_state.resizing )
+ {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_RESIZING;
+ }
+ if ( self->requested_state.activated )
+ {
+ s = wl_array_add(&states, sizeof(uint32_t));
+ *s = ZXDG_TOPLEVEL_V6_STATE_ACTIVATED;
+ }
+
+ zxdg_toplevel_v6_send_configure(self->resource, self->requested_size.width, self->requested_size.height, &states);
+
+ wl_array_release(&states);
+};
+
+static void
+_weston_desktop_xdg_toplevel_set_maximized(struct weston_desktop_surface *surface, void *user_data, bool maximized)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ if ( self->state.maximized == maximized )
+ return;
+
+ self->requested_state.maximized = maximized;
+ _weston_desktop_xdg_surface_schedule_configure(&self->base);
+}
+
+static void
+_weston_desktop_xdg_toplevel_set_fullscreen(struct weston_desktop_surface *surface, void *user_data, bool fullscreen)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ if ( self->state.fullscreen == fullscreen )
+ return;
+
+ self->requested_state.fullscreen = fullscreen;
+ _weston_desktop_xdg_surface_schedule_configure(&self->base);
+}
+
+static void
+_weston_desktop_xdg_toplevel_set_resizing(struct weston_desktop_surface *surface, void *user_data, bool resizing)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ if ( self->state.resizing == resizing )
+ return;
+
+ self->requested_state.resizing = resizing;
+ _weston_desktop_xdg_surface_schedule_configure(&self->base);
+}
+
+static void
+_weston_desktop_xdg_toplevel_set_activated(struct weston_desktop_surface *surface, void *user_data, bool activated)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ if ( self->state.activated == activated )
+ return;
+
+ self->requested_state.activated = activated;
+ _weston_desktop_xdg_surface_schedule_configure(&self->base);
+}
+
+static void
+_weston_desktop_xdg_toplevel_set_size(struct weston_desktop_surface *surface, void *user_data, int32_t width, int32_t height)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+ struct weston_surface *wsurface = weston_desktop_surface_get_surface(self->surface->desktop_surface);
+
+ if ( ( wsurface->width == width ) && ( wsurface->height == height ) )
+ return;
+
+ self->requested_size.width = width;
+ self->requested_size.height = height;
+ _weston_desktop_xdg_surface_schedule_configure(&self->base);
+}
+
+static void
+_weston_desktop_xdg_toplevel_commit(struct weston_desktop_xdg_toplevel *self, int32_t sx, int32_t sy)
+{
+ struct weston_surface *wsurface = weston_desktop_surface_get_surface(self->surface->desktop_surface);
+ bool reconfigure = false;
+
+ if ( self->next_state.maximized || self->next_state.fullscreen )
+ reconfigure = ( ( self->requested_size.width != wsurface->width ) || ( self->requested_size.height != wsurface->height ) );
+ if ( reconfigure )
+ _weston_desktop_xdg_surface_schedule_configure(&self->base);
+ else
+ {
+ self->state = self->next_state;
+ self->min_size = self->next_min_size;
+ self->max_size = self->next_max_size;
+
+ weston_desktop_api_commit(self->surface->desktop, self->surface->desktop_surface, sx, sy);
+ }
+}
+
+static void
+_weston_desktop_xdg_toplevel_close(struct weston_desktop_xdg_toplevel *self)
+{
+ zxdg_toplevel_v6_send_close(self->resource);
+}
+
+static bool
+_weston_desktop_xdg_toplevel_get_maximized(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ return self->state.maximized;
+}
+
+static bool
+_weston_desktop_xdg_toplevel_get_fullscreen(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ return self->state.fullscreen;
+}
+
+static bool
+_weston_desktop_xdg_toplevel_get_resizing(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ return self->state.resizing;
+}
+
+static bool
+_weston_desktop_xdg_toplevel_get_activated(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_toplevel *self = user_data;
+
+ return self->state.activated;
+}
+
+static void
+_weston_desktop_xdg_toplevel_free(struct weston_desktop_xdg_toplevel *self)
+{
+ weston_desktop_api_surface_free(self->surface->desktop, self->surface->desktop_surface);
+}
+
+static void
+_weston_desktop_xdg_toplevel_destroy(struct wl_resource *resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+
+ if ( surface != NULL )
+ weston_desktop_surface_resource_destroy(resource);
+}
+
+
+static const struct zxdg_toplevel_v6_interface _weston_desktop_xdg_toplevel_implementation = {
+ .destroy = weston_desktop_destroy_request,
+ .set_parent = _weston_desktop_xdg_toplevel_protocol_set_parent,
+ .set_title = _weston_desktop_xdg_toplevel_protocol_set_title,
+ .set_app_id = _weston_desktop_xdg_toplevel_protocol_set_app_id,
+ .show_window_menu = _weston_desktop_xdg_toplevel_protocol_show_window_menu,
+ .move = _weston_desktop_xdg_toplevel_protocol_move,
+ .resize = _weston_desktop_xdg_toplevel_protocol_resize,
+ .set_min_size = _weston_desktop_xdg_toplevel_protocol_set_min_size,
+ .set_max_size = _weston_desktop_xdg_toplevel_protocol_set_max_size,
+ .set_maximized = _weston_desktop_xdg_toplevel_protocol_set_maximized,
+ .unset_maximized = _weston_desktop_xdg_toplevel_protocol_unset_maximized,
+ .set_fullscreen = _weston_desktop_xdg_toplevel_protocol_set_fullscreen,
+ .unset_fullscreen = _weston_desktop_xdg_toplevel_protocol_unset_fullscreen,
+ .set_minimized = _weston_desktop_xdg_toplevel_protocol_set_minimized,
+};
+
+
+static void
+_weston_desktop_xdg_popup_protocol_grab(struct wl_client *wl_client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_popup *self = weston_desktop_surface_get_implementation_data(surface);
+ struct weston_desktop_xdg_popup *parent_popup;
+ struct weston_seat *wseat = wl_resource_get_user_data(seat_resource);
+ struct weston_desktop_seat *seat = weston_seat_get_desktop_seat(wseat);
+
+
+ if ( self->parent->role == WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP )
+ {
+ parent_popup = (struct weston_desktop_xdg_popup *) self->parent;
+ if ( parent_popup->parent->role == WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP )
+ {
+ wl_resource_post_error(self->resource, ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP, "xdg_popup was not created on the topmost popup");
+ return;
+ }
+ }
+
+ self->seat = seat;
+ weston_desktop_surface_grab(self->surface->desktop_surface, self->seat, serial);
+}
+
+
+static void
+_weston_desktop_xdg_popup_close(struct weston_desktop_xdg_popup *self)
+{
+ zxdg_popup_v6_send_popup_done(self->resource);
+}
+
+static void
+_weston_desktop_xdg_popup_free(struct weston_desktop_xdg_popup *self)
+{
+ if ( weston_desktop_surface_get_grab(self->base.desktop_surface) )
+ {
+ struct weston_desktop_surface *topmost;
+ struct wl_resource *resource = weston_desktop_client_get_resource(self->base.client);
+
+ topmost = weston_desktop_seat_grab_get_topmost_surface(self->seat);
+ if ( topmost != self->base.desktop_surface )
+ wl_resource_post_error(resource, ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP, "xdg_popup was destroyed while it was not the topmost popup.");
+ weston_desktop_surface_ungrab(self->base.desktop_surface, self->seat);
+ }
+}
+
+static void
+_weston_desktop_xdg_popup_destroy(struct wl_resource *resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+
+ if ( surface != NULL )
+ weston_desktop_surface_resource_destroy(resource);
+}
+
+static const struct zxdg_popup_v6_interface _weston_desktop_xdg_popup_implementation = {
+ .destroy = weston_desktop_destroy_request,
+ .grab = _weston_desktop_xdg_popup_protocol_grab,
+};
+
+
+static void
+_weston_desktop_xdg_surface_send_configure(void *user_data)
+{
+ struct weston_desktop_xdg_surface *self = user_data;
+
+ self->configure_idle = NULL;
+ self->configure_serial = wl_display_next_serial(weston_desktop_get_display(self->desktop));
+
+ switch ( self->role )
+ {
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE:
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL:
+ _weston_desktop_xdg_toplevel_send_configure((struct weston_desktop_xdg_toplevel *) self);
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP:
+ //_weston_desktop_xdg_popup_send_configure((struct weston_desktop_xdg_popup *) self);
+ break;
+ }
+
+ zxdg_surface_v6_send_configure(self->resource, self->configure_serial);
+}
+
+static void
+_weston_desktop_xdg_surface_schedule_configure(struct weston_desktop_xdg_surface *self)
+{
+ struct wl_display *display = weston_desktop_get_display(self->desktop);
+ struct wl_event_loop *loop = wl_display_get_event_loop(display);
+ if ( self->configure_idle != NULL )
+ return;
+ self->configure_idle = wl_event_loop_add_idle(loop, _weston_desktop_xdg_surface_send_configure, self);
+}
+
+static void
+_weston_desktop_xdg_surface_protocol_get_toplevel(struct wl_client *wl_client, struct wl_resource *resource, uint32_t id)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_toplevel *self = weston_desktop_surface_get_implementation_data(surface);
+
+ self->resource = weston_desktop_surface_add_resource(self->surface->desktop_surface, &zxdg_toplevel_v6_interface, &_weston_desktop_xdg_toplevel_implementation, id, _weston_desktop_xdg_toplevel_destroy);
+ if ( self->resource == NULL )
+ return;
+}
+
+static void
+_weston_desktop_xdg_surface_protocol_get_popup(struct wl_client *wl_client, struct wl_resource *resource, uint32_t id, struct wl_resource *parent_resource, struct wl_resource *positioner_resource)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_popup *self = weston_desktop_surface_get_implementation_data(surface);
+ struct weston_desktop_surface *parent_surface = wl_resource_get_user_data(parent_resource);
+ struct weston_desktop_xdg_surface *parent = weston_desktop_surface_get_implementation_data(parent_surface);
+ struct weston_desktop_xdg_positioner *positioner = wl_resource_get_user_data(positioner_resource);
+ struct weston_desktop_surface_position position;
+
+ self->resource = weston_desktop_surface_add_resource(self->surface->desktop_surface, &zxdg_popup_v6_interface, &_weston_desktop_xdg_popup_implementation, id, _weston_desktop_xdg_popup_destroy);
+ if ( self->resource == NULL )
+ return;
+
+ self->parent = parent;
+
+ position = _weston_desktop_xdg_positioner_get_position(positioner, surface, parent_surface);
+
+ weston_desktop_surface_set_parent(self->surface->desktop_surface, parent_surface, position.x, position.y);
+}
+
+static void
+_weston_desktop_xdg_surface_protocol_set_window_geometry(struct wl_client *wl_client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_surface *self = weston_desktop_surface_get_implementation_data(surface);
+
+ self->has_geometry = true;
+ self->next_geometry.x = x;
+ self->next_geometry.y = y;
+ self->next_geometry.width = width;
+ self->next_geometry.height = height;
+}
+
+static void
+_weston_desktop_xdg_surface_protocol_ack_configure(struct wl_client *wl_client, struct wl_resource *resource, uint32_t serial)
+{
+ struct weston_desktop_surface *surface = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_surface *self = weston_desktop_surface_get_implementation_data(surface);
+
+ if ( self->configure_serial != serial )
+ {
+ /* TODO: check better if serial is newer or older */
+ if ( self->configure_serial < serial )
+ _weston_desktop_xdg_surface_schedule_configure(self);
+ return;
+ }
+
+ self->configured = true;
+
+ switch ( self->role )
+ {
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE:
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL:
+ _weston_desktop_xdg_toplevel_ack_configure((struct weston_desktop_xdg_toplevel *) self);
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP:
+ //_weston_desktop_xdg_popup_ack_configure((struct weston_desktop_xdg_popup *) self);
+ break;
+ }
+}
+
+
+static void
+_weston_desktop_xdg_surface_ping(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_surface *self = user_data;
+ uint32_t serial;
+
+ serial = weston_desktop_client_ping(self->client, self->desktop_surface);
+ if ( serial != 0 )
+ zxdg_shell_v6_send_ping(weston_desktop_client_get_resource(self->client), serial);
+}
+
+static void
+_weston_desktop_xdg_surface_commit(struct weston_desktop_surface *surface, void *user_data, int32_t sx, int32_t sy)
+{
+ struct weston_desktop_xdg_surface *self = user_data;
+
+ if ( ! self->configured )
+ {
+ wl_resource_post_error(self->resource, ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER, "xdg_surface has never been configured");
+ return;
+ }
+
+ if ( self->has_geometry )
+ self->geometry = self->next_geometry;
+
+ switch ( self->role )
+ {
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE:
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL:
+ _weston_desktop_xdg_toplevel_commit((struct weston_desktop_xdg_toplevel *) self, sx, sy);
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP:
+ //_weston_desktop_xdg_popup_commit((struct weston_desktop_xdg_popup *) self);
+ break;
+ }
+}
+
+static void
+_weston_desktop_xdg_surface_close(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_surface *self = user_data;
+
+ switch ( self->role )
+ {
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE:
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL:
+ _weston_desktop_xdg_toplevel_close((struct weston_desktop_xdg_toplevel *) self);
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP:
+ _weston_desktop_xdg_popup_close((struct weston_desktop_xdg_popup *) self);
+ break;
+ }
+}
+
+static struct weston_desktop_surface_geometry
+_weston_desktop_xdg_surface_get_geometry(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_surface *self = user_data;
+
+ if ( self->has_geometry )
+ return self->geometry;
+ return weston_surface_get_bounding_box(weston_desktop_surface_get_surface(self->desktop_surface));
+}
+
+static void
+_weston_desktop_xdg_surface_free(struct weston_desktop_surface *surface, void *user_data)
+{
+ struct weston_desktop_xdg_surface *self = user_data;
+
+
+ switch ( self->role )
+ {
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_NONE:
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_TOPLEVEL:
+ _weston_desktop_xdg_toplevel_free((struct weston_desktop_xdg_toplevel *) self);
+ break;
+ case WESTON_DESKTOP_XDG_SURFACE_ROLE_POPUP:
+ _weston_desktop_xdg_popup_free((struct weston_desktop_xdg_popup *) self);
+ break;
+ }
+
+ if ( self->configure_idle != NULL )
+ wl_event_source_remove(self->configure_idle);
+
+ free(self);
+}
+
+
+static const struct zxdg_surface_v6_interface _weston_desktop_xdg_surface_implementation = {
+ .destroy = weston_desktop_destroy_request,
+ .get_toplevel = _weston_desktop_xdg_surface_protocol_get_toplevel,
+ .get_popup = _weston_desktop_xdg_surface_protocol_get_popup,
+ .set_window_geometry = _weston_desktop_xdg_surface_protocol_set_window_geometry,
+ .ack_configure = _weston_desktop_xdg_surface_protocol_ack_configure,
+};
+
+static const struct weston_desktop_surface_implementation _weston_desktop_xdg_surface_internal_implementation = {
+ /* These are used for toplevel only */
+ .set_maximized = _weston_desktop_xdg_toplevel_set_maximized,
+ .set_fullscreen = _weston_desktop_xdg_toplevel_set_fullscreen,
+ .set_resizing = _weston_desktop_xdg_toplevel_set_resizing,
+ .set_activated = _weston_desktop_xdg_toplevel_set_activated,
+ .set_size = _weston_desktop_xdg_toplevel_set_size,
+
+ .get_maximized = _weston_desktop_xdg_toplevel_get_maximized,
+ .get_fullscreen = _weston_desktop_xdg_toplevel_get_fullscreen,
+ .get_resizing = _weston_desktop_xdg_toplevel_get_resizing,
+ .get_activated = _weston_desktop_xdg_toplevel_get_activated,
+
+ /* Common API */
+ .commit =_weston_desktop_xdg_surface_commit,
+ .ping = _weston_desktop_xdg_surface_ping,
+ .close = _weston_desktop_xdg_surface_close,
+
+ .get_geometry =_weston_desktop_xdg_surface_get_geometry,
+
+ .free = _weston_desktop_xdg_surface_free,
+};
+
+static void
+_weston_desktop_xdg_shell_protocol_create_positioner(struct wl_client *wl_client, struct wl_resource *resource, uint32_t id)
+{
+ struct weston_desktop_client *client = wl_resource_get_user_data(resource);
+ struct weston_desktop_xdg_surface *self;
+
+ self = zalloc(sizeof(struct weston_desktop_xdg_positioner));
+ if ( self == NULL )
+ {
+ wl_client_post_no_memory(wl_client);
+ return;
+ }
+
+ self->client = client;
+ self->desktop = weston_desktop_client_get_desktop(self->client);
+
+ self->resource = wl_resource_create(wl_client, &zxdg_positioner_v6_interface, wl_resource_get_version(resource), id);
+ if ( self->resource == NULL )
+ {
+ wl_client_post_no_memory(wl_client);
+ free(self);
+ return;
+ }
+ wl_resource_set_implementation(self->resource, &_weston_desktop_xdg_positioner_implementation, self, _weston_desktop_xdg_positioner_destroy);
+}
+
+static void
+_weston_desktop_xdg_shell_protocol_get_xdg_surface(struct wl_client *wl_client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource)
+{
+ struct weston_desktop_client *client = wl_resource_get_user_data(resource);
+ struct weston_surface *surface = wl_resource_get_user_data(surface_resource);
+ struct weston_desktop_xdg_surface *self;
+
+ self = zalloc(weston_desktop_surface_role_biggest_size);
+ if ( self == NULL )
+ {
+ wl_client_post_no_memory(wl_client);
+ return;
+ }
+
+ self->client = client;
+ self->desktop = weston_desktop_client_get_desktop(self->client);
+ self->surface = surface;
+
+ self->desktop_surface = weston_desktop_surface_create(self->desktop, self->client, self->surface, &_weston_desktop_xdg_surface_internal_implementation, self);
+ if ( self->desktop_surface == NULL )
+ {
+ free(self);
+ return;
+ }
+}
+
+static void
+_weston_desktop_xdg_shell_protocol_pong(struct wl_client *wl_client, struct wl_resource *resource, uint32_t serial)
+{
+ struct weston_desktop_client *client = wl_resource_get_user_data(resource);
+
+ weston_desktop_client_pong(client, serial);
+}
+
+static const struct zxdg_shell_v6_interface _weston_desktop_xdg_shell_implementation = {
+ .destroy = weston_desktop_destroy_request,
+ .create_positioner = _weston_desktop_xdg_shell_protocol_create_positioner,
+ .get_xdg_surface = _weston_desktop_xdg_shell_protocol_get_xdg_surface,
+ .pong = _weston_desktop_xdg_shell_protocol_pong,
+};
+
+static void
+_weston_desktop_xdg_shell_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ struct weston_desktop *desktop = data;
+
+ weston_desktop_client_create(desktop, client, NULL, &zxdg_shell_v6_interface, &_weston_desktop_xdg_shell_implementation, version, id);
+}
+
+struct wl_global *
+weston_desktop_xdg_shell_v6_create(struct weston_desktop *desktop, struct wl_display *display)
+{
+ return wl_global_create(display, &zxdg_shell_v6_interface, WD_XDG_SHELL_PROTOCOL_VERSION, desktop, _weston_desktop_xdg_shell_bind);
+}
--
2.9.0
More information about the wayland-devel
mailing list