wayland: Set up initialization X11 socket

This is used by GDK and the X11 bits, but may also be used for
other initialization services we might need to run along with
Xwayland initialization.

However, as the -initfd argument in Xwayland is a fairly new
feature, add some meson build-time checks so that the feature
is handled transparently while allowing to explicitly set/unset
it.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/945
This commit is contained in:
Carlos Garnacho 2019-07-19 22:50:31 +02:00 committed by Carlos Garnacho
parent 38e58b837b
commit 166a464515
6 changed files with 93 additions and 25 deletions

View File

@ -67,3 +67,6 @@
/* Either <sys/random.h> or <linux/random.h> */
#mesondefine HAVE_SYS_RANDOM
#mesondefine HAVE_LINUX_RANDOM
/* Whether Xwayland has -initfd option */
#mesondefine HAVE_XWAYLAND_INITFD

View File

@ -377,6 +377,7 @@ if cc.has_header_symbol('sys/prctl.h', 'prctl')
cdata.set('HAVE_SYS_PRCTL', 1)
endif
have_xwayland_initfd = false
if have_wayland
xwayland_path = get_option('xwayland_path')
if xwayland_path == ''
@ -392,6 +393,19 @@ if have_wayland
else
error('Required function getrandom not found')
endif
# For Xwayland -initfd usage
use_initfd = get_option('xwayland_initfd')
if use_initfd.auto()
xwayland_options = run_command(xwayland_path, '-help')
have_xwayland_initfd = xwayland_options.stderr().contains('-initfd')
else
have_xwayland_initfd = use_initfd.enabled()
endif
if (have_xwayland_initfd)
cdata.set('HAVE_XWAYLAND_INITFD', 1)
endif
endif
xwayland_grab_default_access_rules = get_option('xwayland_grab_default_access_rules')
@ -450,6 +464,7 @@ output = [
' Startup notification..... ' + have_startup_notification.to_string(),
' Introspection............ ' + have_introspection.to_string(),
' Profiler................. ' + have_profiler.to_string(),
' Xwayland initfd.......... ' + have_xwayland_initfd.to_string(),
'',
' Tests:',
'',

View File

@ -152,3 +152,9 @@ option('xwayland_grab_default_access_rules',
value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr',
description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland'
)
option('xwayland_initfd',
type: 'feature',
value: 'auto',
description: 'Whether Xwayland -initfd argument is used'
)

View File

@ -48,11 +48,18 @@ typedef struct
char *lock_file;
int abstract_fd;
int unix_fd;
char *name;
} MetaXWaylandConnection;
typedef struct
{
MetaXWaylandConnection private_connection;
MetaXWaylandConnection public_connection;
guint xserver_grace_period_id;
struct wl_display *wayland_display;
struct wl_client *client;
struct wl_resource *xserver_resource;
char *display_name;
char *auth_file;
GCancellable *xserver_died_cancellable;

View File

@ -446,7 +446,7 @@ meta_wayland_init (void)
if (meta_get_x11_display_policy () != META_DISPLAY_POLICY_DISABLED)
{
set_gnome_env ("DISPLAY", meta_wayland_get_xwayland_display_name (compositor));
set_gnome_env ("DISPLAY", compositor->xwayland_manager.public_connection.name);
set_gnome_env ("XAUTHORITY", meta_wayland_get_xwayland_auth_file (compositor));
}
@ -462,7 +462,7 @@ meta_wayland_get_wayland_display_name (MetaWaylandCompositor *compositor)
const char *
meta_wayland_get_xwayland_display_name (MetaWaylandCompositor *compositor)
{
return compositor->xwayland_manager.display_name;
return compositor->xwayland_manager.private_connection.name;
}
void

View File

@ -314,6 +314,7 @@ xserver_died (GObject *source,
gpointer user_data)
{
GSubprocess *proc = G_SUBPROCESS (source);
MetaDisplay *display = meta_get_display ();
g_autoptr (GError) error = NULL;
if (!g_subprocess_wait_finish (proc, result, &error))
@ -338,7 +339,6 @@ xserver_died (GObject *source,
else if (meta_get_x11_display_policy () == META_DISPLAY_POLICY_ON_DEMAND)
{
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
MetaDisplay *display = meta_get_display ();
if (display->x11_display)
meta_display_shutdown_x11 (display);
@ -381,6 +381,8 @@ meta_xwayland_override_display_number (int number)
static gboolean
open_display_sockets (MetaXWaylandManager *manager,
int display_index,
int *abstract_fd_out,
int *unix_fd_out,
gboolean *fatal)
{
int abstract_fd, unix_fd;
@ -398,14 +400,15 @@ open_display_sockets (MetaXWaylandManager *manager,
return FALSE;
}
manager->abstract_fd = abstract_fd;
manager->unix_fd = unix_fd;
*abstract_fd_out = abstract_fd;
*unix_fd_out = unix_fd;
return TRUE;
}
static gboolean
choose_xdisplay (MetaXWaylandManager *manager)
choose_xdisplay (MetaXWaylandManager *manager,
MetaXWaylandConnection *connection)
{
int display = 0;
char *lock_file = NULL;
@ -425,7 +428,10 @@ choose_xdisplay (MetaXWaylandManager *manager)
return FALSE;
}
if (!open_display_sockets (manager, display, &fatal))
if (!open_display_sockets (manager, display,
&connection->abstract_fd,
&connection->unix_fd,
&fatal))
{
unlink (lock_file);
@ -445,9 +451,9 @@ choose_xdisplay (MetaXWaylandManager *manager)
}
while (1);
manager->display_index = display;
manager->display_name = g_strdup_printf (":%d", manager->display_index);
manager->lock_file = lock_file;
connection->display_index = display;
connection->name = g_strdup_printf (":%d", connection->display_index);
connection->lock_file = lock_file;
return TRUE;
}
@ -611,14 +617,16 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
launcher = g_subprocess_launcher_new (flags);
g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4);
g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5);
g_subprocess_launcher_take_fd (launcher, manager->public_connection.abstract_fd, 4);
g_subprocess_launcher_take_fd (launcher, manager->public_connection.unix_fd, 5);
g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
g_subprocess_launcher_take_fd (launcher, manager->private_connection.abstract_fd, 7);
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
manager->proc = g_subprocess_launcher_spawn (launcher, &error,
XWAYLAND_PATH, manager->display_name,
XWAYLAND_PATH,
manager->public_connection.name,
"-rootless",
"-noreset",
"-accessx",
@ -627,7 +635,13 @@ meta_xwayland_start_xserver (MetaXWaylandManager *manager,
"-listen", "4",
"-listen", "5",
"-displayfd", "6",
#ifdef HAVE_XWAYLAND_INITFD
"-initfd", "7",
#else
"-listen", "7",
#endif
NULL);
if (!manager->proc)
{
g_task_return_error (task, error);
@ -728,9 +742,11 @@ meta_xwayland_init (MetaXWaylandManager *manager,
MetaDisplayPolicy policy;
gboolean fatal;
if (!manager->display_name)
if (!manager->public_connection.name)
{
if (!choose_xdisplay (manager))
if (!choose_xdisplay (manager, &manager->public_connection))
return FALSE;
if (!choose_xdisplay (manager, &manager->private_connection))
return FALSE;
if (!prepare_auth_file (manager))
@ -738,7 +754,18 @@ meta_xwayland_init (MetaXWaylandManager *manager,
}
else
{
if (!open_display_sockets (manager, manager->display_index, &fatal))
if (!open_display_sockets (manager,
manager->public_connection.display_index,
&manager->public_connection.abstract_fd,
&manager->public_connection.unix_fd,
&fatal))
return FALSE;
if (!open_display_sockets (manager,
manager->private_connection.display_index,
&manager->private_connection.abstract_fd,
&manager->private_connection.unix_fd,
&fatal))
return FALSE;
}
@ -747,7 +774,7 @@ meta_xwayland_init (MetaXWaylandManager *manager,
if (policy == META_DISPLAY_POLICY_ON_DEMAND)
{
g_unix_fd_add (manager->abstract_fd, G_IO_IN,
g_unix_fd_add (manager->public_connection.abstract_fd, G_IO_IN,
xdisplay_connection_activity_cb, manager);
}
@ -793,6 +820,13 @@ meta_xwayland_complete_init (MetaDisplay *display,
}
}
static void
meta_xwayland_connection_release (MetaXWaylandConnection *connection)
{
unlink (connection->lock_file);
g_clear_pointer (&connection->lock_file, g_free);
}
void
meta_xwayland_shutdown (MetaXWaylandManager *manager)
{
@ -800,18 +834,21 @@ meta_xwayland_shutdown (MetaXWaylandManager *manager)
g_cancellable_cancel (manager->xserver_died_cancellable);
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->public_connection.display_index);
unlink (path);
g_clear_pointer (&manager->display_name, g_free);
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->private_connection.display_index);
unlink (path);
g_clear_pointer (&manager->public_connection.name, g_free);
g_clear_pointer (&manager->private_connection.name, g_free);
meta_xwayland_connection_release (&manager->public_connection);
meta_xwayland_connection_release (&manager->private_connection);
if (manager->auth_file)
{
unlink (manager->auth_file);
g_clear_pointer (&manager->auth_file, g_free);
}
if (manager->lock_file)
{
unlink (manager->lock_file);
g_clear_pointer (&manager->lock_file, g_free);
}
}