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>
This commit is contained in:
Jonas Ådahl 2023-01-26 22:52:40 +01:00 committed by Marge Bot
parent f129929c3f
commit 61a3188d44
3 changed files with 98 additions and 1 deletions

View File

@ -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',

View File

@ -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 */

View File

@ -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;
};
@ -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,