[gtk+] wayland: Add API for creating exported window handles



commit 127d2ac956cec1bb26df7d66f9b0859129a900e5
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue Jul 12 11:49:39 2016 +0800

    wayland: Add API for creating exported window handles
    
    Using the xdg_foreign protocol, expose a way to get handles to windows
    that may be shared between processes.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769788

 configure.ac                     |    2 +-
 gdk/wayland/Makefile.am          |    2 +
 gdk/wayland/gdkdisplay-wayland.c |    7 +++
 gdk/wayland/gdkdisplay-wayland.h |    2 +
 gdk/wayland/gdkwaylandwindow.h   |   12 +++++
 gdk/wayland/gdkwindow-wayland.c  |   87 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 111 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a4051ec..431c081 100644
--- a/configure.ac
+++ b/configure.ac
@@ -60,7 +60,7 @@ m4_define([cairo_required_version], [1.14.0])
 m4_define([gdk_pixbuf_required_version], [2.30.0])
 m4_define([introspection_required_version], [1.39.0])
 m4_define([wayland_required_version], [1.9.91])
-m4_define([wayland_protocols_required_version], [1.5])
+m4_define([wayland_protocols_required_version], [1.6])
 m4_define([mirclient_required_version], [0.22.0])
 m4_define([mircookie_required_version], [0.17.0])
 m4_define([epoxy_required_version], [1.0])
diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am
index 1805d4b..5b2e64e 100644
--- a/gdk/wayland/Makefile.am
+++ b/gdk/wayland/Makefile.am
@@ -25,6 +25,8 @@ BUILT_SOURCES =                               \
        pointer-gestures-unstable-v1-protocol.c                 \
        xdg-shell-unstable-v6-client-protocol.h                 \
        xdg-shell-unstable-v6-protocol.c                        \
+       xdg-foreign-unstable-v1-client-protocol.h               \
+       xdg-foreign-unstable-v1-protocol.c                      \
        gtk-primary-selection-client-protocol.h                 \
        gtk-primary-selection-protocol.c                        \
        tablet-unstable-v2-client-protocol.h    \
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index f5b6218..4bb247e 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -45,6 +45,7 @@
 #include "pointer-gestures-unstable-v1-client-protocol.h"
 #include "tablet-unstable-v2-client-protocol.h"
 #include "xdg-shell-unstable-v6-client-protocol.h"
