]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - src/seat.c
Rename xlocal seat to local - it supports Mir and Wayland as well as X. The xlocal...
[sojka/lightdm.git] / src / seat.c
index 2e2afd0ae4fe66ab6c9ca79df9d99cf1b5581a9b..facf7ef9416c05f7592ad3b684fbae17556d5e22 100644 (file)
@@ -16,7 +16,7 @@
 #include "seat.h"
 #include "configuration.h"
 #include "guest-account.h"
-#include "greeter.h"
+#include "greeter-session.h"
 #include "session-config.h"
 
 enum {
@@ -67,7 +67,7 @@ struct SeatPrivate
     gboolean stopped;
     
     /* The greeter to be started to replace the current one */
-    Greeter *replacement_greeter;
+    GreeterSession *replacement_greeter;
 };
 
 static void seat_logger_iface_init (LoggerInterface *iface);
@@ -78,23 +78,32 @@ G_DEFINE_TYPE_WITH_CODE (Seat, seat, G_TYPE_OBJECT,
 
 typedef struct
 {
-    const gchar *name;
+    gchar *name;
     GType type;
 } SeatModule;
 static GHashTable *seat_modules = NULL;
 
 // FIXME: Make a get_display_server() that re-uses display servers if supported
 static DisplayServer *create_display_server (Seat *seat, Session *session);
-static Greeter *create_greeter_session (Seat *seat);
+static gboolean start_display_server (Seat *seat, DisplayServer *display_server);
+static GreeterSession *create_greeter_session (Seat *seat);
 static void start_session (Seat *seat, Session *session);
 
+static void
+free_seat_module (gpointer data)
+{
+    SeatModule *module = data;
+    g_free (module->name);
+    g_free (module);
+}
+
 void
 seat_register_module (const gchar *name, GType type)
 {
     SeatModule *module;
 
     if (!seat_modules)
-        seat_modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+        seat_modules = g_hash_table_new_full (g_str_hash, g_str_equal, free_seat_module, NULL);
 
     g_debug ("Registered seat module %s", name);
 
@@ -147,7 +156,19 @@ seat_get_string_list_property (Seat *seat, const gchar *name)
 gboolean
 seat_get_boolean_property (Seat *seat, const gchar *name)
 {
-    return g_strcmp0 (seat_get_string_property (seat, name), "true") == 0;
+    const gchar *value;
+    gint i, length = 0;
+
+    value = seat_get_string_property (seat, name);
+    if (!value)
+        return FALSE;
+
+    /* Count the number of non-whitespace characters */
+    for (i = 0; value[i]; i++)
+        if (!g_ascii_isspace (value[i]))
+            length = i + 1;
+
+    return strncmp (value, "true", MAX (length, 4)) == 0;
 }
 
 gint
@@ -223,12 +244,12 @@ seat_set_active_session (Seat *seat, Session *session)
         if (s == session || session_get_is_stopping (s))
             continue;
 
-        if (IS_GREETER (s))
+        if (IS_GREETER_SESSION (s))
         {
-            Greeter *greeter = GREETER (s);
+            Greeter *greeter = greeter_session_get_greeter (GREETER_SESSION (s));
             if (greeter_get_resettable (greeter))
             {
-                if (seat->priv->active_session == SESSION (greeter))
+                if (seat->priv->active_session == s)
                 {
                     l_debug (seat, "Idling greeter");
                     /* Do this in an idle callback, because we might very well
@@ -247,7 +268,7 @@ seat_set_active_session (Seat *seat, Session *session)
     }
 
     /* Lock previous sessions */
-    if (seat->priv->active_session && session != seat->priv->active_session && !IS_GREETER (seat->priv->active_session))
+    if (seat->priv->active_session && session != seat->priv->active_session && !IS_GREETER_SESSION (seat->priv->active_session))
         session_lock (seat->priv->active_session);
 
     session_activate (session);
@@ -273,7 +294,7 @@ seat_get_next_session (Seat *seat)
  * Obtains the active session which lightdm expects to be active.
  *
  * This function is different from seat_get_active_session() in that the
- * later (in the case of xlocal seats) dynamically finds the session that is
+ * later (in the case of local seats) dynamically finds the session that is
  * really active (based on the active VT), whereas this function returns the
  * session that lightdm activated last by itself, which may not be the actual
  * active session (i.e. VT changes).
@@ -393,15 +414,14 @@ emit_upstart_signal (const gchar *signal)
 {
     g_return_if_fail (signal != NULL);
     g_return_if_fail (signal[0] != 0);
-    const gchar* argv[] = {"initctl", "-q", "emit", signal, "DISPLAY_MANAGER=lightdm", NULL};
+    GSubprocess *p;
 
     if (getuid () != 0)
         return;
 
     /* OK if it fails, probably not installed or not running upstart */
-    g_spawn_async (NULL, argv, NULL,
-            G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
-            NULL, NULL, NULL, NULL);
+    p = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_SILENCE, NULL, "initctl", "-q", "emit", signal, "DISPLAY_MANAGER=lightdm", NULL);
+    g_object_unref (p);
 }
 
 static void
@@ -454,7 +474,7 @@ display_server_stopped_cb (DisplayServer *display_server, Seat *seat)
             continue;
 
         /* Stop seat if this is the only display server and it failed to start a greeter */
-        if (IS_GREETER (session) &&
+        if (IS_GREETER_SESSION (session) &&
             !session_get_is_started (session) &&
             g_list_length (seat->priv->display_servers) == 0)
         {
@@ -491,7 +511,7 @@ can_share_display_server (Seat *seat, DisplayServer *display_server)
     return seat->priv->share_display_server && display_server_get_can_share (display_server);
 }
 
-static Greeter *
+static GreeterSession *
 find_greeter_session (Seat *seat)
 {
     GList *link;
@@ -499,14 +519,14 @@ find_greeter_session (Seat *seat)
     for (link = seat->priv->sessions; link; link = link->next)
     {
         Session *session = link->data;
-        if (!session_get_is_stopping (session) && IS_GREETER (session))
-            return GREETER (session);
+        if (!session_get_is_stopping (session) && IS_GREETER_SESSION (session))
+            return GREETER_SESSION (session);
     }
 
     return NULL;
 }
 
-static Greeter *
+static GreeterSession *
 find_resettable_greeter (Seat *seat)
 {
     GList *link;
@@ -514,29 +534,30 @@ find_resettable_greeter (Seat *seat)
     for (link = seat->priv->sessions; link; link = link->next)
     {
         Session *session = link->data;
-        if (!session_get_is_stopping (session) && IS_GREETER (session) &&
-            greeter_get_resettable (GREETER (session)))
-            return GREETER (session);
+        if (!session_get_is_stopping (session) && IS_GREETER_SESSION (session) &&
+            greeter_get_resettable (greeter_session_get_greeter (GREETER_SESSION (session))))
+            return GREETER_SESSION (session);
     }
 
     return NULL;
 }
 
 static void
-set_greeter_hints (Seat *seat, Greeter *greeter_session)
+set_greeter_hints (Seat *seat, Greeter *greeter)
 {
-    greeter_clear_hints (greeter_session);
-    greeter_set_hint (greeter_session, "default-session", seat_get_string_property (seat, "user-session"));
-    greeter_set_hint (greeter_session, "hide-users", seat_get_boolean_property (seat, "greeter-hide-users") ? "true" : "false");
-    greeter_set_hint (greeter_session, "show-manual-login", seat_get_boolean_property (seat, "greeter-show-manual-login") ? "true" : "false");
-    greeter_set_hint (greeter_session, "show-remote-login", seat_get_boolean_property (seat, "greeter-show-remote-login") ? "true" : "false");
-    greeter_set_hint (greeter_session, "has-guest-account", seat_get_allow_guest (seat) && seat_get_boolean_property (seat, "greeter-allow-guest") ? "true" : "false");
+    greeter_clear_hints (greeter);
+    greeter_set_hint (greeter, "default-session", seat_get_string_property (seat, "user-session"));
+    greeter_set_hint (greeter, "hide-users", seat_get_boolean_property (seat, "greeter-hide-users") ? "true" : "false");
+    greeter_set_hint (greeter, "show-manual-login", seat_get_boolean_property (seat, "greeter-show-manual-login") ? "true" : "false");
+    greeter_set_hint (greeter, "show-remote-login", seat_get_boolean_property (seat, "greeter-show-remote-login") ? "true" : "false");
+    greeter_set_hint (greeter, "has-guest-account", seat_get_allow_guest (seat) && seat_get_boolean_property (seat, "greeter-allow-guest") ? "true" : "false");
 }
 
 static void
 switch_to_greeter_from_failed_session (Seat *seat, Session *session)
 {
-    Greeter *greeter_session;
+    GreeterSession *greeter_session;
+    Greeter *greeter;  
     gboolean existing = FALSE;
 
     /* Switch to greeter if one open */
@@ -544,22 +565,23 @@ switch_to_greeter_from_failed_session (Seat *seat, Session *session)
     if (greeter_session)
     {
         l_debug (seat, "Switching to existing greeter");
-        set_greeter_hints (seat, greeter_session);
+        set_greeter_hints (seat, greeter_session_get_greeter (greeter_session));
         existing = TRUE;
     }
     else
     {
         greeter_session = create_greeter_session (seat);
     }
+    greeter = greeter_session_get_greeter (greeter_session);
 
     if (session_get_is_guest (session))
-        greeter_set_hint (greeter_session, "select-guest", "true");
+        greeter_set_hint (greeter, "select-guest", "true");
     else
-        greeter_set_hint (greeter_session, "select-user", session_get_username (session));
+        greeter_set_hint (greeter, "select-user", session_get_username (session));
 
     if (existing)
     {
-        greeter_reset (greeter_session);
+        greeter_reset (greeter);
         seat_set_active_session (seat, SESSION (greeter_session));
     }
     else
@@ -575,7 +597,7 @@ switch_to_greeter_from_failed_session (Seat *seat, Session *session)
 
             display_server = create_display_server (seat, session);
             session_set_display_server (session, display_server);
-            if (!display_server_start (display_server))
+            if (!start_display_server (seat, display_server))
             {
                 l_debug (seat, "Failed to start display server for greeter");
                 seat_stop (seat);
@@ -593,23 +615,25 @@ static void
 start_session (Seat *seat, Session *session)
 {
     /* Use system location for greeter log file */
-    if (IS_GREETER (session))
+    if (IS_GREETER_SESSION (session))
     {
         gchar *log_dir, *filename, *log_filename;
+        gboolean backup_logs;
 
         log_dir = config_get_string (config_get_instance (), "LightDM", "log-directory");
         filename = g_strdup_printf ("%s-greeter.log", display_server_get_name (session_get_display_server (session)));
         log_filename = g_build_filename (log_dir, filename, NULL);
         g_free (log_dir);
         g_free (filename);
-        session_set_log_file (session, log_filename);
+        backup_logs = config_get_boolean (config_get_instance (), "LightDM", "backup-logs");
+        session_set_log_file (session, log_filename, backup_logs ? LOG_MODE_BACKUP_AND_TRUNCATE : LOG_MODE_APPEND);
         g_free (log_filename);
     }
 
     if (session_start (session))
         return;
 
-    if (IS_GREETER (session))
+    if (IS_GREETER_SESSION (session))
     {
         l_debug (seat, "Failed to start greeter");
         display_server_stop (session_get_display_server (session));
@@ -625,7 +649,7 @@ run_session (Seat *seat, Session *session)
 {
     const gchar *script;
 
-    if (IS_GREETER (session))
+    if (IS_GREETER_SESSION (session))
         script = seat_get_string_property (seat, "greeter-setup-script");
     else
         script = seat_get_string_property (seat, "session-setup-script");
@@ -636,7 +660,7 @@ run_session (Seat *seat, Session *session)
         return;
     }
 
-    if (!IS_GREETER (session))
+    if (!IS_GREETER_SESSION (session))
     {
         g_signal_emit (seat, signals[RUNNING_USER_SESSION], 0, session);
         emit_upstart_signal ("desktop-session-start");
@@ -719,7 +743,7 @@ session_authentication_complete_cb (Session *session, Seat *seat)
             run_session (seat, session);
         }
     }
-    else if (!IS_GREETER (session))
+    else if (!IS_GREETER_SESSION (session))
     {
         l_debug (seat, "Switching to greeter due to failed authentication");
         switch_to_greeter_from_failed_session (seat, session);
@@ -755,7 +779,7 @@ session_stopped_cb (Session *session, Seat *seat)
     }
 
     /* Cleanup */
-    if (!IS_GREETER (session))
+    if (!IS_GREETER_SESSION (session))
     {
         const gchar *script;
         script = seat_get_string_property (seat, "session-cleanup-script");
@@ -776,9 +800,9 @@ session_stopped_cb (Session *session, Seat *seat)
     }
     
     /* If there is a pending replacement greeter, start it */
-    if (IS_GREETER (session) && seat->priv->replacement_greeter)
+    if (IS_GREETER_SESSION (session) && seat->priv->replacement_greeter)
     {
-        Greeter *replacement_greeter = seat->priv->replacement_greeter;
+        GreeterSession *replacement_greeter = seat->priv->replacement_greeter;
         seat->priv->replacement_greeter = NULL;
         
         if (session_get_is_authenticated (SESSION (replacement_greeter)))
@@ -795,9 +819,9 @@ session_stopped_cb (Session *session, Seat *seat)
         g_object_unref (replacement_greeter);
     }
     /* If this is the greeter session then re-use this display server */
-    else if (IS_GREETER (session) &&
+    else if (IS_GREETER_SESSION (session) &&
         can_share_display_server (seat, display_server) &&
-        greeter_get_start_session (GREETER (session)))
+        greeter_get_start_session (greeter_session_get_greeter (GREETER_SESSION (session))))
     {
         GList *link;
 
@@ -823,8 +847,8 @@ session_stopped_cb (Session *session, Seat *seat)
         }
     }
     /* If this is the greeter and nothing else is running then stop the seat */
-    else if (IS_GREETER (session) &&
-        !greeter_get_start_session (GREETER (session)) &&
+    else if (IS_GREETER_SESSION (session) &&
+        !greeter_get_start_session (greeter_session_get_greeter (GREETER_SESSION (session))) &&
         g_list_length (seat->priv->display_servers) == 1 &&
         g_list_nth_data (seat->priv->display_servers, 0) == display_server)
     {
@@ -832,7 +856,7 @@ session_stopped_cb (Session *session, Seat *seat)
         seat_stop (seat);
     }
     /* If we were the active session, switch to a greeter */
-    else if (!IS_GREETER (session) && session == seat_get_active_session (seat))
+    else if (!IS_GREETER_SESSION (session) && session == seat_get_active_session (seat))
     {
         l_debug (seat, "Active session stopped, starting greeter");
         if (!seat_switch_to_greeter (seat))
@@ -843,24 +867,11 @@ session_stopped_cb (Session *session, Seat *seat)
     }
 
     /* Stop the display server if no-longer required */
-    if (display_server && !display_server_get_is_stopping (display_server))
+    if (display_server && !display_server_get_is_stopping (display_server) &&
+        !SEAT_GET_CLASS (seat)->display_server_is_used (seat, display_server))
     {
-        GList *link;
-        int n_sessions = 0;
-
-        for (link = seat->priv->sessions; link; link = link->next)
-        {
-            Session *s = link->data;
-            if (s == session)
-                continue;
-            if (session_get_display_server (s) == display_server)
-                n_sessions++;
-        }
-        if (n_sessions == 0)
-        {
-            l_debug (seat, "Stopping display server, no sessions require it");
-            display_server_stop (display_server);
-        }
+        l_debug (seat, "Stopping display server, no sessions require it");
+        display_server_stop (display_server);
     }
 
     g_signal_emit (seat, signals[SESSION_REMOVED], 0, session);
@@ -1125,14 +1136,33 @@ create_guest_session (Seat *seat, const gchar *session_name)
     return session;
 }
 
+// FIXME: This is inefficient and we already know the greeter session when we set the callbacks...
+static Session *
+get_greeter_session (Seat *seat, Greeter *greeter)
+{
+    GList *link;
+
+    /* Stop any greeters */
+    for (link = seat->priv->sessions; link; link = link->next)
+    {
+        Session *session = link->data;
+
+        if (IS_GREETER_SESSION (session) && greeter_session_get_greeter (GREETER_SESSION (session)))
+            return session;
+    }
+
+    return NULL;
+}
+
 static Session *
 greeter_create_session_cb (Greeter *greeter, Seat *seat)
 {
-    Session *session;
+    Session *greeter_session, *session;
 
+    greeter_session = get_greeter_session (seat, greeter);
     session = create_session (seat, FALSE);
-    session_set_config (session, session_get_config (SESSION (greeter)));
-    session_set_display_server (session, session_get_display_server (SESSION (greeter)));
+    session_set_config (session, session_get_config (greeter_session));
+    session_set_display_server (session, session_get_display_server (greeter_session));
 
     return g_object_ref (session);
 }
@@ -1140,7 +1170,7 @@ greeter_create_session_cb (Greeter *greeter, Seat *seat)
 static gboolean
 greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *session_name, Seat *seat)
 {
-    Session *session, *existing_session;
+    Session *session, *existing_session, *greeter_session;
     const gchar *username;
     DisplayServer *display_server;
 
@@ -1219,7 +1249,8 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
     }
 
     /* If can re-use the display server, stop the greeter first */
-    display_server = session_get_display_server (SESSION (greeter));
+    greeter_session = get_greeter_session (seat, greeter);
+    display_server = session_get_display_server (greeter_session);
     if (!greeter_get_resettable (greeter) &&
         can_share_display_server (seat, display_server) &&
         strcmp (display_server_get_session_type (display_server), session_get_session_type (session)) == 0)
@@ -1230,7 +1261,7 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
         session_set_display_server (session, display_server);
 
         /* Stop the greeter */
-        session_stop (SESSION (greeter));
+        session_stop (greeter_session);
 
         return TRUE;
     }
@@ -1239,7 +1270,7 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
     {
         display_server = create_display_server (seat, session);
         session_set_display_server (session, display_server);
-        if (!display_server_start (display_server))
+        if (!start_display_server (seat, display_server))
         {
             l_debug (seat, "Failed to start display server for new session");
             return FALSE;
@@ -1249,12 +1280,13 @@ greeter_start_session_cb (Greeter *greeter, SessionType type, const gchar *sessi
     }
 }
 
-static Greeter *
+static GreeterSession *
 create_greeter_session (Seat *seat)
 {
     gchar *sessions_dir, **argv;
     SessionConfig *session_config;
-    Greeter *greeter_session;
+    GreeterSession *greeter_session;
+    Greeter *greeter;  
     const gchar *greeter_wrapper;
     const gchar *autologin_username;
     int autologin_timeout;
@@ -1279,9 +1311,10 @@ create_greeter_session (Seat *seat)
     }
 
     greeter_session = SEAT_GET_CLASS (seat)->create_greeter_session (seat);
+    greeter = greeter_session_get_greeter (greeter_session);
     session_set_config (SESSION (greeter_session), session_config);
     seat->priv->sessions = g_list_append (seat->priv->sessions, SESSION (greeter_session));
-    g_signal_connect (greeter_session, GREETER_SIGNAL_ACTIVE_USERNAME_CHANGED, G_CALLBACK (greeter_active_username_changed_cb), seat);
+    g_signal_connect (greeter, GREETER_SIGNAL_ACTIVE_USERNAME_CHANGED, G_CALLBACK (greeter_active_username_changed_cb), seat);
     g_signal_connect (greeter_session, SESSION_SIGNAL_AUTHENTICATION_COMPLETE, G_CALLBACK (session_authentication_complete_cb), seat);
     g_signal_connect (greeter_session, SESSION_SIGNAL_STOPPED, G_CALLBACK (session_stopped_cb), seat);
 
@@ -1304,15 +1337,15 @@ create_greeter_session (Seat *seat)
     session_set_argv (SESSION (greeter_session), argv);
     g_strfreev (argv);
 
-    greeter_set_pam_services (greeter_session,
+    greeter_set_pam_services (greeter,
                               seat_get_string_property (seat, "pam-service"),
                               seat_get_string_property (seat, "pam-autologin-service"));
-    g_signal_connect (greeter_session, GREETER_SIGNAL_CREATE_SESSION, G_CALLBACK (greeter_create_session_cb), seat);
-    g_signal_connect (greeter_session, GREETER_SIGNAL_START_SESSION, G_CALLBACK (greeter_start_session_cb), seat);
+    g_signal_connect (greeter, GREETER_SIGNAL_CREATE_SESSION, G_CALLBACK (greeter_create_session_cb), seat);
+    g_signal_connect (greeter, GREETER_SIGNAL_START_SESSION, G_CALLBACK (greeter_start_session_cb), seat);
 
     /* Set hints to greeter */
-    greeter_set_allow_guest (greeter_session, seat_get_allow_guest (seat));
-    set_greeter_hints (seat, greeter_session);
+    greeter_set_allow_guest (greeter, seat_get_allow_guest (seat));
+    set_greeter_hints (seat, greeter);
 
     /* Configure for automatic login */
     autologin_username = seat_get_string_property (seat, "autologin-user");
@@ -1325,12 +1358,12 @@ create_greeter_session (Seat *seat)
         gchar *value;
 
         value = g_strdup_printf ("%d", autologin_timeout);
-        greeter_set_hint (greeter_session, "autologin-timeout", value);
+        greeter_set_hint (greeter, "autologin-timeout", value);
         g_free (value);
         if (autologin_username)
-            greeter_set_hint (greeter_session, "autologin-user", autologin_username);
+            greeter_set_hint (greeter, "autologin-user", autologin_username);
         if (autologin_guest)
-            greeter_set_hint (greeter_session, "autologin-guest", "true");
+            greeter_set_hint (greeter, "autologin-guest", "true");
     }
 
     g_object_unref (session_config);
@@ -1346,7 +1379,10 @@ find_session_for_display_server (Seat *seat, DisplayServer *display_server)
     for (link = seat->priv->sessions; link; link = link->next)
     {
         Session *session = link->data;
-        if (session_get_display_server (session) == display_server && !session_get_is_stopping (session))
+
+        if (session_get_display_server (session) == display_server &&
+            !session_get_is_stopping (session) &&
+            !session_get_is_run (session))
             return session;
     }
 
@@ -1403,17 +1439,33 @@ create_display_server (Seat *seat, Session *session)
     if (!display_server)
         return NULL;
 
-    seat->priv->display_servers = g_list_append (seat->priv->display_servers, display_server);
-    g_signal_connect (display_server, DISPLAY_SERVER_SIGNAL_READY, G_CALLBACK (display_server_ready_cb), seat);
-    g_signal_connect (display_server, DISPLAY_SERVER_SIGNAL_STOPPED, G_CALLBACK (display_server_stopped_cb), seat);
+    /* Remember this display server */
+    if (!g_list_find (seat->priv->display_servers, display_server)) 
+    {
+        seat->priv->display_servers = g_list_append (seat->priv->display_servers, display_server);
+        g_signal_connect (display_server, DISPLAY_SERVER_SIGNAL_READY, G_CALLBACK (display_server_ready_cb), seat);
+        g_signal_connect (display_server, DISPLAY_SERVER_SIGNAL_STOPPED, G_CALLBACK (display_server_stopped_cb), seat);
+    }
 
     return display_server;
 }
 
+static gboolean
+start_display_server (Seat *seat, DisplayServer *display_server)
+{
+    if (display_server_get_is_ready (display_server))
+    {
+        display_server_ready_cb (display_server, seat);
+        return TRUE;
+    }
+    else
+        return display_server_start (display_server);
+}
+
 gboolean
 seat_switch_to_greeter (Seat *seat)
 {
-    Greeter *greeter_session;
+    GreeterSession *greeter_session;
     DisplayServer *display_server;
 
     g_return_val_if_fail (seat != NULL, FALSE);
@@ -1440,13 +1492,14 @@ seat_switch_to_greeter (Seat *seat)
     display_server = create_display_server (seat, SESSION (greeter_session));
     session_set_display_server (SESSION (greeter_session), display_server);
 
-    return display_server_start (display_server);
+    return start_display_server (seat, display_server);
 }
 
 static void
 switch_authentication_complete_cb (Session *session, Seat *seat)
 {
-    Greeter *greeter_session;
+    GreeterSession *greeter_session;
+    Greeter *greeter;
     DisplayServer *display_server;
     gboolean existing = FALSE;
 
@@ -1470,7 +1523,7 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
             seat->priv->session_to_activate = g_object_ref (session);
             display_server = create_display_server (seat, session);
             session_set_display_server (session, display_server);
-            display_server_start (display_server);
+            start_display_server (seat, display_server);
         }
 
         return;
@@ -1483,7 +1536,7 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
     if (greeter_session)
     {
         l_debug (seat, "Switching to existing greeter to authenticate session");
-        set_greeter_hints (seat, greeter_session);
+        set_greeter_hints (seat, greeter_session_get_greeter (greeter_session));
         existing = TRUE;
     }
     else
@@ -1491,15 +1544,16 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
         l_debug (seat, "Starting greeter to authenticate session");
         greeter_session = create_greeter_session (seat);
     }
+    greeter = greeter_session_get_greeter (greeter_session);
 
     if (session_get_is_guest (session))
-        greeter_set_hint (greeter_session, "select-guest", "true");
+        greeter_set_hint (greeter, "select-guest", "true");
     else
-        greeter_set_hint (greeter_session, "select-user", session_get_username (session));
+        greeter_set_hint (greeter, "select-user", session_get_username (session));
 
     if (existing)
     {
-        greeter_reset (greeter_session);
+        greeter_reset (greeter);
         seat_set_active_session (seat, SESSION (greeter_session));
     }
     else
@@ -1509,7 +1563,7 @@ switch_authentication_complete_cb (Session *session, Seat *seat)
 
         display_server = create_display_server (seat, SESSION (greeter_session));
         session_set_display_server (SESSION (greeter_session), display_server);
-        display_server_start (display_server);
+        start_display_server (seat, display_server);
     }
 }
 
@@ -1585,13 +1639,14 @@ seat_switch_to_guest (Seat *seat, const gchar *session_name)
     session_set_pam_service (session, seat_get_string_property (seat, "pam-autologin-service"));
     session_set_display_server (session, display_server);
 
-    return display_server_start (display_server);
+    return start_display_server (seat, display_server);
 }
 
 gboolean
 seat_lock (Seat *seat, const gchar *username)
 {
-    Greeter *greeter_session;
+    GreeterSession *greeter_session;
+    Greeter *greeter;
     DisplayServer *display_server = NULL;
     gboolean reset_existing = FALSE;
     gboolean reuse_xserver = FALSE;
@@ -1610,7 +1665,7 @@ seat_lock (Seat *seat, const gchar *username)
     if (greeter_session)
     {
         l_debug (seat, "Switching to existing greeter");
-        set_greeter_hints (seat, greeter_session);
+        set_greeter_hints (seat, greeter_session_get_greeter (greeter_session));
         reset_existing = TRUE;
     }
     else
@@ -1632,14 +1687,15 @@ seat_lock (Seat *seat, const gchar *username)
         if (!greeter_session)
             return FALSE;
     }
+    greeter = greeter_session_get_greeter (greeter_session);
 
-    greeter_set_hint (greeter_session, "lock-screen", "true");
+    greeter_set_hint (greeter, "lock-screen", "true");
     if (username)
-        greeter_set_hint (greeter_session, "select-user", username);
+        greeter_set_hint (greeter, "select-user", username);
 
     if (reset_existing)
     {
-        greeter_reset (greeter_session);
+        greeter_reset (greeter);
         seat_set_active_session (seat, SESSION (greeter_session));
         return TRUE;
     }
@@ -1659,7 +1715,7 @@ seat_lock (Seat *seat, const gchar *username)
             return TRUE;
         }
         else
