[gdm] server: invoke X with the systemd multi seat X wrapper if necessary



commit 2b24451c3816ecea30fdbfff2c249a6ac527e1b6
Author: Lennart Poettering <lennart poettering net>
Date:   Tue Jan 24 00:03:10 2012 +0100

    server: invoke X with the systemd multi seat X wrapper if necessary
    
    systemd 39 and newer provide a small wrapper for X which works around
    the fact that XOrg upstream currently support multi-seat hotplug for
    displays. Let's make use of this as a stop-gap until this feature is
    added to XOrg upstream.
    
    This code tries to be as defensive as possible and makes use of the
    wrapper only if the system as actually booted with systemd, the wrapper
    is available and we actually use a seat != "seat0".

 configure.ac        |    6 +++++-
 daemon/gdm-server.c |   50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 54 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index dec31a9..855948d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -939,7 +939,7 @@ use_systemd=no
 if test "x$with_systemd" != "xno" ; then
         PKG_CHECK_MODULES(SYSTEMD,
                 libsystemd-daemon
-                libsystemd-login
+                libsystemd-login >= 39
         )
         AC_SUBST(SYSTEMD_CFLAGS)
         AC_SUBST(SYSTEMD_LIBS)
@@ -950,6 +950,10 @@ fi
 AM_CONDITIONAL(WITH_SYSTEMD, test x$use_systemd = xyes)
 AC_SUBST(WITH_SYSTEMD)
 
+AC_PATH_PROG(SYSTEMD_X_SERVER, systemd-multi-seat-x, [/lib/systemd/systemd-multi-seat-x], [/lib/systemd:/usr/lib/systemd:$PATH])
+AC_SUBST(SYSTEMD_X_SERVER)
+AC_DEFINE_UNQUOTED(SYSTEMD_X_SERVER,"$SYSTEMD_X_SERVER",[Path to systemd X server wrapper])
+
 dnl ---------------------------------------------------------------------------
 dnl - Check for D-Bus
 dnl ---------------------------------------------------------------------------
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index 9a11ba0..54bf8b3 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -260,6 +260,52 @@ connect_to_parent (GdmServer *server)
 }
 #endif
 
+static void
+gdm_server_init_command (GdmServer *server)
+{
+
+        if (server->priv->command != NULL) {
+                return;
+        }
+
+#ifdef WITH_SYSTEMD
+
+        /* This is a temporary hack to work around the fact that XOrg
+         * currently lacks support for multi-seat hotplugging for
+         * display devices. This bit should be removed as soon as XOrg
+         * gains native support for automatically enumerating usb
+         * based graphics adapters at start-up via udev. */
+
+        /* systemd ships an X server wrapper tool which simply invokes
+         * the usual X but ensures it only uses the display devices of
+         * the seat. */
+
+        /* We do not rely on this wrapper server if, a) the machine
+         * wasn't booted using systemd, or b) the wrapper tool is
+         * missing, or c) we are running for the main seat 'seat0'. */
+
+        if (sd_booted () <= 0) {
+                goto fallback;
+        }
+
+        if (g_access (SYSTEMD_X_SERVER, X_OK) < 0) {
+                goto fallback;
+        }
+
+        if (server->priv->display_seat_id == NULL ||
+            strcmp (server->priv->display_seat_id, "seat0") == 0) {
+                goto fallback;
+        }
+
+        server->priv->command = g_strdup (SYSTEMD_X_SERVER " -br -verbose -logverbose 7");
+        return;
+
+fallback:
+#endif
+
+        server->priv->command = g_strdup (X_SERVER " -br -verbose -logverbose 7");
+}
+
 static gboolean
 gdm_server_resolve_command_line (GdmServer  *server,
                                  const char *vtarg,
@@ -273,6 +319,8 @@ gdm_server_resolve_command_line (GdmServer  *server,
         gboolean gotvtarg = FALSE;
         gboolean query_in_arglist = FALSE;
 
+        gdm_server_init_command (server);
+
         g_shell_parse_argv (server->priv->command, &argc, &argv, NULL);
 
         for (len = 0; argv != NULL && argv[len] != NULL; len++) {
@@ -959,7 +1007,7 @@ gdm_server_init (GdmServer *server)
         server->priv = GDM_SERVER_GET_PRIVATE (server);
 
         server->priv->pid = -1;
-        server->priv->command = g_strdup (X_SERVER " -br -verbose -logverbose 7");
+
         server->priv->log_dir = g_strdup (LOGDIR);
 
         add_ready_handler (server);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]