+#include "xdg-foreign-unstable-v1-client-protocol.h"
 
 /**
  * SECTION:wayland_interaction
@@ -433,6 +434,12 @@ gdk_registry_handle_global (void               *data,
         wl_registry_bind(display_wayland->wl_registry, id,
                          &zwp_tablet_manager_v2_interface, 1);
     }
+  else if (strcmp (interface, "zxdg_exporter_v1") == 0)
+    {
+      display_wayland->xdg_exporter =
+        wl_registry_bind (display_wayland->wl_registry, id,
+                          &zxdg_exporter_v1_interface, 1);
+    }
   else
     handled = FALSE;
 
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index a1f51ef..f21e8b6 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -30,6 +30,7 @@
 #include <gdk/wayland/tablet-unstable-v2-client-protocol.h>
 #include <gdk/wayland/gtk-shell-client-protocol.h>
 #include <gdk/wayland/xdg-shell-unstable-v6-client-protocol.h>
+#include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h>
 
 #include <glib.h>
 #include <gdk/gdkkeys.h>
@@ -74,6 +75,7 @@ struct _GdkWaylandDisplay
   struct zwp_pointer_gestures_v1 *pointer_gestures;
   struct gtk_primary_selection_device_manager *primary_selection_manager;
   struct zwp_tablet_manager_v2 *tablet_manager;
+  struct zxdg_exporter_v1 *xdg_exporter;
 
   GList *async_roundtrips;
 
diff --git a/gdk/wayland/gdkwaylandwindow.h b/gdk/wayland/gdkwaylandwindow.h
index e46ce18..6c006e8 100644
--- a/gdk/wayland/gdkwaylandwindow.h
+++ b/gdk/wayland/gdkwaylandwindow.h
@@ -60,6 +60,18 @@ void                     gdk_wayland_window_set_dbus_properties_libgtk_only (Gdk
                                                                             const char 
*application_object_path,
                                                                             const char *unique_bus_name);
 
+typedef void (*GdkWaylandWindowExported) (GdkWindow  *window,
+                                          const char *handle,
+                                          gpointer    user_data);
+
+GDK_AVAILABLE_IN_3_22
+gboolean                 gdk_wayland_window_export_handle (GdkWindow               *window,
+                                                           GdkWaylandWindowExported callback,
+                                                           gpointer                 user_data,
+                                                           GDestroyNotify           destroy_func);
+
+GDK_AVAILABLE_IN_3_22
+void                     gdk_wayland_window_unexport_handle (GdkWindow *window);
 
 G_END_DECLS
 
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 1a2575e..fe11d94 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -118,6 +118,7 @@ struct _GdkWindowImplWayland
     struct wl_subsurface *wl_subsurface;
     struct wl_egl_window *egl_window;
     struct wl_egl_window *dummy_egl_window;
+    struct zxdg_exported_v1 *xdg_exported;
   } display_server;
 
   EGLSurface egl_surface;
@@ -196,6 +197,12 @@ struct _GdkWindowImplWayland
     int height;
     GdkWindowState state;
   } pending;
+
+  struct {
+    GdkWaylandWindowExported callback;
+    gpointer user_data;
+    GDestroyNotify destroy_func;
+  } exported;
 };
 
 struct _GdkWindowImplWaylandClass
@@ -3828,3 +3835,83 @@ _gdk_wayland_window_offset_next_wl_buffer (GdkWindow *window,
   impl->pending_buffer_offset_x = x;
   impl->pending_buffer_offset_y = y;
 }
+
+static void
+xdg_exported_handle (void                    *data,
+                     struct zxdg_exported_v1 *zxdg_exported_v1,
+                     const char              *handle)
+{
+  GdkWindow *window = data;
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
+  impl->exported.callback (window, handle, impl->exported.user_data);
+  impl->exported.user_data = NULL;
+}
+
+static const struct zxdg_exported_v1_listener xdg_exported_listener = {
+  xdg_exported_handle
+};
+
+/**
+ * gdk_wayland_window_export_handle:
+ *
+ * Stability: unstable
+ */
+gboolean
+gdk_wayland_window_export_handle (GdkWindow               *window,
+                                  GdkWaylandWindowExported callback,
+                                  gpointer                 user_data,
+                                  GDestroyNotify           destroy_func)
+{
+  GdkWindowImplWayland *impl;
+  GdkWaylandDisplay *display_wayland;
+  GdkDisplay *display = gdk_window_get_display (window);
+  struct zxdg_exported_v1 *xdg_exported;
+
+  g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), FALSE);
+  g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
+
+  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  display_wayland = GDK_WAYLAND_DISPLAY (display);
+
+  g_return_val_if_fail (!impl->display_server.xdg_exported, FALSE);
+
+  if (!display_wayland->xdg_exporter)
+    {
+      g_warning ("Server is missing xdg_foreign support");
+      return FALSE;
+    }
+
+  xdg_exported = zxdg_exporter_v1_export (display_wayland->xdg_exporter,
+                                          impl->display_server.wl_surface);
+  zxdg_exported_v1_add_listener (xdg_exported,  &xdg_exported_listener, window);
+
+  impl->display_server.xdg_exported = xdg_exported;
+  impl->exported.callback = callback;
+  impl->exported.user_data = user_data;
+  impl->exported.destroy_func = destroy_func;
+
+  return TRUE;
+}
+
+/**
+ * gdk_wayland_window_unexport_handle:
+ *
+ * Stability: unstable
+ */
+void
+gdk_wayland_window_unexport_handle (GdkWindow *window)
+{
+  GdkWindowImplWayland *impl;
+
+  g_return_if_fail (GDK_IS_WAYLAND_WINDOW (window));
+
+  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
+  g_return_if_fail (impl->display_server.xdg_exported);
+
+  g_clear_pointer (&impl->display_server.xdg_exported,
+                   zxdg_exported_v1_destroy);
+  g_clear_pointer (&impl->exported.user_data,
+                   impl->exported.destroy_func);
+}


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