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 #include @@ -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; }; @@ -125,6 +130,28 @@ child_setup (gpointer user_data) meta_context_restore_rlimit_nofile (context, NULL); } +/** + * 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 @@ -216,6 +243,34 @@ set_wayland_client (MetaWaylandClient *client, &client->client_destroy_listener); } +/** + * 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 @@ -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,