diff -ruN gdm-2.29.4.orig/common/gdm-common.c gdm-2.29.4.test/common/gdm-common.c
--- gdm-2.29.4.orig/common/gdm-common.c	2010-01-01 12:00:51.108181107 -0500
+++ gdm-2.29.4.test/common/gdm-common.c	2010-01-02 11:30:12.665972849 -0500
@@ -26,6 +26,7 @@
 #include <locale.h>
 #include <fcntl.h>
 #include <sys/wait.h>
+#include <pwd.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -451,3 +452,27 @@
         close (fd);
         return bytes;
 }
+
+gboolean
+gdm_dmrc_file_exists (gchar *username)
+{
+    gchar *filename;
+    gboolean ret = FALSE;
+    struct passwd *pwent = NULL;
+    
+    g_return_val_if_fail (username != NULL, ret);
+
+    pwent = getpwnam (username);
+    if (pwent != NULL && pwent->pw_dir != NULL && 
+        g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) {
+
+        filename = g_build_filename (pwent->pw_dir, ".dmrc", NULL);
+        ret = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
+        if (ret)
+            g_debug ("GdmCommon: %s exists for user %s\n", filename, username);
+        else
+            g_debug ("GdmCommon: %s does not exist for user %s\n", filename, username);
+        g_free (filename);
+    }
+    return ret;
+}
diff -ruN gdm-2.29.4.orig/common/gdm-common.h gdm-2.29.4.test/common/gdm-common.h
--- gdm-2.29.4.orig/common/gdm-common.h	2010-01-01 12:00:51.108991154 -0500
+++ gdm-2.29.4.test/common/gdm-common.h	2010-01-02 11:30:12.666147293 -0500
@@ -47,6 +47,7 @@
                                           int            insert_at);
 char          *gdm_generate_random_bytes (gsize          size,
                                           GError       **error);
+gboolean       gdm_dmrc_file_exists      (gchar *username);
 
 G_END_DECLS
 
diff -ruN gdm-2.29.4.orig/common/gdm-settings-keys.h gdm-2.29.4.test/common/gdm-settings-keys.h
--- gdm-2.29.4.orig/common/gdm-settings-keys.h	2010-01-01 12:00:51.109528021 -0500
+++ gdm-2.29.4.test/common/gdm-settings-keys.h	2010-01-02 11:30:12.666292187 -0500
@@ -29,6 +29,7 @@
 #define GDM_KEY_GROUP "daemon/Group"
 #define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
 #define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
+#define GDM_KEY_AUTOMATIC_LOGIN_SHOW_GUI "daemon/AutomaticLoginShowGUI"
 #define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
 #define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
 #define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
diff -ruN gdm-2.29.4.orig/daemon/gdm-display.c gdm-2.29.4.test/daemon/gdm-display.c
--- gdm-2.29.4.orig/daemon/gdm-display.c	2010-01-01 12:00:51.130963801 -0500
+++ gdm-2.29.4.test/daemon/gdm-display.c	2010-01-02 11:30:12.667018564 -0500
@@ -33,10 +33,12 @@
 #include <glib/gi18n.h>
 #include <glib-object.h>
 
+#include "gdm-common.h"
 #include "gdm-display.h"
 #include "gdm-display-glue.h"
 #include "gdm-display-access-file.h"
 
+#include "gdm-settings-utils.h"
 #include "gdm-settings-direct.h"
 #include "gdm-settings-keys.h"
 
