# Random Theme Mode
#
#This feature will add a choice for the graphical greeter.  It will allow
# the user to select any number of themes from the theme directory to be
# picked randomly for the greeter's theme.
#
# to patch:
#   place patch in parent directory of gdm2 directory and then run
#   patch -p0 < THIS_FILENAME
#
# Andrew Case
#   (acase@thoughtcatalyst.com)
# last modified 2005.04.28
#


diff -rup -x configure gdm2/daemon/gdm.h gdm2-patched/daemon/gdm.h
--- gdm2/daemon/gdm.h	2005-04-19 19:47:24.000000000 -0500
+++ gdm2-patched/daemon/gdm.h	2005-04-27 14:47:17.000000000 -0500
@@ -117,6 +117,10 @@ enum {
 #define GDM_INTERRUPT_THEME       'H'
 #define GDM_INTERRUPT_CANCEL      'X'
 
+/* List delimiter for config file lists */
+#define GDM_DELIMITER_MODULES ":"
+#define GDM_DELIMITER_THEMES "/:"
+
 /* The dreaded miscellaneous category */
 #define FIELD_SIZE 256
 #define PIPE_SIZE 4096
@@ -259,6 +263,8 @@ enum {
 #define GDM_KEY_ENTRY_CIRCLES "greeter/UseCirclesInEntry=false"
 #define GDM_KEY_ENTRY_INVISIBLE "greeter/UseInvisibleInEntry=false"
 #define GDM_KEY_GRAPHICAL_THEME "greeter/GraphicalTheme=circles"
+#define GDM_KEY_GRAPHICAL_THEMES "greeter/GraphicalThemes=circles"
+#define GDM_KEY_GRAPHICAL_THEME_RAND "greeter/GraphicalThemeRand=false"
 #define GDM_KEY_GRAPHICAL_THEME_DIR "greeter/GraphicalThemeDir=" EXPANDED_DATADIR "/gdm/themes/"
 
 #define GDM_KEY_INFO_MSG_FILE "greeter/InfoMsgFile="
diff -rup -x configure gdm2/docs/C/gdm.xml gdm2-patched/docs/C/gdm.xml
--- gdm2/docs/C/gdm.xml	2005-04-19 19:47:24.000000000 -0500
+++ gdm2-patched/docs/C/gdm.xml	2005-04-28 17:14:15.844903920 -0500
@@ -2384,6 +2384,35 @@ XKeepsCrashing
           </varlistentry>
 
           <varlistentry>
+            <term>GraphicalThemes</term>
+            <listitem>
+              <synopsis>GraphicalThemes=circles</synopsis>
+              <para>
+                The graphical themes that the Themed Greeter should use is the
+                Mode is set on Random Themes.  This is a "/:" delimited list.
+                It should refer to a directory in the theme directory set by
+                <filename>GraphicalThemeDir</filename>.  This is only used if
+				<filename>GraphicalThemeRand</filename> is set to true.
+              </para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>GraphicalThemeRand</term>
+            <listitem>
+              <synopsis>GraphicalThemeRand=false</synopsis>
+              <para>
+                Whether the graphical greeter will use Only One Theme or Random
+                Theme mode.  Only One Theme mode uses themes listed by
+                <filename>GraphicalTheme</filename>, Random Themes mode uses
+                themes listed by <filename>GraphicalThemes</filename>.  A value
+                of false sets greeter to use Only One Theme mode, a value of
+                true sets the greeter to use Random Theme mode.
+              </para>
+            </listitem>
+          </varlistentry>
+
+          <varlistentry>
             <term>GraphicalThemeDir</term>
             <listitem>
               <synopsis>GraphicalThemeDir=&lt;share&gt;/gdm/themes/</synopsis>
diff -rup -x configure gdm2/gui/gdmsetup.c gdm2-patched/gui/gdmsetup.c
--- gdm2/gui/gdmsetup.c	2005-04-20 13:08:34.000000000 -0500
+++ gdm2-patched/gui/gdmsetup.c	2005-04-28 14:28:39.064191712 -0500
@@ -51,6 +51,7 @@ static gboolean DOING_GDM_DEVELOPMENT = 
 
 static gboolean RUNNING_UNDER_GDM = FALSE;
 
+static gboolean GdmGraphicalThemeRand = FALSE;
 static gboolean gdm_running = FALSE;
 gint  GdmIconMaxHeight;
 gint  GdmIconMaxWidth;
@@ -61,11 +62,8 @@ gboolean GdmIncludeAll;
 gboolean GdmAllowRoot;
 gboolean GdmAllowRemoteRoot;
 static char *GdmSoundProgram = NULL;
-
 static GladeXML *xml;
-
 static GList *timeout_widgets = NULL;
-
 static gchar *last_theme_installed = NULL;
 static int last_remote_login_setting = -1;
 static gboolean have_sound_ready_file = FALSE;
@@ -74,6 +72,7 @@ static gboolean have_sound_failure_file 
 
 enum {
 	THEME_COLUMN_SELECTED,
+	THEME_COLUMN_SELECTED_LIST,
 	THEME_COLUMN_DIR,
 	THEME_COLUMN_FILE,
 	THEME_COLUMN_NAME,
@@ -89,7 +88,14 @@ enum {
     USERLIST_NUM_COLUMNS
 };
 
+enum {
+	ONE_THEME,
+	RANDOM_THEME
+};
+
+static char *selected_themes = NULL;
 static char *selected_theme = NULL;
+
 static void
 simple_spawn_sync (char **argv)
 {
@@ -277,7 +283,7 @@ toggle_timeout (GtkWidget *toggle)
 	if ( ! ve_bool_equal (val, GTK_TOGGLE_BUTTON (toggle)->active)) {
 		ve_config_set_bool (config, key,
 				    GTK_TOGGLE_BUTTON (toggle)->active);
-		ve_config_save (config, FALSE /*force */);
+		ve_config_save (config, FALSE /* force */);
 
 		update_key (notify_key);
 	}
@@ -338,16 +344,15 @@ static gboolean
 combobox_timeout (GtkWidget *combo_box)
 {
 	const char *key = g_object_get_data (G_OBJECT (combo_box), "key");
-	char *new_val = NULL;
-	gchar *val;
-	int selected;
+	int selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
 	VeConfig *config = ve_config_get (GDM_CONFIG_FILE);
 
-	selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
-
 	if (strcmp (key, GDM_KEY_REMOTEGREETER) == 0 ||
 	    strcmp (key, GDM_KEY_GREETER) == 0) {
 
+		char *new_val = NULL;
+		gchar *val;
+
 		if (strcmp (key, GDM_KEY_REMOTEGREETER) == 0 &&
 		    selected == 2) {
 
@@ -359,15 +364,32 @@ combobox_timeout (GtkWidget *combo_box)
 		}
 
 		else if (selected == 0) {
+			/* GTK+ Greeter */
 			new_val = g_strdup (EXPANDED_LIBEXECDIR "/gdmlogin");
 			last_remote_login_setting = 0;
 		} else if (selected == 1) {
+			/* Themed Greeter */
 			new_val = g_strdup (EXPANDED_LIBEXECDIR "/gdmgreeter");
 			last_remote_login_setting = 1;
 		}
+
+		val = ve_config_get_string (config, key);
+
+		if (new_val &&
+		    strcmp (ve_sure_string (val), ve_sure_string (new_val)) != 0) {
+
+			ve_config_set_string (config, key, new_val);
+			ve_config_save (config, FALSE /* force */);
+			update_key (key);
+		}
+		g_free (new_val);
+
 	} else if (strcmp (key, GDM_KEY_AUTOMATICLOGIN) == 0 ||
 		   strcmp (key, GDM_KEY_TIMED_LOGIN) == 0) {
 
+		char *new_val = NULL;
+		gchar *val;
+
 		GtkTreeIter iter;
 		
 		if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), 
@@ -376,18 +398,49 @@ combobox_timeout (GtkWidget *combo_box)
 				GTK_COMBO_BOX (combo_box)), &iter,
 				0, &new_val, -1);
 		}
-	}
 
-	val = ve_config_get_string (config, key);
+		val = ve_config_get_string (config, key);
 
-	if (new_val && strcmp (ve_sure_string (val), ve_sure_string (new_val)) != 0) {
-		ve_config_set_string (config, key, new_val);
-		ve_config_save (config, FALSE /* force */);
+		if (new_val &&
+		    strcmp (ve_sure_string (val), ve_sure_string (new_val)) != 0) {
 
-		update_key (key);
+			ve_config_set_string (config, key, new_val);
+			ve_config_save (config, FALSE /* force */);
+			update_key (key);
+		}
+		g_free (new_val);
+
+	} else if (strcmp (key, GDM_KEY_GRAPHICAL_THEME_RAND) == 0 ) {
+		gboolean new_val = NULL;
+		GtkTreeViewColumn *radioColumn = NULL;
+		GtkTreeViewColumn *checkboxColumn = NULL;
+		gboolean val = ve_config_get_bool (config, key);
+		GtkWidget *theme_list = glade_helper_get (xml, "gg_theme_list",
+		                                         GTK_TYPE_TREE_VIEW);
+
+		/* Choose to display radio or checkbox toggle column */		
+		if (selected == RANDOM_THEME) {
+			new_val = TRUE;
+			radioColumn = gtk_tree_view_get_column (theme_list,ONE_THEME);
+			checkboxColumn = gtk_tree_view_get_column (theme_list,RANDOM_THEME);
+			gtk_tree_view_column_set_visible(radioColumn, FALSE);
+			gtk_tree_view_column_set_visible(checkboxColumn, TRUE);
+		} else { /* Default to one theme */
+			new_val = FALSE;
+			radioColumn = gtk_tree_view_get_column (theme_list,ONE_THEME);
+			checkboxColumn = gtk_tree_view_get_column (theme_list,RANDOM_THEME);
+			gtk_tree_view_column_set_visible(radioColumn, TRUE);
+			gtk_tree_view_column_set_visible(checkboxColumn, FALSE);
+		}
+
+		if (new_val != val)
+		{
+			ve_config_set_bool (config, key,new_val);
+			ve_config_save (config, FALSE /* force */);
+			update_key (key);
+		}
 	}
 
-	g_free (new_val);
 	return FALSE;
 }
 
