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-gtk3.h"
22 
23 #include "parent-private.h"
24 
25 #ifdef GDK_WINDOWING_X11
26 #include <gdk/gdkx.h>
27 #endif
28 #ifdef GDK_WINDOWING_WAYLAND
29 #include <gdk/gdkwayland.h>
30 #endif
31 
32 static void
_xdp_parent_exported_wayland(GdkWindow * window,const char * handle,gpointer data)33 _xdp_parent_exported_wayland (GdkWindow  *window,
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       GdkWindow *w = gtk_widget_get_window (GTK_WIDGET (parent->object));
52       guint32 xid = (guint32) gdk_x11_window_get_xid (w);
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       GdkWindow *w = gtk_widget_get_window (GTK_WIDGET (parent->object));
62       parent->callback = callback;
63       parent->data = data;
64       return gdk_wayland_window_export_handle (w, _xdp_parent_exported_wayland, parent, NULL);
65     }
66 #endif
67   g_warning ("Couldn't export handle, unsupported windowing system");
68   return FALSE;
69 }
70 
71 static void
_xdp_parent_unexport_gtk(XdpParent * parent)72 _xdp_parent_unexport_gtk (XdpParent *parent)
73 {
74 #ifdef GDK_WINDOWING_WAYLAND
75   if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (GTK_WIDGET (parent->object))))
76     {
77       GdkWindow *w = gtk_widget_get_window (GTK_WIDGET (parent->object));
78       gdk_wayland_window_unexport_handle (w);
79     }
80 #endif
81 }
82 
83 /**
84  * xdp_parent_new_gtk:
85  * @window: a [class@Gtk.Window]
86  *
87  * Creates a new [struct@Parent] from @window.
88  *
89  * Returns: (transfer full): a [struct@Parent]
90  */
91 XdpParent *
xdp_parent_new_gtk(GtkWindow * window)92 xdp_parent_new_gtk (GtkWindow *window)
93 {
94   XdpParent *parent = g_new0 (XdpParent, 1);
95   parent->parent_export = _xdp_parent_export_gtk;
96   parent->parent_unexport = _xdp_parent_unexport_gtk;
97   parent->object = (GObject *) g_object_ref (window);
98   return parent;
99 }
100