diff -ur gdm-2.25.2.orig/gui/simple-greeter/gdm-greeter-login-window.c gdm-2.25.2/gui/simple-greeter/gdm-greeter-login-window.c
--- gdm-2.25.2.orig/gui/simple-greeter/gdm-greeter-login-window.c	2008-11-18 17:19:05.000000000 -0500
+++ gdm-2.25.2/gui/simple-greeter/gdm-greeter-login-window.c	2009-01-12 16:42:21.000000000 -0500
@@ -107,10 +107,44 @@
         LOGIN_BUTTON_TIMED_LOGIN
 };
 
+/* Whether to show manual username entry by typing, selection from the
+ * chooser, or both. When the chooser list is empty, SELECTION_TYPE_MANUAL
+ * is used. When the chooser list is non-empty, the dialog starts with
+ * SELECTION_TYPE_CHOOSER but moves to SELECTION_TYPE_BOTH if the
+ * pseudo-user "Other..." is selected from the chooser, and moves back
+ * to SELECTION_TYPE_CHOOSER if a different user is selected from the
+ * chooser. */
+
+enum {
+	SELECTION_TYPE_MANUAL = 0,
+	SELECTION_TYPE_CHOOSER,
+	SELECTION_TYPE_BOTH
+};
+
 struct GdmGreeterLoginWindowPrivate
 {
         GladeXML        *xml;
+
+/* Widget for the original user chooser mechanism. */
+
         GtkWidget       *user_chooser;
+
+/* Widgets for the new manual username entry mechanism:
+ *	manual_user_chooser:         widget shown when in MODE_SELECTION
+ *	manual_user_chooser_entry:   subwidget holding the entered username
+ *	manual_user_chooser_button:  subwidget for the Begin button
+ *	manual_user_chosen:          widget shown when in MODE_AUTHENTICATION
+ *      manual_user_chosen_value:    subwidget displaying the entered username
+ * */
+	GtkWidget	*manual_user_chooser;
+	GtkWidget       *manual_user_chooser_entry;
+	GtkWidget	*manual_user_chooser_button;
+	GtkWidget       *manual_user_chosen;
+	GtkWidget	*manual_user_chosen_value;
+
+/* Which selection type to use (manual, chooser, or both): */
+	guint		user_selection_type;
+
         GtkWidget       *auth_banner_label;
         guint            display_is_local : 1;
         guint            is_interactive : 1;
@@ -204,6 +238,9 @@
 
         if (GTK_WIDGET_REALIZED (entry) && ! GTK_WIDGET_HAS_FOCUS (entry)) {
                 gtk_widget_grab_focus (entry);
+        } else if (GTK_WIDGET_REALIZED (login_window->priv->manual_user_chooser_entry) &&
+				! GTK_WIDGET_HAS_FOCUS (login_window->priv->manual_user_chooser_entry)) {
+                gtk_widget_grab_focus (login_window->priv->manual_user_chooser_entry);
         } else if (GTK_WIDGET_REALIZED (login_window->priv->user_chooser) && ! GTK_WIDGET_HAS_FOCUS (login_window->priv->user_chooser)) {
                 gtk_widget_grab_focus (login_window->priv->user_chooser);
         }
@@ -519,6 +556,38 @@
                                                                                    login_window);
 }
 