@@ -306,27 +308,42 @@
 gdm_display_real_get_timed_login_details (GdmDisplay *display,
                                           gboolean   *enabledp,
                                           char      **usernamep,
-                                          int        *delayp)
+                                          char      **delayp)
 {
         gboolean res;
         gboolean enabled;
         int      delay;
         char    *username;
+        char    *delay_str;
 
         enabled = FALSE;
         username = NULL;
-        delay = 0;
+        delay_str = NULL;
 
         res = gdm_settings_direct_get_boolean (GDM_KEY_AUTO_LOGIN_ENABLE, &enabled);
         if (enabled) {
             res = gdm_settings_direct_get_string (GDM_KEY_AUTO_LOGIN_USER, &username);
         }
 
+        /* 
+         * If AutomaticLoginEnable=true and AutomaticLogin has a 
+         * login name defined, then AutomaticLoginShowGUI is parsed
+         * only if .dmrc file is not existing under the user $HOME.
+         * If this file exists AutomaticLoginShowGUI value is forced
+         * as false.
+         */
         if (enabled && username != NULL && username[0] != '\0') {
+                if (gdm_dmrc_file_exists (username))
+                        delay_str = g_strdup("false");
+                else
+                        res = gdm_settings_direct_get_string (GDM_KEY_AUTOMATIC_LOGIN_SHOW_GUI, &delay_str);
+                g_debug ("GdmDisplay: delay string = %s\n", delay_str);
                 goto out;
         }
 
         g_free (username);
+        g_free (delay_str);
+        delay_str = NULL;
         username = NULL;
         enabled = FALSE;
 
@@ -351,6 +368,8 @@
                 delay = 10;
         }
 
+        delay_str = gdm_settings_parse_double_as_value ((gdouble) delay);
+
  out:
         if (enabledp != NULL) {
                 *enabledp = enabled;
@@ -361,7 +380,9 @@
                 g_free (username);
         }
         if (delayp != NULL) {
-                *delayp = delay;
+                *delayp = delay_str;
+        } else {
+                g_free (delay_str);
         }
 }
 
@@ -369,18 +390,18 @@
 gdm_display_get_timed_login_details (GdmDisplay *display,
                                      gboolean   *enabled,
                                      char      **username,
-                                     int        *delay,
+                                     char      **delay,
                                      GError    **error)
 {
         g_return_val_if_fail (GDM_IS_DISPLAY (display), FALSE);
 
         GDM_DISPLAY_GET_CLASS (display)->get_timed_login_details (display, enabled, username, delay);
 
-        g_debug ("GdmSlave: Got timed login details for display %s: %d '%s' %d",
+        g_debug ("GdmSlave: Got timed login details for display %s: %d '%s' %s",
                  display->priv->x11_display_name,
                  *enabled,
                  *username ? *username : "(null)",
-                 *delay);
+                 *delay ? *delay : "(null)");
 
         return TRUE;
 }
diff -ruN gdm-2.29.4.orig/daemon/gdm-display.h gdm-2.29.4.test/daemon/gdm-display.h
--- gdm-2.29.4.orig/daemon/gdm-display.h	2010-01-01 12:00:51.131040743 -0500
+++ gdm-2.29.4.test/daemon/gdm-display.h	2010-01-02 11:30:12.667240063 -0500
@@ -73,7 +73,7 @@
         void     (*get_timed_login_details)   (GdmDisplay *display,
                                                gboolean   *enabled,
                                                char      **username,
-                                               int        *delay);
+                                               char      **delay);
 } GdmDisplayClass;
 
 typedef enum
@@ -120,7 +120,7 @@
 gboolean            gdm_display_get_timed_login_details        (GdmDisplay *display,
                                                                 gboolean   *enabled,
                                                                 char      **username,
-                                                                int        *delay,
+                                                                char      **delay,
                                                                 GError    **error);
 
 /* exported but protected */
diff -ruN gdm-2.29.4.orig/daemon/gdm-display.xml gdm-2.29.4.test/daemon/gdm-display.xml
--- gdm-2.29.4.orig/daemon/gdm-display.xml	2010-01-01 12:00:51.128513186 -0500
+++ gdm-2.29.4.test/daemon/gdm-display.xml	2010-01-02 11:30:12.667377395 -0500
@@ -38,7 +38,7 @@
     <method name="GetTimedLoginDetails">
       <arg name="enabled" direction="out" type="b"/>
       <arg name="username" direction="out" type="s"/>
-      <arg name="delay" direction="out" type="i"/>
+      <arg name="delay" direction="out" type="s"/>
     </method>
   </interface>
 </node>
