]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
connect_to_server -> connect_sync, start_session -> start_session_sync
authorRobert Ancell <robert.ancell@canonical.com>
Thu, 21 Jul 2011 00:50:57 +0000 (10:50 +1000)
committerRobert Ancell <robert.ancell@canonical.com>
Thu, 21 Jul 2011 00:50:57 +0000 (10:50 +1000)
12 files changed:
NEWS
doc/lightdm-gobject-1-sections.txt
doc/tmpl/greeter.sgml
greeters/gtk/lightdm-gtk-greeter.c
greeters/qt/greeter.cpp
greeters/qt/greeter.h
liblightdm-gobject/greeter.c
liblightdm-gobject/lightdm/greeter.h
liblightdm-qt/QLightDM/Greeter
liblightdm-qt/greeter.cpp
src/greeter.c
tests/src/test-gobject-greeter.c

diff --git a/NEWS b/NEWS
index 7d4f6cf34776feee5e8e2106bbc302696ad3c916..e149bb9937a95fe39b411802a9a510d865dbbc06 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,11 +18,14 @@ Overview of changes in lightdm 0.9.0
       - XDMCP keys now stored in keys.conf
     * liblightdm API changes:
       - Both libraries are now version 1 and have API and ABI guarantees.
-      - Added a session-failed signal to indicate if the session didn't start
-        and the greeter should try authorizing again.
       - Face images are now local paths not URIs
       - liblightdm-gobject now uses lightdm_ prefix instead of ldm_
       - Non-greeter functions are now moved out of the Greeter class
+      - connect_to_server() is now called connect_sync and blocks until
+        completion.
+      - start_session() is now called start_session_sync and blocks until
+        completion. The quit signal is removed, and the greeter should quit if
+        this method returns TRUE.
       - login() is now called authenticate()
       - Greeters now have hints instead of configuration (greeters should load their
         own configuration from /etc/lightdm if they need it).
index 0e71ca85621d40b3f83b0790b2ff4ed970b63210..e3d1821de81720f6ee78136af21eb4d3024792a9 100644 (file)
@@ -118,17 +118,14 @@ LIGHTDM_USER_LIST_GET_CLASS
 <SECTION>
 <FILE>greeter</FILE>
 <TITLE>Greeter Interface</TITLE>
-connected
 autologin_timer_expired
 show_message
 show_prompt
 authentication_complete
-session_failed
-quit
 LightDMMessageType
 LightDMPromptType
 lightdm_greeter_new
-lightdm_greeter_connect_to_server
+lightdm_greeter_connect_sync
 lightdm_greeter_get_default_session_hint
 lightdm_greeter_get_hint
 lightdm_greeter_get_has_guest_account_hint
@@ -146,8 +143,7 @@ lightdm_greeter_cancel_authentication
 lightdm_greeter_get_in_authentication
 lightdm_greeter_get_is_authenticated
 lightdm_greeter_get_authentication_user
-lightdm_greeter_start_session
-lightdm_greeter_start_default_session
+lightdm_greeter_start_session_sync
 <SUBSECTION Standard>
 LIGHTDM_GREETER
 LIGHTDM_IS_GREETER
index c3e2761e084de9c80a7fca7236c87a0e8eac249c..d12b299852148cf7607cc134fafdbbaa2d3a8254 100644 (file)
@@ -16,22 +16,25 @@ int main ()
 {
     LightDMGreeter *greeter = lightdm_greeter_new ();
 
-    g_object_connect (greeter, "connected", G_CALLBACK (connected_cb), NULL);
     g_object_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);
     g_object_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
-    g_object_connect (greeter, "session-failed", G_CALLBACK (session_failed_cb), NULL);
-    g_object_connect (greeter, "quit", G_CALLBACK (quit_cb), NULL);
 
-    if (!lightdm_greeter_connect_to_server (LIGHTDM_GREETER (greeter))) {
+    if (!lightdm_greeter_connect_sync (LIGHTDM_GREETER (greeter))) {
         // Log an error
-        return 0;
+        return EXIT_FAILURE;
     }
-}
 
-static void connected_cb (LightDMGreeter *greeter)
-{
-    // Start authentication
-    lightdm_greeter_authenticate (greeter, NULL);
+    while (TRUE)
+    {
+        // Start authentication
+        while (!lightdm_greeter_get_is_authenticated (greeter))
+            lightdm_greeter_authenticate (greeter, NULL);
+
+        if (lightdm_greeter_start_session_sync (greeter, NULL))
+            return EXIT_SUCCESS;
+    }
+
+    return EXIT_SUCCESS;
 }
 
 static void show_prompt_cb (LightDMGreeter *greeter, const char *text, LightDMPromptType type)
@@ -55,12 +58,6 @@ static void authentication_complete_cb (LightDMGreeter *greeter)
     }
 }
 
-static void session_failed_cb (LightDMGreeter *greeter)
-{
-    // Display a warning and reset the greeter
-    reset_login_screen (``Failed to login'');
-}
-
 static void quit_cb (LightDMGreeter *greeter)
 {
     // Clean up
@@ -83,14 +80,6 @@ static void quit_cb (LightDMGreeter *greeter)
 <!-- ##### SECTION Image ##### -->
 
 
-<!-- ##### USER_FUNCTION connected ##### -->
-<para>
-
-</para>
-
-@greeter: 
-
-
 <!-- ##### USER_FUNCTION autologin_timer_expired ##### -->
 <para>
 
@@ -127,22 +116,6 @@ static void quit_cb (LightDMGreeter *greeter)
 @greeter: 
 
 
-<!-- ##### USER_FUNCTION session_failed ##### -->
-<para>
-
-</para>
-
-@greeter: 
-
-
-<!-- ##### USER_FUNCTION quit ##### -->
-<para>
-
-</para>
-
-@greeter: 
-
-
 <!-- ##### ENUM LightDMMessageType ##### -->
 <para>
 
@@ -168,7 +141,7 @@ static void quit_cb (LightDMGreeter *greeter)
 @Returns: 
 
 
-<!-- ##### FUNCTION lightdm_greeter_connect_to_server ##### -->
+<!-- ##### FUNCTION lightdm_greeter_connect_sync ##### -->
 <para>
 
 </para>
@@ -328,20 +301,13 @@ static void quit_cb (LightDMGreeter *greeter)
 @Returns: 
 
 
-<!-- ##### FUNCTION lightdm_greeter_start_session ##### -->
+<!-- ##### FUNCTION lightdm_greeter_start_session_sync ##### -->
 <para>
 
 </para>
 
 @greeter: 
 @session: 
-
-
-<!-- ##### FUNCTION lightdm_greeter_start_default_session ##### -->
-<para>
-
-</para>
-
-@greeter: 
+@Returns: 
 
 
index 02fdbb1670a67759622f96659fde524f037af901..8bf6543b574d4a95293a5a34e0d04e9c5e38e099 100644 (file)
@@ -183,16 +183,18 @@ authentication_complete_cb (LightDMGreeter *greeter)
     if (lightdm_greeter_get_is_authenticated (greeter))
     {
         gchar *session = get_session ();
-        lightdm_greeter_start_session (greeter, session);
+        if (lightdm_greeter_start_session_sync (greeter, session))
+            exit (EXIT_SUCCESS);
+        else
+            gtk_label_set_text (GTK_LABEL (message_label), "Failed to authenticate");
         g_free (session);
     }
     else
-    {
         gtk_label_set_text (GTK_LABEL (message_label), "Failed to authenticate");
-        gtk_widget_show (message_label);
-        if (lightdm_greeter_get_hide_users_hint (greeter))
-            lightdm_greeter_authenticate (greeter, NULL);
-    }
+
+    gtk_widget_show (message_label);
+    if (lightdm_greeter_get_hide_users_hint (greeter))
+        lightdm_greeter_authenticate (greeter, NULL);
 }
 
 static void
