summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Bradford <rob@linux.intel.com>2013-09-03 14:06:32 +0100
committerRob Bradford <rob@linux.intel.com>2013-09-20 16:39:10 +0100
commit14c045b6f2f3d15996e9c4ee7a852370d341fe66 (patch)
treebe8d087f1d213885ba7f1097ba8349313613bd1a
parent8579a1948bc33314f631fbc0ca268036e5c4f1f2 (diff)
downloadclutter-gtk-wip/wayland.tar.gz
wayland: Use the subsurface protocol to implement GtkClutterEmbedwip/wayland
The subsurface protocol lets us "embed" one surface within another. The compositor will compose the two surfaces together to create a single window. We use it here to take the surface we get from Clutter and make that into a subsurface and then associate that subsurface with the main surface coming from GTK+. https://bugzilla.gnome.org/show_bug.cgi?id=695737
-rw-r--r--clutter-gtk/gtk-clutter-embed.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/clutter-gtk/gtk-clutter-embed.c b/clutter-gtk/gtk-clutter-embed.c
index 14d99bf..adb4407 100644
--- a/clutter-gtk/gtk-clutter-embed.c
+++ b/clutter-gtk/gtk-clutter-embed.c
@@ -46,6 +46,7 @@
#endif
#include <math.h>
+#include <string.h>
#include "gtk-clutter-embed.h"
#include "gtk-clutter-offscreen.h"
#include "gtk-clutter-actor.h"
@@ -66,6 +67,10 @@
#include <clutter/win32/clutter-win32.h>
#endif
+#if defined(CLUTTER_WINDOWING_WAYLAND)
+#include <clutter/wayland/clutter-wayland.h>
+#endif
+
#if defined(GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
#endif
@@ -74,6 +79,14 @@
#include <gdk/gdkwin32.h>
#endif
+#if defined(GDK_WINDOWING_WAYLAND)
+#include <gdk/gdkwayland.h>
+#endif
+
+#if defined(GDK_WINDOWING_WAYLAND) && defined(CLUTTER_WINDOWING_WAYLAND)
+#include "subsurface-client-protocol.h"
+#endif
+
G_DEFINE_TYPE (GtkClutterEmbed, gtk_clutter_embed, GTK_TYPE_CONTAINER);
#define GTK_CLUTTER_EMBED_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_CLUTTER_TYPE_EMBED, GtkClutterEmbedPrivate))
@@ -92,6 +105,11 @@ struct _GtkClutterEmbedPrivate
guint geometry_changed : 1;
guint use_layout_size : 1;
+
+#if defined(GDK_WINDOWING_WAYLAND) && defined(CLUTTER_WINDOWING_WAYLAND)
+ struct wl_subcompositor *subcompositor;
+ struct wl_subsurface *subsurface;
+#endif
};
enum
@@ -363,6 +381,28 @@ gtk_clutter_embed_realize (GtkWidget *widget)
}
#endif
+#if defined(GDK_WINDOWING_WAYLAND) && defined(CLUTTER_WINDOWING_WAYLAND)
+ if (priv->subcompositor)
+ {
+ GdkDisplay *display;
+ struct wl_surface *clutter_surface, *gtk_surface;
+ struct wl_compositor *compositor;
+
+ display = gdk_display_get_default ();
+ compositor = gdk_wayland_display_get_wl_compositor (display);
+ clutter_surface = wl_compositor_create_surface (compositor);
+ gtk_surface = gdk_wayland_window_get_wl_surface (gdk_window_get_toplevel(window));
+ clutter_wayland_stage_set_wl_surface (CLUTTER_STAGE (priv->stage),
+ clutter_surface);
+ priv->subsurface =
+ wl_subcompositor_get_subsurface (priv->subcompositor,
+ clutter_surface,
+ gtk_surface);
+ wl_subsurface_set_position (priv->subsurface, allocation.x, allocation.y);
+ wl_subsurface_set_desync (priv->subsurface);
+ }
+#endif
+
clutter_actor_realize (priv->stage);
if (gtk_widget_get_visible (widget))
@@ -533,7 +573,14 @@ gtk_clutter_embed_size_allocate (GtkWidget *widget,
clutter_x11_handle_event ((XEvent *)&xevent);
}
#endif
+#if defined(GDK_WINDOWING_WAYLAND) && defined(CLUTTER_WINDOWING_WAYLAND)
+ if (priv->subsurface)
+ {
+ wl_subsurface_set_position (priv->subsurface, allocation->x, allocation->y);
+ }
+#endif
}
+
}
static gboolean
@@ -938,6 +985,40 @@ gtk_clutter_embed_class_init (GtkClutterEmbedClass *klass)
g_object_class_install_property (gobject_class, PROP_USE_LAYOUT_SIZE, pspec);
}
+
+
+#if defined(GDK_WINDOWING_WAYLAND) && defined(CLUTTER_WINDOWING_WAYLAND)
+static void
+registry_handle_global (void *data,
+ struct wl_registry *registry,
+ uint32_t name,
+ const char *interface,
+ uint32_t version)
+{
+ GtkClutterEmbed *embed = data;
+ GtkClutterEmbedPrivate *priv = embed->priv;
+
+ if (strcmp (interface, "wl_subcompositor") == 0) {
+ priv->subcompositor = wl_registry_bind (registry,
+ name,
+ &wl_subcompositor_interface,
+ 1);
+ }
+}
+
+static void
+registry_handle_global_remove (void *data,
+ struct wl_registry *registry,
+ uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+#endif
+
static void
gtk_clutter_embed_init (GtkClutterEmbed *embed)
{
@@ -986,6 +1067,25 @@ gtk_clutter_embed_init (GtkClutterEmbed *embed)
g_signal_connect (priv->stage,
"queue-relayout", G_CALLBACK (on_stage_queue_relayout),
embed);
+
+
+#if defined(GDK_WINDOWING_WAYLAND) && defined(CLUTTER_WINDOWING_WAYLAND)
+ {
+ GdkDisplay *gdk_display = gdk_display_get_default ();
+ if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WAYLAND) &&
+ GDK_IS_WAYLAND_DISPLAY (gdk_display))
+ {
+ struct wl_display *display;
+ struct wl_registry *registry;
+
+ display = gdk_wayland_display_get_wl_display (gdk_display);
+ registry = wl_display_get_registry (display);
+ wl_registry_add_listener (registry, &registry_listener, embed);
+
+ wl_display_roundtrip (display);
+ }
+ }
+#endif
}
/**