[mutter/wayland] wayland-surface: Add support for subsurfaces
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wayland] wayland-surface: Add support for subsurfaces
- Date: Mon, 25 Nov 2013 23:33:49 +0000 (UTC)
commit a9424255a52fe22656cae5f3f96307f9b9ffa570
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Mon Nov 25 16:26:02 2013 -0500
wayland-surface: Add support for subsurfaces
The state for a subsurface isn't double-buffered yet, though...
src/wayland/meta-wayland-surface.c | 183 +++++++++++++++++++++++++++++++++--
src/wayland/meta-wayland-surface.h | 1 +
src/wayland/meta-wayland-versions.h | 2 +
3 files changed, 178 insertions(+), 8 deletions(-)
---
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index b2c4c90..2a2402a 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -253,12 +253,12 @@ cursor_surface_commit (MetaWaylandSurface *surface)
meta_wayland_seat_update_sprite (surface->compositor->seat);
}
-static void
-toplevel_surface_commit (MetaWaylandSurface *surface)
+static gboolean
+actor_surface_commit (MetaWaylandSurface *surface)
{
MetaSurfaceActor *surface_actor = surface->surface_actor;
- MetaWindow *window = surface->window;
MetaWaylandBuffer *buffer = surface->pending.buffer;
+ gboolean changed = FALSE;
/* wl_surface.attach */
if (surface->pending.newly_attached && buffer != surface->buffer_ref.buffer)
@@ -267,9 +267,26 @@ toplevel_surface_commit (MetaWaylandSurface *surface)
meta_wayland_buffer_reference (&surface->buffer_ref, buffer);
meta_surface_actor_attach_wayland_buffer (surface_actor, buffer);
surface_process_damage (surface, surface->pending.damage);
+ changed = TRUE;
+ }
- meta_window_set_surface_mapped (window, buffer != NULL);
+ if (surface->pending.opaque_region)
+ meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region);
+ if (surface->pending.input_region)
+ meta_surface_actor_set_input_region (surface_actor, surface->pending.input_region);
+
+ return changed;
+}
+
+static void
+toplevel_surface_commit (MetaWaylandSurface *surface)
+{
+ if (actor_surface_commit (surface))
+ {
+ MetaWindow *window = surface->window;
+ MetaWaylandBuffer *buffer = surface->pending.buffer;
+ meta_window_set_surface_mapped (window, buffer != NULL);
/* We resize X based surfaces according to X events */
if (buffer != NULL && window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
{
@@ -286,11 +303,27 @@ toplevel_surface_commit (MetaWaylandSurface *surface)
surface->pending.dx, surface->pending.dy);
}
}
+}
- if (surface->pending.opaque_region)
- meta_surface_actor_set_opaque_region (surface_actor, surface->pending.opaque_region);
- if (surface->pending.input_region)
- meta_surface_actor_set_input_region (surface_actor, surface->pending.input_region);
+static void
+subsurface_surface_commit (MetaWaylandSurface *surface)
+{
+ if (actor_surface_commit (surface))
+ {
+ MetaSurfaceActor *surface_actor = surface->surface_actor;
+ MetaWaylandBuffer *buffer = surface->pending.buffer;
+ float x, y;
+
+ if (buffer != NULL)
+ clutter_actor_show (CLUTTER_ACTOR (surface_actor));
+ else
+ clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
+
+ clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
+ x += surface->pending.dx;
+ y += surface->pending.dy;
+ clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
+ }
}
static void
@@ -310,6 +343,8 @@ meta_wayland_surface_commit (struct wl_client *client,
cursor_surface_commit (surface);
else if (surface->window)
toplevel_surface_commit (surface);
+ else if (surface->subsurface.resource)
+ subsurface_surface_commit (surface);
if (surface->pending.buffer)
{
@@ -903,6 +938,132 @@ bind_gtk_shell (struct wl_client *client,
gtk_shell_send_capabilities (resource, GTK_SHELL_CAPABILITY_GLOBAL_APP_MENU);
}
+static void
+wl_subsurface_destroy (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy (resource);
+}
+
+static void
+wl_subsurface_set_position (struct wl_client *client,
+ struct wl_resource *resource,
+ int32_t x,
+ int32_t y)
+{
+ MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
+ MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
+
+ clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor), x, y);
+}
+
+static void
+wl_subsurface_place_above (struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *sibling_resource)
+{
+ ClutterActor *parent_actor;
+ MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
+ MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
+ MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
+
+ parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
+
+ clutter_actor_set_child_above_sibling (parent_actor,
+ CLUTTER_ACTOR (surface->surface_actor),
+ CLUTTER_ACTOR (sibling->surface_actor));
+}
+
+static void
+wl_subsurface_place_below (struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *sibling_resource)
+{
+ ClutterActor *parent_actor;
+ MetaWaylandSurfaceExtension *subsurface = wl_resource_get_user_data (resource);
+ MetaWaylandSurface *surface = wl_container_of (subsurface, surface, subsurface);
+ MetaWaylandSurface *sibling = wl_resource_get_user_data (sibling_resource);
+
+ parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->surface_actor));
+
+ clutter_actor_set_child_below_sibling (parent_actor,
+ CLUTTER_ACTOR (surface->surface_actor),
+ CLUTTER_ACTOR (sibling->surface_actor));
+}
+
+static void
+wl_subsurface_set_sync (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ g_warning ("TODO: support wl_subsurface.set_sync");
+}
+
+static void
+wl_subsurface_set_desync (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ g_warning ("TODO: support wl_subsurface.set_desync");
+}
+
+static const struct wl_subsurface_interface meta_wayland_subsurface_interface = {
+ wl_subsurface_destroy,
+ wl_subsurface_set_position,
+ wl_subsurface_place_above,
+ wl_subsurface_place_below,
+ wl_subsurface_set_sync,
+ wl_subsurface_set_desync,
+};
+
+static void
+wl_subcompositor_destroy (struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy (resource);
+}
+
+static void
+wl_subcompositor_get_subsurface (struct wl_client *client,
+ struct wl_resource *resource,
+ guint32 id,
+ struct wl_resource *surface_resource,
+ struct wl_resource *parent_resource)
+{
+ MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
+ MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
+
+ if (!create_surface_extension (&surface->subsurface, client, surface_resource, resource, id,
+ META_GTK_SURFACE_VERSION,
+ &wl_subsurface_interface,
+ &meta_wayland_subsurface_interface))
+ {
+ wl_resource_post_error (surface_resource,
+ WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "wl_subcompositor::get_subsurface already requested");
+ return;
+ }
+
+ clutter_actor_add_child (CLUTTER_ACTOR (parent->surface_actor),
+ CLUTTER_ACTOR (surface->surface_actor));
+}
+
+static const struct wl_subcompositor_interface meta_wayland_subcompositor_interface = {
+ wl_subcompositor_destroy,
+ wl_subcompositor_get_subsurface,
+};
+
+static void
+bind_subcompositor (struct wl_client *client,
+ void *data,
+ guint32 version,
+ guint32 id)
+{
+ struct wl_resource *resource;
+
+ resource = wl_resource_create (client, &wl_subcompositor_interface,
+ MIN (META_WL_SUBCOMPOSITOR_VERSION, version), id);
+ wl_resource_set_implementation (resource, &meta_wayland_subcompositor_interface, data, NULL);
+}
+
void
meta_wayland_init_shell (MetaWaylandCompositor *compositor)
{
@@ -917,6 +1078,12 @@ meta_wayland_init_shell (MetaWaylandCompositor *compositor)
META_GTK_SHELL_VERSION,
compositor, bind_gtk_shell) == NULL)
g_error ("Failed to register a global gtk-shell object");
+
+ if (wl_global_create (compositor->wayland_display,
+ &wl_subcompositor_interface,
+ META_WL_SUBCOMPOSITOR_VERSION,
+ compositor, bind_subcompositor) == NULL)
+ g_error ("Failed to register a global wl-subcompositor object");
}
void
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 4edab87..28dfa14 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -83,6 +83,7 @@ struct _MetaWaylandSurface
MetaWaylandSurfaceExtension xdg_surface;
MetaWaylandSurfaceExtension xdg_popup;
MetaWaylandSurfaceExtension gtk_surface;
+ MetaWaylandSurfaceExtension subsurface;
/* All the pending state, that wl_surface.commit will apply. */
MetaWaylandDoubleBufferedState pending;
diff --git a/src/wayland/meta-wayland-versions.h b/src/wayland/meta-wayland-versions.h
index 7e85f8b..531cbd4 100644
--- a/src/wayland/meta-wayland-versions.h
+++ b/src/wayland/meta-wayland-versions.h
@@ -42,6 +42,7 @@
#define META_XSERVER_VERSION 1
#define META_GTK_SHELL_VERSION 1
#define META_XDG_SHELL_VERSION 1
+#define META_WL_SUBCOMPOSITOR_VERSION 1
/* Slave objects (version inherited from a master object) */
#define META_WL_DATA_OFFER_VERSION 1 /* from wl_data_device */
@@ -55,6 +56,7 @@
#define META_GTK_SURFACE_VERSION 1 /* from gtk_shell */
#define META_XDG_SURFACE_VERSION 1 /* from xdg_shell */
#define META_XDG_POPUP_VERSION 1 /* from xdg_shell */
+#define META_WL_SUBSURFACE_VERSION 1 /* from wl_subcompositor */
/* The first version to implement a specific event */
#define META_WL_SEAT_HAS_NAME 2
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]