-            return display_server_start (display_server);
+            return start_display_server (seat, display_server);
     }
 }
 
@@ -1732,7 +1788,7 @@ seat_real_start (Seat *seat)
 
             display_server = create_display_server (seat, session);
             session_set_display_server (session, display_server);
-            if (!display_server || !display_server_start (display_server))
+            if (!display_server || !start_display_server (seat, display_server))
             {
                 l_debug (seat, "Can't create display server for automatic login");
                 session_stop (session);
@@ -1746,7 +1802,7 @@ seat_real_start (Seat *seat)
     /* Fallback to a greeter */
     if (!session)
     {
-        Greeter *greeter_session;
+        GreeterSession *greeter_session;
         DisplayServer *display_server;
 
         greeter_session = create_greeter_session (seat);
@@ -1762,7 +1818,7 @@ seat_real_start (Seat *seat)
 
         display_server = create_display_server (seat, session);
         session_set_display_server (session, display_server);
-        if (!display_server || !display_server_start (display_server))
+        if (!display_server || !start_display_server (seat, display_server))
         {
             l_debug (seat, "Can't create display server for greeter");
             session_stop (session);
@@ -1786,17 +1842,41 @@ seat_real_start (Seat *seat)
 
         background_display_server = create_display_server (seat, background_session);
         session_set_display_server (background_session, background_display_server);
-        if (!display_server_start (background_display_server))
+        if (!start_display_server (seat, background_display_server))
             l_warning (seat, "Failed to start display server for background session");
     }
 
     return TRUE;
 }
 
-static Greeter *
+static DisplayServer *
+seat_real_create_display_server (Seat *seat, Session *session)
+{
+    return NULL;
+}
+
+static gboolean
+seat_real_display_server_is_used (Seat *seat, DisplayServer *display_server)
+{
+    GList *link;
+
+    for (link = seat->priv->sessions; link; link = link->next)
+    {
+        Session *session = link->data;
+        DisplayServer *d;
+
+        d = session_get_display_server (session);
+        if (d == display_server || display_server_get_parent (d) == display_server)
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static GreeterSession *
 seat_real_create_greeter_session (Seat *seat)
 {
-    return greeter_new ();
+    return greeter_session_new ();
 }
 
 static Session *
@@ -1903,6 +1983,8 @@ seat_class_init (SeatClass *klass)
 
     klass->setup = seat_real_setup;
     klass->start = seat_real_start;
+    klass->create_display_server = seat_real_create_display_server;
+    klass->display_server_is_used = seat_real_display_server_is_used;  
     klass->create_greeter_session = seat_real_create_greeter_session;
     klass->create_session = seat_real_create_session;
     klass->set_active_session = seat_real_set_active_session;