+/* Selects a particular user selection type (SELECTION_TYPE_MANUAL,
+ * SELECTION_TYPE_CHOOSER, or SELECTION_TYPE_BOTH) and clears any 
+ * previous manually entered username. Also shows/hides the widgets
+ * in the state appropriate for MODE_SELECTION (so this routine
+ * should only be called when mode is MODE_SELECTION or about to
+ * be reset to MODE_SELECTION). */
+
+static void
+set_user_selection_type (GdmGreeterLoginWindow *login_window,
+				guint selection_type)
+{
+	gtk_entry_set_text ( GTK_ENTRY(login_window->priv->manual_user_chooser_entry), "");
+	gtk_label_set_text ( GTK_LABEL(login_window->priv->manual_user_chosen_value), "no user selected");
+	gtk_widget_hide_all(login_window->priv->manual_user_chosen);
+	login_window->priv->user_selection_type = selection_type;
+	if (selection_type == SELECTION_TYPE_CHOOSER) 
+	{
+	    gtk_widget_show(login_window->priv->user_chooser);
+	    gtk_widget_hide_all(login_window->priv->manual_user_chooser);
+	}
+	else
+	{
+	    gtk_widget_show_all(login_window->priv->manual_user_chooser);
+	    gtk_widget_grab_default(login_window->priv->manual_user_chooser_button);
+	    if (GTK_WIDGET_REALIZED (login_window->priv->manual_user_chooser_entry) &&
+                                ! GTK_WIDGET_HAS_FOCUS (login_window->priv->manual_user_chooser_entry)) {
+                gtk_widget_grab_focus (login_window->priv->manual_user_chooser_entry);
+	    }
+
+	}
+}
+
 static void
 switch_mode (GdmGreeterLoginWindow *login_window,
              int                    number)
@@ -564,7 +633,11 @@
                 sensitize_widget (login_window, "restart-button", FALSE);
                 sensitize_widget (login_window, "suspend-button", FALSE);
                 sensitize_widget (login_window, "disconnect-button", FALSE);
-
+		gtk_widget_hide_all (login_window->priv->manual_user_chosen);
+                if (gdm_user_chooser_widget_is_empty(GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser)))
+                        set_user_selection_type(login_window, SELECTION_TYPE_MANUAL);
+                else
+                        set_user_selection_type(login_window, SELECTION_TYPE_CHOOSER);
                 default_name = NULL;
                 break;
         case MODE_AUTHENTICATION:
@@ -577,6 +650,11 @@
                 show_widget (login_window, "suspend-button", FALSE);
                 show_widget (login_window, "disconnect-button", FALSE);
                 default_name = "log-in-button";
+		gtk_widget_hide_all (login_window->priv->manual_user_chooser);
+		if (login_window->priv->user_selection_type == SELECTION_TYPE_CHOOSER)
+		     gtk_widget_hide_all (login_window->priv->manual_user_chosen);
+		else  /* SELECTION_TYPE_CHOOSER or SELECTION_TYPE_BOTH */
+		     gtk_widget_show_all (login_window->priv->manual_user_chosen);
                 break;
         default:
                 g_assert_not_reached ();
@@ -709,10 +787,16 @@
 
         switch_mode (login_window, MODE_SELECTION);
 
+	if (gdm_user_chooser_widget_is_empty(GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser)))
+	    set_user_selection_type(login_window, SELECTION_TYPE_MANUAL);
+	else
+	    set_user_selection_type(login_window, SELECTION_TYPE_CHOOSER);
+	
         set_sensitive (login_window, TRUE);
         set_ready (login_window);
         set_focus (GDM_GREETER_LOGIN_WINDOW (login_window));
-        gdm_chooser_widget_propagate_pending_key_events (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
+	if (login_window->priv->user_selection_type != SELECTION_TYPE_MANUAL)
+            gdm_chooser_widget_propagate_pending_key_events (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
 }
 
 static void
@@ -1328,8 +1412,16 @@
                  GdmGreeterLoginWindow *login_window)
 {
         gdm_chooser_widget_activate_if_one_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
+	if (login_window->priv->dialog_mode == MODE_SELECTION)
+	{
+		if (gdm_user_chooser_widget_is_empty(GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser)))
+	    		set_user_selection_type(login_window, SELECTION_TYPE_MANUAL);
+		else
+	    		set_user_selection_type(login_window, SELECTION_TYPE_CHOOSER);
+	}
 }
 
+/* Handle a user or pseudo-user chosen from the chooser list. */
 static void
 on_user_chosen (GdmUserChooserWidget  *user_chooser,
                 GdmGreeterLoginWindow *login_window)