@@ -629,13 +682,14 @@ check_exclude (struct passwd *pwent, cha
 	return FALSE;
 }
 
+/* Sets up Automatic Login and Timed Login user entry comboboxes from the 
+   general configuration tab. */
 static void
 setup_user_combobox (const char *name, const char *key)
 {
 	GtkWidget *combobox_entry = glade_helper_get (xml, name, GTK_TYPE_COMBO_BOX_ENTRY);
 	GtkListStore *combobox_store = gtk_list_store_new (USERLIST_NUM_COLUMNS,
 		G_TYPE_STRING);
-	GtkTreeModel *tree_model;
 	GtkTreeIter iter;
 	GList *users = NULL;
 	GList *users_string = NULL;
@@ -666,7 +720,7 @@ setup_user_combobox (const char *name, c
 	users_string = g_list_reverse (users_string);
 
 	cnt=0;
-        for (li = users_string; li != NULL; li = li->next) {
+	for (li = users_string; li != NULL; li = li->next) {
 		gtk_list_store_append (combobox_store, &iter);
 		if (strcmp (li->data, selected_user) == 0)
 			selected=cnt;
@@ -680,9 +734,9 @@ setup_user_combobox (const char *name, c
 	if (selected != -1)
 		gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_entry), selected);
 
-        g_object_set_data_full (G_OBJECT (combobox_entry),
-                                "key", g_strdup (key),
-                                (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (combobox_entry),
+	                        "key", g_strdup (key),
+	                        (GDestroyNotify) g_free);
 	g_signal_connect (G_OBJECT (combobox_entry), "changed",
 			  G_CALLBACK (combobox_changed), NULL);
 	g_signal_connect (G_OBJECT (combobox_entry), "changed",
@@ -727,9 +781,8 @@ setup_include_exclude (GtkWidget *treevi
 	GtkTreeIter iter;
 	GtkTreeViewColumn *column;
 	GtkCellRenderer *renderer;
-        char **list;
-	char *val;
-        int i;
+	char **list;
+	int i;
 
 	column = gtk_tree_view_column_new ();
 
@@ -797,7 +850,6 @@ face_add (GtkWidget *button, gpointer da
 	FaceData *fd = data;
 	const char *text, *model_text;
 	GtkTreeIter iter;
-	GtkWidget *message;
 	gboolean valid;
 
 	if (fd->type == INCLUDE)
@@ -1217,7 +1269,7 @@ setup_greeter_toggle (const char *name,
 		}
 
 		g_signal_connect (G_OBJECT (toggle), "toggled",	
-			G_CALLBACK (sensitive_entry_toggled), remotewelcome);
+		                  G_CALLBACK (sensitive_entry_toggled), remotewelcome);
 	}
 
 	g_signal_connect (G_OBJECT (toggle), "toggled",
@@ -1595,14 +1647,14 @@ setup_greeter_backselect (void)
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (color_bg), TRUE);
 
 	g_signal_connect (G_OBJECT (no_bg), "toggled",
-			  G_CALLBACK (greeter_backselect_toggled), NULL);
+	                  G_CALLBACK (greeter_backselect_toggled), NULL);
 	g_signal_connect (G_OBJECT (image_bg), "toggled",
-			  G_CALLBACK (greeter_backselect_toggled), NULL);
+	                  G_CALLBACK (greeter_backselect_toggled), NULL);
 	g_signal_connect (G_OBJECT (color_bg), "toggled",
-			  G_CALLBACK (greeter_backselect_toggled), NULL);
+	                  G_CALLBACK (greeter_backselect_toggled), NULL);
 }
 
-
+/* Local and Remote greeter comboboxes from General configuration tab */
 static void
 setup_greeter_combobox (const char *name,
 		      const char *key)
@@ -1638,11 +1690,11 @@ setup_greeter_combobox (const char *name
 		
 	g_free (val);
 
-        g_object_set_data_full (G_OBJECT (combobox),
-                                "key", g_strdup (key),
-                                (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (combobox),
+	                        "key", g_strdup (key),
+	                        (GDestroyNotify) g_free);
 	g_signal_connect (G_OBJECT (combobox), "changed",
-		  G_CALLBACK (combobox_changed), NULL);
+	                  G_CALLBACK (combobox_changed), NULL);
 }
 
 static void
@@ -1738,6 +1790,30 @@ modules_list_contains (const char *modul
 	return FALSE;
 }
 
+static gboolean
+themes_list_contains (const char *themes_list, const char *theme)
+{
+	char **vec;
+	int i;
+
+	if (ve_string_empty (themes_list))
+		return FALSE;
+
+	vec = g_strsplit (themes_list, GDM_DELIMITER_THEMES, -1);
+	if (vec == NULL)
+		return FALSE;
+
+	for (i = 0; vec[i] != NULL; i++) {
+		if (strcmp (vec[i], theme) == 0) {
+			g_strfreev (vec);
+			return TRUE;
+		}
+	}
+
+	g_strfreev (vec);
+	return FALSE;
+}
+
 static char *
 modules_list_remove (char *modules_list, const char *module)
 {
@@ -1768,15 +1844,18 @@ modules_list_remove (char *modules_list,
 	return g_string_free (str, FALSE);
 }
 
+/* This function concatenates *string to *strings_list with the addition of
+   *sep inbetween the strings_list and string, then returns
+   a copy of the new strings_list. */
 static char *
-modules_list_add (char *modules_list, const char *module)
+strings_list_add (char *strings_list, const char *string, const char *sep)
 {
 	char *n;
-	if (ve_string_empty (modules_list))
-		n = g_strdup (module);
+	if (ve_string_empty (strings_list))
+		n = g_strdup (string);
 	else
-		n = g_strconcat (modules_list, ":", module, NULL);
-	g_free (modules_list);
+		n = g_strconcat (strings_list, sep, string, NULL);
+	g_free (strings_list);
 	return n;
 }
 
@@ -1800,10 +1879,15 @@ acc_modules_toggled (GtkWidget *toggle, 
 			modules_list = NULL;
 		}
 
-		modules_list = modules_list_add (modules_list, "gail");
-		modules_list = modules_list_add (modules_list, "atk-bridge");
-		modules_list = modules_list_add (modules_list, EXPANDED_LIBDIR "/gtk-2.0/modules/libkeymouselistener");
-		modules_list = modules_list_add (modules_list, EXPANDED_LIBDIR "/gtk-2.0/modules/libdwellmouselistener");
+		modules_list = strings_list_add (modules_list, "gail",
+		               GDM_DELIMITER_MODULES);
+		modules_list = strings_list_add (modules_list, "atk-bridge",
+		               GDM_DELIMITER_MODULES);
+		modules_list = strings_list_add (modules_list,
+		               EXPANDED_LIBDIR "/gtk-2.0/modules/libkeymouselistener",
+		               GDM_DELIMITER_MODULES);
+		modules_list = strings_list_add (modules_list,
+                       EXPANDED_LIBDIR "/gtk-2.0/modules/libdwellmouselistener",		               GDM_DELIMITER_MODULES);
 
 		add_gtk_modules = TRUE;
 	}
@@ -2241,17 +2325,19 @@ textview_set_buffer (GtkTextView *view, 
 	gtk_text_buffer_set_text (buffer, text, -1);
 }
 
+/* Sets up the preview section of Themed Greeter page
+   after a theme has been selected */
 static void
-selection_changed (GtkTreeSelection *selection, gpointer data)
+gg_selection_changed (GtkTreeSelection *selection, gpointer data)
 {
-        GtkWidget *label;
-        GtkWidget *preview = glade_helper_get (xml, "gg_theme_preview",
-					       GTK_TYPE_IMAGE);
-        GtkWidget *no_preview = glade_helper_get (xml, "gg_theme_no_preview",
-						  GTK_TYPE_WIDGET);
+	GtkWidget *label;
+	GtkWidget *preview = glade_helper_get (xml, "gg_theme_preview",
+	                                       GTK_TYPE_IMAGE);
+	GtkWidget *no_preview = glade_helper_get (xml, "gg_theme_no_preview",
+	                                          GTK_TYPE_WIDGET);
 	GtkWidget *del_button = glade_helper_get (xml, "gg_delete_theme",
-						  GTK_TYPE_BUTTON);
-        char *screenshot;
+	                                          GTK_TYPE_BUTTON);
+	char *screenshot;
 	GtkTreeModel *model;
 	GtkTreeIter iter;
 	GValue value = {0, };
@@ -2263,10 +2349,9 @@ selection_changed (GtkTreeSelection *sel
 
 	gtk_widget_set_sensitive (del_button, TRUE);
 
-	gtk_tree_model_get_value (model, &iter,
-				  THEME_COLUMN_SELECTED,
-				  &value);
-	/* Do not allow deleting of selected theme */
+	gtk_tree_model_get_value (model, &iter, THEME_COLUMN_SELECTED, &value);
+
+	/* Do not allow deleting of radio selected theme */
 	if (g_value_get_boolean (&value)) {
 		gtk_widget_set_sensitive (del_button, FALSE);
 	}
@@ -2275,7 +2360,7 @@ selection_changed (GtkTreeSelection *sel
 	gtk_tree_model_get_value (model, &iter,
 				  THEME_COLUMN_AUTHOR,
 				  &value);
-        label = glade_helper_get (xml, "gg_author_text_view",
+	label = glade_helper_get (xml, "gg_author_text_view",
 				  GTK_TYPE_TEXT_VIEW);
 	textview_set_buffer (GTK_TEXT_VIEW (label),
 			     ve_sure_string (g_value_get_string (&value)));
@@ -2284,7 +2369,7 @@ selection_changed (GtkTreeSelection *sel
 	gtk_tree_model_get_value (model, &iter,
 				  THEME_COLUMN_COPYRIGHT,
 				  &value);
-        label = glade_helper_get (xml, "gg_copyright_text_view",
+	label = glade_helper_get (xml, "gg_copyright_text_view",
 				  GTK_TYPE_TEXT_VIEW);
 	textview_set_buffer (GTK_TEXT_VIEW (label),
 			    ve_sure_string (g_value_get_string (&value)));
@@ -2293,7 +2378,7 @@ selection_changed (GtkTreeSelection *sel
 	gtk_tree_model_get_value (model, &iter,
 				  THEME_COLUMN_DESCRIPTION,
 				  &value);
-        label = glade_helper_get (xml, "gg_desc_text_view",
+	label = glade_helper_get (xml, "gg_desc_text_view",
 				  GTK_TYPE_TEXT_VIEW);
 	textview_set_buffer (GTK_TEXT_VIEW (label),
 			    ve_sure_string (g_value_get_string (&value)));
@@ -2345,7 +2430,8 @@ read_themes (GtkListStore *store, const 
 		char *n, *file, *name, *desc, *author, *copyright, *ss;
 		char *full;
 		GtkTreeIter iter;
-		gboolean sel;
+		gboolean sel_theme;
+		gboolean sel_themes;
 		VeConfig *theme_file;
 		if (dent->d_name[0] == '.')
 			continue;
@@ -2379,11 +2465,19 @@ read_themes (GtkListStore *store, const 
 			continue;
 		}
 		g_free (full);
+
 		if (selected_theme != NULL &&
 		    strcmp (dent->d_name, selected_theme) == 0)
-			sel = TRUE;
+			sel_theme = TRUE;
+		else
+			sel_theme = FALSE;
+
+
+		if (selected_themes != NULL &&
+			themes_list_contains (selected_themes, dent->d_name))
+			sel_themes = TRUE;
 		else
-			sel = FALSE;
+			sel_themes = FALSE;
 
 		name = ve_config_get_translated_string
 			(theme_file, "GdmGreeterTheme/Name");
@@ -2410,7 +2504,8 @@ read_themes (GtkListStore *store, const 
 
 		gtk_list_store_append (store, &iter);
 		gtk_list_store_set (store, &iter,
-				    THEME_COLUMN_SELECTED, sel,
+				    THEME_COLUMN_SELECTED, sel_theme,
+				    THEME_COLUMN_SELECTED_LIST, sel_themes,
 				    THEME_COLUMN_DIR, dent->d_name,
 				    THEME_COLUMN_FILE, file,
 				    THEME_COLUMN_NAME, name,
@@ -2443,21 +2538,34 @@ read_themes (GtkListStore *store, const 
 static gboolean
 greeter_theme_timeout (GtkWidget *toggle)
 {
-	char *val;
+	char *theme;
+	char *themes;
 	VeConfig *config = ve_config_get (GDM_CONFIG_FILE);
 
-	val = ve_config_get_string (config, GDM_KEY_GRAPHICAL_THEME);
+	/* Selected themes according to config file */
+	theme = ve_config_get_string (config, GDM_KEY_GRAPHICAL_THEME);
+	themes = ve_config_get_string (config, GDM_KEY_GRAPHICAL_THEMES);
+
+	/* If no checkbox themes selected */
+	if (selected_themes == NULL)
+		selected_themes = "";
+
+	/* If themes have changed from the config file, update it. */
+	if ((strcmp (ve_sure_string (theme),
+	             ve_sure_string (selected_theme)) != 0) ||
+	    (strcmp (ve_sure_string (themes),
+	             ve_sure_string (selected_themes)) != 0))	{
 
-	if (strcmp (ve_sure_string (val),
-		    ve_sure_string (selected_theme)) != 0) {
 		ve_config_set_string (config, GDM_KEY_GRAPHICAL_THEME,
-				      selected_theme);
+		                      selected_theme);
+		ve_config_set_string (config, GDM_KEY_GRAPHICAL_THEMES,
+		                      selected_themes);
 		ve_config_save (config, FALSE /* force */);
-
 		update_greeters ();
 	}
 
-	g_free (val);
+	g_free (theme);
+	g_free (themes);
 
 	return FALSE;
 }
@@ -2467,39 +2575,90 @@ selected_toggled (GtkCellRendererToggle 
 		  char                  *path_str,
 		  gpointer               data)
 {
+	gchar *theme_name = NULL;
 	GtkTreeModel *model = GTK_TREE_MODEL (data);
 	GtkTreeIter selected_iter;
 	GtkTreeIter iter;
+	GtkTreePath *path;
 	GtkTreePath *sel_path = gtk_tree_path_new_from_string (path_str);
 	GtkWidget *theme_list = glade_helper_get (xml, "gg_theme_list",
-						  GTK_TYPE_TREE_VIEW);
-	GtkTreePath *path;
-
+	                                          GTK_TYPE_TREE_VIEW);
 	gtk_tree_model_get_iter (model, &selected_iter, sel_path);
+	path = gtk_tree_path_new_first ();
+	gboolean is_radio = gtk_cell_renderer_toggle_get_radio(cell);
 
-	g_free (selected_theme);
-	gtk_tree_model_get (model, &selected_iter,
-			    THEME_COLUMN_DIR, &selected_theme,
-			    -1);
+	if (is_radio) { /* Radiobuttons */
 
-	path = gtk_tree_path_new_first ();
-	while (gtk_tree_model_get_iter (model, &iter, path)) {
+		/* Clear list of all selected themes */
+	    g_free (selected_theme);
 
-		if (gtk_tree_path_compare (path, sel_path) == 0) {
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    THEME_COLUMN_SELECTED, TRUE,
-					    -1);
-		} else {
-			gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-					    THEME_COLUMN_SELECTED, FALSE,
-					    -1);
-		}
+		/* Get the new selected theme */
+    	gtk_tree_model_get (model, &selected_iter,
+		                    THEME_COLUMN_DIR, &selected_theme, -1);
+
+
+	    /* Loop through all themes in list */
+    	while (gtk_tree_model_get_iter (model, &iter, path)) {
+        	/* If this toggle was just toggled */
+	        if (gtk_tree_path_compare (path, sel_path) == 0) {
+    	        gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+				                    THEME_COLUMN_SELECTED, TRUE,
+				                    -1); /* Toggle ON */
+    	    } else {
+        	    gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+				                    THEME_COLUMN_SELECTED, FALSE,
+				                    -1); /* Toggle OFF */
+        	}
+
+	        gtk_tree_path_next (path);
+    	}
+
+	} else { /* Checkboxes */
+
+	    /* Clear list of all selected themes */
+    	g_free(selected_themes);
+	    selected_themes = NULL;
+
+    	/* Loop through all checkboxes */
+	    while (gtk_tree_model_get_iter (model, &iter, path)) {
+
+        	/* If this checkbox was just toggled */
+    	    if (gtk_tree_path_compare (path, sel_path) == 0) {
+
+	            gtk_tree_model_get (model, &selected_iter,
+        	                        THEME_COLUMN_DIR, &theme_name, -1);
+    	        if (gtk_cell_renderer_toggle_get_active (cell)) {
+	                gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+        	                            THEME_COLUMN_SELECTED_LIST,
+    	                                FALSE,-1); /* Toggle OFF */
+	            } else {
+        	        gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+    	                                THEME_COLUMN_SELECTED_LIST,
+	                                    TRUE,-1); /* Toggle ON */
+    	        }
+
+	        }
+
+	        gboolean selected = FALSE;
+        	gtk_tree_model_get (model, &iter, THEME_COLUMN_SELECTED_LIST,
+    	                        &selected, THEME_COLUMN_DIR, &theme_name, -1);
+
+	        if (selected) selected_themes = strings_list_add (selected_themes,
+			                                theme_name,
+			                                GDM_DELIMITER_THEMES);
+
+	        g_free(theme_name);
+    	    gtk_tree_path_next (path);
+
+	    }
+
+	    if (selected_themes == NULL)
+    	    selected_themes = g_strdup("");
 
-		gtk_tree_path_next (path);
 	}
 
-	gtk_tree_path_free (path);
-	gtk_tree_path_free (sel_path);
+    gtk_tree_path_free (path);
+    gtk_tree_path_free (sel_path);
 
 	run_timeout (theme_list, 500, greeter_theme_timeout);
 }
@@ -3163,6 +3322,8 @@ setup_graphical_themes (void)
 					      GTK_TYPE_BUTTON);
 	GtkWidget *del_button = glade_helper_get (xml, "gg_delete_theme",
 						  GTK_TYPE_BUTTON);
+	GtkWidget *mode_combobox = glade_helper_get (xml, "gg_mode_combobox",
+						  GTK_TYPE_COMBO_BOX);
 
 	char *theme_dir = get_theme_dir ();
 
@@ -3170,10 +3331,24 @@ setup_graphical_themes (void)
 
 	selected_theme = ve_config_get_string (ve_config_get (GDM_CONFIG_FILE),
 					       GDM_KEY_GRAPHICAL_THEME);
+	selected_themes = ve_config_get_string (ve_config_get (GDM_CONFIG_FILE),
+					       GDM_KEY_GRAPHICAL_THEMES);
+
+	/* FIXME: If a theme directory contains the string GDM_DELIMITER_THEMES
+	          in the name, then this theme won't work when trying to load as it
+ 	          will be perceived as two different themes seperated by
+	          GDM_DELIMITER_THEMES.  This can be fixed by setting up an escape
+	          character for it, but I'm not sure if directories can have the
+	          slash (/) character in them, so I just made GDM_DELIMITER_THEMES
+	          equal to "/:" instead. */
+    GdmGraphicalThemeRand = ve_config_get_bool (
+	                        ve_config_get (GDM_CONFIG_FILE),
+	                        GDM_KEY_GRAPHICAL_THEME_RAND);
 
 	/* create list store */
 	store = gtk_list_store_new (THEME_NUM_COLUMNS,
-				    G_TYPE_BOOLEAN /* selected */,
+				    G_TYPE_BOOLEAN /* selected theme */,
+				    G_TYPE_BOOLEAN /* selected themes */,
 				    G_TYPE_STRING /* dir */,
 				    G_TYPE_STRING /* file */,
 				    G_TYPE_STRING /* name */,
@@ -3182,67 +3357,80 @@ setup_graphical_themes (void)
 				    G_TYPE_STRING /* copyright */,
 				    G_TYPE_STRING /* screenshot */);
 
+	/* Mode */
+	g_object_set_data_full (G_OBJECT (mode_combobox), "key",
+	                        g_strdup (GDM_KEY_GRAPHICAL_THEME_RAND),
+	                        (GDestroyNotify) g_free);
+
+	/* Signals */
+	g_signal_connect (mode_combobox, "changed",
+			  G_CALLBACK (combobox_changed), NULL);
 	g_signal_connect (button, "clicked",
 			  G_CALLBACK (install_new_theme), store);
 	g_signal_connect (del_button, "clicked",
 			  G_CALLBACK (delete_theme), store);
+
+	/* Init controls */
 	gtk_widget_set_sensitive (del_button, FALSE);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (mode_combobox),
+			GdmGraphicalThemeRand);
 
+	/* Read all Themes from directory and store in tree*/
 	dir = opendir (theme_dir);
-
 	if (dir != NULL) {
 		select_iter = read_themes (store, theme_dir, dir,
-					   selected_theme);
+		                           selected_theme);
 		closedir (dir);
 	}
-
 	g_free (theme_dir);
-
 	gtk_tree_view_set_model (GTK_TREE_VIEW (theme_list), 
 				 GTK_TREE_MODEL (store));
 
-	/* The toggle column */
-
+	
+	/* The radio toggle column */
 	column = gtk_tree_view_column_new ();
-
 	renderer = gtk_cell_renderer_toggle_new ();
 	gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer),
-					    TRUE);
-        gtk_tree_view_column_pack_start (column, renderer, FALSE);
-
-        gtk_tree_view_column_set_attributes (column, renderer,
-                                             "active", THEME_COLUMN_SELECTED,
-                                             NULL);
-
+	                                    TRUE);
 	g_signal_connect (G_OBJECT (renderer), "toggled",
-			  G_CALLBACK (selected_toggled), store);
+	                  G_CALLBACK (selected_toggled), store);
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_set_attributes (column, renderer,
+	                                     "active", THEME_COLUMN_SELECTED,
+	                                     NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (theme_list), column);
+	gtk_tree_view_column_set_visible(column, !GdmGraphicalThemeRand);
 
