[gdm/wip/wayland-for-merge: 15/20] session-worker: Allocate a new VT for sessions with their own display server



commit 8b635e0ef5ad3a5b0dd5670873a95ebdc67bef92
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Wed Feb 12 18:35:19 2014 -0500

    session-worker: Allocate a new VT for sessions with their own display server
    
    Ideally, we would simply set XDG_VTNR=auto, but that doesn't work yet,
    so query the first open VT, and set XDG_VTNR to it when we have a
    display server.

 daemon/gdm-session-worker.c   |   65 ++++++++++++++++++++++++++++++++++++++++-
 daemon/gdm-session-worker.xml |    3 ++
 daemon/gdm-session.c          |    6 ++++
 3 files changed, 73 insertions(+), 1 deletions(-)
---
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 881a22d..2823ab4 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -28,6 +28,8 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <sys/vt.h>
 #include <errno.h>
 #include <grp.h>
 #include <pwd.h>
@@ -159,6 +161,7 @@ struct GdmSessionWorkerPrivate
         guint32           is_program_session : 1;
         guint32           is_reauth_session : 1;
         guint32           display_is_local : 1;
+        guint32           session_has_own_display_server : 1;
         guint             state_change_idle_id;
 
         char                 *server_address;
@@ -1927,6 +1930,48 @@ gdm_session_worker_start_session (GdmSessionWorker  *worker,
 }
 
 static gboolean
+set_up_for_new_vt (GdmSessionWorker *worker)
+{
+        int fd;
+        char vt_string[256];
+        struct vt_stat vt_state = { 0 };
+        int session_vt = 0;
+
+        fd = open ("/dev/tty0", O_RDWR | O_NOCTTY);
+
+        if (fd < 0) {
+                g_debug ("GdmSessionWorker: couldn't open VT master: %m");
+                return FALSE;
+        }
+
+        if (ioctl (fd, VT_GETSTATE, &vt_state) < 0) {
+                g_debug ("GdmSessionWorker: couldn't get current VT: %m");
+                goto fail;
+        }
+
+        if (ioctl(fd, VT_OPENQRY, &session_vt) < 0) {
+                g_debug ("GdmSessionWorker: couldn't open new VT: %m");
+                goto fail;
+        }
+
+        close (fd);
+        fd = -1;
+
+        g_assert (session_vt > 0);
+
+        g_snprintf(vt_string, sizeof (vt_string), "%d", session_vt);
+        gdm_session_worker_set_environment_variable (worker,
+                                                     "XDG_VTNR",
+                                                     vt_string);
+
+        return TRUE;
+
+fail:
+        close (fd);
+        return FALSE;
+}
+
+static gboolean
 set_up_for_current_vt (GdmSessionWorker  *worker,
                        GError           **error)
 {
@@ -2004,7 +2049,11 @@ gdm_session_worker_open_session (GdmSessionWorker  *worker,
         g_assert (worker->priv->state == GDM_SESSION_WORKER_STATE_ACCOUNT_DETAILS_SAVED);
         g_assert (geteuid () == 0);
 
-        set_up_for_current_vt (worker, NULL);
+        if (worker->priv->session_has_own_display_server) {
+                set_up_for_new_vt (worker);
+        } else {
+                set_up_for_current_vt (worker, NULL);
+        }
 
         flags = 0;
 
@@ -2171,6 +2220,19 @@ gdm_session_worker_handle_set_session_type (GdmDBusWorker         *object,
 }
 
 static gboolean
+gdm_session_worker_handle_set_session_has_own_display_server (GdmDBusWorker         *object,
+                                                              GDBusMethodInvocation *invocation,
+                                                              gboolean               has_own_display_server)
+{
+        GdmSessionWorker *worker = GDM_SESSION_WORKER (object);
+
+        g_debug ("GdmSessionWorker: session has own display server: %s", has_own_display_server ? "yes" : 
"no");
+        worker->priv->session_has_own_display_server = has_own_display_server;
+        gdm_dbus_worker_complete_set_session_has_own_display_server (object, invocation);
+        return TRUE;
+}
+
+static gboolean
 gdm_session_worker_handle_set_language_name (GdmDBusWorker         *object,
                                              GDBusMethodInvocation *invocation,
                                              const char            *language_name)
@@ -2952,6 +3014,7 @@ worker_interface_init (GdmDBusWorkerIface *interface)
         interface->handle_set_language_name = gdm_session_worker_handle_set_language_name;
         interface->handle_set_session_name = gdm_session_worker_handle_set_session_name;
         interface->handle_set_session_type = gdm_session_worker_handle_set_session_type;
+        interface->handle_set_session_has_own_display_server = 
gdm_session_worker_handle_set_session_has_own_display_server;
         interface->handle_set_environment_variable = gdm_session_worker_handle_set_environment_variable;
         interface->handle_start_program = gdm_session_worker_handle_start_program;
         interface->handle_start_reauthentication = gdm_session_worker_handle_start_reauthentication;
diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml
index 4595ac7..add696a 100644
--- a/daemon/gdm-session-worker.xml
+++ b/daemon/gdm-session-worker.xml
@@ -16,6 +16,9 @@
     <method name="SetSessionType">
       <arg name="session_type" direction="in" type="s"/>
     </method>
+    <method name="SetSessionHasOwnDisplayServer">
+      <arg name="has_own_display_server" direction="in" type="b"/>
+    </method>
     <method name="SetEnvironmentVariable">
       <arg name="name" direction="in" type="s"/>
       <arg name="value" direction="in" type="s"/>
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index 45b8acc..381fe51 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -2732,6 +2732,7 @@ gdm_session_select_session (GdmSession *self,
 {
         GHashTableIter iter;
         gpointer key, value;
+        gboolean has_own_display_server;
 
         g_free (self->priv->selected_session);
 
@@ -2741,6 +2742,8 @@ gdm_session_select_session (GdmSession *self,
                 self->priv->selected_session = g_strdup (text);
         }
 
+        has_own_display_server = gdm_session_has_own_display_server (self);
+
         g_hash_table_iter_init (&iter, self->priv->conversations);
         while (g_hash_table_iter_next (&iter, &key, &value)) {
                 GdmSessionConversation *conversation;
@@ -2750,6 +2753,9 @@ gdm_session_select_session (GdmSession *self,
                 gdm_dbus_worker_call_set_session_name (conversation->worker_proxy,
                                                        get_session_name (self),
                                                        NULL, NULL, NULL);
+                gdm_dbus_worker_call_set_session_has_own_display_server (conversation->worker_proxy,
+                                                                         has_own_display_server,
+                                                                         NULL, NULL, NULL);
         }
 }
 


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