diff -ruN gdm-2.29.4.orig/daemon/gdm-greeter-server.c gdm-2.29.4.test/daemon/gdm-greeter-server.c
--- gdm-2.29.4.orig/daemon/gdm-greeter-server.c	2010-01-01 12:00:51.132627176 -0500
+++ gdm-2.29.4.test/daemon/gdm-greeter-server.c	2010-01-02 11:30:12.668013078 -0500
@@ -253,6 +253,18 @@
 }
 
 void
+gdm_greeter_server_layout_popup_requested (GdmGreeterServer *greeter_server)
+{
+        send_dbus_void_signal (greeter_server, "LayoutPopupRequested");
+}
+
+void
+gdm_greeter_server_language_popup_requested (GdmGreeterServer *greeter_server)
+{
+        send_dbus_void_signal (greeter_server, "LanguagePopupRequested");
+}
+
+void
 gdm_greeter_server_selected_user_changed (GdmGreeterServer *greeter_server,
                                           const char       *username)
 {
@@ -739,6 +751,10 @@
                                "    <signal name=\"InfoQuery\">\n"
                                "      <arg name=\"text\" type=\"s\"/>\n"
                                "    </signal>\n"
+                               "    <signal name=\"LayoutPopupRequested\">\n"
+                               "    </signal>\n"
+                               "    <signal name=\"LanguagePopupRequested\">\n"
+                               "    </signal>\n"
                                "    <signal name=\"SecretInfoQuery\">\n"
                                "      <arg name=\"text\" type=\"s\"/>\n"
                                "    </signal>\n"
diff -ruN gdm-2.29.4.orig/daemon/gdm-greeter-server.h gdm-2.29.4.test/daemon/gdm-greeter-server.h
--- gdm-2.29.4.orig/daemon/gdm-greeter-server.h	2010-01-01 12:00:51.129111831 -0500
+++ gdm-2.29.4.test/daemon/gdm-greeter-server.h	2010-01-02 11:30:12.668204543 -0500
@@ -86,6 +86,8 @@
                                                               const char       *text);
 gboolean            gdm_greeter_server_reset                 (GdmGreeterServer *greeter_server);
 gboolean            gdm_greeter_server_ready                 (GdmGreeterServer *greeter_server);