+	/* The checkbox toggle column */
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_toggle_new ();
+	gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (renderer),
+	                                    FALSE);
+	g_signal_connect (G_OBJECT (renderer), "toggled",
+	                  G_CALLBACK (selected_toggled), store);
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_set_attributes (column, renderer, "active",
+	                                     THEME_COLUMN_SELECTED_LIST,
+	                                     NULL);
 	gtk_tree_view_append_column (GTK_TREE_VIEW (theme_list), column);
+	gtk_tree_view_column_set_visible(column, GdmGraphicalThemeRand);
 
 	/* The text column */
-
 	column = gtk_tree_view_column_new ();
-
-
 	renderer = gtk_cell_renderer_text_new ();
-        gtk_tree_view_column_pack_start (column, renderer, TRUE);
-
-        gtk_tree_view_column_set_attributes (column, renderer,
-                                             "text", THEME_COLUMN_NAME,
-                                             NULL);
-
+	gtk_tree_view_column_pack_start (column, renderer, TRUE);
+	gtk_tree_view_column_set_attributes (column, renderer,
+	                                     "text", THEME_COLUMN_NAME,
+	                                     NULL);
 	gtk_tree_view_append_column (GTK_TREE_VIEW (theme_list), column);
 
-	/* Selection setup */
 
