1 /*
2  * Copyright (C) 2021, Georges Basile Stavracas Neto
3  *
4  * This file is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, version 3.0 of the
7  * License.
8  *
9  * This file is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  * SPDX-License-Identifier: LGPL-3.0-only
18  */
19 
20 #include "config.h"
21 #include "portal-gtk4.h"
22 
23 #include "parent-private.h"
24 
25 #ifdef GDK_WINDOWING_X11
26 #include <gdk/x11/gdkx.h>
27 #endif
28 #ifdef GDK_WINDOWING_WAYLAND
29 #include <gdk/wayland/gdkwayland.h>
30 #endif
31 
32 static void
_xdp_parent_exported_wayland(GdkToplevel * toplevel,const char * handle,gpointer data)33 _xdp_parent_exported_wayland (GdkToplevel *toplevel,
34                               const char  *handle,
35                               gpointer     data)
36 
37 {
38   XdpParent *parent = data;
39   g_autofree char *handle_str = g_strdup_printf ("wayland:%s", handle);
40   parent->callback (parent, handle_str, parent->data);
41 }
42 
43 static gboolean
_xdp_parent_export_gtk(XdpParent * parent,XdpParentExported callback,gpointer data)44 _xdp_parent_export_gtk (XdpParent         *parent,
45                         XdpParentExported  callback,
46                         gpointer           data)
47 {
48 #ifdef GDK_WINDOWING_X11
49   if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (GTK_WIDGET (parent->object))))
50     {
51       GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (parent->object));
52       guint32 xid = (guint32) gdk_x11_surface_get_xid (surface);
53       g_autofree char *handle = g_strdup_printf ("x11:%x", xid);
54       callback (parent, handle, data);
55       return TRUE;
56     }
57 #endif
58 #ifdef GDK_WINDOWING_WAYLAND
59   if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (parent->object))))
60     {
61       GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (parent->object));
62       parent->callback = callback;
63       parent->data = data;
64       return gdk_wayland_toplevel_export_handle (GDK_TOPLEVEL (surface),
65                                                  _xdp_parent_exported_wayland,
66                                                  parent,
67                                                  NULL);
68     }
69 #endif
70   g_warning ("Couldn't export handle, unsupported windowing system");
71   return FALSE;
72 }
73 
74 static void
_xdp_parent_unexport_gtk(XdpParent * parent)75 _xdp_parent_unexport_gtk (XdpParent *parent)
76 {
77 #ifdef GDK_WINDOWING_WAYLAND
78   if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (parent->object))))
79     {
80       GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (parent->object));
81       gdk_wayland_toplevel_unexport_handle (GDK_TOPLEVEL (surface));
82     }
83 #endif
84 }
85 
86 /**
87  * xdp_parent_new_gtk:
88  * @window: a [class@Gtk.Window]
89  *
90  * Creates a new [struct@Parent] from @window.
91  *
92  * Returns: (transfer full): a [struct@Parent]
93  */
94 XdpParent *
xdp_parent_new_gtk(GtkWindow * window)95 xdp_parent_new_gtk (GtkWindow *window)
96 {
97   XdpParent *parent = g_new0 (XdpParent, 1);
98   parent->parent_export = _xdp_parent_export_gtk;
99   parent->parent_unexport = _xdp_parent_unexport_gtk;
100   parent->object = (GObject *) g_object_ref (window);
101   return parent;
102 }
103