@@ -1343,12 +1435,21 @@
                 return;
         }
 
+/* For the "Other..." pseudo-user, do nothing except activate the
+ * manual username entry mechanism in addition to the chooser,
+ * and activate the Cancel button. */
+
+       if (strcmp (user_name, GDM_USER_CHOOSER_USER_OTHER) == 0) {
+               set_user_selection_type(login_window, SELECTION_TYPE_BOTH);
+		show_widget(login_window, "cancel-button", TRUE);
+		return;
+	}
+
+
         g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED],
                        0, user_name);
 
-        if (strcmp (user_name, GDM_USER_CHOOSER_USER_OTHER) == 0) {
-                g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0);
-        } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_GUEST) == 0) {
+        if (strcmp (user_name, GDM_USER_CHOOSER_USER_GUEST) == 0) {
                 /* FIXME: handle guest account stuff */
         } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_AUTO) == 0) {
                 g_signal_emit (login_window, signals[BEGIN_AUTO_LOGIN], 0,
@@ -1369,6 +1470,33 @@
         g_free (user_name);
 }
 
+/* Handle a username typed in manually. */
+
+static void
+on_user_chosen_manually (GtkButton *button,
+				GdmGreeterLoginWindow *login_window) 
+{
+        const char *user_name;
+
+/* This should not happen, but just in case any spurious events get
+ * received while in chooser-only mode, ignore them. */
+	if (login_window->priv->user_selection_type == SELECTION_TYPE_CHOOSER) return;
+
+	user_name = gtk_entry_get_text (GTK_ENTRY(login_window->priv->manual_user_chooser_entry));
+	g_debug ("Manual selection %s\n", user_name);
+	if (! user_name || ! *user_name) {
+            set_focus (GDM_GREETER_LOGIN_WINDOW (login_window));
+	    return;
+	}
+	gtk_label_set_text (GTK_LABEL(login_window->priv->manual_user_chosen_value), user_name);
+        g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED], 0, user_name);
+        g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, user_name); 
+        switch_mode (login_window, MODE_AUTHENTICATION);
+/* Note: unlike on_user_chosen, we do not free user_name, as it was
+ * returned by gtk_entry_get_text and hence is a pointer to the
+ * internal buffer and must not be freed here. */
+}
+
 static void
 on_user_unchosen (GdmUserChooserWidget  *user_chooser,
                   GdmGreeterLoginWindow *login_window)
@@ -1577,11 +1705,20 @@
         box = glade_xml_get_widget (login_window->priv->xml, "window-frame");
         gtk_container_add (GTK_CONTAINER (login_window), box);
 
-        login_window->priv->user_chooser = glade_xml_get_widget (login_window->priv->xml,
-                                                                 "user-chooser");
-        if (login_window->priv->user_chooser == NULL) {
-                g_critical ("Userlist box not found");
-        }
+/* We have a lot of widgets to load with the new manual entry widget,
+ * so do it in a macro to save writing the same code out over and over. */
+
+#define loadwidget(privname, widgname)  login_window->priv->privname =  glade_xml_get_widget (login_window->priv->xml, widgname); \
+        if (login_window->priv->privname == NULL) { \
+                g_critical ("Widget " widgname " not found"); \
+        } \
+
+	loadwidget(user_chooser, "user-chooser")
+	loadwidget(manual_user_chooser, "manual-user-chooser")
+	loadwidget(manual_user_chooser_entry, "manual-user-chooser-entry")
+	loadwidget(manual_user_chooser_button, "manual-user-chooser-button")
+	loadwidget(manual_user_chosen, "manual-user-chosen")
+	loadwidget(manual_user_chosen_value, "manual-user-chosen-value")
 
         gdm_user_chooser_widget_set_show_only_chosen (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser), TRUE);
 
@@ -1597,8 +1734,15 @@
                           "deactivated",
                           G_CALLBACK (on_user_unchosen),
                           login_window);