@@ -283,23 +285,6 @@ shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter)
     gtk_widget_destroy (dialog);
 }
 
-static gboolean
-fade_timer_cb (gpointer data)
-{
-    gdouble opacity;
-
-    opacity = gtk_window_get_opacity (GTK_WINDOW (window));
-    opacity -= 0.1;
-    if (opacity <= 0)
-    {
-        gtk_main_quit ();
-        return FALSE;
-    }
-    gtk_window_set_opacity (GTK_WINDOW (window), opacity);
-
-    return TRUE;
-}
-
 static void
 user_added_cb (LightDMUserList *user_list, LightDMUser *user)
 {
@@ -370,13 +355,6 @@ user_removed_cb (LightDMUserList *user_list, LightDMUser *user)
     gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
 }
 
-static void
-quit_cb (LightDMGreeter *greeter, const gchar *username)
-{
-    /* Fade out the greeter */
-    g_timeout_add (40, (GSourceFunc) fade_timer_cb, NULL);
-}
-
 void a11y_font_cb (GtkWidget *widget);
 G_MODULE_EXPORT
 void
@@ -479,8 +457,8 @@ load_user_list ()
                         -1);
 }
 
-static void
-connected_cb (LightDMGreeter *greeter)
+int
+main(int argc, char **argv)
 {
     GdkWindow *root;
     GdkDisplay *display;
@@ -494,6 +472,21 @@ connected_cb (LightDMGreeter *greeter)
     gchar *rc_file, *background_image;
     GError *error = NULL;
 
+    /* Disable global menus */
+    unsetenv ("UBUNTU_MENUPROXY");
+
+    signal (SIGTERM, sigterm_cb);
+  
+    gtk_init (&argc, &argv);
+
+    greeter = lightdm_greeter_new ();
+    g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);  
+    g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
+    g_signal_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
+    g_signal_connect (greeter, "autologin-timer-expired", G_CALLBACK (autologin_timer_expired_cb), NULL);
+    if (!lightdm_greeter_connect_sync (greeter))
+        return EXIT_FAILURE;
+
     display = gdk_display_get_default ();
     screen = gdk_display_get_default_screen (display);
     screen_width = gdk_screen_get_width (screen);
@@ -513,7 +506,7 @@ connected_cb (LightDMGreeter *greeter)
     if (!gtk_builder_add_from_file (builder, GREETER_DATA_DIR "/greeter.ui", &error))
     {
         g_warning ("Error loading UI: %s", error->message);
-        return;
+        return EXIT_FAILURE;
     }
     g_clear_error (&error);
     window = GTK_WIDGET (gtk_builder_get_object (builder, "greeter_window"));
@@ -604,28 +597,8 @@ connected_cb (LightDMGreeter *greeter)
     gtk_widget_show (window);
 
     gtk_widget_grab_focus (user_view);
-}
-
-int
-main(int argc, char **argv)
-{
-    /* Disable global menus */
-    unsetenv ("UBUNTU_MENUPROXY");
-
-    signal (SIGTERM, sigterm_cb);
-  
-    gtk_init (&argc, &argv);
-
-    greeter = lightdm_greeter_new ();
-    g_signal_connect (greeter, "connected", G_CALLBACK (connected_cb), NULL);
-    g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);  
-    g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
-    g_signal_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
-    g_signal_connect (greeter, "autologin-timer-expired", G_CALLBACK (autologin_timer_expired_cb), NULL);
-    g_signal_connect (greeter, "quit", G_CALLBACK (quit_cb), NULL);
-    lightdm_greeter_connect_to_server (greeter);
 
     gtk_main ();
 
-    return 0;
+    return EXIT_SUCCESS;
 }
index ee51fd341870ce9af226d0fe4669f0d94baa6044..ce28021743ec7edf4bd5e7fe0e9ad62fcfef3fc7 100644 (file)
@@ -34,13 +34,13 @@ Greeter::Greeter() :
     background->setPixmap(QPixmap("/usr/share/wallpapers/Horos/contents/images/1920x1200.png"));
 
     m_greeter = new QLightDM::Greeter(this);
-    m_greeter->connectToServer();
-    connect(m_greeter, SIGNAL(quit()), this, SLOT(close()));
+    if (!m_greeter->connectSync())
+        close();
 
     m_prompt = new LoginPrompt(m_greeter, this);
     m_prompt->move(this->width()/2 - m_prompt->width()/2, this->height()/2 - m_prompt->height()/2);
     m_prompt->setAutoFillBackground(true);
-    connect(m_prompt, SIGNAL(startSession()), SLOT(onStartSession()));
+    connect(m_prompt, SIGNAL(startSessionSync()), SLOT(onStartSession()));
 
     m_panel = new Panel(m_greeter, this);
     m_panel->setGeometry(QRect(QPoint(0, screen.height() - m_panel->height()), screen.bottomRight()));
@@ -52,6 +52,6 @@ Greeter::~Greeter()
 {
 }
 
-void Greeter::onStartSession() {
-    m_greeter->startSession(m_panel->session());
-}
\ No newline at end of file
+bool Greeter::onStartSession() {
+    return m_greeter->startSessionSync(m_panel->session());
+}
index 0ec20aa7654d0dd1e9e4b7bcbbbc2e979020ee23..c0f322430993b7a8b2f5775131e528d1004b738f 100644 (file)
@@ -30,7 +30,7 @@ public:
     ~Greeter();
 
 private slots:
-    void onStartSession();
+    bool onStartSession();
     
 private:
     QLightDM::Greeter *m_greeter;
index fe821030069b64df50cdeb625bf39197fbb947d0..053972d6257fcaf840cf3acdb1f718f5d980eeee 100644 (file)
@@ -33,13 +33,10 @@ enum {
 };
 
 enum {
-    CONNECTED,
     SHOW_PROMPT,
     SHOW_MESSAGE,
     AUTHENTICATION_COMPLETE,
-    SESSION_FAILED,
     AUTOLOGIN_TIMER_EXPIRED,
-    QUIT,
     LAST_SIGNAL
 };
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -82,10 +79,9 @@ typedef enum
 typedef enum
 {
     SERVER_MESSAGE_CONNECTED = 0,
-    SERVER_MESSAGE_QUIT,
     SERVER_MESSAGE_PROMPT_AUTHENTICATION,
     SERVER_MESSAGE_END_AUTHENTICATION,
-    SERVER_MESSAGE_SESSION_FAILED,
+    SERVER_MESSAGE_SESSION_RESULT
 } ServerMessage;
 
 /**
@@ -157,19 +153,18 @@ write_string (guint8 *buffer, gint buffer_length, const gchar *value, gsize *off
 }
 
 static guint32
-read_int (LightDMGreeter *greeter, gsize *offset)
+read_int (guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     guint32 value;
     guint8 *buffer;
 
-    if (priv->n_read - *offset < int_length ())
+    if (message_length - *offset < int_length ())
     {
-        g_warning ("Not enough space for int, need %i, got %zi", int_length (), priv->n_read - *offset);
+        g_warning ("Not enough space for int, need %i, got %zi", int_length (), message_length - *offset);
         return 0;
     }
 
-    buffer = priv->read_buffer + *offset;
+    buffer = message + *offset;
     value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
     *offset += int_length ();
 
@@ -177,21 +172,20 @@ read_int (LightDMGreeter *greeter, gsize *offset)
 }
 
 static gchar *
-read_string (LightDMGreeter *greeter, gsize *offset)
+read_string (guint8 *message, gsize message_length, gsize *offset)
 {
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     guint32 length;
     gchar *value;
 
-    length = read_int (greeter, offset);
-    if (priv->n_read - *offset < length)
+    length = read_int (message, message_length, offset);
+    if (message_length - *offset < length)
     {
-        g_warning ("Not enough space for string, need %u, got %zu", length, priv->n_read - *offset);
+        g_warning ("Not enough space for string, need %u, got %zu", length, message_length - *offset);
         return g_strdup ("");
     }
 
     value = g_malloc (sizeof (gchar) * (length + 1));
-    memcpy (value, priv->read_buffer + *offset, length);
+    memcpy (value, message + *offset, length);
     value[length] = '\0';
     *offset += length;
 
@@ -211,28 +205,29 @@ write_header (guint8 *buffer, gint buffer_length, guint32 id, guint32 length, gs
     write_int (buffer, buffer_length, length, offset);
 }
 
-static guint32 get_packet_length (LightDMGreeter *greeter)
+static guint32
+get_message_length (guint8 *message, gsize message_length)
 {
     gsize offset = 4;
-    return read_int (greeter, &offset);
+    return read_int (message, message_length, &offset);
 }
 
 static void
-handle_connected (LightDMGreeter *greeter, guint32 length, gsize *offset)
+handle_connected (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
     LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     gchar *version;
     GString *hint_string;
     int timeout;
 
-    version = read_string (greeter, offset);
+    version = read_string (message, message_length, offset);
     hint_string = g_string_new ("");
-    while (*offset < length)
+    while (*offset < message_length)
     {
         gchar *name, *value;
       
-        name = read_string (greeter, offset);
-        value = read_string (greeter, offset);
+        name = read_string (message, message_length, offset);
+        value = read_string (message, message_length, offset);
         g_hash_table_insert (priv->hints, name, value);
         g_string_append_printf (hint_string, " %s=%s", name, value);
     }
@@ -248,16 +243,15 @@ handle_connected (LightDMGreeter *greeter, guint32 length, gsize *offset)
         g_debug ("Setting autologin timer for %d seconds", timeout);
         priv->autologin_timeout = g_timeout_add (timeout * 1000, timed_login_cb, greeter);
     }
-    g_signal_emit (G_OBJECT (greeter), signals[CONNECTED], 0);
 }
 
 static void
-handle_prompt_authentication (LightDMGreeter *greeter, gsize *offset)
+handle_prompt_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
     LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     guint32 sequence_number, n_messages, i;
 
-    sequence_number = read_int (greeter, offset);
+    sequence_number = read_int (message, message_length, offset);
     if (sequence_number != priv->authenticate_sequence_number)
     {
         g_debug ("Ignoring prompt authentication with invalid sequence number %d", sequence_number);
@@ -270,7 +264,7 @@ handle_prompt_authentication (LightDMGreeter *greeter, gsize *offset)
         return;
     }
 
-    n_messages = read_int (greeter, offset);
+    n_messages = read_int (message, message_length, offset);
     g_debug ("Prompt user with %d message(s)", n_messages);
 
     for (i = 0; i < n_messages; i++)
@@ -278,8 +272,8 @@ handle_prompt_authentication (LightDMGreeter *greeter, gsize *offset)
         int msg_style;
         gchar *msg;
 
-        msg_style = read_int (greeter, offset);
-        msg = read_string (greeter, offset);
+        msg_style = read_int (message, message_length, offset);
+        msg = read_string (message, message_length, offset);
 
         // FIXME: Should stop on prompts?
         switch (msg_style)
@@ -303,13 +297,13 @@ handle_prompt_authentication (LightDMGreeter *greeter, gsize *offset)
 }
 
 static void
-handle_end_authentication (LightDMGreeter *greeter, gsize *offset)
+handle_end_authentication (LightDMGreeter *greeter, guint8 *message, gsize message_length, gsize *offset)
 {
     LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     guint32 sequence_number, return_code;
 
-    sequence_number = read_int (greeter, offset);
-    return_code = read_int (greeter, offset);
+    sequence_number = read_int (message, message_length, offset);
+    return_code = read_int (message, message_length, offset);
 
     if (sequence_number != priv->authenticate_sequence_number)
     {
@@ -325,35 +319,23 @@ handle_end_authentication (LightDMGreeter *greeter, gsize *offset)
         g_free (priv->authentication_user);
         priv->authentication_user = NULL;
     }
+
     g_signal_emit (G_OBJECT (greeter), signals[AUTHENTICATION_COMPLETE], 0);
     priv->in_authentication = FALSE;
 }
 
-static void
-handle_session_failed (LightDMGreeter *greeter, gsize *offset)
-{ 
-    g_debug ("Session failed to start");
-    g_signal_emit (G_OBJECT (greeter), signals[SESSION_FAILED], 0);
-}
-
-static void
-handle_quit (LightDMGreeter *greeter, gsize *offset)
-{
-    g_debug ("Got quit request from server");
-    g_signal_emit (G_OBJECT (greeter), signals[QUIT], 0);
-}
-
-static gboolean
-read_packet (LightDMGreeter *greeter, gboolean block)
+static guint8 *
+read_message (LightDMGreeter *greeter, gsize *length, gboolean block)
 {
     LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     gsize n_to_read, n_read;
+    guint8 *buffer;
     GError *error = NULL;
 
-    /* Read the header, or the whole packet if we already have that */
+    /* Read the header, or the whole message if we already have that */
     n_to_read = HEADER_SIZE;
     if (priv->n_read >= HEADER_SIZE)