+	/* Selection setup */
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (theme_list));
-
 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
-
-        g_signal_connect (selection, "changed",
-			  G_CALLBACK (selection_changed),
-			  NULL);
-
+	g_signal_connect (selection, "changed",
+	                  G_CALLBACK (gg_selection_changed),
+	                  NULL);
 	if (select_iter != NULL) {
 		gtk_tree_selection_select_iter (selection, select_iter);
 		g_free (select_iter);
@@ -3349,17 +3537,13 @@ setup_gui (void)
 	glade_helper_tagify_label (xml, "greeter_cat_label", "b");
 	glade_helper_tagify_label (xml, "autologin_cat_label", "b");
 	glade_helper_tagify_label (xml, "timedlogin_cat_label", "b");
-
 	glade_helper_tagify_label (xml, "sg_logo_cat_label", "b");
 	glade_helper_tagify_label (xml, "sg_background_cat_label", "b");
-
 	glade_helper_tagify_label (xml, "options_cat_label", "b");
-
 	glade_helper_tagify_label (xml, "gg_preview_cat_label", "b");
 	glade_helper_tagify_label (xml, "gg_author_label", "b");
 	glade_helper_tagify_label (xml, "gg_desc_label", "b");
 	glade_helper_tagify_label (xml, "gg_copyright_label", "b");
-
 	glade_helper_tagify_label (xml, "acc_options_cat_label", "b");
 
 	setup_accessibility_support ();
@@ -3368,7 +3552,7 @@ setup_gui (void)
 	setup_greeter_backselect ();
 	setup_graphical_themes ();
 
-       	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 	add_to_size_group (sg, "local_greeter");
 	add_to_size_group (sg, "remote_greeter");
 	add_to_size_group (sg, "welcome");
@@ -3378,7 +3562,7 @@ setup_gui (void)
 	add_to_size_group (sg, "timedlogin_seconds");
 	g_object_unref (G_OBJECT (sg));
 
-       	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 	add_to_size_group (sg, "local_greeter_label");
 	add_to_size_group (sg, "remote_greeter_label");
 	add_to_size_group (sg, "welcome_label");
@@ -3388,13 +3572,13 @@ setup_gui (void)
 	add_to_size_group (sg, "timedlogin_seconds_label");
 	g_object_unref (G_OBJECT (sg));
 
-       	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 	add_to_size_group (sg, "greeter_table");
 	add_to_size_group (sg, "autologin_table");
 	add_to_size_group (sg, "timed_login_table");
 	g_object_unref (G_OBJECT (sg));
 
-       	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+	sg = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 	add_to_size_group (sg, "sg_use_24_clock");
 	add_to_size_group (sg, "autologin");
 	add_to_size_group (sg, "timedlogin");
@@ -3419,6 +3603,7 @@ setup_gui (void)
 			     GDM_KEY_TIMED_LOGIN_ENABLE,
 			     GDM_KEY_TIMED_LOGIN_ENABLE /* notify_key */);
 