+	g_signal_connect (login_window->priv->manual_user_chooser_button,
+				"clicked",
+				G_CALLBACK (on_user_chosen_manually),
+				login_window );
+
+/* Set to chooser-only mode for now. Once user list is loaded into chooser,
+ * manual mode will be activated if chooser list is empty. */
 
-        gtk_widget_show (login_window->priv->user_chooser);
+	set_user_selection_type(login_window, SELECTION_TYPE_CHOOSER);
 
         login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
         /*make_label_small_italic (login_window->priv->auth_banner_label);*/
diff -ur gdm-2.25.2.orig/gui/simple-greeter/gdm-greeter-login-window.glade gdm-2.25.2/gui/simple-greeter/gdm-greeter-login-window.glade
--- gdm-2.25.2.orig/gui/simple-greeter/gdm-greeter-login-window.glade	2008-11-18 17:34:37.000000000 -0500
+++ gdm-2.25.2/gui/simple-greeter/gdm-greeter-login-window.glade	2009-01-12 16:42:01.000000000 -0500
@@ -667,6 +667,146 @@
 			</packing>
 		      </child>
 
+<child>
+  <widget class="GtkHBox" id="manual-user-chosen">
+    <property name="visible">True</property>
+    <property name="homogeneous">False</property>
+    <property name="spacing">6</property>
+
+    <child>
+      <widget class="GtkLabel" id="manual-user-chosen-label">
+	<property name="visible">True</property>
+	<property name="label" translatable="yes">Logging in as</property>
+	<property name="justify">GTK_JUSTIFY_LEFT</property>
+	<property name="selectable">False</property>
+      </widget>
+      <packing>
+	<property name="padding">0</property>
+	<property name="expand">False</property>
+	<property name="fill">False</property>
+      </packing>
+    </child>
+    <child>
+      <widget class="GtkLabel" id="manual-user-chosen-value">
+	<property name="visible">True</property>
+	<property name="label">-- no user selected --</property>
+	<property name="justify">GTK_JUSTIFY_LEFT</property>
+	<property name="selectable">False</property>
+      </widget>
+      <packing>
+	<property name="padding">0</property>
+	<property name="expand">False</property>
+	<property name="fill">False</property>
+      </packing>
+    </child>
+  </widget>
+  <packing>
+    <property name="padding">0</property>
+    <property name="expand">False</property>
+    <property name="fill">False</property>
+  </packing>
+</child>
+                                                        
+
+<child>
+  <widget class="GtkHBox" id="manual-user-chooser">
+    <property name="visible">True</property>
+    <property name="homogeneous">False</property>
+    <property name="spacing">6</property>
+
+    <child>
+      <widget class="GtkLabel" id="manual-user-chooser-prompt">
+	<property name="visible">True</property>
+	<property name="label" translatable="yes">Username:</property>
+	<property name="justify">GTK_JUSTIFY_LEFT</property>
+	<property name="selectable">False</property>
+      </widget>
+      <packing>
+	<property name="padding">0</property>
+	<property name="expand">False</property>
+	<property name="fill">False</property>
+      </packing>
+    </child>
+
+    <child>
+       <widget class="GtkEntry" id="manual-user-chooser-entry">
+	<property name="visible">True</property>
+	<property name="can_focus">True</property>
+	<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+	<property name="editable">True</property>
+	<property name="max_length">0</property>
+	<property name="text" translatable="yes"></property>
+	<property name="has_frame">True</property>
+	<property name="activates_default">True</property>
+      </widget>
+      <packing>
+	<property name="padding">0</property>
+	<property name="expand">True</property>
+	<property name="fill">True</property>
+      </packing>
+    </child>
+
+    <child>
+      <widget class="GtkButton" id="manual-user-chooser-button">
+	<property name="visible">True</property>
+	<property name="can_default">True</property>
+	<property name="has_default">True</property>
+	<property name="can_focus">True</property>
+	<property name="relief">GTK_RELIEF_NORMAL</property>
+	<property name="focus_on_click">True</property>
+
+	<child>
+	  <widget class="GtkHBox" id="manual-user-chooser-button-contents">
+	    <property name="visible">True</property>
+	    <property name="homogeneous">False</property>
+	    <property name="spacing">0</property>
+
+	    <child>
+	      <widget class="GtkImage" id="manual-user-chooser-button-image">
+		<property name="visible">True</property>
+		<property name="icon_name">go-home</property>
+		<property name="pixel_size">16</property>
+	      </widget>
+	      <packing>
+		<property name="padding">0</property>
+		<property name="expand">False</property>
+		<property name="fill">False</property>
+	      </packing>
+	    </child>
+
+	    <child>
+	      <widget class="GtkLabel" id="manual-user-chooser-button-label">
+		<property name="visible">True</property>
+		<property name="label" translatable="yes">Begin</property>
+		<property name="justify">GTK_JUSTIFY_LEFT</property>
+		<property name="wrap">False</property>
+		<property name="selectable">False</property>
+	      </widget>
+	      <packing>
+		<property name="padding">10</property>
+		<property name="expand">True</property>
+		<property name="fill">True</property>
+	      </packing>
+	    </child>
+
+	  </widget>
+	</child>
+
+      </widget>
+      <packing>
+	<property name="padding">0</property>
+	<property name="expand">False</property>
+	<property name="fill">False</property>
+      </packing>
+    </child>
+  </widget>
+  <packing>
+    <property name="padding">0</property>
+    <property name="expand">False</property>
+    <property name="fill">False</property>
+  </packing>
+</child>
+
 		      <child>
 			<widget class="GtkHBox" id="auth-input-box">
 			  <property name="visible">True</property>