-        n_to_read += get_packet_length (greeter);
+        n_to_read += get_message_length (priv->read_buffer, priv->n_read);
 
     do
     {
@@ -381,73 +363,72 @@ read_packet (LightDMGreeter *greeter, gboolean block)
     /* If have header, rerun for content */
     if (priv->n_read == HEADER_SIZE)
     {
-        n_to_read = get_packet_length (greeter);
+        n_to_read = get_message_length (priv->read_buffer, priv->n_read);
         if (n_to_read > 0)
         {
             priv->read_buffer = g_realloc (priv->read_buffer, HEADER_SIZE + n_to_read);
-            return read_packet (greeter, block);
+            return read_message (greeter, length, block);
         }
     }
 
-    return TRUE;
+    buffer = priv->read_buffer;
+    *length = priv->n_read;
+
+    priv->read_buffer = g_malloc (priv->n_read);
+    priv->n_read = 0;
+
+    return buffer;
 }
 
 static gboolean
 from_server_cb (GIOChannel *source, GIOCondition condition, gpointer data)
 {
     LightDMGreeter *greeter = data;
-    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
-    gsize offset;
-    guint32 id, length;
+    guint8 *message;
+    gsize message_length, offset;
+    guint32 id;
 
-    if (!read_packet (greeter, FALSE))
+    message = read_message (greeter, &message_length, FALSE);
+    if (!message)
         return TRUE;
 
     offset = 0;
-    id = read_int (greeter, &offset);
-    length = read_int (greeter, &offset);
+    id = read_int (message, message_length, &offset);
+    read_int (message, message_length, &offset);
     switch (id)
     {
-    case SERVER_MESSAGE_CONNECTED:
-        handle_connected (greeter, length, &offset);
-        break;
     case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
-        handle_prompt_authentication (greeter, &offset);
+        handle_prompt_authentication (greeter, message, message_length, &offset);
         break;
     case SERVER_MESSAGE_END_AUTHENTICATION:
-        handle_end_authentication (greeter, &offset);
-        break;
-    case SERVER_MESSAGE_SESSION_FAILED:
-        handle_session_failed (greeter, &offset);
-        break;
-    case SERVER_MESSAGE_QUIT:
-        handle_quit (greeter, &offset);
+        handle_end_authentication (greeter, message, message_length, &offset);
         break;
     default:
         g_warning ("Unknown message from server: %d", id);
         break;
     }
-
-    priv->n_read = 0;
+    g_free (message);
 
     return TRUE;
 }
 
 /**
- * lightdm_greeter_connect_to_server:
+ * lightdm_greeter_connect_sync:
  * @greeter: The greeter to connect
  *
- * Connects the greeter to the display manager.
+ * Connects the greeter to the display manager.  Will block until connected.
  *
  * Return value: #TRUE if successfully connected
  **/
 gboolean
-lightdm_greeter_connect_to_server (LightDMGreeter *greeter)
+lightdm_greeter_connect_sync (LightDMGreeter *greeter)
 {
     LightDMGreeterPrivate *priv;
     const gchar *fd;
     guint8 message[MAX_MESSAGE_LENGTH];
-    gsize offset = 0;
+    guint8 *response;
+    gsize response_length, offset = 0;
+    guint32 id;
 
     g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
 
@@ -477,6 +458,20 @@ lightdm_greeter_connect_to_server (LightDMGreeter *greeter)
     write_string (message, MAX_MESSAGE_LENGTH, VERSION, &offset);
     write_message (greeter, message, offset);
 
+    response = read_message (greeter, &response_length, TRUE);
+    if (!response)
+        return FALSE;
+
+    offset = 0;
+    id = read_int (response, response_length, &offset);
+    read_int (response, response_length, &offset);
+    if (id == SERVER_MESSAGE_CONNECTED)
+        handle_connected (greeter, response, response_length, &offset);
+    else
+        g_warning ("Expected CONNECTED message, got %d", id);
+  
+    g_free (response);
+
     return TRUE;
 }
 
@@ -816,39 +811,53 @@ lightdm_greeter_get_authentication_user (LightDMGreeter *greeter)
 }
 
 /**
- * lightdm_greeter_start_session:
+ * lightdm_greeter_start_session_sync:
  * @greeter: A #LightDMGreeter
- * @session: (allow-none): The session to log into or #NULL to use the default
+ * @session: (allow-none): The session to log into or #NULL to use the default.
+ *
+ * Start a session for the authenticated user.
  *
- * Start a session for the logged in user.
+ * Return value: TRUE if the session was started.
  **/
-void
-lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session)
+gboolean
+lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session)
 {
+    LightDMGreeterPrivate *priv = GET_PRIVATE (greeter);
     guint8 message[MAX_MESSAGE_LENGTH];
-    gsize offset = 0;
+    guint8 *response;
+    gsize response_length, offset = 0;
+    guint32 id, return_code = 1;
+
+    g_return_val_if_fail (LIGHTDM_IS_GREETER (greeter), FALSE);
+    g_return_val_if_fail (priv->is_authenticated, FALSE);
 
-    g_return_if_fail (LIGHTDM_IS_GREETER (greeter));
-  
     if (!session)
+    {
         session = "";
+        g_debug ("Starting default session");
+    }
+    else
+        g_debug ("Starting session %s", session);
 
-    g_debug ("Starting session %s", session);
     write_header (message, MAX_MESSAGE_LENGTH, GREETER_MESSAGE_START_SESSION, string_length (session), &offset);
     write_string (message, MAX_MESSAGE_LENGTH, session, &offset);
     write_message (greeter, message, offset);
-}
 