+	/* Security */
 	setup_notify_toggle ("allowroot",
 			     GDM_KEY_ALLOWROOT,
 			     GDM_KEY_ALLOWROOT /* notify_key */);
@@ -3441,6 +3626,7 @@ setup_gui (void)
 			     GDM_KEY_DISALLOWTCP,
 			     GDM_KEY_DISALLOWTCP /* notify_key */);
 
+	/* General */
 	GdmDefaultWelcome = g_strdup (_(GDM_DEFAULT_WELCOME_MSG));
 	GdmDefaultRemoteWelcome = g_strdup (_(GDM_DEFAULT_REMOTEWELCOME_MSG));
 
@@ -3467,11 +3653,9 @@ setup_gui (void)
 	setup_intspin ("retry_delay",
 		       GDM_KEY_RETRYDELAY,
 		       GDM_KEY_RETRYDELAY /* notify_key */);
-
 	setup_intspin ("udpport",
 		       GDM_KEY_UDPPORT,
 		       GDM_KEY_UDPPORT /* notify_key */);
-
 	setup_intspin ("maxpending",
 		       GDM_KEY_MAXPEND,
 		       "xdmcp/PARAMETERS" /* notify_key */);
@@ -3494,6 +3678,7 @@ setup_gui (void)
 		       GDM_KEY_PINGINTERVAL,
 		       "xdmcp/PARAMETERS" /* notify_key */);
 