diff -ur gdm-2.25.2.orig/gui/simple-greeter/gdm-user-chooser-widget.c gdm-2.25.2/gui/simple-greeter/gdm-user-chooser-widget.c
--- gdm-2.25.2.orig/gui/simple-greeter/gdm-user-chooser-widget.c	2009-01-12 15:40:42.000000000 -0500
+++ gdm-2.25.2/gui/simple-greeter/gdm-user-chooser-widget.c	2009-01-12 16:42:01.000000000 -0500
@@ -68,6 +68,7 @@
         guint           show_normal_users : 1;
 
         guint           load_idle_id;
+	guint		number_of_users;
 };
 
 enum {
@@ -122,6 +123,49 @@
         return height;
 }
 
+/* Adjust number of users when a user is added or removed.
+ *
+ * If this changes the widget from empty to non-empty,
+ * ensure that the Other item is added too.
+ *
+ * If it changes the widget to just one item, remove the
+ * Other item if present (because if it is present, it
+ * would be the only entry).
+ *
+ * If the widget is now newly empty or newly non-empty
+ * and has already been marked as loaded, send another
+ * "loaded" signal so that the greeter can adjust
+ * the presence/absence of the manual entry area
+ * as needed. */
+
+static void
+adjust_number_of_users (GdmUserChooserWidget *widget, guint increment)
+{
+	guint old_number = widget->priv->number_of_users;
+	guint new_number = old_number + increment;
+	if (new_number < 0) g_critical ("Number of users dropped below zero!");
+	widget->priv->number_of_users = new_number;
+
+	g_debug("Number of users in chooser changed from %d to %d", old_number, new_number);
+	if (new_number > 0 && ! widget->priv->show_user_other)
+        	gdm_user_chooser_widget_set_show_user_other(GDM_USER_CHOOSER_WIDGET (widget), TRUE);
+
+	if (new_number == 1 && old_number > 1 && widget->priv->show_user_other)
+        	gdm_user_chooser_widget_set_show_user_other(GDM_USER_CHOOSER_WIDGET (widget), FALSE);
+
+	if (! widget->priv->loaded) return;
+
+	if (new_number > 0 && old_number == 0) gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET(widget));
+	if (new_number == 0 && old_number > 0) gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET(widget));
+}
+
+gboolean
+gdm_user_chooser_widget_is_empty(GdmUserChooserWidget *widget)
+{
+	if (widget->priv->number_of_users > 0) return FALSE;
+	return TRUE;
+}
+
 static void
 add_user_other (GdmUserChooserWidget *widget)
 {
@@ -133,6 +177,7 @@
                                      0,
                                      FALSE,
                                      TRUE);