-/**
- * lightdm_greeter_start_default_session:
- * @greeter: A #LightDMGreeter
- *
- * Start the default session for the authenticated user.
- **/
-void
-lightdm_greeter_start_default_session (LightDMGreeter *greeter)
-{
-    lightdm_greeter_start_session (greeter, NULL);
+    response = read_message (greeter, &response_length, TRUE);
+    if (!response)
+        return FALSE;
+
+    offset = 0;
+    id = read_int (response, response_length, &offset);
+    read_int (response, response_length, &offset);
+    if (id == SERVER_MESSAGE_SESSION_RESULT)
+        return_code = read_int (response, response_length, &offset);
+    else
+        g_warning ("Expected SESSION_RESULT message, got %d", id);
+
+    g_free (response);
+
+    return return_code == 0;
 }
 
 static void
@@ -1068,22 +1077,6 @@ lightdm_greeter_class_init (LightDMGreeterClass *klass)
                                                            FALSE,
                                                            G_PARAM_READABLE));
 
-    /**
-     * LightDMGreeter::connected:
-     * @greeter: A #LightDMGreeter
-     *
-     * The ::connected signal gets emitted when the greeter connects to the
-     * LightDM server.
-     **/
-    signals[CONNECTED] =
-        g_signal_new ("connected",
-                      G_TYPE_FROM_CLASS (klass),
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (LightDMGreeterClass, connected),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__VOID,
-                      G_TYPE_NONE, 0);
-
     /**
      * LightDMGreeter::show-prompt:
      * @greeter: A #LightDMGreeter
@@ -1143,22 +1136,6 @@ lightdm_greeter_class_init (LightDMGreeterClass *klass)
                       g_cclosure_marshal_VOID__VOID,
                       G_TYPE_NONE, 0);
 
-    /**
-     * LightDMGreeter::session-failed:
-     * @greeter: A #LightDMGreeter
-     *
-     * The ::session-failed signal gets emitted when the deamon has failed
-     * to start the requested session.
-     **/
-    signals[SESSION_FAILED] =
-        g_signal_new ("session-failed",
-                      G_TYPE_FROM_CLASS (klass),
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (LightDMGreeterClass, session_failed),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__VOID,
-                      G_TYPE_NONE, 0);
-
     /**
      * LightDMGreeter::autologin-timer-expired:
      * @greeter: A #LightDMGreeter
@@ -1174,19 +1151,4 @@ lightdm_greeter_class_init (LightDMGreeterClass *klass)
                       NULL, NULL,
                       g_cclosure_marshal_VOID__VOID,
                       G_TYPE_NONE, 0);
-
-    /**
-     * LightDMGreeter::quit:
-     * @greeter: A #LightDMGreeter
-     *
-     * The ::quit signal gets emitted when the greeter should exit.
-     **/
-    signals[QUIT] =
-        g_signal_new ("quit",
-                      G_TYPE_FROM_CLASS (klass),
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (LightDMGreeterClass, quit),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__VOID,
-                      G_TYPE_NONE, 0);
 }
index f8b9827643162fd046958262043de0f37807ef6c..b0786ef71b347b844e76bc0cb2f07e6ddbb6c469 100644 (file)
@@ -54,20 +54,17 @@ typedef struct
 {
     GObjectClass parent_class;
 
-    void (*connected)(LightDMGreeter *greeter);
     void (*show_prompt)(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type);
     void (*show_message)(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type);
     void (*authentication_complete)(LightDMGreeter *greeter);
-    void (*session_failed)(LightDMGreeter *greeter);
     void (*autologin_timer_expired)(LightDMGreeter *greeter);
-    void (*quit)(LightDMGreeter *greeter);
 } LightDMGreeterClass;
 
 GType lightdm_greeter_get_type (void);
 
 LightDMGreeter *lightdm_greeter_new (void);
 
-gboolean lightdm_greeter_connect_to_server (LightDMGreeter *greeter);
+gboolean lightdm_greeter_connect_sync (LightDMGreeter *greeter);
 
 const gchar *lightdm_greeter_get_hint (LightDMGreeter *greeter, const gchar *name);
 
@@ -103,9 +100,7 @@ gboolean lightdm_greeter_get_is_authenticated (LightDMGreeter *greeter);
 
 const gchar *lightdm_greeter_get_authentication_user (LightDMGreeter *greeter);
 
-void lightdm_greeter_start_session (LightDMGreeter *greeter, const gchar *session);
-
-void lightdm_greeter_start_default_session (LightDMGreeter *greeter);
+gboolean lightdm_greeter_start_session_sync (LightDMGreeter *greeter, const gchar *session);
 
 G_END_DECLS
 
index 83d7d75b397153c702d4b85110994d85b245f9a7..f6170e31c980fdd261457695b79aafece28b46e1 100644 (file)
@@ -59,21 +59,18 @@ namespace QLightDM
         QString authenticationUser() const;
 
     public slots:
-        void connectToServer();
+        bool connectSync();
         void authenticate(const QString &username=QString());
         void authenticateAsGuest();
         void respond(const QString &response);
         void cancelAuthentication();
-        void startSession(const QString &session=QString());
+        bool startSessionSync(const QString &session=QString());
 
     signals:
-        void connected();
         void showPrompt(QString prompt, PromptType type);
         void showMessage(QString message, MessageType type);
         void authenticationComplete();
-        void sessionFailed();
         void autologinTimerExpired();
-        void quit();
 
     private slots:
         void onRead(int fd);
@@ -84,9 +81,7 @@ namespace QLightDM
         void writeString(QString value);
         void writeHeader(int id, int length);
         void flush();
-        int getPacketLength();
-        int readInt(int *offset);
-        QString readString(int *offset);
+        char *readMessage(int *length, bool block);
     };
 };
 
index 950af627c438876a7b68e074e055cb57b090a5e7..69aee65f80139ac6841d452d7ea53f04672fc87e 100644 (file)
@@ -42,10 +42,9 @@ typedef enum
 typedef enum
 {
     SERVER_MESSAGE_CONNECTED = 0,
-    SERVER_MESSAGE_QUIT,
     SERVER_MESSAGE_PROMPT_AUTHENTICATION,
     SERVER_MESSAGE_END_AUTHENTICATION,
-    SERVER_MESSAGE_SESSION_FAILED,
+    SERVER_MESSAGE_SESSION_RESULT
 } ServerMessage;
 
 #define HEADER_SIZE 8