+void                gdm_greeter_server_layout_popup_requested (GdmGreeterServer *greeter_server);
+void                gdm_greeter_server_language_popup_requested (GdmGreeterServer *greeter_server);
 void                gdm_greeter_server_selected_user_changed (GdmGreeterServer *greeter_server,
                                                               const char       *text);
 void                gdm_greeter_server_default_language_name_changed (GdmGreeterServer *greeter_server,
diff -ruN gdm-2.29.4.orig/daemon/gdm-simple-slave.c gdm-2.29.4.test/daemon/gdm-simple-slave.c
--- gdm-2.29.4.orig/daemon/gdm-simple-slave.c	2010-01-01 12:00:51.132741948 -0500
+++ gdm-2.29.4.test/daemon/gdm-simple-slave.c	2010-01-02 11:30:12.668778326 -0500
@@ -297,8 +297,23 @@
                        GdmSimpleSlave *slave)
 {
         if (slave->priv->greeter_server != NULL) {
+                gboolean res;
+                gboolean enabled;
+                char    *username;
+                int      delay;
+
+                enabled = FALSE;
                 gdm_greeter_server_user_authorized (slave->priv->greeter_server);
                 gdm_simple_slave_accredit_when_ready (slave);
+
+                gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, &username, &delay);
+               if (enabled && username != NULL && username[0] != '\0' && delay == -1) {
+#ifdef HAVE_LIBXKLAVIER
+                        gdm_greeter_server_layout_popup_requested (slave->priv->greeter_server);
+#endif
+                        gdm_greeter_server_language_popup_requested (slave->priv->greeter_server);
+                }
+                g_free (username);
         } else {
                 slave->priv->start_session_when_ready = TRUE;
                 gdm_simple_slave_accredit_when_ready (slave);
@@ -1023,7 +1038,7 @@
                 delay = 0;
                 enabled = FALSE;
                 gdm_slave_get_timed_login_details (GDM_SLAVE (slave), &enabled, NULL, &delay);
-                if (! enabled || delay > 0) {
+                if (! enabled || delay != 0) {
                         start_greeter (slave);
                         create_new_session (slave);
                 } else {
diff -ruN gdm-2.29.4.orig/daemon/gdm-slave.c gdm-2.29.4.test/daemon/gdm-slave.c
--- gdm-2.29.4.orig/daemon/gdm-slave.c	2010-01-01 12:00:51.130450238 -0500
+++ gdm-2.29.4.test/daemon/gdm-slave.c	2010-01-02 11:57:06.988532841 -0500
@@ -767,25 +767,25 @@
 }
 
 static gchar *
-gdm_slave_parse_enriched_login (GdmSlave *slave,
-                                char *username,
+gdm_slave_parse_enriched_item (GdmSlave *slave,
+                                char *item,
                                 char *display_name)
 {
         char in_buffer[20];
         char **argv = NULL;
         gint pipe1[2], in_buffer_len;
-        int  username_length;
+        int  item_length;
         pid_t pid;
 
-        if (username == NULL)
+        if (item == NULL)
                 return (NULL);
 
-        /* A script may be used to generate the automatic/timed login name
-           based on the display/host by ending the name with the pipe symbol
-           '|'. */
+        /* A script may be used to generate the valid values based on 
+           certain conditions in the script. The script need to end
+           with the pipe symbol '|'. */
 
-        username_length = strlen (username);
-        if (username_length > 0 && username[username_length-1] == '|') {
+        item_length = strlen (item);
+        if (item_length > 0 && item[item_length-1] == '|') {
                 GPtrArray *env;
                 GError    *error;
                 gboolean   res;
@@ -794,17 +794,17 @@
                 char      *std_error;
 
                 /* Remove the pipe symbol */
-                username[username_length-1] = '\0';
+                item[item_length-1] = '\0';
 
                 argv = NULL;
                 error = NULL;
-                if (! g_shell_parse_argv (username, NULL, &argv, &error)) {
+                if (! g_shell_parse_argv (item, NULL, &argv, &error)) {
                       g_warning ("Could not parse command: %s", error->message);
                       return (NULL);
                 }
 
-                g_debug ("Calling script %s to acquire auto/timed username",
-                         username);
+                g_debug ("Calling script %s to acquire auto/timed item",
+                         item);
 
                 env = get_script_environment (slave, NULL);
                 error = NULL;
@@ -836,12 +836,57 @@
                         return NULL;
                 }
         } else {
-                return (g_strdup (username));
+                return (g_strdup (item));
         }
 
 	return NULL;
 }
 
+static gint
+gdm_slave_parse_delay_string (char *s)
+{
+        gint ret = 0;
+
+        if (s && !g_ascii_strcasecmp (s, "true") || !g_ascii_strcasecmp (s, "yes")) {
+                ret = -1;
+        } else if (s && !g_ascii_strcasecmp (s, "false") || !g_ascii_strcasecmp (s, "no")) {
+                ret = 0;
+        } else if (s) {
+                ret = (gint) g_ascii_strtod (s, NULL);
+                if (ret <= 0)
+                        ret = 10;
+        } 
+        return ret;
+}
+
+static gint
+gdm_slave_parse_delay (GdmSlave *slave,
+                                char *delay,
+                                char *display_name)
+{
+        gchar *s;
+        gint  ret;
+
+        /* Parsing for AutomaticLoginShowGUI/TimedLoginDelay values.
+           Valid values for AutomaticLoginShowGUI
+           AutomaticLoginShowGUI=true
+           AutomaticLoginShowGUI=false
+           AutomaticLoginShowGUI=yes
+           AutomaticLoginShowGUI=no
+           AutomaticLoginShowGUI=/path/to/script|
+           script may be used to generate yes/no or true/false or
+           timed delay value for AutomaticLoginShowGUI based on certain
+           conditions. 
+           TimedLoginDelay value also passed as a string and parsed here. 
+           It takes in delay in seconds 
+         */
+
+         s = gdm_slave_parse_enriched_item (slave, delay, display_name);
+         ret = gdm_slave_parse_delay_string (s);
+         g_free (s);
+         return ret;
+}
+
 gboolean
 gdm_slave_get_timed_login_details (GdmSlave   *slave,
                                    gboolean   *enabledp,
@@ -853,11 +898,11 @@
         gboolean       res;
         gboolean       enabled;
         char          *username;
-        int            delay;
+        char          *delay;
 
         username = NULL;
         enabled = FALSE;
-        delay = 0;
+        delay = NULL;
 
         g_debug ("GdmSlave: Requesting timed login details");
 
@@ -868,7 +913,7 @@
                                  G_TYPE_INVALID,
                                  G_TYPE_BOOLEAN, &enabled,
                                  G_TYPE_STRING, &username,
-                                 G_TYPE_INT, &delay,
+                                 G_TYPE_STRING, &delay,
                                  G_TYPE_INVALID);
 
         if (! res) {
@@ -879,11 +924,18 @@
                         g_warning ("Failed to get timed login details");
                 }
         } else {
-                g_debug ("GdmSlave: Got timed login details: %d %s %d", enabled, username, delay);
+                g_debug ("GdmSlave: Got timed login details: %d %s %s", enabled, username, delay);
+        }
+
+        if (delayp != NULL) {
+                *delayp = gdm_slave_parse_delay (slave,
+                        delay, slave->priv->display_name);
         }
 
+        g_free (delay);
+
         if (usernamep != NULL) {
-                *usernamep = gdm_slave_parse_enriched_login (slave,
+                *usernamep = gdm_slave_parse_enriched_item (slave,
                         username, slave->priv->display_name);
         } else {
                 g_free (username);
@@ -891,9 +943,6 @@
                 if (enabledp != NULL) {
                         *enabledp = enabled;
                 }
-                if (delayp != NULL) {
-                        *delayp = delay;
-                }
                 return TRUE;
         }
         g_free (username);
@@ -912,9 +961,6 @@
                         if (enabledp != NULL) {
                                 *enabledp = enabled;
                         }
-                        if (delayp != NULL) {
-                                *delayp = delay;
-                        }
                }
         } else {
                 g_debug ("Invalid NULL username for auto/timed login");
diff -ruN gdm-2.29.4.orig/data/gdm.schemas.in.in gdm-2.29.4.test/data/gdm.schemas.in.in
--- gdm-2.29.4.orig/data/gdm.schemas.in.in	2010-01-01 12:00:51.107074170 -0500
+++ gdm-2.29.4.test/data/gdm.schemas.in.in	2010-01-02 11:30:12.669880747 -0500
@@ -33,6 +33,11 @@
       <default></default>
     </schema>
     <schema>
+      <key>daemon/AutomaticLoginShowGUI</key>
+      <signature>s</signature>
+      <default>false</default>
+    </schema>
+    <schema>
       <key>daemon/TimedLoginEnable</key>
       <signature>b</signature>
       <default>false</default>
diff -ruN gdm-2.29.4.orig/docs/C/gdm.xml gdm-2.29.4.test/docs/C/gdm.xml
--- gdm-2.29.4.orig/docs/C/gdm.xml	2010-01-01 12:00:51.121211954 -0500
+++ gdm-2.29.4.test/docs/C/gdm.xml	2010-01-02 11:50:18.004424000 -0500
@@ -1241,6 +1241,32 @@
           </varlistentry>
 
           <varlistentry>
+            <term>AutomaticLoginShowGUI</term>
+            <listitem>
+              <synopsis>AutomaticLoginShowGUI=</synopsis>
+              <para>
+                AutomaticLoginShowGUI indicates if the Keyboard/Language 
+                dialogs should popup automatically. It can take up
+                true, false or the name of a script (value should end 
+                with a vertical bar | (the pipe symbol)), which can return
+                true or false depending on some conditions.  Even if 
+                the value is set to true, if $HOME/.dmrc for the 
+                AutomaticLogin user exists then the popup won't be activated.
+              </para>
+              <para>
+                If the value ends with a vertical bar | (the pipe symbol),
+                then GDM will execute the program specified and use whatever
+                value is returned on standard out from the program as the value.
+                The program is run with the DISPLAY environment variable set so
+                that it is possible to specify the value in a per-display
+                fashion.  For example if the value is "/usr/bin/getshowgui|",
+                then the program "/usr/bin/getshowgui" will be run to get the
+                user value.
+              </para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
             <term>User</term>
             <listitem>
               <synopsis>User=gdm</synopsis>
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-client.c gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-client.c
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-client.c	2010-01-01 12:00:51.114649928 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-client.c	2010-01-02 11:30:12.671535469 -0500
@@ -71,6 +71,8 @@
         DEFAULT_SESSION_NAME_CHANGED,
         TIMED_LOGIN_REQUESTED,
         USER_AUTHORIZED,
+        LANGUAGE_POPUP_REQUESTED,
+        LAYOUT_POPUP_REQUESTED,
         LAST_SIGNAL
 };
 
@@ -206,6 +208,24 @@
 }
 
 static void
+on_layout_popup_requested (GdmGreeterClient *client,
+                          DBusMessage      *message)
+{
+        g_signal_emit (client,
+                       gdm_greeter_client_signals[LAYOUT_POPUP_REQUESTED],
+                       0);
+}
+
+static void
+on_language_popup_requested (GdmGreeterClient *client,
+                          DBusMessage      *message)
+{
+        g_signal_emit (client,
+                       gdm_greeter_client_signals[LANGUAGE_POPUP_REQUESTED],
+                       0);
+}
+
+static void
 on_info_query (GdmGreeterClient *client,
                DBusMessage      *message)
 {
@@ -657,6 +677,10 @@
                 on_timed_login_requested (client, message);
         } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "UserAuthorized")) {
                 on_user_authorized (client, message);
+        } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "LayoutPopupRequested")) {
+                on_layout_popup_requested (client, message);
+        } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "LanguagePopupRequested")) {
+                on_language_popup_requested (client, message);
         } else {
                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
         }
