[clutter-gtk/wip/wayland: 5/5] wayland: Use the subsurface protocol to implement GtkClutterEmbed



commit 12397014f3ddeb77260a59f2bb928332ff623ee1
Author: Rob Bradford <rob linux intel com>
Date:   Tue Sep 3 14:06:32 2013 +0100

    wayland: Use the subsurface protocol to implement GtkClutterEmbed
    
    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

 clutter-gtk/gtk-clutter-embed.c |  100 +++++++++++++++++++++++++++++++++++++++
 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
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]