+	adjust_number_of_users(widget, +1);
 }
 
 static void
@@ -146,6 +191,7 @@
                                      0,
                                      FALSE,
                                      TRUE);
+	adjust_number_of_users(widget, +1);
 }
 
 static void
@@ -159,6 +205,7 @@
                                      0,
                                      FALSE,
                                      TRUE);
+	adjust_number_of_users(widget, +1);
 }
 
 static void
@@ -166,6 +213,7 @@
 {
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         GDM_USER_CHOOSER_USER_OTHER);
+	adjust_number_of_users(widget, -1);
 }
 
 static void
@@ -173,6 +221,7 @@
 {
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         GDM_USER_CHOOSER_USER_GUEST);
+	adjust_number_of_users(widget, -1);
 }
 
 static void
@@ -180,6 +229,7 @@
 {
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         GDM_USER_CHOOSER_USER_AUTO);
+	adjust_number_of_users(widget, -1);
 }
 
 void
@@ -369,6 +419,7 @@
         if (pixbuf != NULL) {
                 g_object_unref (pixbuf);
         }
+	adjust_number_of_users(widget, +1);
 }
 
 static void
@@ -400,6 +451,7 @@
 
         gdm_chooser_widget_remove_item (GDM_CHOOSER_WIDGET (widget),
                                         user_name);
+	adjust_number_of_users(widget, -1);
 }
 
 static void
@@ -444,8 +496,13 @@
 {
         GSList *users;
 
+/* Move below, after we have added the users to the
+ * chooser widget. 
+ 
         widget->priv->loaded = TRUE;
 
+*/
+
         g_debug ("GdmUserChooserWidget: Users loaded");
 
         users = gdm_user_manager_list_users (manager);
@@ -454,8 +511,7 @@
                 users = g_slist_delete_link (users, users);
         }
 
-        gtk_widget_grab_focus (GTK_WIDGET (widget));
-
+        widget->priv->loaded = TRUE;
         gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET (widget));
 }
 
@@ -505,6 +561,7 @@
                                                                                                               n_construct_properties,
                                                                                                               construct_properties));
 
+	widget->priv->number_of_users = 0;
         widget->priv->show_normal_users = !is_user_list_disabled (widget);
 
         widget->priv->load_idle_id = g_idle_add ((GSourceFunc)load_users, widget);
@@ -568,7 +625,9 @@
                                          g_param_spec_boolean ("show-user-other",
                                                                "show user other",
                                                                "show user other",
-                                                               TRUE,
+                                                               FALSE,   /* Start without an Other user, until a real user is added
+									   (when list is empty, manual entry will be used and Other
+									   is therefore not needed). */
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
         g_type_class_add_private (klass, sizeof (GdmUserChooserWidgetPrivate));
diff -ur gdm-2.25.2.orig/gui/simple-greeter/gdm-user-chooser-widget.h gdm-2.25.2/gui/simple-greeter/gdm-user-chooser-widget.h
--- gdm-2.25.2.orig/gui/simple-greeter/gdm-user-chooser-widget.h	2008-09-02 16:31:43.000000000 -0400
+++ gdm-2.25.2/gui/simple-greeter/gdm-user-chooser-widget.h	2009-01-12 16:42:01.000000000 -0500
@@ -65,6 +65,7 @@
                                                                            gboolean              show);
 void                   gdm_user_chooser_widget_set_show_user_auto         (GdmUserChooserWidget *widget,
                                                                            gboolean              show);
+gboolean	       gdm_user_chooser_widget_is_empty			  (GdmUserChooserWidget *widget);
 G_END_DECLS
 
 #endif /* __GDM_USER_CHOOSER_WIDGET_H */