@@ -954,6 +978,26 @@
                               NULL,
                               g_cclosure_marshal_VOID__VOID,
                               G_TYPE_NONE, 0);
+
+        gdm_greeter_client_signals[LANGUAGE_POPUP_REQUESTED] =
+                g_signal_new ("language-popup-requested",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (GdmGreeterClientClass, language_popup_requested),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
+
+        gdm_greeter_client_signals[LAYOUT_POPUP_REQUESTED] =
+                g_signal_new ("layout-popup-requested",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (GdmGreeterClientClass, layout_popup_requested),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE, 0);
 }
 
 static void
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-client.h gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-client.h
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-client.h	2010-01-01 12:00:51.114689689 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-client.h	2010-01-02 11:30:12.671725537 -0500
@@ -70,6 +70,8 @@
                                           const char        *username,
                                           int                delay);
         void (* user_authorized)         (GdmGreeterClient  *client);
+        void (* language_popup_requested)         (GdmGreeterClient  *client);
+        void (* layout_popup_requested)         (GdmGreeterClient  *client);
 } GdmGreeterClientClass;
 
 #define GDM_GREETER_CLIENT_ERROR (gdm_greeter_client_error_quark ())
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-login-window.c gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-login-window.c
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-login-window.c	2010-01-01 12:00:51.110659962 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-login-window.c	2010-01-02 11:30:12.672436060 -0500
@@ -298,7 +298,8 @@
 {
         remove_timed_login_timeout (login_window);
 
-        if (login_window->priv->timed_login_enabled) {
+        if (login_window->priv->timed_login_enabled &&
+            login_window->priv->timed_login_delay != UINT_MAX) {
                 g_debug ("GdmGreeterLoginWindow: adding timed login timer");
                 watch_for_user_interaction (login_window);
                 login_window->priv->timed_login_timeout_id = g_timeout_add_seconds (login_window->priv->timed_login_delay,
@@ -645,7 +646,12 @@
                 timed_login_already_enabled = FALSE;
         }
         login_window->priv->timed_login_username = g_strdup (username);
-        login_window->priv->timed_login_delay = delay;
+
+        if (delay == -1) {
+                login_window->priv->timed_login_delay = UINT_MAX;
+        } else {
+                login_window->priv->timed_login_delay = delay;
+        }
 
         if (login_window->priv->dialog_mode != MODE_SELECTION) {
                 reset_dialog (login_window);
@@ -870,7 +876,8 @@
 
                 /* just wait for the user to select language and stuff */
                 set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
-                set_message (login_window, _("Select language and click Log In"));
+                if (login_window->priv->timed_login_delay != UINT_MAX)
+                        set_message (login_window, _("Select language and click Log In"));
         } else {
                 g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, user_name);
         }
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-panel.c gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-panel.c
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-panel.c	2010-01-01 12:00:51.114277315 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-panel.c	2010-01-02 11:30:12.672972945 -0500
@@ -1020,6 +1020,18 @@
 }
 
 void
+gdm_greeter_panel_popup_language_dialog (GdmGreeterPanel *panel)
+{
+                gdm_language_option_widget_popup_language_dialog (GDM_LANGUAGE_OPTION_WIDGET(panel->priv->language_option_widget));
+}
+
+void
+gdm_greeter_panel_popup_layout_dialog (GdmGreeterPanel *panel)
+{
+                gdm_layout_option_widget_popup_layout_dialog (GDM_LAYOUT_OPTION_WIDGET(panel->priv->layout_option_widget));
+}
+
+void
 gdm_greeter_panel_show_user_options (GdmGreeterPanel *panel)
 {
         gtk_widget_show (panel->priv->session_option_widget);
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-panel.h gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-panel.h
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-panel.h	2010-01-01 12:00:51.114055241 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-panel.h	2010-01-02 11:30:12.673139576 -0500
@@ -73,6 +73,9 @@
                                                                          const char      *layout_name);
 void                   gdm_greeter_panel_set_default_session_name       (GdmGreeterPanel *panel,
                                                                          const char      *session_name);
+void     gdm_greeter_panel_popup_language_dialog                        (GdmGreeterPanel *panel);
+void     gdm_greeter_panel_popup_layout_dialog                          (GdmGreeterPanel *panel);
+
 G_END_DECLS
 
 #endif /* __GDM_GREETER_PANEL_H */
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-session.c gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-session.c
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-greeter-session.c	2010-01-01 12:00:51.114759476 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-greeter-session.c	2010-01-02 11:30:12.673518930 -0500
@@ -170,6 +170,23 @@
         gdm_greeter_login_window_user_authorized (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window));
 }
 
