summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonas Ã…dahl <jadahl@gmail.com>2023-01-26 22:52:40 +0100
committerMarge Bot <marge-bot@gnome.org>2023-02-13 15:34:24 +0000
commit61a3188d44201c291b99e7ee7fa403a46f1cdd94 (patch)
treed7f368984ba3b419fe4ef2c30bf5e4f9b398168f /src
parentf129929c3feff3bb7cf22fbd3df0c12da56b9c21 (diff)
downloadmutter-61a3188d44201c291b99e7ee7fa403a46f1cdd94.tar.gz
wayland/client: Add way to create indirectly launched clients
This API creates a "client" then later sets up a wl_client and returns a file descriptor some Wayland client can connect to. It's meant to be used as a method other than WAYLAND_SOCKET and process launching, e.g. passing a file descriptor via a D-Bus API. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2810>
Diffstat (limited to 'src')
-rw-r--r--src/meson.build1
-rw-r--r--src/wayland/meta-wayland-client-private.h34
-rw-r--r--src/wayland/meta-wayland-client.c64
3 files changed, 98 insertions, 1 deletions
diff --git a/src/meson.build b/src/meson.build
index 0200d7cf2..a902f7df1 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -576,6 +576,7 @@ if have_wayland
'wayland/meta-wayland-buffer.h',
'wayland/meta-wayland.c',
'wayland/meta-wayland-client.c',
+ 'wayland/meta-wayland-client-private.h',
'wayland/meta-wayland-cursor-surface.c',
'wayland/meta-wayland-cursor-surface.h',
'wayland/meta-wayland-data-device.c',
diff --git a/src/wayland/meta-wayland-client-private.h b/src/wayland/meta-wayland-client-private.h
new file mode 100644
index 000000000..0f67a2e66
--- /dev/null
+++ b/src/wayland/meta-wayland-client-private.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2023 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_WAYLAND_CLIENT_PRIVATE_H
+#define META_WAYLAND_CLIENT_PRIVATE_H
+
+#include "core/util-private.h"
+#include "meta/meta-wayland-client.h"
+
+META_EXPORT_TEST
+MetaWaylandClient * meta_wayland_client_new_indirect (MetaContext *context,
+ GError **error);
+
+META_EXPORT_TEST
+int meta_wayland_client_setup_fd (MetaWaylandClient *client,
+ GError **error);
+
+#endif /* META_WAYLAND_CLIENT_PRIVATE_H */
diff --git a/src/wayland/meta-wayland-client.c b/src/wayland/meta-wayland-client.c
index fd0242dcd..56d8f4bcc 100644
--- a/src/wayland/meta-wayland-client.c
+++ b/src/wayland/meta-wayland-client.c
@@ -2,6 +2,7 @@
/*
* Copyright 2019 Sergio Costas (rastersoft@gmail.com)
+ * Copyright 2023 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -29,7 +30,7 @@
#include "config.h"
-#include "meta/meta-wayland-client.h"
+#include "wayland/meta-wayland-client-private.h"
#include <gio/gio.h>
#include <glib-object.h>
@@ -66,6 +67,10 @@ struct _MetaWaylandClient
gboolean process_launched;
} subprocess;
+ struct {
+ int fd;
+ } indirect;
+
struct wl_client *wayland_client;
struct wl_listener client_destroy_listener;
};
@@ -126,6 +131,28 @@ child_setup (gpointer user_data)
}
/**
+ * meta_wayland_client_new_indirect: (skip)
+ */
+MetaWaylandClient *
+meta_wayland_client_new_indirect (MetaContext *context,
+ GError **error)
+{
+ MetaWaylandClient *client;
+
+ if (!meta_is_wayland_compositor ())
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "MetaWaylandClient can be used only with Wayland.");
+ return NULL;
+ }
+
+ client = g_object_new (META_TYPE_WAYLAND_CLIENT, NULL);
+ client->context = context;
+
+ return client;
+}
+
+/**
* meta_wayland_client_new:
* @context: (not nullable): a #MetaContext
* @launcher: (not nullable): a GSubprocessLauncher to use to launch the subprocess
@@ -217,6 +244,34 @@ set_wayland_client (MetaWaylandClient *client,
}
/**
+ * meta_wayland_client_setup_fd: (skip)
+ * @client: a #MetaWaylandClient
+ *
+ * Initialize a wl_client that can be connected to via the returned file
+ * descriptor. May only be used with a #MetaWaylandClient created with
+ * meta_wayland_client_new_indirect().
+ *
+ * Returns: (transfer full): A new file descriptor
+ */
+int
+meta_wayland_client_setup_fd (MetaWaylandClient *client,
+ GError **error)
+{
+ struct wl_client *wayland_client;
+ int fd;
+
+ g_return_val_if_fail (!client->wayland_client, -1);
+ g_return_val_if_fail (!client->subprocess.launcher, -1);
+
+ if (!init_wayland_client (client, &wayland_client, &fd, error))
+ return -1;
+
+ set_wayland_client (client, wayland_client);
+
+ return fd;
+}
+
+/**
* meta_wayland_client_spawnv:
* @client: a #MetaWaylandClient
* @display: (not nullable): the current MetaDisplay
@@ -247,6 +302,13 @@ meta_wayland_client_spawnv (MetaWaylandClient *client,
argv[0][0] != '\0',
NULL);
+ if (!client->subprocess.launcher)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "This client can not be launched");
+ return NULL;
+ }
+
if (client->subprocess.process_launched)
{
g_set_error (error,