@@ -69,12 +68,11 @@ public:
     bool cancellingAuthentication;
 };
 
-
 Greeter::Greeter(QObject *parent) :
     QObject(parent),
     d(new GreeterPrivate)
 {
-    d->readBuffer = (char *)malloc (HEADER_SIZE);
+    d->readBuffer = (char *)malloc(HEADER_SIZE);
     d->nRead = 0;
     d->authenticateSequenceNumber = 0;
 }
@@ -128,38 +126,38 @@ void Greeter::flush()
     fsync(d->toServerFd);
 }
 
-int Greeter::getPacketLength()
-{
-    int offset = intLength();
-    return readInt(&offset);
-}
-
-int Greeter::readInt(int *offset)
+static int readInt(char *message, int messageLength, int *offset)
 {
-    if(d->nRead - *offset < intLength()) {
-        qDebug() << "Not enough space for int, need " << intLength() << ", got " << (d->nRead - *offset);
+    if(messageLength - *offset < intLength()) {
+        qDebug() << "Not enough space for int, need " << intLength() << ", got " << (messageLength - *offset);
         return 0;
     }
 
-    char *buffer = d->readBuffer + *offset;
+    char *buffer = message + *offset;
     int value = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
     *offset += intLength();
     return value;
 }
 
-QString Greeter::readString(int *offset)
+static int getMessageLength(char *message, int messageLength)
+{
+    int offset = intLength();
+    return readInt(message, messageLength, &offset);
+}
+
+static QString readString(char *message, int messageLength, int *offset)
 {
-    int length = readInt(offset);
-    if(d->nRead - *offset < length) {
-        qDebug() << "Not enough space for string, need " << length << ", got " << (d->nRead - *offset);
+    int length = readInt(message, messageLength, offset);
+    if(messageLength - *offset < length) {
+        qDebug() << "Not enough space for string, need " << length << ", got " << (messageLength - *offset);
         return "";
     }
-    char *start = d->readBuffer + *offset;
+    char *start = message + *offset;
     *offset += length;
     return QString::fromUtf8(start, length);
 }
 
-void Greeter::connectToServer()
+bool Greeter::connectSync()
 {
     QDBusConnection busType = QDBusConnection::systemBus();
     QString ldmBus(qgetenv("LIGHTDM_BUS"));
@@ -170,7 +168,7 @@ void Greeter::connectToServer()
     char* fd = getenv("LIGHTDM_TO_SERVER_FD");
     if(!fd) {
        qDebug() << "No LIGHTDM_TO_SERVER_FD environment variable";
-       return;
+       return false;
     }
     d->toServerFd = atoi(fd);
 
@@ -181,7 +179,7 @@ void Greeter::connectToServer()
     fd = getenv("LIGHTDM_FROM_SERVER_FD");
     if(!fd) {
        qDebug() << "No LIGHTDM_FROM_SERVER_FD environment variable";
-       return;
+       return false;
     }
     d->fromServerFd = atoi(fd);
 
@@ -192,6 +190,38 @@ void Greeter::connectToServer()
     writeHeader(GREETER_MESSAGE_CONNECT, stringLength(VERSION));
     writeString(VERSION);
     flush();
+
+    int responseLength;
+    char *response = readMessage(&responseLength, false);
+    if (!response)
+        return false;
+
+    int offset = 0;
+    int id = readInt(response, responseLength, &offset);
+    int length = readInt(response, responseLength, &offset);
+    bool connected = false;
+    if (id == SERVER_MESSAGE_CONNECTED)
+    {
+        QString version = readString(response, responseLength, &offset);
+        QString hintString = "";
+        while (offset < length)
+        {
+            QString name = readString(response, responseLength, &offset);
+            QString value = readString(response, responseLength, &offset);
+            hintString.append (" ");
+            hintString.append (name);
+            hintString.append ("=");
+            hintString.append (value);
+        }
+
+        qDebug() << "Connected version=" << version << hintString;
+        connected = true;
+    }
+    else
+        qDebug() << "Expected CONNECTED message, got " << id;
+    free(response);
+
+    return connected;
 }
 
 void Greeter::authenticate(const QString &username)
@@ -254,95 +284,115 @@ QString Greeter::authenticationUser() const
     return d->authenticationUser;
 }
 
-void Greeter::startSession(const QString &session)
+bool Greeter::startSessionSync(const QString &session)
 {
-    qDebug() << "Starting session " << session;
+    if (session == "")
+        qDebug() << "Starting default session";
+    else
+        qDebug() << "Starting session " << session;
+
     writeHeader(GREETER_MESSAGE_START_SESSION, stringLength(session));
     writeString(session);
     flush();
+
+    int responseLength;
+    char *response = readMessage(&responseLength, false);
+    if (!response)
+        return false;
+
+    int offset = 0;
+    int id = readInt(response, responseLength, &offset);
+    readInt(response, responseLength, &offset);
+    int returnCode = -1;
+    if (id == SERVER_MESSAGE_SESSION_RESULT)
+        returnCode = readInt(response, responseLength, &offset);
+    else
+        qDebug() << "Expected SESSION_RESULT message, got " << id;
+    free(response);
+
+    return returnCode == 0;
 }
 
-void Greeter::onRead(int fd)
+char *Greeter::readMessage(int *length, bool block)
 {
-    //qDebug() << "Reading from server";
-
+    /* Read the header, or the whole message if we already have that */
     int nToRead = HEADER_SIZE;
     if(d->nRead >= HEADER_SIZE)
-        nToRead += getPacketLength();
+        nToRead += getMessageLength(d->readBuffer, d->nRead);
 
-    ssize_t nRead;
-    nRead = read(fd, d->readBuffer + d->nRead, nToRead - d->nRead);
-    if(nRead < 0)
-    {
-        qDebug() << "Error reading from server";
-        return;
-    }
-    if (nRead == 0)
-    {
-        qDebug() << "EOF reading from server";
-        return;
-    }
+    do
+    {      
+        ssize_t nRead = read(d->fromServerFd, d->readBuffer + d->nRead, nToRead - d->nRead);
+        if(nRead < 0)
+        {
+            qDebug() << "Error reading from server";
+            return NULL;
+        }
+        if (nRead == 0)
+        {
+            qDebug() << "EOF reading from server";
+            return NULL;
+        }
+
+        qDebug() << "Read " << nRead << " octets from daemon";
+        d->nRead += nRead;
+    } while(d->nRead < nToRead && block);
 
-    //qDebug() << "Read " << nRead << "octets";
-    d->nRead += nRead;
+    /* Stop if haven't got all the data we want */  
     if(d->nRead != nToRead)
-        return;
+        return NULL;
 
     /* If have header, rerun for content */
     if(d->nRead == HEADER_SIZE)
     {
-        nToRead = getPacketLength();
+        nToRead = getMessageLength(d->readBuffer, d->nRead);
         if(nToRead > 0)
         {
             d->readBuffer = (char *)realloc(d->readBuffer, HEADER_SIZE + nToRead);
-            onRead(fd);
-            return;
+            return readMessage(length, block);
         }
     }
 
+    char *buffer = d->readBuffer;
+    *length = d->nRead;
+
+    d->readBuffer = (char *)malloc(d->nRead);
+    d->nRead = 0;
+
+    return buffer;
+}
+
+void Greeter::onRead(int fd)
+{
+    qDebug() << "Reading from server";
+
+    int messageLength;
+    char *message = readMessage(&messageLength, false);
+    if (!message)
+        return;
+
     int offset = 0;
-    int id = readInt(&offset);
-    int length = readInt(&offset);
+    int id = readInt(message, messageLength, &offset);
+    int length = readInt(message, messageLength, &offset);
     int nMessages, sequenceNumber, returnCode;
     QString version, username;
-    QString hintString = "";
     switch(id)
     {
-    case SERVER_MESSAGE_CONNECTED:
-        version = readString(&offset);
-        while (offset < length)
-        {
-            QString name = readString(&offset);
-            QString value = readString(&offset);
-            hintString.append (" ");
-            hintString.append (name);
-            hintString.append ("=");
-            hintString.append (value);
-        }
-
-        qDebug() << "Connected version=" << version << hintString;
-
-        emit connected();
-        break;
-    case SERVER_MESSAGE_QUIT:
-        qDebug() << "Got quit request from server";
-        emit quit();
-        break;
     case SERVER_MESSAGE_PROMPT_AUTHENTICATION:
-        sequenceNumber = readInt(&offset);
+        sequenceNumber = readInt(message, messageLength, &offset);
 
         if (sequenceNumber == d->authenticateSequenceNumber &&
             !d->cancellingAuthentication)
         {
-            nMessages = readInt(&offset);
+            nMessages = readInt(message, messageLength, &offset);
             qDebug() << "Prompt user with " << nMessages << " message(s)";
             for(int i = 0; i < nMessages; i++)
             {
-                int msg_style = readInt (&offset);
-                QString msg = readString (&offset);
+                int msgStyle = readInt(message, messageLength, &offset);
+                QString msg = readString(message, messageLength, &offset);
 
                 // FIXME: Should stop on prompts?
-                switch (msg_style)
+                switch (msgStyle)
                 {
                 case PAM_PROMPT_ECHO_OFF:
                     emit showPrompt(msg, PROMPT_TYPE_SECRET);
@@ -361,8 +411,8 @@ void Greeter::onRead(int fd)
         }
         break;
     case SERVER_MESSAGE_END_AUTHENTICATION:
-        sequenceNumber = readInt(&offset);
-        returnCode = readInt(&offset);
+        sequenceNumber = readInt(message, messageLength, &offset);
+        returnCode = readInt(message, messageLength, &offset);
 
         if (sequenceNumber == d->authenticateSequenceNumber)
         {
@@ -378,15 +428,10 @@ void Greeter::onRead(int fd)
         else
             qDebug () << "Ignoring end authentication with invalid sequence number " << sequenceNumber;
         break;
-    case SERVER_MESSAGE_SESSION_FAILED:
-        qDebug() << "Session failed to start";
-        emit sessionFailed();
-        break;
     default:
         qDebug() << "Unknown message from server: " << id;
     }
-
-    d->nRead = 0;
+    free(message);
 }
 
 QString Greeter::getHint(QString name) const
index 55157dd2877678e8bcc05c388fe85bb07c96c005..12d068b9ee58bc305b44a5ab32a0ae4b5eac1e37 100644 (file)
@@ -71,10 +71,9 @@ typedef enum
 typedef enum
 {
     SERVER_MESSAGE_CONNECTED = 0,
-    SERVER_MESSAGE_QUIT,
     SERVER_MESSAGE_PROMPT_AUTHENTICATION,
     SERVER_MESSAGE_END_AUTHENTICATION,
-    SERVER_MESSAGE_SESSION_FAILED,
+    SERVER_MESSAGE_SESSION_RESULT
 } ServerMessage;
 
 Greeter *
@@ -376,7 +375,8 @@ handle_start_session (Greeter *greeter, gchar *session)
         guint8 message[MAX_MESSAGE_LENGTH];
         gsize offset = 0;
 
-        write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_SESSION_FAILED, 0, &offset);
+        write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_SESSION_RESULT, int_length (), &offset);
+        write_int (message, MAX_MESSAGE_LENGTH, 1, &offset);
         write_message (greeter, message, offset);
     }
 }