+	/* General */
 	setup_greeter_combobox ("local_greeter", GDM_KEY_GREETER);
 	setup_greeter_combobox ("remote_greeter", GDM_KEY_REMOTEGREETER);
 
diff -rup -x configure gdm2/gui/greeter/greeter.c gdm2-patched/gui/greeter/greeter.c
--- gdm2/gui/greeter/greeter.c	2005-04-18 21:57:56.000000000 -0500
+++ gdm2-patched/gui/greeter/greeter.c	2005-04-27 15:58:46.000000000 -0500
@@ -60,7 +60,9 @@ GtkWidget *canvas;
 
 gboolean GDM_IS_LOCAL = FALSE;
 char *GdmGraphicalTheme = NULL;
+char *GdmGraphicalThemes = NULL;
 char *GdmGraphicalThemeDir = NULL;
+gboolean GdmGraphicalThemeRand = FALSE;
 int GdmXineramaScreen = 0;
 gboolean GdmShowGnomeFailsafeSession = FALSE;
 gboolean GdmShowXtermFailsafeSession = FALSE;
@@ -145,13 +147,21 @@ greeter_parse_config (void)
 
     config = ve_config_get (GDM_CONFIG_FILE);
 
-    GdmGraphicalTheme = ve_config_get_string (config, GDM_KEY_GRAPHICAL_THEME);
-    if (GdmGraphicalTheme == NULL ||
-	GdmGraphicalTheme[0] == '\0')
-      {
-	g_free (GdmGraphicalTheme);
-	GdmGraphicalTheme = g_strdup ("circles");
-      }
+	GdmGraphicalThemeRand = ve_config_get_bool (config,
+	                                            GDM_KEY_GRAPHICAL_THEME_RAND);
+
+	if (GdmGraphicalThemeRand)
+		GdmGraphicalTheme = get_random_theme(); 
+	else
+		GdmGraphicalTheme = ve_config_get_string (config,
+		                                          GDM_KEY_GRAPHICAL_THEME);
+
+	if (GdmGraphicalTheme == NULL || GdmGraphicalTheme[0] == '\0')
+	{
+		g_free (GdmGraphicalTheme);
+		GdmGraphicalTheme = g_strdup ("circles");
+	}
+
 
     GdmGraphicalThemeDir = ve_config_get_string (config, GDM_KEY_GRAPHICAL_THEME_DIR);
     if (GdmGraphicalThemeDir == NULL ||
@@ -1038,6 +1048,38 @@ get_theme_file (const char *in, char **t
   return file;
 }
 
+/* If in random theme mode then grab a random theme from those selected */
+static char *
+get_random_theme ()
+{
+    char **vec;
+	char *themes_list;
+	char *theme;
+    int size;
+	int i;
+
+    VeConfig *config = ve_config_get (GDM_CONFIG_FILE);
+	themes_list = ve_config_get_string (config, GDM_KEY_GRAPHICAL_THEMES);
+
+    if (ve_string_empty (themes_list))
+        return NULL;
+
+    vec = g_strsplit (themes_list, GDM_DELIMITER_THEMES, -1);
+    if (vec == NULL)
+        return NULL;
+
+	/* Get Number of elements in vector */
+    for (size = 0; vec[size] != NULL; size++) {}
+
+	/* Get Random Theme from list */
+	srand ( time(NULL) );
+	i = rand() % size;
+	theme = g_strdup (vec[i]);
+    g_strfreev (vec);
+
+    return theme;
+}
+
 /* Not to look too shaby on Xinerama setups */
 static void
 setup_background_color (void)
--- gdm2/gui/gdmsetup.glade	2005-04-19 19:47:24.000000000 -0500
+++ gdm2-patched/gui/gdmsetup.glade	2005-04-28 17:54:54.578293352 -0500
@@ -258,7 +258,7 @@
 			      <property name="max_length">0</property>
 			      <property name="text" translatable="yes"></property>
 			      <property name="has_frame">True</property>
-			      <property name="invisible_char" translatable="yes">*</property>
+			      <property name="invisible_char">*</property>
 			      <property name="activates_default">False</property>
 			      <accessibility>
 				<atkrelation target="welcome_label" type="labelled-by"/>
@@ -284,7 +284,7 @@
 			      <property name="max_length">0</property>
 			      <property name="text" translatable="yes"></property>
 			      <property name="has_frame">True</property>
-			      <property name="invisible_char" translatable="yes">*</property>
+			      <property name="invisible_char">*</property>
 			      <property name="activates_default">False</property>
 			      <accessibility>
 				<atkrelation target="remote_welcome_label" type="labelled-by"/>
@@ -1386,23 +1386,83 @@ Disabled</property>
 	      <property name="spacing">8</property>
 
 	      <child>
-		<widget class="GtkScrolledWindow" id="scrolledwindow1">
+		<widget class="GtkVBox" id="vbox29">
 		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">8</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox33">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">10</property>
+
+		      <child>
+			<widget class="GtkLabel" id="gg_mode_label">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">_Mode:</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkComboBox" id="gg_mode_combobox">
+			  <property name="visible">True</property>
+			  <property name="items" translatable="yes">Only One Theme
+Random Theme</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
 
 		  <child>
-		    <widget class="GtkTreeView" id="gg_theme_list">
+		    <widget class="GtkScrolledWindow" id="scrolledwindow1">
 		      <property name="visible">True</property>
 		      <property name="can_focus">True</property>
-		      <property name="headers_visible">False</property>
-		      <property name="rules_hint">False</property>
-		      <property name="reorderable">False</property>
-		      <property name="enable_search">False</property>
+		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		      <property name="shadow_type">GTK_SHADOW_IN</property>
+		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		      <child>
+			<widget class="GtkTreeView" id="gg_theme_list">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="headers_visible">False</property>
+			  <property name="rules_hint">False</property>
+			  <property name="reorderable">False</property>
+			  <property name="enable_search">False</property>
+			</widget>
+		      </child>
 		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
 		  </child>
 		</widget>
 		<packing>
@@ -1904,7 +1964,7 @@ widget</property>
 			      <property name="max_length">0</property>
 			      <property name="text" translatable="yes"></property>
 			      <property name="has_frame">True</property>
-			      <property name="invisible_char" translatable="yes">*</property>
+			      <property name="invisible_char">*</property>
 			      <property name="activates_default">False</property>
 			    </widget>
 			    <packing>
@@ -2095,7 +2155,7 @@ widget</property>
 			      <property name="max_length">0</property>
 			      <property name="text" translatable="yes"></property>
 			      <property name="has_frame">True</property>
-			      <property name="invisible_char" translatable="yes">*</property>
+			      <property name="invisible_char">*</property>
 			      <property name="activates_default">False</property>
 			    </widget>
 			    <packing>
--- gdm2/gui/gdmsetup-strings.c	2005-04-19 19:47:24.000000000 -0500
+++ gdm2-patched/gui/gdmsetup-strings.c	2005-04-28 17:54:54.578293352 -0500
@@ -12,9 +12,7 @@ gchar *s = N_("_Remote: ");
 gchar *s = N_("_Welcome string: ");
 gchar *s = N_("Re_mote welcome string (%n = hostname): ");
 gchar *s = N_("String to be shown in the greeter as welcome.  You can insert %n in here and it will be replaced by the name of your computer.");
-gchar *s = N_("*");
 gchar *s = N_("String to be shown in the greeter for people logging in remotely with XDMCP.  You can insert %n in here and it will be replaced by the name of your computer.");
-gchar *s = N_("*");
 gchar *s = N_("Always use 24 hour cloc_k format");
 gchar *s = N_("GTK+ Greeter");
 gchar *s = N_("Themed Greeter");
@@ -51,6 +49,9 @@ gchar *s = N_("_Only color on remote dis
 gchar *s = N_("_Background color: ");
 gchar *s = N_("Pick a color");
 gchar *s = N_("_2 GTK+ Greeter");
+gchar *s = N_("_Mode:");
+gchar *s = N_("Only One Theme");
+gchar *s = N_("Random Theme");
 gchar *s = N_("Preview:");
 gchar *s = N_("No screenshot available");
 gchar *s = N_("Description:");
@@ -67,14 +68,12 @@ gchar *s = N_("_Show choosable user imag
 gchar *s = N_("_Include All Users");
 gchar *s = N_("Include");
 gchar *s = N_("User to Include");
-gchar *s = N_("*");
 gchar *s = N_("_Add");
 gchar *s = N_("Delete");
 gchar *s = N_("<");
 gchar *s = N_(">");
 gchar *s = N_("Exclude");
 gchar *s = N_("User to exclude");
-gchar *s = N_("*");
 gchar *s = N_("_Add");
 gchar *s = N_("Delete");
 gchar *s = N_("Apply");
--- gdm2/config/gdm.conf.in	2005-04-25 14:38:54.000000000 -0500
+++ gdm2-patched/config/gdm.conf.in	2005-04-28 18:12:24.217018296 -0500
@@ -236,15 +236,6 @@ Enable=false
 # or mail details for some user, or some such.
 #Willing=@EXPANDED_SYSCONFDIR@/gdm/Xwilling
 
-# Run XDMCP sessions on a local proxy X server
-#EnableProxy=false
-# Proxy X server on which XDMCP session should be run
-#ProxyXServer=@X_XNEST_PATH@/Xnest @X_XNEST_CONFIG_OPTIONS@ -geometry 768x576
-#ProxyXServer=@X_SERVER_PATH@/Xdmx @X_CONFIG_OPTIONS@ -addremovescreens -norender -noglxproxy
-# Command which enables the proxy X server to be reconnected
-# to another backend display
-#ProxyReconnect=@GDM_RECONNECT_PROXY@
-
 [gui]
 # The specific gtkrc file we use.  It should be the full path to the gtkrc
 # that we need.  Unless you need a specific gtkrc that doesn't correspond to
@@ -359,21 +350,8 @@ DefaultRemoteWelcome=true
 # Program to run to draw the background in the standard greeter.  Perhaps
 # something like an xscreensaver hack or some such.
 #BackgroundProgram=
-# If this is true then the background program is run always, otherwise
+# if this is true then the background program is run always, otherwise
 # it is only run when the BackgroundType is 0 (None)
-#BackgroundProgramInitialDelay=30
-#  The background program will be started after at least that many 
-#  seconds of inactivity. Note that in the current implementation, the actual
-#  delay could be twice as long as the one specified here in the worst case. 
-#  Basically GDM checks from time to time if there was activity and runs
-#  the program if there was none.
-#RestartBackgroundProgram=true
-#  If set the background program will be restarted when it has exited, after 
-#  the delay described below has elapsed.  This option can be useful when you
-#  wish to run a screen saver program when no user is using the machine.
-#BackgroundProgramRestartDelay=30
-#  The background program will be restarted after at least that many seconds 
-#  of inactivity.
 #RunBackgroundProgramAlways=false
 # Show the Failsafe sessions.  These are much MUCH nicer (focus for xterm for
 # example) and more failsafe then those supplied by scripts so distros should
@@ -393,9 +371,14 @@ DefaultRemoteWelcome=true
 # for instance in console, xdm and ssh.
 #UseInvisibleInEntry=false
 # These two keys are for the new greeter.  Circles is the standard
-# shipped theme
+# shipped theme.  If you want gdm to select a random theme from a list
+# then provide a list that is delimited by /: to the GraphicalThemes key and 
+# set GraphicalThemeRand to true.  Otherwise use GraphicalTheme and specify
+# just one theme.
 #GraphicalTheme=circles
+#GraphicalThemes=circles/:happygnome
 GraphicalThemeDir=@EXPANDED_DATADIR@/gdm/themes/
+GraphicalThemeRand=false
 # If InfoMsgFile points to a file, the greeter will display the contents of the
 # file in a modal dialog box before the user is allowed to log in.
 #InfoMsgFile=