+
+static void
+on_language_popup_requested (GdmGreeterClient  *client,
+                    GdmGreeterSession *session)
+{
+        g_debug ("GdmGreeterSession: language dialog requested");
+        gdm_greeter_panel_popup_language_dialog (GDM_GREETER_PANEL (session->priv->panel));
+}
+
+static void
+on_layout_popup_requested (GdmGreeterClient  *client,
+                    GdmGreeterSession *session)
+{
+        g_debug ("GdmGreeterSession: layout dialog requested");
+        gdm_greeter_panel_popup_layout_dialog (GDM_GREETER_PANEL (session->priv->panel));
+}
+
 static void
 on_info_query (GdmGreeterClient  *client,
                const char        *text,
@@ -603,6 +620,14 @@
                           "user-authorized",
                           G_CALLBACK (on_user_authorized),
                           session);
+        g_signal_connect (session->priv->client,
+                          "language-popup-requested",
+                          G_CALLBACK (on_language_popup_requested),
+                          session);
+        g_signal_connect (session->priv->client,
+                          "layout-popup-requested",
+                          G_CALLBACK (on_layout_popup_requested),
+                          session);
 
         /* We want to listen for panel mnemonics even if the
          * login window is focused, so we intercept them here.
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-language-option-widget.c gdm-2.29.4.test/gui/simple-greeter/gdm-language-option-widget.c
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-language-option-widget.c	2010-01-01 12:00:51.112656277 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-language-option-widget.c	2010-01-02 11:30:12.673791644 -0500
@@ -40,6 +40,7 @@
 #include "gdm-language-option-widget.h"
 #include "gdm-recent-option-widget.h"
 #include "gdm-language-chooser-dialog.h"
+#include "gdm-settings-client.h"
 
 #define GDM_LANGUAGE_OPTION_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_LANGUAGE_OPTION_WIDGET, GdmLanguageOptionWidgetPrivate))
 
@@ -321,3 +322,16 @@
         gdm_option_widget_set_active_item (GDM_OPTION_WIDGET (widget), normalized_language_name);
         g_free (normalized_language_name);
 }
+
+void
+gdm_language_option_widget_popup_language_dialog (GdmLanguageOptionWidget *widget)
+{
+        char *active_item_id;
+
+        active_item_id = gdm_option_widget_get_default_item (GDM_OPTION_WIDGET (widget));
+        gdm_language_option_widget_set_current_language_name (widget, active_item_id);
+        gdm_language_option_widget_show_dialog (widget, active_item_id);
+        g_signal_emit (G_OBJECT (widget), signals[LANGUAGE_ACTIVATED], 0);
+        g_free (active_item_id);
+        gtk_dialog_run (GTK_DIALOG (widget->priv->dialog));
+}
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-language-option-widget.h gdm-2.29.4.test/gui/simple-greeter/gdm-language-option-widget.h
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-language-option-widget.h	2010-01-01 12:00:51.111628672 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-language-option-widget.h	2010-01-02 11:30:12.673940611 -0500
@@ -57,6 +57,7 @@
 char *                 gdm_language_option_widget_get_current_language_name      (GdmLanguageOptionWidget *widget);
 void                   gdm_language_option_widget_set_current_language_name      (GdmLanguageOptionWidget *widget,
                                                                                   const char              *lang_name);
+void                  gdm_language_option_widget_popup_language_dialog (GdmLanguageOptionWidget *widget);
 
 
 
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-layout-option-widget.c gdm-2.29.4.test/gui/simple-greeter/gdm-layout-option-widget.c
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-layout-option-widget.c	2010-01-01 12:00:51.114559163 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-layout-option-widget.c	2010-01-02 11:30:12.674167340 -0500
@@ -304,3 +304,16 @@
         g_debug ("GdmLayoutOptionWidget: Setting active item: '%s'", id);
         gdm_option_widget_set_active_item (GDM_OPTION_WIDGET (widget), id);
 }
+
+void
+gdm_layout_option_widget_popup_layout_dialog (GdmLayoutOptionWidget *widget)
+{
+        char *active_item_id;
+
+        active_item_id = gdm_option_widget_get_default_item (GDM_OPTION_WIDGET (widget));
+        gdm_layout_option_widget_set_current_layout_name (widget, active_item_id);
+        gdm_layout_option_widget_show_dialog (widget, active_item_id);
+        g_signal_emit (G_OBJECT (widget), signals[LAYOUT_ACTIVATED], 0);
+        g_free (active_item_id);
+        gtk_dialog_run (GTK_DIALOG (widget->priv->dialog));
+}
diff -ruN gdm-2.29.4.orig/gui/simple-greeter/gdm-layout-option-widget.h gdm-2.29.4.test/gui/simple-greeter/gdm-layout-option-widget.h
--- gdm-2.29.4.orig/gui/simple-greeter/gdm-layout-option-widget.h	2010-01-01 12:00:51.112417883 -0500
+++ gdm-2.29.4.test/gui/simple-greeter/gdm-layout-option-widget.h	2010-01-02 11:30:12.674310466 -0500
@@ -57,6 +57,7 @@
 char *                 gdm_layout_option_widget_get_current_layout_name      (GdmLayoutOptionWidget *widget);
 void                   gdm_layout_option_widget_set_current_layout_name      (GdmLayoutOptionWidget *widget,
                                                                                   const char              *name);
+void                   gdm_layout_option_widget_popup_layout_dialog (GdmLayoutOptionWidget *widget);
 
 
 