@@ -571,7 +571,8 @@ greeter_quit (Greeter *greeter)
 
     g_return_if_fail (greeter != NULL);
 
-    write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_QUIT, 0, &offset);
+    write_header (message, MAX_MESSAGE_LENGTH, SERVER_MESSAGE_SESSION_RESULT, int_length (), &offset);
+    write_int (message, MAX_MESSAGE_LENGTH, 0, &offset);
     write_message (greeter, message, offset);
 }
 
index 27ddb2f252ececd09e31e80c843e097ef44a434e..41aad9943565751eb9a7e63593ffe967a202de2b 100644 (file)
@@ -9,68 +9,6 @@
 static xcb_connection_t *connection = NULL;
 static GKeyFile *config;
 
-static void
-connected_cb (LightDMGreeter *greeter)
-{
-    gchar *login_lock;
-    FILE *f;
-
-    notify_status ("GREETER CONNECTED-TO-DAEMON");
-
-    if (g_key_file_get_boolean (config, "test-greeter-config", "crash-xserver", NULL))
-    {
-        const gchar *name = "SIGSEGV";
-        notify_status ("GREETER CRASH-XSERVER");
-        xcb_intern_atom (connection, FALSE, strlen (name), name);
-        xcb_flush (connection);
-    }
-
-    /* Automatically log in as requested user */
-    if (lightdm_greeter_get_select_user_hint (greeter))
-    {
-        notify_status ("GREETER AUTHENTICATE-SELECTED USERNAME=%s", lightdm_greeter_get_select_user_hint (greeter));
-        lightdm_greeter_authenticate (greeter, lightdm_greeter_get_select_user_hint (greeter));
-        return;
-    }
-
-    login_lock = g_build_filename (g_getenv ("LIGHTDM_TEST_HOME_DIR"), ".greeter-logged-in", NULL);
-    f = fopen (login_lock, "r");
-    if (f == NULL)
-    {
-        if (g_key_file_get_boolean (config, "test-greeter-config", "login-guest", NULL))
-        {
-            notify_status ("GREETER AUTHENTICATE-GUEST");
-            lightdm_greeter_authenticate_as_guest (greeter);
-        }
-        else if (g_key_file_get_boolean (config, "test-greeter-config", "prompt-username", NULL))
-        {
-            notify_status ("GREETER AUTHENTICATE");
-            lightdm_greeter_authenticate (greeter, NULL);
-        }
-        else
-        {
-            gchar *username;
-
-            username = g_key_file_get_string (config, "test-greeter-config", "username", NULL);
-            if (!username)
-                return;
-
-            notify_status ("GREETER AUTHENTICATE USERNAME=%s", username);
-            lightdm_greeter_authenticate (greeter, username);
-            g_free (username);
-        }
-
-        /* Write lock to stop repeatedly logging in */
-        f = fopen (login_lock, "w");
-        fclose (f);
-    }
-    else
-    {
-        g_debug ("Not logging in, lock file detected %s", login_lock);
-        fclose (f);
-    }
-}
-
 static void
 show_message_cb (LightDMGreeter *greeter, const gchar *text, LightDMMessageType type)
 {
@@ -109,21 +47,16 @@ static void
 authentication_complete_cb (LightDMGreeter *greeter)
 {
     notify_status ("GREETER AUTHENTICATION-COMPLETE AUTHENTICATED=%s", lightdm_greeter_get_is_authenticated (greeter) ? "TRUE" : "FALSE");
-    if (lightdm_greeter_get_is_authenticated (greeter))
-        lightdm_greeter_start_default_session (greeter);
-}
-
-static void
-session_failed_cb (LightDMGreeter *greeter)
-{
-    notify_status ("GREETER SESSION-FAILED");
-}
+    if (!lightdm_greeter_get_is_authenticated (greeter))
+        return;
 
-static void
-quit_cb (LightDMGreeter *greeter)
-{
-    notify_status ("GREETER QUIT");
-    exit (EXIT_SUCCESS);
+    if (lightdm_greeter_start_session_sync (greeter, NULL))
+    {
+        notify_status ("GREETER QUIT");
+        exit (EXIT_SUCCESS);
+    }
+    else
+        notify_status ("GREETER SESSION-FAILED");
 }
 
 static void
@@ -136,6 +69,7 @@ signal_cb (int signum)
 int
 main (int argc, char **argv)
 {
+    GMainLoop *main_loop;
     LightDMGreeter *greeter;
 
     signal (SIGINT, signal_cb);
@@ -148,29 +82,87 @@ main (int argc, char **argv)
         g_key_file_load_from_file (config, g_getenv ("LIGHTDM_TEST_CONFIG"), G_KEY_FILE_NONE, NULL);
 
     g_type_init ();
+    main_loop = g_main_loop_new (NULL, FALSE);
 
     connection = xcb_connect (NULL, NULL);
 
     if (xcb_connection_has_error (connection))
     {
-        fprintf (stderr, "Error connecting\n");
+        fprintf (stderr, "Error connecting to X server\n");
         return EXIT_FAILURE;
     }
 
     notify_status ("GREETER CONNECT-XSERVER %s", getenv ("DISPLAY"));
 
     greeter = lightdm_greeter_new ();
-    g_signal_connect (greeter, "connected", G_CALLBACK (connected_cb), NULL);
     g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
     g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);
     g_signal_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
-    g_signal_connect (greeter, "session-failed", G_CALLBACK (session_failed_cb), NULL);
-    g_signal_connect (greeter, "quit", G_CALLBACK (quit_cb), NULL);
 
     notify_status ("GREETER CONNECT-TO-DAEMON");
-    lightdm_greeter_connect_to_server (greeter);
+    if (!lightdm_greeter_connect_sync (greeter))
+        return EXIT_FAILURE;
+
+    notify_status ("GREETER CONNECTED-TO-DAEMON");
+
+    if (g_key_file_get_boolean (config, "test-greeter-config", "crash-xserver", NULL))
+    {
+        const gchar *name = "SIGSEGV";
+        notify_status ("GREETER CRASH-XSERVER");
+        xcb_intern_atom (connection, FALSE, strlen (name), name);
+        xcb_flush (connection);
+    }
+
+    /* Automatically log in as requested user */
+    if (lightdm_greeter_get_select_user_hint (greeter))
+    {
+        notify_status ("GREETER AUTHENTICATE-SELECTED USERNAME=%s", lightdm_greeter_get_select_user_hint (greeter));
+        lightdm_greeter_authenticate (greeter, lightdm_greeter_get_select_user_hint (greeter));
+    }
+    else
+    {
+        gchar *login_lock;
+        FILE *f;
+
+        login_lock = g_build_filename (g_getenv ("LIGHTDM_TEST_HOME_DIR"), ".greeter-logged-in", NULL);
+        f = fopen (login_lock, "r");
+        if (f == NULL)
+        {
+            if (g_key_file_get_boolean (config, "test-greeter-config", "login-guest", NULL))
+            {
+                notify_status ("GREETER AUTHENTICATE-GUEST");
+                lightdm_greeter_authenticate_as_guest (greeter);
+            }
+            else if (g_key_file_get_boolean (config, "test-greeter-config", "prompt-username", NULL))
+            {
+                notify_status ("GREETER AUTHENTICATE");
+                lightdm_greeter_authenticate (greeter, NULL);
+            }
+            else
+            {
+                gchar *username;
+
+                username = g_key_file_get_string (config, "test-greeter-config", "username", NULL);
+                if (username)
+                {
+                    notify_status ("GREETER AUTHENTICATE USERNAME=%s", username);
+                    lightdm_greeter_authenticate (greeter, username);
+                    g_free (username);
+                }
+            }
+
+            /* Write lock to stop repeatedly logging in */
+            f = fopen (login_lock, "w");
+            fclose (f);
+        }
+        else
+        {
+            g_debug ("Not logging in, lock file detected %s", login_lock);
+            fclose (f);
+        }
+    }
 
-    g_main_loop_run (g_main_loop_new (NULL, FALSE));
+    g_main_loop_run (main_loop);
 
     return EXIT_SUCCESS;
 }