--- gdm2/ChangeLog.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/ChangeLog	2007-07-01 13:04:08.000000000 +0100
@@ -0,0 +1,34 @@
+2007-07-01  Lukasz Zalewski <lukas@dcs.qmul.ac.uk>
+
+	* daemon/gdm-daemon-config-keys.h:
+	* daemon/gdm-daemon-config.[ch]:
+	* daemon/gdm-socket-protocol.h:
+	* daemon/slave.c:
+	* common/gdm-config.[ch]:
+	* common/gdm-common-config.[ch]:
+	* common/test-config.c:
+	* gui/gdmsetup.[ch]:
+	* gui/gdmuser.[ch]:
+	* gui/gdmconfig.c:
+	  Fix for bug #404891. Removed all GDM_NOTIFY_*
+	  keys used in the notification process and substituted them with
+	  group/key pairs of the actual keys (All the GDM_NOTIFY_* keys 
+	  represented was manually defined key part without the group). 
+	  Added all/PARAMETERS option to the gdm_daemon_config_update_key 
+	  function which perfroms bulk update of most available keys 
+	  (forbidden keys + xserver sections excluded) and notifies 
+	  the slaves if appropriate. This option can be used with 
+	  flexiserver --command "UPDATE_CONFIG ..". Also simplified
+	    gdm_slave_handle_notify such that the config is re-read and 
+	  updated entirely keeping all the configs in sync and all the keys
+	  of interest are grouped wrt the following action rather than the
+	  type of value they going to set.
+	  Gdmsetup now uses local cache for current daemon config entries,
+	  meaning that the keys are requested on the need to have basis and
+	  cached locally. Changes are storred locally and applied in bulk
+	  when user requires. All the widget timout functions have been 
+	  removed. [servers] and [server-*] sections are loaded from the
+	  config files directly.
+	  Fixed some memory leaks.
+	  Also fixes bugs #451635, #450357, #44973, #340465 and #335712
+
--- gdm2/daemon/gdm-daemon-config.h.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/daemon/gdm-daemon-config.h	2007-06-29 17:39:00.000000000 +0100
@@ -44,6 +44,8 @@
 gint           gdm_daemon_config_get_high_display_num (void);
 void           gdm_daemon_config_set_high_display_num (gint val);
 
+gboolean       gdm_daemon_config_update_all_no_notify (void);
+
 /* deprecated */
 char *         gdm_daemon_config_get_display_custom_config_file (const char *display);
 char *         gdm_daemon_config_get_custom_config_file (void);
@@ -101,6 +103,7 @@
 char *         gdm_daemon_config_get_session_exec     (const char *session_name,
                                                        gboolean check_try_exec);
 char *         gdm_daemon_config_get_session_xserver_args (const char *session_name);
+gboolean       is_key (const gchar *key1, const gchar *key2);
 
 
 G_END_DECLS
--- gdm2/daemon/gdm-socket-protocol.h.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/daemon/gdm-socket-protocol.h	2007-06-29 17:39:00.000000000 +0100
@@ -174,6 +174,15 @@
 /* send the question dialog response */
 #define GDM_SLAVE_NOTIFY_QUESTION_RESPONSE 'Q'
 
+/* Update flags used in conjunction with GDM_SLAVE_NOTIFY_KEY */
+typedef enum {
+	GDM_NOTIFY_FLAG_DO_NOTHING           = 0x0,
+	GDM_NOTIFY_FLAG_NO_RESTART           = 0x1,
+	GDM_NOTIFY_FLAG_RESTART_STATIC       = 0x2,
+	GDM_NOTIFY_FLAG_RESTART_XMDCP        = 0x4,
+	GDM_NOTIFY_FLAG_RESTART_STATIC_XMDCP = 0x6,
+} GdmNotifyStatus;
+
 /*
  * Maximum number of messages allowed over the sockets protocol.  This
  * is set to 80 since the gdmlogin/gdmgreeter programs have ~60 config
--- gdm2/daemon/slave.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/daemon/slave.c	2007-07-01 12:31:00.000000000 +0100
@@ -4947,6 +4947,7 @@
 			unhandled_notifies =
 				g_list_append (unhandled_notifies,
 					       g_strdup (&s[1]));
+			check_notifies_now ();
 		} else if (s[0] == GDM_SLAVE_NOTIFY_COMMAND) {
 			if (strcmp (&s[1], GDM_NOTIFY_DIRTY_SERVERS) == 0) {
 				/* never restart flexi servers
@@ -5719,164 +5720,91 @@
 }
 
 static void
+gdm_terminate_slave (gint type_to_terminate) 
+{
+	do_restart_greeter = TRUE;
+	if (restart_greeter_now) {
+		; /* will get restarted later */
+	} else if (d->type == type_to_terminate) {
+		/* FIXME: can't handle flexi servers like this
+		 * without going all cranky */
+		if ( ! d->logged_in) {
+			gdm_slave_quick_exit (DISPLAY_REMANAGE);
+		} else {
+			remanage_asap = TRUE;
+		}
+	}	
+}
+
+static void
 gdm_slave_handle_notify (const char *msg)
 {
 	int val;
 
 	gdm_debug ("Handling slave notify: '%s'", msg);
 
-	if (sscanf (msg, GDM_NOTIFY_ALLOW_ROOT " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_ROOT, val);
-	} else if (sscanf (msg, GDM_NOTIFY_ALLOW_REMOTE_ROOT " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_REMOTE_ROOT, val);
-	} else if (sscanf (msg, GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN, val);
-	} else if (sscanf (msg, GDM_NOTIFY_SYSTEM_MENU " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_SYSTEM_MENU, val);
-		if (d->greetpid > 1)
-			kill (d->greetpid, SIGHUP);
-	} else if (sscanf (msg, GDM_NOTIFY_CONFIG_AVAILABLE " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_CONFIG_AVAILABLE, val);
-		if (d->greetpid > 1)
-			kill (d->greetpid, SIGHUP);
-	} else if (sscanf (msg, GDM_NOTIFY_CHOOSER_BUTTON " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_CHOOSER_BUTTON, val);
-		if (d->greetpid > 1)
-			kill (d->greetpid, SIGHUP);
-	} else if (sscanf (msg, GDM_NOTIFY_RETRY_DELAY " %d", &val) == 1) {
-		gdm_daemon_config_set_value_int (GDM_KEY_RETRY_DELAY, val);
-	} else if (sscanf (msg, GDM_NOTIFY_DISALLOW_TCP " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_DISALLOW_TCP, val);
-		remanage_asap = TRUE;
-	} else if (strncmp (msg, GDM_NOTIFY_GREETER " ",
-			    strlen (GDM_NOTIFY_GREETER) + 1) == 0) {
-		gdm_daemon_config_set_value_string (GDM_KEY_GREETER, ((gchar *)&msg[strlen (GDM_NOTIFY_GREETER) + 1]));
-
-		if (d->attached) {
-			do_restart_greeter = TRUE;
-			if (restart_greeter_now) {
-				; /* will get restarted later */
-			} else if (d->type == TYPE_STATIC) {
-				/* FIXME: can't handle flexi servers like this
-				 * without going all cranky */
-				if ( ! d->logged_in) {
-					gdm_slave_quick_exit (DISPLAY_REMANAGE);
-				} else {
-					remanage_asap = TRUE;
-				}
-			}
-		}
-	} else if (strncmp (msg, GDM_NOTIFY_CUSTOM_CMD_TEMPLATE,
-			    strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE)) == 0) {
-    	        if (sscanf (msg, GDM_NOTIFY_CUSTOM_CMD_TEMPLATE "%d", &val) == 1) {
-			gchar * key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, val);
-			/* This assumes that the number of commands is < 100, i.e two digits
-			   if that is not the case then this will fail */
-			gdm_daemon_config_set_value_string (key_string, ((gchar *)&msg[strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE) + 2]));
-			g_free(key_string);
-
-			if (d->attached) {
+	gchar **splitstr = g_strsplit (msg, " ", 2);
+	if (splitstr[0] != NULL) {
+		if (splitstr[1] != NULL) {			
+			if (gdm_daemon_config_update_all_no_notify () == FALSE)
+				return;
+			
+			if (is_key (splitstr[0], GDM_KEY_SYSTEM_MENU) ||
+			    is_key (splitstr[0], GDM_KEY_CONFIG_AVAILABLE) ||
+			    is_key (splitstr[0], GDM_KEY_CHOOSER_BUTTON) ||
+			    is_key (splitstr[0], GDM_KEY_SOUND_ON_LOGIN_FILE) ||
+			    is_key (splitstr[0], GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE) ||
+			    is_key (splitstr[0], GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE)) {
+				if (d->greetpid > 1)
+					kill (d->greetpid, SIGHUP);
+				
+			} else if (is_key (splitstr[0], GDM_KEY_DISALLOW_TCP)) {
+				remanage_asap = TRUE;
+				
+			} else if (is_key (splitstr[0], GDM_KEY_GREETER) ||
+				   is_key (splitstr[0],GDM_KEY_ADD_GTK_MODULES) ||
+				   is_key (splitstr[0], GDM_KEY_GTK_MODULES_LIST)) {
+				if (d->attached) 
+					gdm_terminate_slave (TYPE_STATIC);
+
+			} else if (is_key (splitstr[0], GDM_KEY_REMOTE_GREETER)) {
+				if (!d->attached) 
+					gdm_terminate_slave (TYPE_XDMCP);			
+		
+			} else if (is_key (splitstr[0], GDM_KEY_TIMED_LOGIN) ||
+				   is_key (splitstr[0], GDM_KEY_TIMED_LOGIN_ENABLE) ||
+				   is_key (splitstr[0], GDM_KEY_TIMED_LOGIN_DELAY)) {
 				do_restart_greeter = TRUE;
-				if (restart_greeter_now) {
-					; /* will get restarted later */
-				} else if (d->type == TYPE_STATIC) {
-					/* FIXME: can't handle flexi servers like this
-					 * without going all cranky */
+				/* FIXME: this is fairly nasty, we should handle this nicer   */
+				/* FIXME: can't handle flexi servers without going all cranky */
+				if (d->type == TYPE_STATIC || d->type == TYPE_XDMCP) {
 					if ( ! d->logged_in) {
 						gdm_slave_quick_exit (DISPLAY_REMANAGE);
 					} else {
 						remanage_asap = TRUE;
 					}
+				}				
+			
+			} else if (is_key (splitstr[0], GDM_NOTIFY_UPDATE_ALL_GREETERS)) {				
+				if (sscanf (splitstr[1], "%d", &val) == 1) {
+					if (d->attached && 
+					    (val & GDM_NOTIFY_FLAG_RESTART_STATIC) == GDM_NOTIFY_FLAG_RESTART_STATIC) {
+						gdm_terminate_slave (TYPE_STATIC);
+
+					} else if (!d->attached && 
+						   (val & GDM_NOTIFY_FLAG_RESTART_XMDCP) == GDM_NOTIFY_FLAG_RESTART_XMDCP) {
+						gdm_terminate_slave (TYPE_XDMCP);
+
+					} else if ((val & GDM_NOTIFY_FLAG_NO_RESTART) == GDM_NOTIFY_FLAG_NO_RESTART) {
+						if (d->greetpid > 1)
+							kill (d->greetpid, SIGHUP);
+					}
 				}
 			}
 		}
-	} else if (strncmp (msg, GDM_NOTIFY_REMOTE_GREETER " ",
-			    strlen (GDM_NOTIFY_REMOTE_GREETER) + 1) == 0) {
-		gdm_daemon_config_set_value_string (GDM_KEY_REMOTE_GREETER,
-						    (gchar *)(&msg[strlen (GDM_NOTIFY_REMOTE_GREETER) + 1]));
-		if ( ! d->attached) {
-			do_restart_greeter = TRUE;
-			if (restart_greeter_now) {
-				; /* will get restarted later */
-			} else if (d->type == TYPE_XDMCP) {
-				/* FIXME: can't handle flexi servers like this
-				 * without going all cranky */
-				if ( ! d->logged_in) {
-					gdm_slave_quick_exit (DISPLAY_REMANAGE);
-				} else {
-					remanage_asap = TRUE;
-				}
-			}
-		}
-	} else if ((strncmp (msg, GDM_NOTIFY_TIMED_LOGIN " ",
-			     strlen (GDM_NOTIFY_TIMED_LOGIN) + 1) == 0) ||
-	           (strncmp (msg, GDM_NOTIFY_TIMED_LOGIN_DELAY " ",
-			     strlen (GDM_NOTIFY_TIMED_LOGIN_DELAY) + 1) == 0) ||
-	           (strncmp (msg, GDM_NOTIFY_TIMED_LOGIN_ENABLE " ",
-			     strlen (GDM_NOTIFY_TIMED_LOGIN_ENABLE) + 1) == 0)) {
-		do_restart_greeter = TRUE;
-		/* FIXME: this is fairly nasty, we should handle this nicer   */
-		/* FIXME: can't handle flexi servers without going all cranky */
-		if (d->type == TYPE_STATIC || d->type == TYPE_XDMCP) {
-			if ( ! d->logged_in) {
-				gdm_slave_quick_exit (DISPLAY_REMANAGE);
-			} else {
-				remanage_asap = TRUE;
-			}
-		}
-	} else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FILE " ",
-			    strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1) == 0) {
-		gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE,
-						    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1]));
-		if (d->greetpid > 1)
-			kill (d->greetpid, SIGHUP);
-	} else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE " ",
-			    strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1) == 0) {
-		gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE,
-						    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1]));
-		if (d->greetpid > 1)
-			kill (d->greetpid, SIGHUP);
-	} else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE " ",
-			    strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1) == 0) {
-		gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE,
-						    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1]));
-		if (d->greetpid > 1)
-			kill (d->greetpid, SIGHUP);
-	} else if (strncmp (msg, GDM_NOTIFY_GTK_MODULES_LIST " ",
-			    strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1) == 0) {
-		gdm_daemon_config_set_value_string (GDM_KEY_GTK_MODULES_LIST,
-						    (gchar *)(&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1]));
-
-		if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES)) {
-			do_restart_greeter = TRUE;
-			if (restart_greeter_now) {
-				; /* will get restarted later */
-			} else if (d->type == TYPE_STATIC) {
-				/* FIXME: can't handle flexi servers like this
-				 * without going all cranky */
-				if ( ! d->logged_in) {
-					gdm_slave_quick_exit (DISPLAY_REMANAGE);
-				} else {
-					remanage_asap = TRUE;
-				}
-			}
-		}
-	} else if (sscanf (msg, GDM_NOTIFY_ADD_GTK_MODULES " %d", &val) == 1) {
-		gdm_daemon_config_set_value_bool (GDM_KEY_ADD_GTK_MODULES, val);
-
-		do_restart_greeter = TRUE;
-		if (restart_greeter_now) {
-			; /* will get restarted later */
-		} else if (d->type == TYPE_STATIC) {
-			/* FIXME: can't handle flexi servers like this
-			 * without going all cranky */
-			if ( ! d->logged_in) {
-				gdm_slave_quick_exit (DISPLAY_REMANAGE);
-			} else {
-				remanage_asap = TRUE;
-			}
-		}
-	}
+		
+	}	   
+	g_strfreev (splitstr);		
 }
 
 /* do cleanup but only if we are a slave, if we're not a slave, just
--- gdm2/daemon/gdm-daemon-config.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/daemon/gdm-daemon-config.c	2007-06-29 17:39:00.000000000 +0100
@@ -67,6 +67,8 @@
 
 static GdmConfig *daemon_config = NULL;
 
+static GdmNotifyStatus notify_status = GDM_NOTIFY_FLAG_DO_NOTHING;
+
 static GSList *displays = NULL;
 static GSList *xservers = NULL;
 
@@ -84,7 +86,7 @@
  * keys passed and compares them, returning TRUE if they are the same, 
  * FALSE otherwise.
  */
-static gboolean
+gboolean
 is_key (const gchar *key1, const gchar *key2)
 {
 	gchar *key1d, *key2d, *p;
@@ -794,66 +796,15 @@
 }
 
 static char *
-lookup_notify_key (GdmConfig  *config,
-		   const char *group,
-		   const char *key)
+get_notify_key (GdmConfig  *config,
+		const char *group,
+		const char *key)
 {
-	char *nkey;
 	char *keystring;
-
+	
 	keystring = g_strdup_printf ("%s/%s", group, key);
-
-	/* pretty lame but oh well */
-	nkey = NULL;
-
-	/* bools */
-	if (is_key (keystring, GDM_KEY_ALLOW_ROOT))
-		nkey = g_strdup (GDM_NOTIFY_ALLOW_ROOT);
-	else if (is_key (keystring, GDM_KEY_ALLOW_REMOTE_ROOT))
-		nkey = g_strdup (GDM_NOTIFY_ALLOW_REMOTE_ROOT);
-	else if (is_key (keystring, GDM_KEY_ALLOW_REMOTE_AUTOLOGIN))
-		nkey = g_strdup (GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN);
-	else if (is_key (keystring, GDM_KEY_SYSTEM_MENU))
-		nkey = g_strdup (GDM_NOTIFY_SYSTEM_MENU);
-	else if (is_key (keystring, GDM_KEY_CONFIG_AVAILABLE))
-		nkey = g_strdup (GDM_NOTIFY_CONFIG_AVAILABLE);
-	else if (is_key (keystring, GDM_KEY_CHOOSER_BUTTON))
-		nkey = g_strdup (GDM_NOTIFY_CHOOSER_BUTTON);
-	else if (is_key (keystring, GDM_KEY_DISALLOW_TCP))
-		nkey = g_strdup (GDM_NOTIFY_DISALLOW_TCP);
-	else if (is_key (keystring, GDM_KEY_ADD_GTK_MODULES))
-		nkey = g_strdup (GDM_NOTIFY_ADD_GTK_MODULES);
-	else if (is_key (keystring, GDM_KEY_TIMED_LOGIN_ENABLE))
-		nkey = g_strdup (GDM_NOTIFY_TIMED_LOGIN_ENABLE);
-	/* ints */
-	else if (is_key (keystring, GDM_KEY_RETRY_DELAY))
-		nkey = g_strdup (GDM_NOTIFY_RETRY_DELAY);
-	else if (is_key (keystring, GDM_KEY_TIMED_LOGIN_DELAY))
-		nkey = g_strdup (GDM_NOTIFY_TIMED_LOGIN_DELAY);
-	/* strings */
-	else if (is_key (keystring, GDM_KEY_GREETER))
-		nkey = g_strdup (GDM_NOTIFY_GREETER);
-	else if (is_key (keystring, GDM_KEY_REMOTE_GREETER))
-		nkey = g_strdup (GDM_NOTIFY_REMOTE_GREETER);
-	else if (is_key (keystring, GDM_KEY_SOUND_ON_LOGIN_FILE))
-		nkey = g_strdup (GDM_NOTIFY_SOUND_ON_LOGIN_FILE);
-	else if (is_key (keystring, GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE))
-		nkey = g_strdup (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE);
-	else if (is_key (keystring, GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE))
-		nkey = g_strdup (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE);
-	else if (is_key (keystring, GDM_KEY_GTK_MODULES_LIST))
-		nkey = g_strdup (GDM_NOTIFY_GTK_MODULES_LIST);
-	else if (is_key (keystring, GDM_KEY_TIMED_LOGIN))
-		nkey = g_strdup (GDM_NOTIFY_TIMED_LOGIN);
-	else if (strcmp (group, GDM_CONFIG_GROUP_CUSTOM_CMD) == 0 &&
-		 g_str_has_prefix (key, "CustomCommand") &&
-		 strlen (key) == 14) {
-		/* this should match 'CustomCommandN' */
-		nkey = g_strdup (key);
-	}
-	g_free (keystring);
-
-	return nkey;
+	
+	return keystring;
 }
 
 /**
@@ -876,7 +827,7 @@
 	char   *valstr;
 	char   *keystr;
 
-	keystr = lookup_notify_key (config, group, key);
+	keystr = get_notify_key (config, group, key);
 
 	/* unfortunately, can't always gdm_config_value_to_string()
 	 * here because booleans need to be sent as ints
@@ -1217,7 +1168,7 @@
                 entry.id = GDM_CONFIG_INVALID_ID;
 
                 gdm_config_add_entry (config, &entry);
-                gdm_config_process_entry (config, &entry, NULL);
+                gdm_config_process_entry (config, &entry, NULL, TRUE, FALSE);
 
                 res = gdm_config_get_value (config, entry.group, entry.key, &value);
                 if (! res) {
@@ -1245,7 +1196,7 @@
                         srv_entry = gdm_config_entry_copy (&gdm_daemon_server_config_entries[j]);
                         g_free (srv_entry->group);
                         srv_entry->group = g_strdup (new_group);
-                        gdm_config_process_entry (config, srv_entry, NULL);
+                        gdm_config_process_entry (config, srv_entry, NULL, TRUE, FALSE);
                         gdm_config_entry_free (srv_entry);
                 }
 		g_free (new_group);
@@ -1265,6 +1216,27 @@
 	gdm_daemon_config_ensure_one_xserver (config);
 }
 
+gboolean
+gdm_daemon_config_update_all_no_notify ()
+{
+	GError          *error;
+	gboolean         res;
+	GdmConfigStatus  reload_status;
+	
+	error = NULL;
+	/* reload backend files if necessary */
+	reload_status = gdm_config_load (daemon_config, NULL);
+	if (reload_status == GDM_CONFIG_FILE_UNCHANGED)
+		return FALSE;
+	
+	res = gdm_config_process_all (daemon_config, &error, FALSE, TRUE);
+	if (error != NULL) {
+		gdm_error ("Unable to update configuration: %s", error->message);
+		g_error_free (error);
+	}		
+	return res;
+}
+
 /**
  * gdm_daemon_config_update_key
  *
@@ -1275,10 +1247,9 @@
  * used by the daemon.  This function is called when the UPDDATE_CONFIG
  * sockets command is called.
  *
- * To add a new notification, a GDM_NOTIFY_* argument will need to be
- * defined in gdm-daemon-config-keys.h, supporting logic placed in the
- * notify_cb function and in the gdm_slave_handle_notify function
- * in slave.c.
+ * To add a new notification, notify_status_cb will have to be modified
+ * such that it supports logic placed in the notify_status_cb function 
+ * and in the gdm_slave_handle_notify function in slave.c.
  */
 gboolean
 gdm_daemon_config_update_key (const char *keystring)
@@ -1289,29 +1260,19 @@
 	char                 *key;
 	char                 *locale;
 	const GdmConfigEntry *entry;
-
+	GdmConfigStatus       reload_status;
+	GError               *error;
+	GdmConfigValue       *notify_value;
+	
 	rc = FALSE;
 	group = key = locale = NULL;
-
-	/*
-	 * Do not allow these keys to be updated, since GDM would need
-	 * additional work, or at least heavy testing, to make these keys
-	 * flexible enough to be changed at runtime.
-	 */
-	if (is_key (keystring, GDM_KEY_PID_FILE) ||
-	    is_key (keystring, GDM_KEY_CONSOLE_NOTIFY) ||
-	    is_key (keystring, GDM_KEY_USER) ||
-	    is_key (keystring, GDM_KEY_GROUP) ||
-	    is_key (keystring, GDM_KEY_LOG_DIR) ||
-	    is_key (keystring, GDM_KEY_SERV_AUTHDIR) ||
-	    is_key (keystring, GDM_KEY_USER_AUTHDIR) ||
-	    is_key (keystring, GDM_KEY_USER_AUTHFILE) ||
-	    is_key (keystring, GDM_KEY_USER_AUTHDIR_FALLBACK)) {
-		return FALSE;
-	}
+	notify_value = NULL;
+	error = NULL;
 
 	/* reload backend files if necessary */
-	gdm_config_load (daemon_config, NULL);
+	reload_status = gdm_config_load (daemon_config, NULL);
+	if (reload_status == GDM_CONFIG_FILE_UNCHANGED)
+		return TRUE;
 
 	/* Shortcut for updating all XDMCP parameters */
 	if (is_key (keystring, "xdmcp/PARAMETERS")) {
@@ -1333,6 +1294,24 @@
 		goto out;
 	}
 
+	if (is_key (keystring, "all/PARAMETERS")) {
+		/* populate the database with all changed entries */
+		notify_status = GDM_NOTIFY_FLAG_DO_NOTHING;
+		gdm_config_process_all (daemon_config, &error, FALSE, TRUE);
+		if (error != NULL) {
+			gdm_error ("Unable to process configuration: %s", error->message);
+			g_error_free (error);
+		}		
+		if (notify_status != GDM_NOTIFY_FLAG_DO_NOTHING) {
+			notify_value = gdm_config_value_new (GDM_CONFIG_VALUE_INT);
+			gdm_config_value_set_int (notify_value, notify_status);
+			notify_displays_value (daemon_config, "all", "PARAMETERS", notify_value);
+			gdm_config_value_free (notify_value);
+		}
+		rc = TRUE;
+		goto out;
+	}
+
 	/* find the entry for the key */
 	res = gdm_common_config_parse_key_string (keystring,
 						  &group,
@@ -1350,7 +1329,7 @@
 		goto out;
 	}
 
-	rc = gdm_config_process_entry (daemon_config, entry, NULL);
+	rc = gdm_config_process_entry (daemon_config, entry, NULL, TRUE, TRUE);
 
  out:
 	g_free (group);
@@ -1819,6 +1798,39 @@
 	return res;
 }
 
+/*
+ * Do not allow these keys to be updated, since GDM would need
+ * additional work, or at least heavy testing, to make these keys
+ * flexible enough to be changed at runtime.
+ */
+
+static gboolean
+updatable_value_cb (GdmConfig          *config,
+		    GdmConfigSourceType source,
+		    const char         *group,
+		    const char         *key,
+		    GdmConfigValue     *value,
+		    int                 id,
+		    gpointer            data)
+{
+	
+	switch (id) {
+	case GDM_ID_CONSOLE_NOTIFY:
+	case GDM_ID_USER:
+	case GDM_ID_GROUP:
+	case GDM_ID_LOG_DIR:
+	case GDM_ID_SERV_AUTHDIR:
+	case GDM_ID_USER_AUTHDIR:
+	case GDM_ID_USER_AUTHFILE:
+	case GDM_ID_USER_AUTHDIR_FALLBACK:
+		return FALSE;
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+
 static const char *
 source_to_name (GdmConfigSourceType source)
 {
@@ -1911,6 +1923,50 @@
         return TRUE;
 }
 
+static gboolean
+notify_status_cb (GdmConfig          *config,
+		  GdmConfigSourceType source,
+		  const char         *group,
+		  const char         *key,
+		  GdmConfigValue     *value,
+		  int                 id,
+		  gpointer            data)
+{
+	GdmNotifyStatus *status;
+
+	if (data == NULL)
+		return FALSE;
+	
+	status = (GdmNotifyStatus*)data;
+
+        switch (id) {
+	case GDM_ID_GREETER:
+	case GDM_ID_GTK_MODULES_LIST:
+        case GDM_ID_ADD_GTK_MODULES:
+        case GDM_ID_DISALLOW_TCP:
+		*status |= GDM_NOTIFY_FLAG_RESTART_STATIC;
+		break;
+	case GDM_ID_REMOTE_GREETER:
+		*status |= GDM_NOTIFY_FLAG_RESTART_XMDCP;
+		break;
+        case GDM_ID_TIMED_LOGIN:
+	case GDM_ID_TIMED_LOGIN_ENABLE:
+	case GDM_ID_TIMED_LOGIN_DELAY:
+		*status |= GDM_NOTIFY_FLAG_RESTART_STATIC_XMDCP;
+		break;
+	default:
+		*status |= GDM_NOTIFY_FLAG_NO_RESTART;
+		break;
+	}
+	
+	gdm_debug ("Notification status for %s/%s is %d\n",
+		   group,
+		   key,
+		   *status);
+	
+        return TRUE;
+}
+
 static void
 handle_no_displays (GdmConfig *config,
 		    gboolean   no_console)
@@ -2180,6 +2236,8 @@
 
 	gdm_config_set_notify_func (daemon_config, notify_cb, NULL);
 	gdm_config_set_validate_func (daemon_config, validate_cb, NULL);
+	gdm_config_set_notify_status_func (daemon_config, notify_status_cb, (gpointer)&notify_status);
+	gdm_config_set_updatable_value_func (daemon_config, updatable_value_cb, NULL);
 
 	gdm_config_add_static_entries (daemon_config, gdm_daemon_config_entries);
 
@@ -2195,7 +2253,7 @@
 	}
 
 	/* populate the database with all specified entries */
-	gdm_config_process_all (daemon_config, &error);
+	gdm_config_process_all (daemon_config, &error, TRUE, FALSE);
 
 	gdm_daemon_config_load_xservers (daemon_config);
 
--- gdm2/daemon/gdm-daemon-config-keys.h.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/daemon/gdm-daemon-config-keys.h	2007-06-29 17:39:00.000000000 +0100
@@ -201,25 +201,7 @@
 
 /* Notification protocol */
 /* keys */
-#define GDM_NOTIFY_ALLOW_REMOTE_ROOT "AllowRemoteRoot" /* <true/false as int> */
-#define GDM_NOTIFY_ALLOW_ROOT "AllowRoot" /* <true/false as int> */
-#define GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN "AllowRemoteAutoLogin" /* <true/false as int> */
-#define GDM_NOTIFY_SYSTEM_MENU "SystemMenu" /* <true/false as int> */
-#define GDM_NOTIFY_CONFIG_AVAILABLE "ConfigAvailable" /* <true/false as int> */
-#define GDM_NOTIFY_CHOOSER_BUTTON "ChooserButton" /* <true/false as int> */
-#define GDM_NOTIFY_RETRY_DELAY "RetryDelay" /* <seconds> */
-#define GDM_NOTIFY_GREETER "Greeter" /* <greeter binary> */
-#define GDM_NOTIFY_REMOTE_GREETER "RemoteGreeter" /* <greeter binary> */
-#define GDM_NOTIFY_TIMED_LOGIN "TimedLogin" /* <login> */
-#define GDM_NOTIFY_TIMED_LOGIN_DELAY "TimedLoginDelay" /* <seconds> */
-#define GDM_NOTIFY_TIMED_LOGIN_ENABLE "TimedLoginEnable" /* <true/false as int> */
-#define GDM_NOTIFY_DISALLOW_TCP "DisallowTCP" /* <true/false as int> */
-#define GDM_NOTIFY_SOUND_ON_LOGIN_FILE "SoundOnLoginFile" /* <sound file> */
-#define GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE "SoundOnLoginSuccessFile" /* <sound file> */
-#define GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE "SoundOnLoginFailureFile" /* <sound file> */
-#define GDM_NOTIFY_ADD_GTK_MODULES "AddGtkModules" /* <true/false as int> */
-#define GDM_NOTIFY_GTK_MODULES_LIST "GtkModulesList" /* <modules list> */
-#define GDM_NOTIFY_CUSTOM_CMD_TEMPLATE "CustomCommand" /* <custom command path> */
+#define GDM_NOTIFY_UPDATE_ALL_GREETERS "all/PARAMETERS" /* <GdmNotifyStatus flag> */
 
 /* commands, seel GDM_SLAVE_NOTIFY_COMMAND */
 #define GDM_NOTIFY_DIRTY_SERVERS "DIRTY_SERVERS"
--- gdm2/common/gdm-common-config.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/common/gdm-common-config.c	2007-06-29 17:39:00.000000000 +0100
@@ -28,6 +28,7 @@
 
 #include <glib.h>
 
+#include "gdm-common.h"
 #include "gdm-common-config.h"
 
 gboolean
@@ -190,6 +191,146 @@
 	return TRUE;
 }
 
+/* This is essentially a simplified duplicate of the
+   key_file_get_value from common/gdm-config.c. 
+   As the mentioned function is "private" to GdmConfig 
+   and deals with key parsing in terms of GdmConfig rather 
+   than GKeyFile(s) this is necessary evil.
+*/
+gboolean
+gdm_common_config_get_value (GKeyFile            *config,
+			     const char          *keystring,
+			     GdmConfigValue     **valuep,
+			     GdmConfigValueType   type,
+			     gboolean             use_default,
+			     GError             **error)
+{
+	char           *group;
+	char           *key;
+	char           *val;
+	char           *locale;
+	char           *default_value;
+	GdmConfigValue *value = NULL;
+	GError         *local_error;
+	gboolean        ret;
+
+	ret = FALSE;
+	
+	group = key = default_value = val = NULL;
+	if (! gdm_common_config_parse_key_string (keystring, &group, &key, &locale, &default_value))
+		return FALSE;
+
+	local_error = NULL;
+
+	if (type == GDM_CONFIG_VALUE_LOCALE_STRING) {
+		if (locale) {
+			val = g_key_file_get_locale_string (config, group, key, locale, &local_error);
+		}
+		
+		if (val == NULL) {
+			if (local_error) {
+				g_propagate_error (error, local_error);
+			}
+			val = g_key_file_get_value (config,
+						    group,
+						    key,
+						    &local_error);
+		}
+	}
+	else {
+		val = g_key_file_get_value (config,
+					    group,
+					    key,
+					    &local_error);
+	}
+	
+	if (local_error != NULL) {
+		/* use the default */
+		if (use_default && !ve_string_empty (default_value)) {
+			ret = TRUE;
+			val = g_strdup (default_value);
+			g_error_free (local_error);
+			local_error = NULL;
+					
+		} else {
+			val = NULL;
+			g_propagate_error (error, local_error);
+		}		
+	} else {
+		ret = TRUE;
+	}
+	
+	if (val != NULL) {
+		value = gdm_config_value_new_from_string (type, val, &local_error);
+		if (local_error)
+			g_propagate_error (error, local_error);
+	}
+	*valuep = value;
+
+	g_free (val);
+	g_free (locale);
+	g_free (key);
+	g_free (group);
+	g_free (default_value);
+
+	return ret;
+}
+
+void
+gdm_common_config_set_value (GKeyFile             *config,
+			     const char           *keystring,
+			     const GdmConfigValue *value)
+{
+	char    *group;
+	char    *key;
+	char    *locale;
+
+	group = key = NULL;
+	if (! gdm_common_config_parse_key_string (keystring, &group, &key, &locale, NULL)) {
+		return;
+	}
+
+	switch (value->type) {
+	case GDM_CONFIG_VALUE_INT:
+		g_key_file_set_integer (config, group, key, gdm_config_value_get_int (value));
+		break;
+	case GDM_CONFIG_VALUE_BOOL:
+		g_key_file_set_boolean (config, group, key, gdm_config_value_get_bool (value));
+		break;
+	case GDM_CONFIG_VALUE_STRING:
+		g_key_file_set_string (config, group, key, gdm_config_value_get_string (value));
+		break;
+	case GDM_CONFIG_VALUE_LOCALE_STRING:
+	{
+		/* This is really nasty. We shouldn't be removing user translations but use
+		   the one that was chosen in the first place. FIXME
+		*/
+		gint i;
+		gchar *prefix;
+		gchar **keys;
+
+		prefix = g_strdup_printf ("%s[", key);
+		keys = g_key_file_get_keys (config, group, NULL, NULL);
+		for (i = 0; keys[i] != NULL; i++) {
+			if (g_str_has_prefix (keys[i], prefix)) {
+				g_key_file_remove_key (config, group, keys[i], NULL);
+			}
+		}
+		g_strfreev (keys);
+		g_free (prefix);
+		
+		g_key_file_set_string (config, group, key, gdm_config_value_get_locale_string (value));
+		break;
+	}
+	default:
+		g_assert_not_reached ();
+	}
+
+	g_free (key);
+	g_free (group);
+	g_free (locale);
+}
+
 gboolean
 gdm_common_config_get_int (GKeyFile   *config,
 			   const char *keystring,
@@ -285,8 +426,9 @@
 		ret = TRUE;
 	}
 
-	*value = val;
+	*value = g_strdup (val);
 
+	g_free (val);
 	g_free (key);
 	g_free (group);
 	g_free (default_value);
--- gdm2/common/test-config.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/common/test-config.c	2007-06-29 17:39:00.000000000 +0100
@@ -180,7 +180,7 @@
                 entry.id = GDM_CONFIG_INVALID_ID;
 
                 gdm_config_add_entry (config, &entry);
-                gdm_config_process_entry (config, &entry, NULL);
+                gdm_config_process_entry (config, &entry, NULL, TRUE, FALSE);
 
                 res = gdm_config_get_value (config, entry.group, entry.key, &value);
                 if (! res) {
@@ -198,7 +198,7 @@
                         srv_entry = gdm_config_entry_copy (&gdm_daemon_server_config_entries[j]);
                         g_free (srv_entry->group);
                         srv_entry->group = g_strdup (new_group);
-                        gdm_config_process_entry (config, srv_entry, NULL);
+                        gdm_config_process_entry (config, srv_entry, NULL, TRUE, FALSE);
                         gdm_config_entry_free (srv_entry);
                 }
                 g_free (new_group);
@@ -232,7 +232,7 @@
                 g_error_free (error);
         } else {
                 /* populate the database with all specified entries */
-                gdm_config_process_all (config, &error);
+                gdm_config_process_all (config, &error, TRUE, FALSE);
         }
 
         g_message ("Getting all standard values");
@@ -284,7 +284,7 @@
                 g_error_free (error);
         } else {
                 /* populate the database with all specified entries */
-                gdm_config_process_all (config, &error);
+                gdm_config_process_all (config, &error, TRUE, FALSE);
         }
 
 
--- gdm2/common/gdm-config.h.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/common/gdm-config.h	2007-06-29 17:39:00.000000000 +0100
@@ -25,7 +25,12 @@
 
 G_BEGIN_DECLS
 
-typedef struct _GdmConfig GdmConfig;
+/* Status flags for the loaded config files */
+typedef enum {
+    GDM_CONFIG_LOAD_FAILURE   = 0x0,
+    GDM_CONFIG_LOAD_SUCCESS   = 0x1,
+    GDM_CONFIG_FILE_UNCHANGED = 0x2,
+} GdmConfigStatus; 
 
 typedef enum {
         GDM_CONFIG_VALUE_INVALID,
@@ -55,6 +60,8 @@
 
 typedef struct _GdmConfigValue GdmConfigValue;
 
+typedef struct _GdmConfig GdmConfig;
+
 typedef gboolean (* GdmConfigFunc) (GdmConfig          *config,
 				    GdmConfigSourceType source,
 				    const char         *group,
@@ -63,6 +70,7 @@
 				    int                 id,
 				    gpointer            data);
 
+
 typedef struct {
 	char              *group;
 	char              *key;
@@ -92,6 +100,12 @@
 void                   gdm_config_set_notify_func        (GdmConfig       *config,
 							  GdmConfigFunc    func,
 							  gpointer         data);
+void                   gdm_config_set_notify_status_func (GdmConfig       *config,
+							  GdmConfigFunc    func,
+							  gpointer         data);
+void                   gdm_config_set_updatable_value_func (GdmConfig     *config,
+							    GdmConfigFunc  func,
+							    gpointer       data);
 void                   gdm_config_set_default_file       (GdmConfig       *config,
 							  const char      *name);
 void                   gdm_config_set_mandatory_file     (GdmConfig       *config,
@@ -108,17 +122,23 @@
 const GdmConfigEntry * gdm_config_lookup_entry_for_id    (GdmConfig            *config,
 							  int                   id);
 
-gboolean               gdm_config_load                   (GdmConfig             *config,
+GdmConfigStatus        gdm_config_load                   (GdmConfig             *config,
 							  GError               **error);
 gboolean               gdm_config_process_all            (GdmConfig             *config,
-							  GError               **error);
+							  GError               **error,
+							  gboolean               do_notify,
+							  gboolean               doing_update);
 gboolean               gdm_config_process_entry          (GdmConfig             *config,
 							  const GdmConfigEntry  *entry,
-							  GError               **error);
+							  GError               **error,
+							  gboolean               do_notify,
+							  gboolean               doing_update);
 gboolean               gdm_config_process_entries        (GdmConfig             *config,
 							  const GdmConfigEntry **entries,
 							  gsize                  n_entries,
-							  GError               **error);
+							  GError               **error,
+							  gboolean               do_notify,
+							  gboolean               doing_update);
 
 gboolean               gdm_config_save_custom_file       (GdmConfig       *config,
 							  GError         **error);
--- gdm2/common/gdm-config.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/common/gdm-config.c	2007-06-29 17:39:00.000000000 +0100
@@ -40,10 +40,10 @@
 	char            *default_filename;
 	char            *custom_filename;
 
-	gboolean         mandatory_loaded;
-	gboolean         default_loaded;
-	gboolean         custom_loaded;
-
+	GdmConfigStatus  mandatory_loaded;
+	GdmConfigStatus  default_loaded;
+	GdmConfigStatus  custom_loaded;
+	
 	GKeyFile        *mandatory_key_file;
 	GKeyFile        *default_key_file;
 	GKeyFile        *custom_key_file;
@@ -60,18 +60,21 @@
 	gpointer         validate_func_data;
 	GdmConfigFunc    notify_func;
 	gpointer         notify_func_data;
+	GdmConfigFunc    notify_status_func;
+	gpointer         notify_status_func_data;
+	GdmConfigFunc    updatable_value_func;
+	gpointer         updatable_value_func_data;
 };
 
-
 typedef struct _GdmConfigRealValue
 {
-	GdmConfigValueType type;
-	union {
-		gboolean bool;
-		int      integer;
-		char    *str;
-		char   **array;
-	} val;
+        GdmConfigValueType type;
+        union {
+                gboolean bool;
+                int      integer;
+                char    *str;
+                char   **array;
+        } val;
 } GdmConfigRealValue;
 
 #define REAL_VALUE(x) ((GdmConfigRealValue *)(x))
@@ -744,6 +747,28 @@
 	config->notify_func_data = data;
 }
 
+void
+gdm_config_set_notify_status_func (GdmConfig       *config,
+				   GdmConfigFunc    func,
+				   gpointer         data)
+{
+	g_return_if_fail (config != NULL);
+	
+	config->notify_status_func = func;
+	config->notify_status_func_data = data;
+}
+
+void
+gdm_config_set_updatable_value_func (GdmConfig       *config,
+				     GdmConfigFunc    func,
+				     gpointer         data)
+{
+	g_return_if_fail (config != NULL);
+
+	config->updatable_value_func = func;
+	config->updatable_value_func_data = data;
+}
+
 static gboolean
 key_file_get_value (GdmConfig            *config,
 		    GKeyFile             *key_file,
@@ -929,7 +954,8 @@
 		    GdmConfigSourceType source,
 		    const char         *group,
 		    const char         *key,
-		    GdmConfigValue     *value)
+		    GdmConfigValue     *value,
+		    gboolean            do_notify)
 {
 	char           *key_path;
 	int             id;
@@ -959,8 +985,15 @@
 
 	id = lookup_id_for_key (config, group, key);
 
-	if (config->notify_func) {
-		(* config->notify_func) (config, source, group, key, value, id, config->notify_func_data);
+	if (do_notify) {
+		if (config->notify_func) {
+			(* config->notify_func) (config, source, group, key, value, id, config->notify_func_data);
+		}
+	}
+	else {
+		if (config->notify_status_func) {
+			(* config->notify_status_func) (config, source, group, key, value, id, config->notify_status_func_data);
+		}
 	}
  out:
 	g_free (key_path);
@@ -970,14 +1003,17 @@
 store_entry_value (GdmConfig            *config,
 		   const GdmConfigEntry *entry,
 		   GdmConfigSourceType   source,
-		   GdmConfigValue       *value)
+		   GdmConfigValue       *value,
+		   gboolean              do_notify)
 {
-	internal_set_value (config, source, entry->group, entry->key, value);
+	internal_set_value (config, source, entry->group, entry->key, value, do_notify);
 }
 
 static gboolean
 load_entry (GdmConfig            *config,
-	    const GdmConfigEntry *entry)
+	    const GdmConfigEntry *entry,
+	    gboolean              do_notify,
+	    gboolean              doing_update)
 {
 	GdmConfigValue     *value;
 	GdmConfigSourceType source;
@@ -992,16 +1028,21 @@
 	}
 
 	res = TRUE;
+	
 	if (config->validate_func) {
 		res = (* config->validate_func) (config, source, entry->group, entry->key, value, entry->id, config->validate_func_data);
 	}
 
+	if (doing_update && config->updatable_value_func) {
+		res = (* config->updatable_value_func) (config, source, entry->group, entry->key, value, entry->id, config->updatable_value_func_data);
+	}
+
 	if (res) {
 		/* store runs notify */
-		store_entry_value (config, entry, source, value);
+		store_entry_value (config, entry, source, value, do_notify);
 	}
 
-	return TRUE;
+	return res;
 }
 
 static void
@@ -1078,7 +1119,7 @@
 	return (char **)g_ptr_array_free (array, FALSE);
 }
 
-static gboolean
+static GdmConfigStatus
 load_backend (GdmConfig  *config,
 	      const char *filename,
 	      GKeyFile  **key_file,
@@ -1092,11 +1133,11 @@
 	time_t      lmtime;
 
 	if (filename == NULL) {
-		return FALSE;
+		return GDM_CONFIG_LOAD_FAILURE;
 	}
 
 	if (g_stat (filename, &statbuf) != 0) {
-		return FALSE;
+		return GDM_CONFIG_LOAD_FAILURE;
 	}
 	lmtime = statbuf.st_mtime;
 
@@ -1107,7 +1148,7 @@
 			g_key_file_free (*key_file);
 		} else {
 			/* no reload necessary so we're done */
-			return TRUE;
+			return GDM_CONFIG_FILE_UNCHANGED;
 		}
 	}
 
@@ -1123,9 +1164,9 @@
 		g_key_file_free (kf);
 		kf = NULL;
 		lmtime = 0;
-		ret = FALSE;
+		ret = GDM_CONFIG_LOAD_FAILURE;
 	} else {
-		ret = TRUE;
+		ret = GDM_CONFIG_LOAD_SUCCESS;
 	}
 
 	*key_file = kf;
@@ -1134,7 +1175,7 @@
 	return ret;
 }
 
-gboolean
+GdmConfigStatus
 gdm_config_load (GdmConfig *config,
 		 GError   **error)
 {
@@ -1153,14 +1194,27 @@
 					      &config->custom_key_file,
 					      &config->custom_mtime);
 
-	return TRUE;
+	
+	/*	 
+	  Atm config->mandatory_loaded is not used hence is not included
+	  in the return value. if that isn't the case anymore it will have to
+	  be included in the return value (if applicable)
+	*/
+	return (config->default_loaded | config->custom_loaded);
 }
 
+/* The key ID's should correspond to the ID's of the keys present in the 
+ * gdm_daemon_config_update_key function and marked not to be updated 
+ * during runtime. If you decide to add a key dont foret to update its
+ * value in the function mentined earlier, in this function and also
+ */
 static gboolean
 process_entries (GdmConfig             *config,
 		 const GdmConfigEntry **entries,
 		 gsize                  n_entries,
-		 GError               **error)
+		 GError               **error,
+		 gboolean               do_notify,
+		 gboolean               doing_update)
 {
 	gboolean ret;
 	int      i;
@@ -1168,23 +1222,25 @@
 	ret = TRUE;
 
 	for (i = 0; i < n_entries; i++) {
-		load_entry (config, entries[i]);
+		load_entry (config, entries[i], do_notify, doing_update);		
 	}
-
+	
 	return ret;
 }
 
 gboolean
 gdm_config_process_entry (GdmConfig            *config,
 			  const GdmConfigEntry *entry,
-			  GError              **error)
+			  GError              **error,
+			  gboolean              do_notify,
+			  gboolean              doing_update)
 {
 	gboolean  ret;
 
 	g_return_val_if_fail (config != NULL, FALSE);
-	g_return_val_if_fail (entry != NULL, FALSE);
+	g_return_val_if_fail (entry != NULL, FALSE);	
 
-	ret = load_entry (config, entry);
+	ret = load_entry (config, entry, do_notify, doing_update);
 
 	return ret;
 }
@@ -1193,7 +1249,9 @@
 gdm_config_process_entries (GdmConfig             *config,
 			    const GdmConfigEntry **entries,
 			    gsize                  n_entries,
-			    GError               **error)
+			    GError               **error,
+			    gboolean               do_notify,
+			    gboolean               doing_update)
 {
 	gboolean  ret;
 
@@ -1201,14 +1259,16 @@
 	g_return_val_if_fail (entries != NULL, FALSE);
 	g_return_val_if_fail (n_entries > 0, FALSE);
 
-	ret = process_entries (config, entries, n_entries, error);
+	ret = process_entries (config, entries, n_entries, error, do_notify, doing_update);
 
 	return ret;
 }
 
 gboolean
 gdm_config_process_all (GdmConfig *config,
-			GError   **error)
+			GError   **error,
+			gboolean   do_notify,
+			gboolean   doing_update)
 {
 	gboolean  ret;
 
@@ -1217,7 +1277,9 @@
 	ret = process_entries (config,
 			       (const GdmConfigEntry **)config->entries->pdata,
 			       config->entries->len,
-			       error);
+			       error,
+		               do_notify,
+			       doing_update);
 
 	return ret;
 }
@@ -1281,7 +1343,7 @@
 	g_return_val_if_fail (key != NULL, FALSE);
 	g_return_val_if_fail (value != NULL, FALSE);
 
-	internal_set_value (config, GDM_CONFIG_SOURCE_RUNTIME_USER, group, key, value);
+	internal_set_value (config, GDM_CONFIG_SOURCE_RUNTIME_USER, group, key, value, TRUE);
 
 	return TRUE;
 }
--- gdm2/common/gdm-common-config.h.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/common/gdm-common-config.h	2007-06-29 17:39:00.000000000 +0100
@@ -21,7 +21,8 @@
 #ifndef _GDM_COMMON_CONFIG_H
 #define _GDM_COMMON_CONFIG_H
 
-#include <glib.h>
+//#include <glib.h>
+#include "gdm-config.h"
 
 G_BEGIN_DECLS
 
@@ -34,6 +35,15 @@
 					       const char *filename,
 					       GError    **error);
 
+gboolean   gdm_common_config_get_value        (GKeyFile            *config,
+					       const char          *keystring,
+					       GdmConfigValue     **valuep,
+					       GdmConfigValueType   type,
+					       gboolean             use_default,
+					       GError             **error);
+void       gdm_common_config_set_value        (GKeyFile             *config,
+					       const char           *keystring,
+					       const GdmConfigValue *value);
 gboolean   gdm_common_config_get_string       (GKeyFile   *config,
 					       const char *keystring,
 					       char      **value,
--- gdm2/gui/gdmsetup.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/gui/gdmsetup.c	2007-07-01 21:35:52.000000000 +0100
@@ -56,12 +56,8 @@
 #include "server.h"
 
 static char     *GdmSoundProgram = NULL;
-static gchar    *GdmExclude      = NULL;
-static gchar    *GdmInclude      = NULL;
 static gint      GdmIconMaxHeight;
 static gint      GdmIconMaxWidth;
-static gboolean  GdmIncludeAll;
-static gboolean  GdmUserChangesUnsaved;
 static gboolean  GdmRandomFromSelectedChangesWarn;
 static gint      last_selected_command;
 
@@ -81,17 +77,20 @@
 static GladeXML  *xml_xservers;
 static GladeXML  *xml_commands;
 static GtkWidget *setup_notebook;
-static GList     *timeout_widgets = NULL;
 static gchar     *last_theme_installed = NULL;
 static char      *selected_themes = NULL;
 static char      *selected_theme  = NULL;
 static gchar     *config_file;
 static gchar     *custom_config_file;
-static GSList    *xservers;
+static GSList    *xservers = NULL;
 
 /* This is used to store changes made to all
-   possible fields of custom/normal commands */
-static GHashTable  *GdmCommandChangesUnsaved = NULL;
+   fields of gdmsetup */
+static GHashTable  *GdmChangesUnsaved = NULL;
+
+/* This is used to cache current config information used
+   by gdmsetup */
+static GHashTable  *GdmCurrentConfigValues = NULL;
 
 /* Used to store all available sessions */
 static GList *sessions = NULL;
@@ -177,6 +176,13 @@
 	BACKGROUND_IMAGE
 };
 
+enum {
+	WARN_NONE = 0,
+	WARN_INCLUDE_LIST = 1,
+	WARN_AUTO_TIMED_LOGIN = 2,
+	WARN_BOTH = 3,
+};
+
 
 static GtkTargetEntry target_table[] = {
 	{ "text/uri-list", 0, 0 }
@@ -260,241 +266,404 @@
   	return dialog;
 }
 
+/* This executes full config update through
+   the socket command.
+*/
 static void
 update_greeters (void)
 {
-	char *p, *ret;
-	long pid;
-	static gboolean shown_error = FALSE;
-	gboolean have_error = FALSE;
-
 	/* recheck for gdm */
 	gdm_running = gdmcomm_check (FALSE);
+	
+	if (gdm_running) {
+		char *ret;
+		char *s = g_strdup_printf ("%s %s", GDM_SUP_UPDATE_CONFIG,
+					   "all/PARAMETERS");
+		ret = gdmcomm_call_gdm (s,
+					NULL /* auth_cookie */,
+					"2.3.90.2",
+					5);
+		g_free (s);
+		g_free (ret);
+	}	
+}
 
-	if ( ! gdm_running)
-		return;
+/* Forward declarations */
+static void gdm_setup_config_set_bool_cache (const char *key, gboolean val);
+static void gdm_setup_config_set_int_cache (const char *key, gint val);
+static void gdm_setup_config_set_string_cache (const char *key, const gchar *val);
+static void gdm_setup_config_set_translated_string_cache (const char *key, const gchar *val);
 
-	ret = gdmcomm_call_gdm (GDM_SUP_GREETERPIDS,
-				NULL /* auth_cookie */,
-				"2.3.90.2",
-				5);
-	if (ret == NULL)
-		return;
-	p = strchr (ret, ' ');
-	if (p == NULL) {
-		g_free (ret);
-		return;
-	}
-	p++;
+/* Inserts the value into the unsaved changes hash and
+   enables the Apply button when necessary
+*/
+static void
+gdm_setup_config_set_value (const char *key, GdmConfigValue *value)
+{
+	GtkWidget *apply_button;
+
+	g_hash_table_insert (GdmChangesUnsaved, g_strdup (key), value);
+	
+	apply_button = glade_xml_get_widget (xml, "setup_apply_button");
+	if (!GTK_WIDGET_IS_SENSITIVE (apply_button) &&
+	    g_hash_table_size (GdmChangesUnsaved) > 0)
+		gtk_widget_set_sensitive (apply_button, TRUE);
+}
 
-	for (;;) {
-		if (sscanf (p, "%ld", &pid) != 1) {
-			g_free (ret);
-			goto check_update_error;
+/* Removes the value from the unsaved changes hash and
+   disables the Apply button when necessary
+*/
+static void
+gdm_setup_config_remove_value (const char *key)
+{
+	GtkWidget *apply_button;
+	
+	if (g_hash_table_remove (GdmChangesUnsaved, key)) {		
+		
+		apply_button = glade_xml_get_widget (xml, "setup_apply_button");
+		if (GTK_WIDGET_IS_SENSITIVE (apply_button) &&
+		    g_hash_table_size (GdmChangesUnsaved) == 0) {		
+			gtk_widget_set_sensitive (apply_button, FALSE);
 		}
+	}
+}
 
-		/* sanity */
-		if (pid <= 0)
-			continue;
+/* 
+ * There are two types of storage hashes used in those functions: 
+ * 1. GdmCurrentConfigValues (local cache of daemon current 
+ *    loaded entries) stores orginal config values 
+ *    obtained through the socket command (the lookup only 
+ *    happens for the first key request).
+ *    For certain types of keys (mainly entry widget keys)
+ *    there is not much point in badgering the daemon when
+ *    single letter is typed hence the local cache
+ * 2. GdmChangesUnsaved stores the changes to be applied
+ *
+ * gdm_setup_config_get_* functions obtain the current daemon
+ * config values from the local cache. If the value doesnt exist 
+ * in the local cache its lokked up through the socket command
+ * and the inserted into the cache.
+ *     
+ * gdm_setup_config_get_working_* functions obtain the values 
+ * changed through gdmsetup. if the value does not exist locally
+ * cached value is returned (but not added to the changed storage)
+ *  
+ * gdm_setup_config_set_* adds a value to the set of values changed
+ * through gdmsetup. Additionally of the value exists in the local 
+ * chache (i.e. is equal to the original config value) that value
+ * is removed.
+ *
+ * gdm_setup_config_set_*_cache adds a value to the local cache. No
+ * lookups of the original values are performed as it is assumed that
+ * value might not exist in the original configuration. They are 
+ * used directly for adding [servers] and [server-*] related entries
+ * and indirectly through gdm_setup_config_get_* functions
+ */
+
+static gint
+gdm_setup_config_get_int (const char *key)
+{
+	GdmConfigValue *value = NULL;
+	gint config_val;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmCurrentConfigValues, key);
 
-		if (kill (pid, SIGHUP) != 0)
-			have_error = TRUE;
-		p = strchr (p, ';');
-		if (p == NULL) {
-			g_free (ret);
-			goto check_update_error;
+	if (value == NULL) {
+		/* This value has not been required before */
+		config_val = gdm_config_get_int (key);
+		gdm_setup_config_set_int_cache (key, config_val);
+	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_INT) {
+			/* This is pretty serious we shouldn't continue */
+			g_assert_not_reached ();
 		}
-		p++;
+		
+		config_val = gdm_config_value_get_int (value);		
 	}
+	return config_val;	
+}
 
-check_update_error:
-	if ( ! shown_error && have_error) {
-		GtkWidget *setup_dialog;
-		GtkWidget *dlg;
-		setup_dialog = glade_xml_get_widget (xml, "setup_dialog");
-		dlg = hig_dialog_new (GTK_WINDOW (setup_dialog),
-				      GTK_DIALOG_MODAL |
-				      GTK_DIALOG_DESTROY_WITH_PARENT,
-				      GTK_MESSAGE_ERROR,
-				      GTK_BUTTONS_OK,
-				      _("An error occurred while "
-					"trying to contact the "
-					"login screens.  Not all "
-					"updates may have taken "
-					"effect."),
-				      "");
-		gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-		gtk_dialog_run (GTK_DIALOG (dlg));
-		gtk_widget_destroy (dlg);
-		shown_error = TRUE;
+static gint
+gdm_setup_config_get_working_int (const char *key)
+{
+	GdmConfigValue *value = NULL;
+	gint config_val;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmChangesUnsaved, key);
+
+	if (value == NULL) {
+		return gdm_setup_config_get_int (key);
+	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_INT) {
+			/* This is pretty serious we shouldn't continue */
+			g_assert_not_reached ();
+		}
+		
+		config_val = gdm_config_value_get_int (value);		
 	}
+	return config_val;	
 }
 
 static gboolean
-the_timeout (gpointer data)
+gdm_setup_config_get_bool (const char *key)
 {
-	GtkWidget *widget = data;
-	gboolean (*func) (GtkWidget *);
+	GdmConfigValue *value = NULL;
+	gboolean config_val;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmCurrentConfigValues, key);
+	
+	if (value == NULL) {
+		/* This value has not been required before */		
+		config_val = gdm_config_get_bool (key);
+		gdm_setup_config_set_bool_cache (key, config_val);
+	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_BOOL) {
+			/* This is pretty serious we shouldn't continue */
+			   g_assert_not_reached ();
+		}
+		
+		config_val = gdm_config_value_get_bool (value);		
+	}
+	return config_val;
+}
 
-	func = g_object_get_data (G_OBJECT (widget), "timeout_func");
+static gboolean
+gdm_setup_config_get_working_bool (const char *key)
+{	
+	GdmConfigValue *value = NULL;
+	gboolean config_val;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmChangesUnsaved, key);
 
-	if ( ! (*func) (widget)) {
-		g_object_set_data (G_OBJECT (widget), "change_timeout", NULL);
-		g_object_set_data (G_OBJECT (widget), "timeout_func", NULL);
-		timeout_widgets = g_list_remove (timeout_widgets, widget);
-		return FALSE;
-	} else {
-		return TRUE;
+	if (value == NULL) {
+		return gdm_setup_config_get_bool (key);
 	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_BOOL) {
+			/* This is pretty serious we shouldn't continue */
+			g_assert_not_reached ();
+		}
+		
+		config_val = gdm_config_value_get_bool (value);		
+	}
+	return config_val;	
 }
 
-static void
-run_timeout (GtkWidget *widget, guint tm, gboolean (*func) (GtkWidget *))
+static const gchar*
+gdm_setup_config_get_string (const char *key)
 {
-	guint id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
-							"change_timeout"));
-	if (id != 0) {
-		g_source_remove (id);
-	} else {
-		timeout_widgets = g_list_prepend (timeout_widgets, widget);
+	GdmConfigValue *value = NULL;
+	const gchar *config_val;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmCurrentConfigValues, key);
+
+	if (value == NULL) {
+		/* This value has not been required before */
+		config_val = gdm_config_get_string (key);
+		gdm_setup_config_set_string_cache (key, config_val);
+	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_STRING) {
+			/* This is pretty serious we shouldn't continue */
+			g_assert_not_reached ();
+		}
+		
+		config_val = gdm_config_value_get_string (value);
 	}
+	return config_val;	
+}
 
-	id = g_timeout_add (tm, the_timeout, widget);
-	g_object_set_data (G_OBJECT (widget), "timeout_func", func);
+static const gchar*
+gdm_setup_config_get_working_string (const char *key)
+{
+	GdmConfigValue *value = NULL;
+	const gchar *config_val = NULL;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmChangesUnsaved, key);
 
-	g_object_set_data (G_OBJECT (widget), "change_timeout",
-			   GUINT_TO_POINTER (id));
+	if (value == NULL) {
+		return gdm_setup_config_get_string (key);
+	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_STRING) {
+			/* This is pretty serious we shouldn't continue */
+			g_assert_not_reached ();
+		}
+		
+		config_val = gdm_config_value_get_string (value);
+	}
+	return config_val;	
 }
 
-static void
-update_key (const char *key)
+static const gchar*
+gdm_setup_config_get_translated_string (const char *key)
 {
-	if (key == NULL)
-	       return;
+	GdmConfigValue *value = NULL;
+	const gchar *config_val;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmCurrentConfigValues, key);
 
-	/* recheck for gdm */
-	gdm_running = gdmcomm_check (FALSE);
+	if (value == NULL) {
+		/* This value has not been required before */
+		config_val = gdm_config_get_translated_string (key);
+		gdm_setup_config_set_translated_string_cache (key, config_val);
+	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_LOCALE_STRING) {
+			/* This is pretty serious we shouldn't continue */
+			g_assert_not_reached ();
+		}
+		
+		config_val = gdm_config_value_get_locale_string (value);
+	}
+	return config_val;	
+}
 
-	if (gdm_running) {
-		char *ret;
-		char *s = g_strdup_printf ("%s %s", GDM_SUP_UPDATE_CONFIG,
-					   key);
-		ret = gdmcomm_call_gdm (s,
-					NULL /* auth_cookie */,
-					"2.3.90.2",
-					5);
-		g_free (s);
-		g_free (ret);
+#ifdef GDM_UNUSED_CODE
+static const gchar*
+gdm_setup_config_get_working_translated_string (const char *key)
+{
+	GdmConfigValue *value = NULL;
+	const gchar *config_val = NULL;
+	
+	value = (GdmConfigValue*) g_hash_table_lookup (GdmChangesUnsaved, key);
+
+	if (value == NULL) {
+		return gdm_setup_config_get_translated_string (key);
 	}
+	else {		
+		if (value->type != GDM_CONFIG_VALUE_LOCALE_STRING) {
+			/* This is pretty serious we shouldn't continue */
+			g_assert_not_reached ();
+		}
+		
+		config_val = gdm_config_value_get_locale_string (value);
+	}
+	return config_val;	
 }
+#endif
 
-static void
+static gboolean
 gdm_setup_config_set_bool (const char *key, gboolean val)
 {
-	GKeyFile *cfg;
-	GKeyFile *custom_cfg;
-        gboolean defaultval;
+	GdmConfigValue *value;
+	gboolean old_val;
 
-        cfg = gdm_common_config_load (config_file, NULL);
-	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
-	gdm_common_config_get_boolean (cfg, key, &defaultval, NULL);
-
-        if (val == defaultval) {
-		gdm_common_config_remove_key (custom_cfg, key, NULL);
-	} else {
-		gdm_common_config_set_boolean (custom_cfg, key, val);
+	old_val = gdm_setup_config_get_bool (key);
+	if (old_val == val) {
+		gdm_setup_config_remove_value (key);
+		return FALSE;
 	}
+	else {
+		value = gdm_config_value_new (GDM_CONFIG_VALUE_BOOL);
+		gdm_config_value_set_bool (value, val);
+		gdm_setup_config_set_value (key, value);
+	}	
+	
+	return TRUE;
+}
 
-	gdm_common_config_save (custom_cfg, custom_config_file, NULL);
-
-	g_key_file_free (cfg);
-	g_key_file_free (custom_cfg);
+static void
+gdm_setup_config_set_bool_cache (const char *key, gboolean val)
+{
+	GdmConfigValue *value;
 
-	update_key (key);
+	value = gdm_config_value_new (GDM_CONFIG_VALUE_BOOL);
+	gdm_config_value_set_bool (value, val);
+	g_hash_table_insert (GdmCurrentConfigValues, g_strdup (key), value);
 }
 
-static void
+static gboolean
 gdm_setup_config_set_int (const char *key, int val)
 {
-	GKeyFile *cfg;
-	GKeyFile *custom_cfg;
-        int       defaultval;
-
-        cfg = gdm_common_config_load (config_file, NULL);
-	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
-	gdm_common_config_get_int (cfg, key, &defaultval, NULL);
+	GdmConfigValue *value;
+	gint old_val;
 
-	if (val == defaultval) {
-		gdm_common_config_remove_key (custom_cfg, key, NULL);
-	} else {
-		gdm_common_config_set_int (custom_cfg, key, val);
+	old_val = gdm_setup_config_get_int (key);
+	if (old_val == val) {
+		gdm_setup_config_remove_value (key);
+		return FALSE;
+	}
+	else {
+		value = gdm_config_value_new (GDM_CONFIG_VALUE_INT);
+		gdm_config_value_set_int (value, val);
+		gdm_setup_config_set_value (key, value);
 	}
 
-	gdm_common_config_save (custom_cfg, custom_config_file, NULL);
-
-	g_key_file_free (cfg);
-	g_key_file_free (custom_cfg);
-
-	update_key (key);
+	return TRUE;
 }
 
 static void
-gdm_setup_config_set_string (const char *key, gchar *val)
+gdm_setup_config_set_int_cache (const char *key, gint val)
 {
-	GKeyFile *cfg;
-	GKeyFile *custom_cfg;
-        char     *defaultval;
-
-        cfg = gdm_common_config_load (config_file, NULL);
-	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
-	gdm_common_config_get_string (cfg, key, &defaultval, NULL);
+	GdmConfigValue *value;
+	
+	value = gdm_config_value_new (GDM_CONFIG_VALUE_INT);
+	gdm_config_value_set_int (value, val);
+	g_hash_table_insert (GdmCurrentConfigValues, g_strdup (key), value);
+}
 
-	if (defaultval != NULL &&
-	    strcmp (ve_sure_string (val), ve_sure_string (defaultval)) == 0) {
-		gdm_common_config_remove_key (custom_cfg, key, NULL);
-	} else {
-		gdm_common_config_set_string (custom_cfg, key, val);
+static gboolean
+gdm_setup_config_set_string (const char *key, gchar *val)
+{
+	GdmConfigValue *value;
+	const gchar *old_val;
+	
+	old_val = gdm_setup_config_get_string (key);	
+	if (strcmp (ve_sure_string (val), ve_sure_string (old_val)) == 0) {
+		gdm_setup_config_remove_value (key);
+		return FALSE;
 	}
+	else {	
+		value = gdm_config_value_new (GDM_CONFIG_VALUE_STRING);
+		gdm_config_value_set_string (value, val);
+		gdm_setup_config_set_value (key, value);
+	}
+	
+	return TRUE;
+}
 
-	if (defaultval)
-		g_free (defaultval);
-
-	gdm_common_config_save (custom_cfg, custom_config_file, NULL);
-
-	g_key_file_free (cfg);
-	g_key_file_free (custom_cfg);
+static void
+gdm_setup_config_set_string_cache (const char *key, const gchar *val)
+{
+	GdmConfigValue *value;
 
-	update_key (key);
+	value = gdm_config_value_new (GDM_CONFIG_VALUE_STRING);
+	gdm_config_value_set_string (value, val);
+	g_hash_table_insert (GdmCurrentConfigValues, g_strdup (key), value);
 }
 
 static gboolean
-radiogroup_timeout (GtkWidget *toggle)
-{	
-	const char *key = g_object_get_data (G_OBJECT (toggle), "key");
-	GSList *radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (toggle));
-		
-	if (strcmp (ve_sure_string (key), GDM_KEY_RELAX_PERM) == 0) {
-		GSList *tmp;
-		gint val;
-		gint selected = 0;
-		gint i = 0;
-		gint list_size;
-		
-		val = gdm_config_get_int ((gchar *)key);
-		list_size = g_slist_length (radio_group) - 1;
-		
-		for (tmp = radio_group; tmp != NULL; tmp = tmp->next, i++) {
-			GtkWidget *radio_button;
-			radio_button = (GtkWidget *) tmp->data;
-			if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_button)))
-				selected = list_size - i;
-		}
-		
-		if (val != selected)
-			gdm_setup_config_set_int (key, selected);
-			
+gdm_setup_config_set_translated_string (const char *key, gchar *val)
+{
+	GdmConfigValue *value;
+	const gchar *old_val;
+	
+	old_val = gdm_setup_config_get_translated_string (key);
+	if (strcmp (ve_sure_string (val), ve_sure_string (old_val)) == 0) {
+		gdm_setup_config_remove_value (key);
+		return FALSE;
+	}
+	else {
+		value = gdm_config_value_new (GDM_CONFIG_VALUE_LOCALE_STRING);
+		gdm_config_value_set_locale_string (value, val);
+		gdm_setup_config_set_value (key, value);
 	}
-	return FALSE;	
+	
+	return TRUE;
+}
+
+static void
+gdm_setup_config_set_translated_string_cache (const char *key, const gchar *val)
+{
+	GdmConfigValue *value;
+	
+	value = gdm_config_value_new (GDM_CONFIG_VALUE_LOCALE_STRING);
+	gdm_config_value_set_locale_string (value, val);
+	g_hash_table_insert (GdmCurrentConfigValues, g_strdup (key), value);
 }
 
 static gboolean
@@ -505,19 +674,33 @@
 	else
 		return FALSE;
 }
+/* Forward declaration */
+static void
+setup_user_combobox_list (const char *name, const char *key);
 
-static gboolean
-toggle_timeout (GtkWidget *toggle)
+static void
+toggle_toggled_other (GtkWidget *toggle, GtkWidget *toggle_other)
+{
+	const char *key              = g_object_get_data (G_OBJECT (toggle), "key");
+	gboolean toggle_active       = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle));
+	gboolean other_toggle_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle_other));
+	
+	if (other_toggle_active != toggle_active) {
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle_other), toggle_active);
+	
+		gdm_setup_config_set_bool (key, toggle_active);
+	}
+}
+
+static void
+toggle_toggled (GtkWidget *toggle, gpointer func_data)
 {
 	const char *key = g_object_get_data (G_OBJECT (toggle), "key");
-	gboolean    val = gdm_config_get_bool ((gchar *)key);
 
 	if (strcmp (ve_sure_string (key), GDM_KEY_ENTRY_INVISIBLE) == 0) {
 		/* This is a lil bit back to front
 		   true is false and false is true in this case */
-		if ( bool_equal (val, GTK_TOGGLE_BUTTON (toggle)->active)) {
-			gdm_setup_config_set_bool (key, !GTK_TOGGLE_BUTTON (toggle)->active);
-		}
+		gdm_setup_config_set_bool (key, !GTK_TOGGLE_BUTTON (toggle)->active);		
 	}
 	else if (strcmp (ve_sure_string (key), GDM_KEY_GLOBAL_FACE_DIR) == 0) {
 		/* Once enabled write the curently selected item
@@ -528,15 +711,13 @@
 			GtkWidget *file_chooser;
 
 			file_chooser = glade_xml_get_widget (xml, "global_face_dir_filechooser");
-			filename  = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-			if (strcmp (ve_sure_string (gdm_config_get_string ((char*)key)),
-				    ve_sure_string (filename)) != 0)
-				gdm_setup_config_set_string (key, ve_sure_string (filename));
+			filename  = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));			
+			gdm_setup_config_set_string (key, ve_sure_string (filename));
 
 			g_free (filename);
 		}
 		else
-			gdm_setup_config_set_string (key, "");		    
+			gdm_setup_config_set_string (key, "");		
 	}	
 	else if (strcmp (ve_sure_string (key), GDM_KEY_DEFAULT_FACE) == 0) {
 		/* Once enabled write the curently selected item
@@ -547,17 +728,13 @@
 			GtkWidget *file_chooser;
 			
 			file_chooser = glade_xml_get_widget (xml, "default_face_filechooser");
-
 			filename  = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-			
-			if (strcmp (ve_sure_string (gdm_config_get_string ((char*)key)), 
-				    ve_sure_string (filename)) != 0)				
-				gdm_setup_config_set_string (key, ve_sure_string (filename));
+			gdm_setup_config_set_string (key, ve_sure_string (filename));
 			
 			g_free (filename);
 		}
 		else
-			gdm_setup_config_set_string (key, "");		    
+			gdm_setup_config_set_string (key, "");		
 	}
 	else if (strcmp (ve_sure_string (key), GDM_KEY_GTKRC) == 0) {
 		/* Once enabled write the curently selected item
@@ -567,12 +744,9 @@
 			gchar *filename;
 			GtkWidget *file_chooser;
 			
-			file_chooser = glade_xml_get_widget (xml, "gtkrc_chooserbutton");
-
+			file_chooser = glade_xml_get_widget (xml, "gtkrc_filechooserbutton");
 			filename  = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-			
-			if (strcmp (ve_sure_string (gdm_config_get_string ((char*)key)), 
-				    ve_sure_string (filename)) != 0)				
+			if (filename != NULL)
 				gdm_setup_config_set_string (key, ve_sure_string (filename));
 			
 			g_free (filename);
@@ -584,123 +758,74 @@
 		/* Once enabled write the curently selected item
 		   in the combobox widget, otherwise disable
 		   the config entry, i.e. write an empty string */		
-
 		if (GTK_TOGGLE_BUTTON (toggle)->active == TRUE) {
 			gint selected;
-			gchar *value;
+			const gchar *value;
 			gchar *new_val = NULL;			
 			GtkWidget *default_session_combobox;
 			
 			default_session_combobox = glade_xml_get_widget (xml, "default_session_combobox");
-
-			selected = gtk_combo_box_get_active (GTK_COMBO_BOX (default_session_combobox));
-			
-			value = gdm_config_get_string ((gchar *)key);
-									
-			new_val = g_strdup ((gchar*) g_list_nth_data (sessions, selected));					
+			selected = gtk_combo_box_get_active (GTK_COMBO_BOX (default_session_combobox));			
+			value = gdm_setup_config_get_string ((gchar *)key);
 			
-			if (strcmp (ve_sure_string (value), ve_sure_string (new_val)) != 0)				
-				gdm_setup_config_set_string (key, ve_sure_string (new_val));
+			new_val = g_strdup ((gchar*) g_list_nth_data (sessions, selected));
+			gdm_setup_config_set_string (key, ve_sure_string (new_val));
 			
-			g_free (value);
 			g_free (new_val);
 		}
 		else
 			gdm_setup_config_set_string (key, "");		    
 	}	
 	else {
-		/* All other cases */
-		if ( ! bool_equal (val, GTK_TOGGLE_BUTTON (toggle)->active)) {
-			gdm_setup_config_set_bool (key, GTK_TOGGLE_BUTTON (toggle)->active);
-		}
+		/* All other cases */	
+		gdm_setup_config_set_bool (key, GTK_TOGGLE_BUTTON (toggle)->active);		
 	}	
-
-	return FALSE;
 }
 
-static gboolean
-command_toggle_timeout (GtkWidget *toggle)
+static void
+command_toggle_toggled (GtkWidget *toggle, gpointer data)
 {
+	const GtkWidget *command_combobox;	
+	gchar *key_string = NULL;
+	gboolean val = FALSE;
+
 	const char *key = g_object_get_data (G_OBJECT (toggle), "key");
+	command_combobox = (const GtkWidget*)data;
 	
 	if (strcmp (ve_sure_string (key), GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE) == 0 ||
 	    strcmp (ve_sure_string (key), GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE) == 0) {
 		/* This only applies to custom commands
 		   First find which command has been ticked on/off then put the new value 
-		   together with the corresponding key into the command changed hash. 
-		   Enable apply command changes button. If command is equal to the existing
-		   config value remove it from the hash and disable the apply command changes 
-		   button (if applicable) */
-		
-		gchar *key_string;
-		gboolean old_val = FALSE;
-		gboolean val;
-		GtkWidget *apply_cmd_changes;
-		GtkWidget *command_combobox;
+		   together with the corresponding key into the changed storage hash.*/
+			
 		gint selected, i;
 		
-		val = GTK_TOGGLE_BUTTON (toggle)->active;
-		apply_cmd_changes = glade_xml_get_widget (xml_commands, "command_apply_button");
-		command_combobox = glade_xml_get_widget (xml_commands, "cmd_type_combobox");
+		val = GTK_TOGGLE_BUTTON (toggle)->active;       
 		
 		selected = gtk_combo_box_get_active (GTK_COMBO_BOX (command_combobox));
 		
 		i = selected - CUSTOM_CMD;
-		key_string = g_strdup_printf("%s%d=", ve_sure_string (key), i); 
-		old_val = gdm_config_get_bool (key_string);
-		
-		if (val != old_val) {	
-			gboolean *p_val = g_new0 (gboolean, 1);
-			*p_val = val;
-			g_hash_table_insert (GdmCommandChangesUnsaved, g_strdup (key_string), p_val);
-		}
-		else if (g_hash_table_lookup (GdmCommandChangesUnsaved, key_string) != NULL) {
-			g_hash_table_remove (GdmCommandChangesUnsaved, key_string);
-		}
-		
-		g_free (key_string);
-		
-		if (g_hash_table_size (GdmCommandChangesUnsaved) == 0)
-			gtk_widget_set_sensitive (apply_cmd_changes, FALSE);
-		else 
-			gtk_widget_set_sensitive (apply_cmd_changes, TRUE);
-	}		
+		key_string = g_strdup_printf("%s%d=", ve_sure_string (key), i);		
+	}
 	
-	return FALSE;
+	gdm_setup_config_set_bool (key_string, val);
+	
+	g_free (key_string);
 }
 
-static gboolean
-logo_toggle_timeout (GtkWidget *toggle)
+static void
+logo_toggle_toggled (GtkWidget *toggle, gpointer data)
 {
 	const char *key = g_object_get_data (G_OBJECT (toggle), "key");
 	GtkWidget  *chooserbutton;
 	gchar      *filename;
-
-	chooserbutton = glade_xml_get_widget (xml, "local_logo_image_chooserbutton");
-						
-	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooserbutton));
 	
- 	if ((GTK_TOGGLE_BUTTON (toggle)->active) == FALSE) {
-		gdm_setup_config_set_string (GDM_KEY_CHOOSER_BUTTON_LOGO, filename);	
-		gdm_setup_config_set_string (key, "");
-	}
-	else if (filename != NULL) {
-		gdm_setup_config_set_string (GDM_KEY_CHOOSER_BUTTON_LOGO, filename);
-		gdm_setup_config_set_string (key, filename);
-	}
-	update_greeters ();
-	g_free (filename);
-	return FALSE;
-}
-
-static void
-logo_toggle_toggled (GtkWidget *toggle, gpointer data)
-{
 	if (gtk_notebook_get_current_page (GTK_NOTEBOOK (setup_notebook)) == LOCAL_TAB) {
 
 		GtkWidget *checkbutton;
 		
 		checkbutton = glade_xml_get_widget (xml, "remote_logo_image_checkbutton");
+		chooserbutton = glade_xml_get_widget (xml, "local_logo_image_chooserbutton");
 
 		g_signal_handlers_disconnect_by_func (checkbutton,
 		                                      (gpointer) logo_toggle_toggled,
@@ -716,6 +841,7 @@
 		GtkWidget *checkbutton;
 
 		checkbutton = glade_xml_get_widget (xml, "local_logo_image_checkbutton");
+		chooserbutton = glade_xml_get_widget (xml, "remote_logo_image_chooserbutton");
 
 		g_signal_handlers_disconnect_by_func (checkbutton,
 		                                      (gpointer) logo_toggle_toggled,
@@ -727,26 +853,47 @@
 		g_signal_connect (G_OBJECT (checkbutton), "toggled", 
 		                  G_CALLBACK (logo_toggle_toggled), NULL);
 	}
-	run_timeout (toggle, 200, logo_toggle_timeout);
+
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooserbutton));
+		
+	if (filename != NULL)
+		gdm_setup_config_set_string (GDM_KEY_CHOOSER_BUTTON_LOGO, filename);
+
+ 	if ((GTK_TOGGLE_BUTTON (toggle)->active) == FALSE) {	       
+		gdm_setup_config_set_string (key, "");
+	}
+	else if (filename != NULL) {
+		gdm_setup_config_set_string (key, filename);
+	}
+
+	g_free (filename);
 }
 
 /* Forward declarations */
-static void
-setup_user_combobox_list (const char *name, const char *key);
 static char *
 strings_list_add (char *strings_list, const char *string, const char *sep);
 static char *
 strings_list_remove (char *strings_list, const char *string, const char *sep);
 
-static gboolean
-intspin_timeout (GtkWidget *spin)
+static void
+intspin_changed_other (GtkWidget *spin, GtkWidget *spin_other)
 {
 	const char *key = g_object_get_data (G_OBJECT (spin), "key");
-	int new_val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
-	int val;
-	gboolean greeters_need_update = FALSE;
+	int val         = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));	
+	int val_other   = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin_other));
+	
+	if (val_other != val) {
+		gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_other), val);		
+		gdm_setup_config_set_int (key, val);
+	}
+}
 
-	val = gdm_config_get_int ((gchar *)key);
+static void
+intspin_changed (GtkWidget *spin, gpointer data)
+{	
+	const char *key = g_object_get_data (G_OBJECT (spin), "key");
+	int new_val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
+	gboolean greeters_need_update = FALSE;	
 
 	if (strcmp (ve_sure_string (key), GDM_KEY_MINIMAL_UID) == 0){
 		/* We have changed MinimalUID, so we need to go through
@@ -754,12 +901,19 @@
 		   the entries that do not match the criteria anymore. If there 
 		   are any user is informed about the changes. Auto login and 
 		   timed login comboboxes are adjusted and greeters restarted */
+		GtkWidget *setup_dialog; 
+		GtkWidget *dlg = NULL;
 		char **list;
 		char *removed = NULL;	
 		int i;
-		gchar *autologon_user;
-		gchar *timedlogon_user;
+		const gchar *autologon_user;
+		const gchar *timedlogon_user;
+		gchar *GdmInclude;
+		gint show_warning = WARN_NONE;
 		
+		gdm_setup_config_set_int (key, new_val);
+
+		GdmInclude = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_INCLUDE));
 		
 		list = g_strsplit (GdmInclude, ",", 0);
 		for (i=0; list != NULL && list[i] != NULL; i++) {
@@ -778,23 +932,9 @@
 			gchar *text;
 			GtkWidget *include_treeview;
 			GtkTreeModel *include_model;			
-			GtkWidget *dlg;	
-			GtkTreeIter iter;			
-			GtkWidget *setup_dialog;
-
-			setup_dialog = glade_xml_get_widget(xml, "setup_dialog");
+			GtkTreeIter iter;
 
-			//Inform user about the change and its implications
-			dlg = hig_dialog_new (GTK_WINDOW (setup_dialog),
-					      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-					      GTK_MESSAGE_WARNING,
-					      GTK_BUTTONS_OK,
-					      _("Users include list modification"),
-					      _("Some of the users in the Include list "
-						"(Users tab) now have uid lower than "
-						"MinimalUID and will be removed."));
-			gtk_dialog_run (GTK_DIALOG (dlg));
-			gtk_widget_destroy (dlg);						
+			show_warning |= WARN_INCLUDE_LIST;
 
 			include_treeview  = glade_xml_get_widget (xml, "fb_include_treeview");
 
@@ -815,23 +955,24 @@
 			g_free (text);
 			/* Now we need to save updated list, toggle the 
 			   automatic and timed loggon comboboxes and update greeters */
-			gdm_setup_config_set_string (GDM_KEY_INCLUDE, GdmInclude);				
-			
+			gdm_setup_config_set_string (GDM_KEY_INCLUDE, GdmInclude);
+			g_free (GdmInclude);
+
 			greeters_need_update = TRUE;
 
-		}
-		
+		}	       		   		
 		g_free (removed);
-
+		
 		/* We also need to check if user (if any) in the
 		   autologon/timed logon still match the criteria */
-		autologon_user = gdm_config_get_string (GDM_KEY_AUTOMATIC_LOGIN);
-		timedlogon_user = gdm_config_get_string (GDM_KEY_TIMED_LOGIN);
+		autologon_user = gdm_setup_config_get_working_string (GDM_KEY_AUTOMATIC_LOGIN);
+		timedlogon_user = gdm_setup_config_get_working_string (GDM_KEY_TIMED_LOGIN);
 
 		if(!ve_string_empty (autologon_user)) {
 			if (gdm_is_user_valid (autologon_user) && gdm_user_uid (autologon_user) < new_val) {
 				gdm_setup_config_set_string (GDM_KEY_AUTOMATIC_LOGIN, "");			
 				greeters_need_update = TRUE;
+				show_warning |= WARN_AUTO_TIMED_LOGIN;
 			}
 		}
 
@@ -839,93 +980,71 @@
 			if (gdm_is_user_valid (timedlogon_user) && gdm_user_uid (timedlogon_user) < new_val) {
 				gdm_setup_config_set_string (GDM_KEY_TIMED_LOGIN, "");						
 				greeters_need_update = TRUE;
+				show_warning |= WARN_AUTO_TIMED_LOGIN;
 			}
 		}
 
-		g_free (autologon_user);
-		g_free (timedlogon_user);
+		if (gdm_setup_config_get_working_bool (GDM_KEY_INCLUDE_ALL))
+			greeters_need_update = TRUE;
 
-	}
+		if (show_warning != WARN_NONE) {
+			gchar *warn_msg = NULL;
+			gchar *dlg_title = NULL;
+			
+			switch (show_warning) {
+			case WARN_INCLUDE_LIST: {
+				warn_msg = g_strdup (_("Some of the users in the Include list "
+						       "(Users tab) now have uid lower than "
+						       "MinimalUID and will be removed."));
+				dlg_title = g_strdup (_("Users include list modification"));
+				break;
+			}
+			case WARN_AUTO_TIMED_LOGIN: {
+				warn_msg = g_strdup (_("Some of the Timed Login "
+						       "and Automatic Login users"
+						       " (Security tab) have uid lower than "
+						       "MinimalUID and will be removed."));
+				dlg_title = g_strdup (_("Timed and Automatic Login list modification"));
+				break;
+			}
+			case WARN_BOTH: {
+				warn_msg = g_strdup (_("Some of the users in the Include list "
+						       "(Users tab) now have uid lower than "
+						       "MinimalUID and will be removed."
+						       "This also affects Timed Login "
+						       "and Automatic Login users (Security tab)."));
+				dlg_title = g_strdup (_("Users include list modification"));
+				break;
+			}
+			default: {
+				warn_msg = g_strdup ("");
+				dlg_title = g_strdup ("");
+				break;
+			}
+			}
+			
+			setup_dialog = glade_xml_get_widget(xml, "setup_dialog");
+			
+			//Inform user about the change and its implications
+			dlg = hig_dialog_new (GTK_WINDOW (setup_dialog),
+					      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+					      GTK_MESSAGE_WARNING,
+					      GTK_BUTTONS_OK,
+					      dlg_title,
+					      warn_msg);
 
-	if (val != new_val)
-		gdm_setup_config_set_int (key, new_val);
+			gtk_dialog_run (GTK_DIALOG (dlg));
+			gtk_widget_destroy (dlg);
+			g_free (dlg_title);
+			g_free (warn_msg);
+		}
+	}		
 
 	if (greeters_need_update) {
 		setup_user_combobox_list ("autologin_combo",
 					  GDM_KEY_AUTOMATIC_LOGIN);
 		setup_user_combobox_list ("timedlogin_combo",
 					  GDM_KEY_TIMED_LOGIN);
-		update_greeters ();
-	}
-
-	return FALSE;
-}
-
-static gint
-display_sort_func (gpointer d1, gpointer d2)
-{
-   return (strcmp (ve_sure_string ((gchar *)d1), ve_sure_string ((gchar *)d2)));
-}
-
-static GSList *displays          = NULL;
-static GSList *displays_inactive = NULL;
-static GHashTable *dispval_hash  = NULL;
-
-static void
-gdm_load_displays (GKeyFile *cfg,
-		   char    **keys)
-{
-	GSList *li2;
-	int i;
-
-	for (i = 0; keys[i] != NULL; i++) {
-		const gchar *key = keys[i];
-
-		if (isdigit (*key)) {
-			gchar *fullkey;
-			gchar *dispval;
-			int keynum = atoi (key);
-			gboolean skip_entry = FALSE;
-
-			fullkey = g_strdup_printf ("%s/%s", GDM_KEY_SECTION_SERVERS, key);
-			gdm_common_config_get_string (cfg, fullkey, &dispval, NULL);
-			g_free (fullkey);
-
-			/* Do not add if already in the list */
-			for (li2 = displays; li2 != NULL; li2 = li2->next) {
-				gchar *disp = li2->data;
-				if (atoi (disp) == keynum) {
-					skip_entry = TRUE;
-					break;
-				}
-			}
-
-			/* Do not add if this display was marked as inactive already */
-			for (li2 = displays_inactive; li2 != NULL; li2 = li2->next) {
-				gchar *disp = li2->data;
-				if (atoi (disp) == keynum) {
-					skip_entry = TRUE;
-					break;
-				}
-			}
-
-			if (skip_entry == TRUE) {
-				g_free (dispval);
-				continue;
-			}
-
-			if (g_ascii_strcasecmp (ve_sure_string (dispval), "inactive") == 0) {
-				displays_inactive = g_slist_append (displays_inactive, g_strdup (key));
-			} else {
-				if (dispval_hash == NULL)
-					dispval_hash = g_hash_table_new (g_str_hash, g_str_equal);            
-
-				displays = g_slist_insert_sorted (displays, g_strdup (key), (GCompareFunc) display_sort_func);
-				g_hash_table_insert (dispval_hash, g_strdup (key), g_strdup (dispval));
-			}
-
-			g_free (dispval);
-		}
 	}
 }
 
@@ -970,63 +1089,6 @@
 }
 
 static void
-xservers_get_displays (GtkListStore *store)
-{
-	/* Find server definitions */
-	GKeyFile *custom_cfg;
-	GKeyFile *cfg;
-	char    **keys;
-	GSList *li;
-	gchar *server, *options;
-
-	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
-        cfg = gdm_common_config_load (config_file, NULL);
-
-	/* Fill list with all the active displays */
-	if (custom_cfg != NULL) {
-		keys = g_key_file_get_keys (custom_cfg, GDM_KEY_SECTION_SERVERS, NULL, NULL);
-		gdm_load_displays (custom_cfg, keys);
-		g_strfreev (keys);
-	}
-
-	keys = g_key_file_get_keys (cfg, GDM_KEY_SECTION_SERVERS, NULL, NULL);
-	gdm_load_displays (cfg, keys);
-	g_strfreev (keys);
-
-	for (li = displays; li != NULL; li = li->next) {
-		GtkTreeIter iter;
-		gchar *key = li->data;
-		int vt = atoi (key);
-		server = ve_first_word (g_hash_table_lookup (dispval_hash, key));
-		options = ve_rest (g_hash_table_lookup (dispval_hash, key));
-
-		gtk_list_store_append (store, &iter);
-		gtk_list_store_set (store, &iter,
-				    XSERVER_COLUMN_VT, vt,
-				    XSERVER_COLUMN_SERVER, server,
-				    XSERVER_COLUMN_OPTIONS, options,
-				    -1);
-		g_free (server);
-	}
-	for (li = displays; li != NULL; li = li->next) {
-		gchar *disp = li->data;
-		g_free (disp);
-	}
-	g_slist_free (displays);
-        displays = NULL;
-	for (li = displays_inactive; li != NULL; li = li->next) {
-		gchar *disp = li->data;
-		g_free (disp);
-	}
-	g_slist_free (displays_inactive);
-        displays_inactive = NULL;
-        if (dispval_hash) {
-           g_hash_table_destroy (dispval_hash);
-           dispval_hash = NULL;
-        }
-}
-
-static void
 xserver_update_delete_sensitivity ()
 {
 	GtkWidget *modify_combobox, *delete_button;
@@ -1047,8 +1109,6 @@
 	                            G_TYPE_STRING /* server type */,
 	                            G_TYPE_STRING /* options */);
 
-	/* Get list of servers and determine which one was selected */
-	xservers_get_displays (store);
 
 	i = gtk_combo_box_get_active (GTK_COMBO_BOX (modify_combobox));
 	if (i < 0) {
@@ -1093,7 +1153,6 @@
 	GtkWidget *handled_checkbutton;
 	GtkWidget *flexible_checkbutton;
 	GtkWidget *priority_spinbutton;
-	GtkListStore *store;
 	GdmXserver *xserver;
 
 	mod_combobox = glade_xml_get_widget (xml_xservers, "xserver_mod_combobox");
@@ -1104,13 +1163,6 @@
 	flexible_checkbutton = glade_xml_get_widget (xml_xservers, "xserver_flexible_checkbutton");
 	priority_spinbutton = glade_xml_get_widget(xml_xservers, "xserv_priority_spinbutton");
 
-	/* Get list of servers that are set to start */
-	store = gtk_list_store_new (XSERVER_NUM_COLUMNS,
-	                            G_TYPE_INT    /* virtual terminal */,
-	                            G_TYPE_STRING /* server type */,
-	                            G_TYPE_STRING /* options */);
-	xservers_get_displays (store);
-
 	xserver = g_slist_nth_data (xservers, index);
 
 	gtk_combo_box_set_active (GTK_COMBO_BOX (mod_combobox), index);
@@ -1138,7 +1190,7 @@
 update_remote_sensitivity (gboolean value)
 {
 	GtkWidget *remote_background_color_hbox;
-	GtkWidget *remote_background_image_hhox;
+	GtkWidget *remote_background_image_hbox;
 	GtkWidget *remote_background_image_checkbutton;
 	GtkWidget *remote_background_image_chooserbutton;
 	GtkWidget *remote_logo_image_checkbutton;
@@ -1147,9 +1199,10 @@
 	GtkWidget *remote_theme_mode_hbox;
 	GtkWidget *remote_theme_select_hbox;
 	GtkWidget *sg_scale_background_remote_hbox;
-
+	GtkWidget *remote_behaviour_vbox;
+	
 	remote_background_color_hbox = glade_xml_get_widget (xml, "remote_background_color_hbox");
-	remote_background_image_hhox = glade_xml_get_widget (xml, "remote_background_image_hhox");
+	remote_background_image_hbox = glade_xml_get_widget (xml, "remote_background_image_hbox");
 	remote_background_image_checkbutton = glade_xml_get_widget (xml, "remote_background_image_checkbutton");
 	remote_background_image_chooserbutton = glade_xml_get_widget (xml, "remote_background_image_chooserbutton");
 	remote_logo_image_checkbutton = glade_xml_get_widget (xml, "remote_logo_image_checkbutton");
@@ -1158,9 +1211,10 @@
 	remote_theme_mode_hbox = glade_xml_get_widget (xml, "remote_theme_mode_hbox");
 	remote_theme_select_hbox = glade_xml_get_widget (xml, "remote_theme_select_hbox");
 	sg_scale_background_remote_hbox = glade_xml_get_widget (xml, "sg_scale_background_remote_hbox");
-
+	remote_behaviour_vbox = glade_xml_get_widget (xml, "remote_behaviour_vbox");
+					       
 	gtk_widget_set_sensitive (remote_background_color_hbox, value);
-	gtk_widget_set_sensitive (remote_background_image_hhox, value);
+	gtk_widget_set_sensitive (remote_background_image_hbox, value);
 	gtk_widget_set_sensitive (remote_background_image_checkbutton, value);
 	gtk_widget_set_sensitive (remote_background_image_chooserbutton, value);
 	gtk_widget_set_sensitive (remote_logo_image_checkbutton, value);
@@ -1168,7 +1222,8 @@
 	gtk_widget_set_sensitive (remote_theme_background_hbox, value);
 	gtk_widget_set_sensitive (remote_theme_mode_hbox, value);
 	gtk_widget_set_sensitive (remote_theme_select_hbox, value);
-	gtk_widget_set_sensitive (sg_scale_background_remote_hbox, value);
+	gtk_widget_set_sensitive (sg_scale_background_remote_hbox, value);	
+	gtk_widget_set_sensitive (remote_behaviour_vbox, value);	
 }
 
 static void
@@ -1182,7 +1237,7 @@
 	GtkWidget *welcome_message_vbox;
 	GtkWidget *allowremoteroot;
 	GtkWidget *allowremoteauto;
-	gchar *remote_style;
+	const gchar *remote_style;
 	gint local_style;
 
 	local_greeter = glade_xml_get_widget (xml, "local_greeter");
@@ -1198,9 +1253,9 @@
 	gtk_combo_box_remove_text (GTK_COMBO_BOX (remote_greeter), REMOTE_PLAIN);
 	
 	local_style  = gtk_combo_box_get_active (GTK_COMBO_BOX (local_greeter));
-	remote_style = gdm_config_get_string (GDM_KEY_REMOTE_GREETER);
+	remote_style = gdm_setup_config_get_working_string (GDM_KEY_REMOTE_GREETER);
 					     			 
-	if (gdm_config_get_bool (GDM_KEY_XDMCP) == FALSE) {
+	if (gdm_setup_config_get_bool (GDM_KEY_XDMCP) == FALSE) {
 				
 		if (local_style == LOCAL_PLAIN) {
 			gtk_combo_box_append_text (GTK_COMBO_BOX (remote_greeter), _("Themed"));
@@ -1224,7 +1279,7 @@
 		gtk_widget_hide (configure_xdmcp_vbox);
 	}
 	else {
-		gboolean use_browser = gdm_config_get_bool (GDM_KEY_BROWSER);
+		gboolean use_browser = gdm_setup_config_get_bool (GDM_KEY_BROWSER);
 		
 		if (local_style == LOCAL_PLAIN || local_style == LOCAL_PLAIN_WITH_FACE) {
 
@@ -1269,7 +1324,7 @@
 				gtk_widget_show (remote_themed_vbox);
 			}
 		}
-		gtk_widget_set_sensitive (allowremoteauto, gdm_config_get_bool (GDM_KEY_XDMCP));
+		gtk_widget_set_sensitive (allowremoteauto, gdm_setup_config_get_bool (GDM_KEY_XDMCP));
 		gtk_widget_set_sensitive (allowremoteroot, TRUE);
 		gtk_widget_show (welcome_message_vbox);
 		gtk_widget_show (configure_xdmcp_vbox);
@@ -1277,394 +1332,109 @@
 }
 
 /*
- * We probably should check the server definition in the defaults.conf file
- * and just erase the section if the values are the same, like we do for the
- * displays section and the normal configuration sections.
+ * For a given server we save all of its parameters.
  */
 static void
 update_xserver (gchar *section, GdmXserver *svr)
 {
-	GKeyFile *custom_cfg;
 	gchar *real_section;
 	gchar *key;
 
-	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
 	real_section = g_strdup_printf ("%s%s", GDM_KEY_SERVER_PREFIX, section);
-
+	
 	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_NAME, NULL);
-	gdm_common_config_set_string (custom_cfg, key, svr->name);
+	gdm_setup_config_set_string (key, svr->name);
 	g_free (key);
 
 	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_COMMAND, NULL);
-	gdm_common_config_set_string (custom_cfg, key, svr->command);
+	gdm_setup_config_set_string (key, svr->command);
 	g_free (key);
 
 	key = g_strconcat (real_section, "/", GDM_KEY_SERVER_CHOOSER, NULL);
-	gdm_common_config_set_boolean (custom_cfg, key, svr->chooser);
+	gdm_setup_config_set_bool (key, svr->chooser);
 	g_free (key);
 
 	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_HANDLED, NULL);
-	gdm_common_config_set_boolean (custom_cfg, key, svr->handled);
+	gdm_setup_config_set_bool (key, svr->handled);
 	g_free (key);
 
 	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_FLEXIBLE, NULL);
-	gdm_common_config_set_boolean (custom_cfg, key, svr->flexible);
+	gdm_setup_config_set_bool (key, svr->flexible);
 	g_free (key);
 
 	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_PRIORITY, NULL);
-	gdm_common_config_set_int (custom_cfg, key, svr->priority);
+	gdm_setup_config_set_int (key, svr->priority);
 	g_free (key);
 
         g_free (real_section);
-	gdm_common_config_save (custom_cfg, custom_config_file, NULL);
-
-	g_key_file_free (custom_cfg);
-
-	update_key ("xservers/PARAMETERS");
 }
 
-static gboolean
-combobox_timeout (GtkWidget *combo_box)
+/*
+ * For a given server we save all of its parameters into the local cache.
+ * This is usually performed when the servers are loaded.
+ */
+static void
+update_xserver_local_cache (GdmXserver *svr)
 {
-	const char *key = g_object_get_data (G_OBJECT (combo_box), "key");
-	int selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combo_box));
+	gchar *section;
+	gchar *real_section;
+	gchar *key;
 
-	/* Local Greeter Comboboxes */
-	if (strcmp (ve_sure_string (key), GDM_KEY_GREETER) == 0) {
+	section = g_strdup (svr->id);
+	real_section = g_strdup_printf ("%s%s", GDM_KEY_SERVER_PREFIX, section);
+	
+	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_NAME, NULL);
+	gdm_setup_config_set_string_cache (key, svr->name);
+	g_free (key);
 
-		gchar *old_key_val;
-		gchar *new_key_val;
-		gboolean browser_val;
+	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_COMMAND, NULL);
+	gdm_setup_config_set_string_cache (key, svr->command);
+	g_free (key);
 
-		old_key_val = gdm_config_get_string ((gchar *)key);
-		new_key_val = NULL;
+	key = g_strconcat (real_section, "/", GDM_KEY_SERVER_CHOOSER, NULL);
+	gdm_setup_config_set_bool_cache (key, svr->chooser);
+	g_free (key);
 
-		if (selected == LOCAL_PLAIN_WITH_FACE) {		
-			new_key_val = g_strdup (LIBEXECDIR "/gdmlogin");
-			browser_val = TRUE;
-		} 
-		else if (selected == LOCAL_THEMED) {
-			new_key_val = g_strdup (LIBEXECDIR "/gdmgreeter");
-			browser_val = FALSE;
-		}
-		else if (selected == LOCAL_THEMED_WITH_FACE) {
-			new_key_val = g_strdup (LIBEXECDIR "/gdmgreeter");
-			browser_val = TRUE;
-		}
-		else {  /* Plain style */
-			new_key_val = g_strdup (LIBEXECDIR "/gdmlogin");
-			browser_val = FALSE;
-		}		
-		
-		if (new_key_val && 
-		    strcmp (ve_sure_string (old_key_val), ve_sure_string (new_key_val)) != 0) {	
-		    
-			gdm_setup_config_set_string (key, new_key_val);
-			gdm_setup_config_set_bool (GDM_KEY_BROWSER, browser_val);
-		}
-		else {
-			gdm_setup_config_set_bool (GDM_KEY_BROWSER, browser_val);
-		}
-		update_greeters ();
-		
-		refresh_remote_tab ();
-		g_free (new_key_val);
-	}
-	/* Remote Greeter Comboboxes */
-	else if (strcmp (ve_sure_string (key), GDM_KEY_REMOTE_GREETER) == 0) {
-		
-		if (selected == REMOTE_DISABLED) {
-			gdm_setup_config_set_bool (GDM_KEY_XDMCP, FALSE);		
-		} else {
-			gchar    *new_key_val = NULL;
-			gboolean free_new_val = TRUE;
-						
-			if (selected == REMOTE_SAME_AS_LOCAL) {
-				new_key_val  = gdm_config_get_string (GDM_KEY_GREETER);
-				free_new_val = FALSE;
-			}
-			else {
-				gchar *selected_text;
+	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_HANDLED, NULL);
+	gdm_setup_config_set_bool_cache (key, svr->handled);
+	g_free (key);
 
-				selected_text = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo_box));
+	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_FLEXIBLE, NULL);
+	gdm_setup_config_set_bool_cache (key, svr->flexible);
+	g_free (key);
 
-				if (strstr (ve_sure_string (selected_text), _("Themed")) != NULL) {
-					new_key_val = g_strdup (LIBEXECDIR "/gdmgreeter");
-				}
-				else {
-					new_key_val = g_strdup (LIBEXECDIR "/gdmlogin");
-				}
-				g_free (selected_text);
-			}			
-			
-			gdm_setup_config_set_string (key, new_key_val);
-			gdm_setup_config_set_bool (GDM_KEY_XDMCP, TRUE);
-			if (free_new_val)
-				g_free (new_key_val);
-		}
-		update_greeters ();
-		return FALSE;
+	key = g_strconcat (real_section, "/" GDM_KEY_SERVER_PRIORITY, NULL);
+	gdm_setup_config_set_int_cache (key, svr->priority);
 
-	/* Automatic Login Combobox */
-	} else if (strcmp (ve_sure_string (key), GDM_KEY_AUTOMATIC_LOGIN) == 0 ||
-	           strcmp (ve_sure_string (key), GDM_KEY_TIMED_LOGIN) == 0) {
+	g_free (key);
+	g_free (section);
+        g_free (real_section);
+}
 
-		GtkTreeIter iter;
-		char *new_val = NULL;
-		gchar *val;
+static void
+radiogroup_toggled (GtkWidget *toggle, gpointer data)
+{
+	const char *key = g_object_get_data (G_OBJECT (toggle), "key");
+	GSList *radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (toggle));
+	
+	if (strcmp (ve_sure_string (key), GDM_KEY_RELAX_PERM) == 0) {
+		GSList *tmp;
+		gint selected = 0;
+		gint i = 0;
+		gint list_size;
 		
-		if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box), 
-		    &iter)) {
-			gtk_tree_model_get (gtk_combo_box_get_model (
-				GTK_COMBO_BOX (combo_box)), &iter,
-				0, &new_val, -1);
+		list_size = g_slist_length (radio_group) - 1;
+		
+		for (tmp = radio_group; tmp != NULL; tmp = tmp->next, i++) {
+			GtkWidget *radio_button;
+			radio_button = (GtkWidget *) tmp->data;
+			if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_button)))
+				selected = list_size - i;
 		}
-		else {
-			/* The selection was typed so there are two possibilities
-			   1. The typed value is a user
-			   2. The typed value is a script, garbage, ete (anything but an
-			   existing user)
-			   If its case 1. then we check if the user matches the MinimalUID 
-			   criteria or is not root. If its case 2. we do not do any checking */
-			
-			new_val = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo_box));
-			if (gdm_is_user_valid (ve_sure_string (new_val))) {
-				gint user_uid = gdm_user_uid (new_val);
-				gint GdmMinimalUID = gdm_config_get_int (GDM_KEY_MINIMAL_UID);
-				
-				if (user_uid == 0 || user_uid < GdmMinimalUID) {
-					/* we can't accept users that have uid lower
-					   than minimal uid, or uid = 0 (root) */
-					gchar *str;
-					GtkWidget *dialog;
-					GtkWidget *setup_dialog;
-					
-					if (gdm_user_uid (new_val) == 0)
-						str = g_strdup (_("Autologin or timed login to the root account is forbidden."));
-					else 
-						str = g_strdup_printf (_("The \"%s\" user UID is lower than allowed MinimalUID."), new_val);				
-					setup_dialog = glade_xml_get_widget(xml, "setup_dialog");
-										
-					dialog = hig_dialog_new (GTK_WINDOW (setup_dialog),
-								 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-								 GTK_MESSAGE_ERROR,
-								 GTK_BUTTONS_OK,
-								 _("User not allowed"),
-								 str);
-					gtk_dialog_run (GTK_DIALOG (dialog));
-					gtk_widget_destroy (dialog);
-					g_free (str);
-					
-					gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
-					return TRUE;
-				}
-			}
-		}
-
-
-		val = gdm_config_get_string ((gchar *)key);
-		if (new_val &&
-		    strcmp (ve_sure_string (val), ve_sure_string (new_val)) != 0) {
-
-			gdm_setup_config_set_string (key, new_val);
-		}
-		g_free (new_val);
-	} 
-	else if (strcmp (ve_sure_string (key), GDM_KEY_GRAPHICAL_THEME_RAND) == 0 ) {	
-	
-		/* Theme Combobox */
-		gboolean new_val;
-		gboolean old_val ;
-		
-		old_val = gdm_config_get_bool ((gchar *)key);
-
-		/* Choose to display radio or checkbox toggle column.
-		   We will only set this option to true if there is at least one
-		   item in the selected_themes list otherwise Random from selected
-		   will be disabled */
-		if (selected == RANDOM_THEME && !ve_string_empty (selected_themes))
-			new_val = TRUE;
-		else /* Default to one theme */
-			new_val = FALSE;
-
-		/* Update config */
-		if (new_val != old_val)
-			gdm_setup_config_set_bool (key, new_val);
-	}
-	/* Style combobox */
-	else if (strcmp (ve_sure_string (key), GDM_KEY_SERVER_CHOOSER) == 0) {
-		GtkWidget *mod_combobox;
-		GtkWidget *style_combobox;
-		GSList *li;
-		gchar *section;
-		gboolean val_old, val_new;
-
-		mod_combobox    = glade_xml_get_widget (xml_xservers, "xserver_mod_combobox");
-		style_combobox  = glade_xml_get_widget (xml_xservers, "xserver_style_combobox");
-
-		/* Get xserver section to update */
-		section = gtk_combo_box_get_active_text (GTK_COMBO_BOX (mod_combobox));
-
-		for (li = xservers; li != NULL; li = li->next) {
-			GdmXserver *svr = li->data;
-			if (strcmp (ve_sure_string (svr->id), ve_sure_string (section)) == 0) {
-
-				val_old = svr->chooser;
-				val_new = (gtk_combo_box_get_active (GTK_COMBO_BOX (style_combobox)) != 0);
-
-				/* Update this servers configuration */
-				if (! bool_equal (val_old, val_new)) {
-					svr->chooser = val_new;
-					update_xserver (section, svr);
-				}
-				break;
-			}
-		}
-		g_free (section);
-	}
-	/* Use 24 clock combobox */
-	else if (strcmp (ve_sure_string (key), GDM_KEY_USE_24_CLOCK) == 0) {		
-		gchar *val;		
-		gchar *new_val;
-		
-		new_val = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo_box));
-		val = gdm_config_get_string ((gchar *)key);
-		if (new_val &&
-		    strcmp (ve_sure_string (val), ve_sure_string (new_val)) != 0) {			
-			gdm_setup_config_set_string (key, new_val);
-		}
-		g_free (new_val);
-		g_free (val);
-	}
-	/* Commands combobox */
-	else if (strcmp (ve_sure_string (key), "command_chooser_combobox") == 0) {
-		/* We need to set the data according to selected command */
-		GtkWidget *hrs_cmd_entry = NULL;
-		GtkWidget *cust_cmd_entry = NULL;
-		GtkWidget *cust_cmd_label_entry = NULL;
-		GtkWidget *cust_cmd_lrlabel_entry = NULL;
-		GtkWidget *cust_cmd_text_entry = NULL;
-		GtkWidget *cust_cmd_tooltip_entry = NULL;
-		GtkWidget *cust_cmd_persistent_checkbox = NULL;
-		GtkWidget *cust_cmd_norestart_checkbox = NULL;
-		GtkWidget *status_label;
-		gchar *val = NULL;		
-		gboolean bool_val = FALSE;		
-		gboolean enabled_command = FALSE;
-		
-		hrs_cmd_entry = glade_xml_get_widget (xml_commands, "hrs_cmd_path_entry");
-		cust_cmd_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_path_entry");
-		status_label = glade_xml_get_widget (xml_commands, "command_status_label");
-
-		if (selected == HALT_CMD) {
-			val = gdm_config_get_string (GDM_KEY_HALT);		
-			gtk_entry_set_text (GTK_ENTRY (hrs_cmd_entry), ve_sure_string (val));
-			enabled_command = !ve_string_empty (val);
-		}
-		else if (selected == REBOOT_CMD) {
-			val = gdm_config_get_string (GDM_KEY_REBOOT);			
-			gtk_entry_set_text (GTK_ENTRY (hrs_cmd_entry), ve_sure_string (val));
-			enabled_command = !ve_string_empty (val);
-		}
-		else if (selected == SUSPEND_CMD) {
-			val = gdm_config_get_string (GDM_KEY_SUSPEND);			
-			gtk_entry_set_text (GTK_ENTRY (hrs_cmd_entry), ve_sure_string (val));
-			enabled_command = !ve_string_empty (val);
-		}
-		else {
-			gchar *key_string = NULL;
-
-			gint i = selected - CUSTOM_CMD;
-			/* Here we are going to deal with custom commands */
-			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, i);
-			val = gdm_config_get_string (key_string);
-			gtk_entry_set_text (GTK_ENTRY (cust_cmd_entry), ve_sure_string (val));
-			enabled_command = !ve_string_empty (val);
-			g_free (key_string);
-			g_free (val);
-			
-			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_LABEL_TEMPLATE, i);
-			cust_cmd_label_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_label_entry");
-			val = gdm_config_get_string (key_string);
-			gtk_entry_set_text (GTK_ENTRY (cust_cmd_label_entry), ve_sure_string (val));
-			g_free (key_string);
-			g_free (val);
-
-			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_LR_LABEL_TEMPLATE, i);
-			cust_cmd_lrlabel_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_lrlabel_entry");
-			val = gdm_config_get_string (key_string);
-			gtk_entry_set_text (GTK_ENTRY (cust_cmd_lrlabel_entry), ve_sure_string (val));
-			g_free (key_string);
-			g_free (val);
-
-			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEXT_TEMPLATE, i);
-			cust_cmd_text_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_text_entry");
-			val = gdm_config_get_string (key_string);
-			gtk_entry_set_text (GTK_ENTRY (cust_cmd_text_entry), ve_sure_string (val));
-			g_free (key_string);
-			g_free (val);
-			
-			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TOOLTIP_TEMPLATE, i);
-			cust_cmd_tooltip_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_tooltip_entry");
-			val = gdm_config_get_string (key_string);
-			gtk_entry_set_text (GTK_ENTRY (cust_cmd_tooltip_entry), ve_sure_string (val));
-			g_free (key_string);
-			
-			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE, i);
-			cust_cmd_norestart_checkbox  = glade_xml_get_widget (xml_commands, "custom_cmd_norestart_checkbutton");
-			bool_val = gdm_config_get_bool (key_string);
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cust_cmd_norestart_checkbox), bool_val);
-			g_free (key_string);
-			
-			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE, i);
-			cust_cmd_persistent_checkbox  = glade_xml_get_widget (xml_commands, "custom_cmd_persistent_checkbutton");
-			bool_val = gdm_config_get_bool (key_string);
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cust_cmd_persistent_checkbox), bool_val);
-			g_free (key_string);
-
-		}
-		g_free (val);
-
-		if (enabled_command)
-			gtk_label_set_text (GTK_LABEL (status_label), _("(Enabled)"));			
-		else 
-			gtk_label_set_text (GTK_LABEL (status_label), _("(Disabled)"));	
-	}
-	/* Default session combobox*/
-	else if (strcmp (ve_sure_string (key), GDM_KEY_DEFAULT_SESSION) == 0) {
-		/* First we get the selected index. Next we lookup the actual
-		   filename in the List of sessions */
-		gchar *val;
-		gchar *new_val = NULL;
 		
-		val = gdm_config_get_string ((gchar *)key);
-		new_val = g_strdup ((gchar*) g_list_nth_data (sessions, selected));
+		gdm_setup_config_set_int (key, selected);
 		
-		if (strcmp (ve_sure_string (val), ve_sure_string (new_val)) != 0)
-			gdm_setup_config_set_string (key,  ve_sure_string (new_val));
-
-		g_free (new_val);
-		g_free (val);		
 	}
-	return FALSE;
-}
-
-static void
-toggle_toggled (GtkWidget *toggle)
-{
-	run_timeout (toggle, 200, toggle_timeout);
-}
-
-static void
-command_toggle_toggled (GtkWidget *toggle)
-{
-	run_timeout (toggle, 200, command_toggle_timeout);
-}
-
-static void
-radiogroup_toggled (GtkWidget *toggle)
-{
-	run_timeout (toggle, 200, radiogroup_timeout);
 }
 
 static void
@@ -1685,37 +1455,111 @@
 	selection = gtk_tree_view_get_selection (
 	            GTK_TREE_VIEW (include_treeview));
 
-	if ((val == FALSE) && (gtk_tree_selection_get_selected (selection, &(include_model), &iter))) {
+	if ((val == FALSE) && (gtk_tree_selection_get_selected (selection, &include_model, &iter))) {
 		gtk_widget_set_sensitive (widget, TRUE);
 	} else {
 		gtk_widget_set_sensitive (widget, FALSE);
 	}
-
-	run_timeout (toggle, 200, toggle_timeout);
 }
 
-static void
-intspin_changed (GtkWidget *spin)
-{
-	run_timeout (spin, 500, intspin_timeout);
-}
+/* Forward declaration */
+static void combobox_changed (GtkWidget *combobox, gpointer data);
 
+static gboolean
+validate_command_path_entry (const gint last_selected)
+{	
+	GtkWidget *cmd_entry;
+	gchar *old_cmd_key_string;
+	const gchar *old_cmd_entry_value;
+	gboolean res = TRUE;
+	
+	if (last_selected_command > SUSPEND_CMD) {
+		gint last_custom = CUSTOM_CMD - last_selected;
+		cmd_entry = glade_xml_get_widget (xml_commands, "custom_cmd_path_entry");
+		old_cmd_key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, last_custom);
+		old_cmd_entry_value = gtk_entry_get_text (GTK_ENTRY (cmd_entry));
+	}
+	else {
+		cmd_entry = glade_xml_get_widget (xml_commands, "hrs_cmd_path_entry");
+		old_cmd_entry_value = gtk_entry_get_text (GTK_ENTRY (cmd_entry));
+		switch (last_selected_command) {
+		case HALT_CMD:
+			old_cmd_key_string = g_strdup (GDM_KEY_HALT);
+			break;
+		case REBOOT_CMD:
+			old_cmd_key_string = g_strdup (GDM_KEY_REBOOT);
+			break;
+		case SUSPEND_CMD:
+			old_cmd_key_string = g_strdup (GDM_KEY_SUSPEND);
+			break;
+		default:
+			/* Oooops We shouldn't be here */
+			g_assert_not_reached ();
+		}
+	}
+	
+	if (!ve_string_empty (old_cmd_entry_value) && 
+	    !gdm_working_command_exists (old_cmd_entry_value)) {
+		GtkWidget *command_chooser;
+		gint selected;
+		
+		command_chooser = glade_xml_get_widget (xml_commands, "cmd_type_combobox");
+		selected = gtk_combo_box_get_active (GTK_COMBO_BOX (command_chooser));
+
+		g_signal_handlers_disconnect_by_func (G_OBJECT (command_chooser),
+						      G_CALLBACK (combobox_changed), NULL);
+
+		if (selected != last_selected_command)
+			gtk_combo_box_set_active (GTK_COMBO_BOX (command_chooser), last_selected);
+						
+		GtkWidget *parent = glade_xml_get_widget (xml_commands, "commands_dialog");
+		gint response;
+		GtkWidget *dialog = hig_dialog_new (GTK_WINDOW (parent),
+						    GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+						    GTK_MESSAGE_WARNING,
+						    GTK_BUTTONS_YES_NO,
+						    _("Invalid command path"),
+						    _("The path you provided for this "
+						      "command is not valid and changes "
+						      "will not be applied. Do you want to continue?"));
+		response = gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);				
+		
+		if (response == GTK_RESPONSE_YES) {
+			gdm_setup_config_remove_value (old_cmd_key_string);
+			res = TRUE;
+
+			if (selected != last_selected)
+				gtk_combo_box_set_active (GTK_COMBO_BOX (command_chooser), selected);
+		}
+		else if (response == GTK_RESPONSE_NO ||
+			 response == GTK_RESPONSE_CLOSE) {
+			res = FALSE;		
+		}
+
+		g_signal_connect (G_OBJECT (command_chooser), "changed", 
+					  G_CALLBACK (combobox_changed), NULL);
+	}
+	g_free (old_cmd_key_string);		
+
+	return res;
+}
 static void
-combobox_changed (GtkWidget *combobox)
+combobox_changed (GtkWidget *combobox, gpointer data)
 {
 	const char *key = g_object_get_data (G_OBJECT (combobox), "key");
-	
+	gint selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
+
 	if (strcmp (ve_sure_string (key), GDM_KEY_GREETER) == 0) {
 
 		GtkWidget *local_plain_vbox;
 		GtkWidget *local_themed_vbox;
-		gint selected;
+		gchar *new_key_val;
+		gboolean browser_val;
 		
 		local_plain_vbox = glade_xml_get_widget (xml, "local_plain_properties_vbox");
 		local_themed_vbox = glade_xml_get_widget (xml, "local_themed_properties_vbox");
 
-		selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
-
 		if (selected == LOCAL_THEMED ||
 		    selected == LOCAL_THEMED_WITH_FACE) {						
 			gtk_widget_hide (local_plain_vbox);
@@ -1725,6 +1569,36 @@
 			gtk_widget_show (local_plain_vbox);
 			gtk_widget_hide (local_themed_vbox);
 		}
+
+		new_key_val = NULL;
+
+		if (selected == LOCAL_PLAIN_WITH_FACE) {		
+			new_key_val = g_strdup (LIBEXECDIR "/gdmlogin");
+			browser_val = TRUE;
+		} 
+		else if (selected == LOCAL_THEMED) {
+			new_key_val = g_strdup (LIBEXECDIR "/gdmgreeter");
+			browser_val = FALSE;
+		}
+		else if (selected == LOCAL_THEMED_WITH_FACE) {
+			new_key_val = g_strdup (LIBEXECDIR "/gdmgreeter");
+			browser_val = TRUE;
+		}
+		else {  /* Plain style */
+			new_key_val = g_strdup (LIBEXECDIR "/gdmlogin");
+			browser_val = FALSE;
+		}		
+		
+		if (new_key_val) {			
+			gdm_setup_config_set_string (key, new_key_val);
+			gdm_setup_config_set_bool (GDM_KEY_BROWSER, browser_val);
+		}
+		else {
+			gdm_setup_config_set_bool (GDM_KEY_BROWSER, browser_val);
+		}
+		
+		refresh_remote_tab ();
+		g_free (new_key_val);
 	}
 	else if (strcmp (ve_sure_string (key), GDM_KEY_REMOTE_GREETER) == 0) {
 
@@ -1732,15 +1606,12 @@
 		GtkWidget *remote_themed_vbox;
 		GtkWidget *configure_xdmcp_vbox;
 		GtkWidget *welcome_message_vbox;
-		gint selected;
 
 		remote_plain_vbox = glade_xml_get_widget (xml, "remote_plain_properties_vbox");
 		remote_themed_vbox = glade_xml_get_widget (xml, "remote_themed_properties_vbox");
 		configure_xdmcp_vbox = glade_xml_get_widget (xml, "remote_configure_xdmcp_vbox");
 		welcome_message_vbox = glade_xml_get_widget (xml, "remote_welcome_message_vbox");
 
-		selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
-
 		if (selected == REMOTE_DISABLED) {
 			GtkWidget *allowremoteauto;
 			GtkWidget *allowremoteroot;
@@ -1755,11 +1626,19 @@
 			gtk_widget_hide (remote_themed_vbox);
 			gtk_widget_hide (welcome_message_vbox);
 			gtk_widget_hide (configure_xdmcp_vbox);
+
+			gdm_setup_config_set_bool (GDM_KEY_XDMCP, FALSE);
+			
+			/* We need to remove this key from the current config storage
+			   so the no-change status is kept on the part of this key */
+			gdm_setup_config_remove_value (key);			
+			
 		}
 		else {
 			GtkWidget *timedlogin;
 			GtkWidget *allowremoteauto;
 			GtkWidget *allowremoteroot;
+			gchar     *new_key_val;
 
 			timedlogin = glade_xml_get_widget (xml, "timedlogin");
 			allowremoteauto = glade_xml_get_widget (xml, "allowremoteauto");
@@ -1772,9 +1651,9 @@
 			gtk_widget_show (configure_xdmcp_vbox);
 			
 			if (selected == REMOTE_SAME_AS_LOCAL) {
-				gchar *greeter_style;
+				const gchar *greeter_style;
 				
-				greeter_style = gdm_config_get_string (GDM_KEY_GREETER);
+				greeter_style = gdm_setup_config_get_working_string (GDM_KEY_GREETER);
 				update_remote_sensitivity (FALSE);
 				
 				if (strstr (greeter_style, "/gdmgreeter") != NULL) {
@@ -1785,6 +1664,8 @@
 					gtk_widget_hide (remote_themed_vbox);
 					gtk_widget_show (remote_plain_vbox);
 				}
+
+				new_key_val  = g_strdup (greeter_style);
 			}		
 			else {
 				gchar *selected_text;
@@ -1795,15 +1676,19 @@
 				if (strstr (ve_sure_string (selected_text), _("Themed")) != NULL) {
 					gtk_widget_hide (remote_plain_vbox);
 					gtk_widget_show (remote_themed_vbox);
+					new_key_val = g_strdup (LIBEXECDIR "/gdmgreeter");
 				}
 				else {
 					gtk_widget_hide (remote_themed_vbox);
 					gtk_widget_show (remote_plain_vbox);
+					new_key_val = g_strdup (LIBEXECDIR "/gdmlogin");
 				}
 				g_free (selected_text);
 			}
+			gdm_setup_config_set_string (key, new_key_val);
+			gdm_setup_config_set_bool (GDM_KEY_XDMCP, TRUE);
+			g_free (new_key_val);
 		}
-
 	}
 	else if (strcmp (ve_sure_string (key), GDM_KEY_GRAPHICAL_THEME_RAND) == 0) {
 
@@ -1817,15 +1702,12 @@
 		GtkTreeViewColumn *checkboxColumnRemote = NULL;
 		GtkTreeSelection *selection;
 		GtkTreeIter iter;
-		gint selected;
 				
 		theme_list = glade_xml_get_widget (xml, "gg_theme_list");
 		theme_list_remote = glade_xml_get_widget (xml, "gg_theme_list_remote");
 		delete_button = glade_xml_get_widget (xml, "gg_delete_theme");
 		delete_button_remote = glade_xml_get_widget (xml, "gg_delete_theme_remote");
 
-		selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
-
 		if (gtk_notebook_get_current_page (GTK_NOTEBOOK (setup_notebook)) == LOCAL_TAB) {
 			GtkWidget *mode_combobox;
 			
@@ -1940,7 +1822,7 @@
 			/* Determine if the theme selected is currently active */
 			model = gtk_tree_view_get_model (GTK_TREE_VIEW (theme_list));
 			
-			GdmGraphicalThemeRand = gdm_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
+			GdmGraphicalThemeRand = gdm_setup_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
 			if (GdmGraphicalThemeRand) {
 				gtk_tree_model_get_value (model, &iter,
 				                          THEME_COLUMN_SELECTED_LIST, &value);
@@ -1977,108 +1859,241 @@
 			}
 
 			g_value_unset (&value);
-		}      			      
+		}
+		
+
+		/* Theme Combobox */
+		gboolean new_val;
+
+		/* Choose to display radio or checkbox toggle column.
+		   We will only set this option to true if there is at least one
+		   item in the selected_themes list otherwise Random from selected
+		   will be disabled */
+		if (selected == RANDOM_THEME && !ve_string_empty (selected_themes))
+			new_val = TRUE;
+		else /* Default to one theme */
+			new_val = FALSE;
+
+		/* Update config */
+		gdm_setup_config_set_bool (key, new_val);			      
+
+	} else if (strcmp (ve_sure_string (key), GDM_KEY_AUTOMATIC_LOGIN) == 0 ||
+	           strcmp (ve_sure_string (key), GDM_KEY_TIMED_LOGIN) == 0) {
+
+		GtkTreeIter iter;
+		char *new_val = NULL;
+		
+		if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), 
+		    &iter)) {
+			gtk_tree_model_get (gtk_combo_box_get_model (
+				GTK_COMBO_BOX (combobox)), &iter,
+				0, &new_val, -1);
+		}
+		else {
+			/* The selection was typed so there are two possibilities
+			   1. The typed value is a user
+			   2. The typed value is a script, garbage, ete (anything but an
+			   existing user)
+			   If its case 1. then we check if the user matches the MinimalUID 
+			   criteria or is not root. If its case 2. we do not do any checking */
+			
+			new_val = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combobox));
+			if (gdm_is_user_valid (ve_sure_string (new_val))) {
+				gint user_uid = gdm_user_uid (new_val);
+				gint GdmMinimalUID = gdm_setup_config_get_int (GDM_KEY_MINIMAL_UID);
+				
+				if (user_uid == 0 || user_uid < GdmMinimalUID) {
+					/* we can't accept users that have uid lower
+					   than minimal uid, or uid = 0 (root) */
+					gchar *str;
+					GtkWidget *dialog;
+					GtkWidget *setup_dialog;
+					
+					if (gdm_user_uid (new_val) == 0)
+						str = g_strdup (_("Autologin or timed login to the root account is forbidden."));
+					else 
+						str = g_strdup_printf (_("The \"%s\" user UID is lower than allowed MinimalUID."), new_val);				
+					setup_dialog = glade_xml_get_widget(xml, "setup_dialog");
+										
+					dialog = hig_dialog_new (GTK_WINDOW (setup_dialog),
+								 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+								 GTK_MESSAGE_ERROR,
+								 GTK_BUTTONS_OK,
+								 _("User not allowed"),
+								 str);
+					gtk_dialog_run (GTK_DIALOG (dialog));
+					gtk_widget_destroy (dialog);
+					g_free (str);
+					
+					gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0);
+					return;
+				}
+			}
+		}
+
+
+		if (new_val) {
+			gdm_setup_config_set_string (key, new_val);
+		}
+		g_free (new_val);
 	}
 	else if (strcmp (ve_sure_string (key), GDM_KEY_SERVER_PREFIX) == 0 ) {
 		init_servers_combobox (gtk_combo_box_get_active (GTK_COMBO_BOX (combobox)));
 	}
+	else if (strcmp (ve_sure_string (key), GDM_KEY_SERVER_CHOOSER) == 0) {
+		GtkWidget *mod_combobox;
+		GSList *li;
+		gchar *section;
+		gboolean val_old, val_new;
+
+		mod_combobox    = glade_xml_get_widget (xml_xservers, "xserver_mod_combobox");
+
+		/* Get xserver section to update */
+		section = gtk_combo_box_get_active_text (GTK_COMBO_BOX (mod_combobox));
+
+		for (li = xservers; li != NULL; li = li->next) {
+			GdmXserver *svr = li->data;
+			if (strcmp (ve_sure_string (svr->id), ve_sure_string (section)) == 0) {
+
+				val_old = svr->chooser;
+				val_new = (gtk_combo_box_get_active (GTK_COMBO_BOX (combobox)) != 0);
+
+				/* Update this servers configuration */
+				if (! bool_equal (val_old, val_new)) {
+					svr->chooser = val_new;
+					update_xserver (section, svr);
+				}
+				break;
+			}
+		}
+		g_free (section);
+	}
+	else if (strcmp (ve_sure_string (key), GDM_KEY_USE_24_CLOCK) == 0) {
+		gchar *new_val;
+		
+		new_val = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combobox));
+		if (new_val) {
+			gdm_setup_config_set_string (key, new_val);
+		}
+		g_free (new_val);
+	}
 	else if (strcmp (ve_sure_string (key), "command_chooser_combobox") == 0) {
-		gint selected;
 		GtkWidget *hrs_cmd_vbox;
 		GtkWidget *custom_cmd_vbox;
 		
-		selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));			
-
-		/* First of all we need to check if we had made any changes
-		   to any of the command fields. If so user gets reminded and
-		   given an option to save, or discard */
-		if (g_hash_table_size (GdmCommandChangesUnsaved) != 0) {
-			GtkWidget *prompt;
-			GtkWidget *setup_dialog;
-			GtkWidget *apply_command;
-			gint response;
-			
-			setup_dialog = glade_xml_get_widget (xml, "setup_dialog");
-			
-			prompt = hig_dialog_new (GTK_WINDOW (setup_dialog),
-						 GTK_DIALOG_MODAL |
-						 GTK_DIALOG_DESTROY_WITH_PARENT,
-						 GTK_MESSAGE_WARNING,
-						 GTK_BUTTONS_NONE,
-						 _("Apply changes to the modified command?"),
-						 _("If you don't apply, the changes "
-						   "will be discarded."));
-			
-			gtk_dialog_add_button (GTK_DIALOG (prompt), "gtk-cancel", GTK_RESPONSE_CANCEL); 
-			gtk_dialog_add_button (GTK_DIALOG (prompt), "gtk-apply", GTK_RESPONSE_APPLY);
-			
-			response = gtk_dialog_run (GTK_DIALOG (prompt));
-			gtk_widget_destroy (prompt);	       
-			
-			apply_command = glade_xml_get_widget (xml_commands, "command_apply_button");
-			if (response == GTK_RESPONSE_APPLY)				
-				g_signal_emit_by_name (G_OBJECT (apply_command), "clicked");
-			
-			else {
-				g_hash_table_remove_all (GdmCommandChangesUnsaved);				
-				gtk_widget_set_sensitive (apply_command, FALSE);	
-			}
-		}
+		/* We need to set the data according to selected command */
+		GtkWidget *hrs_cmd_entry = NULL;
+		GtkWidget *cust_cmd_entry = NULL;
+		GtkWidget *cust_cmd_label_entry = NULL;
+		GtkWidget *cust_cmd_lrlabel_entry = NULL;
+		GtkWidget *cust_cmd_text_entry = NULL;
+		GtkWidget *cust_cmd_tooltip_entry = NULL;
+		GtkWidget *cust_cmd_persistent_checkbox = NULL;
+		GtkWidget *cust_cmd_norestart_checkbox = NULL;
+		GtkWidget *status_label;
+		const gchar *val = NULL;		
+		gboolean bool_val = FALSE;		
+		gboolean enabled_command = FALSE;		
 		
-		last_selected_command = selected;
+		if (validate_command_path_entry (last_selected_command) == FALSE)
+			return;
+		
+		last_selected_command = selected;	
 
 		hrs_cmd_vbox = glade_xml_get_widget (xml_commands, "hrs_command_vbox");
 		custom_cmd_vbox = glade_xml_get_widget (xml_commands, "custom_command_vbox");
+		status_label = glade_xml_get_widget (xml_commands, "command_status_label");
 		if (selected > SUSPEND_CMD) {
 			/* We are dealing with custom commands */							
 			gtk_widget_show (custom_cmd_vbox);
-			gtk_widget_hide (hrs_cmd_vbox);					
-		}
-		else {
-			/* We are dealing with hrs (Halt, Reboot, Shutdown) commands */
-			gtk_widget_hide (custom_cmd_vbox);
-			gtk_widget_show (hrs_cmd_vbox);	
-		}
+			gtk_widget_hide (hrs_cmd_vbox);
 
-		/* We dont want default timeout for this one so we
-		   are going to bail out now */
-		run_timeout (combobox, 10, combobox_timeout);		
-		return;
-	}
-	run_timeout (combobox, 500, combobox_timeout);
-}
+			gchar *key_string = NULL;
 
-static void
-timeout_remove (GtkWidget *widget)
-{
-	gboolean (*func) (GtkWidget *);
-	guint id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (widget),
-							"change_timeout"));
-	if (id != 0) {
-		g_source_remove (id);
-		g_object_set_data (G_OBJECT (widget), "change_timeout", NULL);
-	}
+			gint i = selected - CUSTOM_CMD;
+			cust_cmd_entry = glade_xml_get_widget (xml_commands, "custom_cmd_path_entry");	
+
+			/* Here we are going to deal with custom commands */
+			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, i);		
+			val = gdm_setup_config_get_working_string (key_string);
+			gtk_entry_set_text (GTK_ENTRY (cust_cmd_entry), ve_sure_string (val));
+			enabled_command = !ve_string_empty (val);
+			g_free (key_string);
+			
+			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_LABEL_TEMPLATE, i);
+			cust_cmd_label_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_label_entry");
+			val = gdm_setup_config_get_working_string (key_string);
+			gtk_entry_set_text (GTK_ENTRY (cust_cmd_label_entry), ve_sure_string (val));
+			g_free (key_string);
+
+			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_LR_LABEL_TEMPLATE, i);
+			cust_cmd_lrlabel_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_lrlabel_entry");
+			val = gdm_setup_config_get_working_string (key_string);
+			gtk_entry_set_text (GTK_ENTRY (cust_cmd_lrlabel_entry), ve_sure_string (val));
+			g_free (key_string);
+
+			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEXT_TEMPLATE, i);
+			cust_cmd_text_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_text_entry");
+			val = gdm_setup_config_get_working_string (key_string);
+			gtk_entry_set_text (GTK_ENTRY (cust_cmd_text_entry), ve_sure_string (val));
+			g_free (key_string);
+			
+			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TOOLTIP_TEMPLATE, i);
+			cust_cmd_tooltip_entry  = glade_xml_get_widget (xml_commands, "custom_cmd_tooltip_entry");
+			val = gdm_setup_config_get_working_string (key_string);
+			gtk_entry_set_text (GTK_ENTRY (cust_cmd_tooltip_entry), ve_sure_string (val));
+			g_free (key_string);
+			
+			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE, i);
+			cust_cmd_norestart_checkbox  = glade_xml_get_widget (xml_commands, "custom_cmd_norestart_checkbutton");
+			bool_val = gdm_setup_config_get_bool (key_string);
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cust_cmd_norestart_checkbox), bool_val);
+			g_free (key_string);
+			
+			key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE, i);
+			cust_cmd_persistent_checkbox  = glade_xml_get_widget (xml_commands, "custom_cmd_persistent_checkbutton");
+			bool_val = gdm_setup_config_get_bool (key_string);
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cust_cmd_persistent_checkbox), bool_val);
+			g_free (key_string);
+		}
+		else {
+			/* We are dealing with hrs (Halt, Reboot, Shutdown) commands */
+			gtk_widget_hide (custom_cmd_vbox);
+			gtk_widget_show (hrs_cmd_vbox);	
 
-	func = g_object_get_data (G_OBJECT (widget), "timeout_func");
-	if (func != NULL) {
-		(*func) (widget);
-		g_object_set_data (G_OBJECT (widget), "timeout_func", NULL);
+			hrs_cmd_entry = glade_xml_get_widget (xml_commands, "hrs_cmd_path_entry");
+			if (selected == HALT_CMD) {
+				val = gdm_setup_config_get_working_string (GDM_KEY_HALT);		
+				gtk_entry_set_text (GTK_ENTRY (hrs_cmd_entry), ve_sure_string (val));
+				enabled_command = !ve_string_empty (val);
+			}
+			else if (selected == REBOOT_CMD) {
+				val = gdm_setup_config_get_working_string (GDM_KEY_REBOOT);			
+				gtk_entry_set_text (GTK_ENTRY (hrs_cmd_entry), ve_sure_string (val));
+				enabled_command = !ve_string_empty (val);
+			}
+			else if (selected == SUSPEND_CMD) {
+				val = gdm_setup_config_get_working_string (GDM_KEY_SUSPEND);			
+				gtk_entry_set_text (GTK_ENTRY (hrs_cmd_entry), ve_sure_string (val));
+				enabled_command = !ve_string_empty (val);
+			}
+		}
+		
+		if (enabled_command)
+			gtk_label_set_text (GTK_LABEL (status_label), _("(Enabled)"));			
+		else 
+			gtk_label_set_text (GTK_LABEL (status_label), _("(Disabled)"));	
 	}
-}
-
-static void
-timeout_remove_all (void)
-{
-	GList *li, *list;
-
-	list = timeout_widgets;
-	timeout_widgets = NULL;
+	else if (strcmp (ve_sure_string (key), GDM_KEY_DEFAULT_SESSION) == 0) {
+		/* First we get the selected index. Next we lookup the actual
+		   filename in the List of sessions */
+		gchar *new_val = NULL;
+		
+		new_val = g_strdup ((gchar*) g_list_nth_data (sessions, selected));		
+		gdm_setup_config_set_string (key, ve_sure_string (new_val));
 
-	for (li = list; li != NULL; li = li->next) {
-		timeout_remove (li->data);
-		li->data = NULL;
+		g_free (new_val);
 	}
-	g_list_free (list);
 }
 
 static void
@@ -2096,7 +2111,7 @@
 static void
 timedlogin_allow_remote_toggled (GtkWidget *toggle, GtkWidget *depend)
 {
-	if (gdm_config_get_bool (GDM_KEY_XDMCP) == TRUE) {
+	if (gdm_setup_config_get_bool (GDM_KEY_XDMCP) == TRUE) {
 		gtk_widget_set_sensitive (depend, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
 	}
 	else {
@@ -2112,7 +2127,7 @@
 	gboolean val;
 
 	toggle = glade_xml_get_widget (xml, name);
-	val    = gdm_config_get_bool ((gchar *)key);
+	val    = gdm_setup_config_get_bool ((gchar *)key);
 
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), val);
 
@@ -2180,7 +2195,7 @@
 		gtk_widget_set_sensitive (timedlogin_seconds_spin_button, val);
 		gtk_widget_set_sensitive (timedlogin_seconds_units, val);
 
-		if (gdm_config_get_bool (GDM_KEY_XDMCP) == FALSE) {
+		if (gdm_setup_config_get_bool (GDM_KEY_XDMCP) == FALSE) {
 			gtk_widget_set_sensitive (timedlogin_allow_remote, FALSE);
 		}
 		else {
@@ -2217,20 +2232,52 @@
 		                  G_CALLBACK (toggle_toggled_sensitivity_positive), use_circles_in_passwd);
 		
 	}
-	else if (strcmp ("local_set_pos_checkbox", ve_sure_string (name)) == 0) {
+	else if (strcmp ("local_quiver_checkbox" , ve_sure_string (name)) == 0) {
+		GtkWidget *other;
+		
+		other = glade_xml_get_widget (xml, "remote_quiver_checkbox");
+		
+		g_signal_connect (G_OBJECT (toggle), "toggled",
+		                  G_CALLBACK (toggle_toggled_other), other);		
+	}
+	else if (strcmp ("remote_quiver_checkbox" , ve_sure_string (name)) == 0) {
+		GtkWidget *other;
+		
+		other = glade_xml_get_widget (xml, "local_quiver_checkbox");
+		
+		g_signal_connect (G_OBJECT (toggle), "toggled",
+		                  G_CALLBACK (toggle_toggled_other), other);		
+	}
+	else if (strcmp ("local_lock_pos_checkbox" , ve_sure_string (name)) == 0) {
+		GtkWidget *other;
+		
+		other = glade_xml_get_widget (xml, "remote_lock_pos_checkbox");
+		
+		g_signal_connect (G_OBJECT (toggle), "toggled",
+		                  G_CALLBACK (toggle_toggled_other), other);		
+	}
+	else if (strcmp ("remote_lock_pos_checkbox" , ve_sure_string (name)) == 0) {
+		GtkWidget *other;
 		
+		other = glade_xml_get_widget (xml, "local_lock_pos_checkbox");
+		
+		g_signal_connect (G_OBJECT (toggle), "toggled",
+		                  G_CALLBACK (toggle_toggled_other), other);		
+	}
+	else if (strcmp ("local_set_pos_checkbox", ve_sure_string (name)) == 0) {		
 		GtkWidget *posx;
 		GtkWidget *posy;
-
+		GtkWidget *other;
+		
 		posx =  glade_xml_get_widget (xml, "local_posx_spinbutton");
-
 		posy =  glade_xml_get_widget (xml, "local_posy_spinbutton");
+		other = glade_xml_get_widget (xml, "remote_set_pos_checkbox");
 
 		gtk_widget_set_sensitive (posx, val);
 		gtk_widget_set_sensitive (posy, val);
 
 		g_signal_connect (G_OBJECT (toggle), "toggled",
-		                  G_CALLBACK (toggle_toggled), toggle);	
+		                  G_CALLBACK (toggle_toggled_other), other);	
 		g_signal_connect (G_OBJECT (toggle), "toggled",
 		                  G_CALLBACK (toggle_toggled_sensitivity_positive), posx);
 		g_signal_connect (G_OBJECT (toggle), "toggled",
@@ -2240,15 +2287,17 @@
 		
 		GtkWidget *posx;
 		GtkWidget *posy;
+		GtkWidget *other;
 
 		posx =  glade_xml_get_widget (xml, "remote_posx_spinbutton");
 		posy =  glade_xml_get_widget (xml, "remote_posy_spinbutton");
+		other = glade_xml_get_widget (xml, "local_set_pos_checkbox");
 
 		gtk_widget_set_sensitive (posx, val);
 		gtk_widget_set_sensitive (posy, val);
 		
 		g_signal_connect (G_OBJECT (toggle), "toggled",
-		                  G_CALLBACK (toggle_toggled), toggle);	
+		                  G_CALLBACK (toggle_toggled_other), other);	
 		g_signal_connect (G_OBJECT (toggle), "toggled",
 		                  G_CALLBACK (toggle_toggled_sensitivity_positive), posx);
 		g_signal_connect (G_OBJECT (toggle), "toggled",
@@ -2256,25 +2305,29 @@
 	}
 	else if (strcmp ("local_title_bar_checkbutton", ve_sure_string (name)) == 0) {
 		GtkWidget *lockpos;
+		GtkWidget *other;
 		
 		lockpos = glade_xml_get_widget (xml, "local_lock_pos_checkbox");
+		other = glade_xml_get_widget (xml, "remote_title_bar_checkbutton");
 
 		gtk_widget_set_sensitive (lockpos, val);
 		
 		g_signal_connect (G_OBJECT (toggle), "toggled",
-		                  G_CALLBACK (toggle_toggled), toggle);	
+		                  G_CALLBACK (toggle_toggled_other), other);	
 		g_signal_connect (G_OBJECT (toggle), "toggled",
 		                  G_CALLBACK (toggle_toggled_sensitivity_positive), lockpos);
 	}
 	else if (strcmp ("remote_title_bar_checkbutton", ve_sure_string (name)) == 0) {
 		GtkWidget *lockpos;
+		GtkWidget *other;
 		
 		lockpos = glade_xml_get_widget (xml, "remote_lock_pos_checkbox");
+		other = glade_xml_get_widget (xml, "local_title_bar_checkbutton");
 
 		gtk_widget_set_sensitive (lockpos, val);
 		
 		g_signal_connect (G_OBJECT (toggle), "toggled",
-		                  G_CALLBACK (toggle_toggled), toggle);	
+		                  G_CALLBACK (toggle_toggled_other), other);	
 		g_signal_connect (G_OBJECT (toggle), "toggled",
 		                  G_CALLBACK (toggle_toggled_sensitivity_positive), lockpos);
 	}
@@ -2297,77 +2350,42 @@
 	}
 }
 
-static gboolean
-commands_entry_timeout (GtkWidget *entry)
+static void
+commands_entry_changed (GtkWidget *entry, gpointer data)
 {
-	GtkWidget *apply_cmd_changes;
 	GtkWidget *command_combobox;
 	gint selected;
-
-	const char  *key  = g_object_get_data (G_OBJECT (entry), "key");
+	gchar *cmd_key = NULL;
+	
+	const gchar *key  = g_object_get_data (G_OBJECT (entry), "key");
 	const gchar *val  = gtk_entry_get_text (GTK_ENTRY (entry));
 	
-	apply_cmd_changes = glade_xml_get_widget (xml_commands, "command_apply_button");
-	command_combobox = glade_xml_get_widget (xml_commands, "cmd_type_combobox");
+	
+	command_combobox = (GtkWidget*)data;
 	
 	selected = gtk_combo_box_get_active (GTK_COMBO_BOX (command_combobox));	
 
 	/* All hrs (Halt, Shutdown, Suspend) commands will fall into this category */
-	if (strcmp ("hrs_custom_cmd", ve_sure_string (key)) == 0) {
-		gchar *old_val = NULL;
-		gchar *cmd_key = NULL;
-
+	if (strcmp ("hrs_custom_cmd", ve_sure_string (key)) == 0) {	
 		if (selected == HALT_CMD)
 			cmd_key = g_strdup (GDM_KEY_HALT);			
 		else if (selected == REBOOT_CMD)
 			cmd_key = g_strdup (GDM_KEY_REBOOT);
 		else if (selected == SUSPEND_CMD)
-			cmd_key = g_strdup (GDM_KEY_SUSPEND);
-		
-		old_val = gdm_config_get_string (cmd_key);		
-			
-		if (strcmp (ve_sure_string (val), ve_sure_string (old_val)) != 0) 			
-			g_hash_table_insert (GdmCommandChangesUnsaved, g_strdup (cmd_key), g_strdup (val));
-
-		else if (g_hash_table_lookup (GdmCommandChangesUnsaved, cmd_key) != NULL)			
-			g_hash_table_remove (GdmCommandChangesUnsaved, cmd_key);		
-		
-		g_free (old_val);
-		g_free (cmd_key);
+			cmd_key = g_strdup (GDM_KEY_SUSPEND);				
 	}
 	/* All the custom commands will fall into this category */
-	else {
-		gchar *key_string = NULL;
-		gchar *old_val = NULL;
+	else {	
 		gint i;			
 
 		i = selected - CUSTOM_CMD;
-		key_string = g_strdup_printf("%s%d=", ve_sure_string (key), i); 
-		old_val = gdm_config_get_string (key_string);				
-	
-		
-		if (strcmp (ve_sure_string (val), ve_sure_string (old_val)) != 0)
-			g_hash_table_insert (GdmCommandChangesUnsaved, g_strdup (key_string), g_strdup (val));
-		
-		else if (g_hash_table_lookup (GdmCommandChangesUnsaved, key_string) != NULL)
-			g_hash_table_remove (GdmCommandChangesUnsaved, key_string);
-		
-		g_free (old_val);
-		g_free (key_string);
+		cmd_key = g_strdup_printf("%s%d=", ve_sure_string (key), i); 
+					
 	}	
 	
-	if (g_hash_table_size (GdmCommandChangesUnsaved) == 0)
-		gtk_widget_set_sensitive (apply_cmd_changes, FALSE);
-	else 
-		gtk_widget_set_sensitive (apply_cmd_changes, TRUE);
-	
-	return FALSE;
-}
+	gdm_setup_config_set_string (cmd_key, g_strdup (val));		
 
-static void
-commands_entry_changed (GtkWidget *entry)
-{
-	run_timeout (entry, 100, commands_entry_timeout);
+	g_free (cmd_key);
 }
 
 static void
@@ -2375,7 +2393,9 @@
                            const char *key)
 {
 	GtkWidget *entry;
-
+	GtkWidget *cmd_combobox;
+	
+	cmd_combobox = glade_xml_get_widget (xml_commands, "cmd_type_combobox");
 	entry = glade_xml_get_widget (xml_commands, name);
 	
 	g_object_set_data_full (G_OBJECT (entry),
@@ -2383,7 +2403,7 @@
 	                        (GDestroyNotify) g_free);
 
 	g_signal_connect (G_OBJECT (entry), "changed",
-		          G_CALLBACK (commands_entry_changed), NULL);
+		          G_CALLBACK (commands_entry_changed), cmd_combobox);
 }
 
 static void
@@ -2391,15 +2411,17 @@
 			      const char *key)
 {
 	GtkWidget *toggle;
-	
-	toggle = glade_xml_get_widget (xml_commands, name);
-	
+	GtkWidget *cmd_combobox;
+
+	cmd_combobox = glade_xml_get_widget (xml_commands, "cmd_type_combobox");
+	toggle = glade_xml_get_widget (xml_commands, name);	
+
 	g_object_set_data_full (G_OBJECT (toggle),
 	                        "key", g_strdup (key),
 	                        (GDestroyNotify) g_free);
 	
 	g_signal_connect (G_OBJECT (toggle), "toggled",
-		          G_CALLBACK (command_toggle_toggled), NULL);
+		          G_CALLBACK (command_toggle_toggled), cmd_combobox);
 }
 
 #ifdef HAVE_LIBXDMCP
@@ -2412,7 +2434,7 @@
 
 	toggle = glade_xml_get_widget (xml_xdmcp, name);
 
-	val = gdm_config_get_bool ((gchar *)key);
+	val = gdm_setup_config_get_bool ((gchar *)key);
 
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), val);
 
@@ -2464,6 +2486,156 @@
 	return strcmp(a, b);
 }
 
+/* These is more less a copy of gdmuser.c funtions gdm_users_init, setup_user and
+   gdm_check_exclude. As wrong as it may seem it is still better to writing many 
+   wrapper functions with large number of parameters IMHO
+*/
+static gboolean
+gdm_setup_check_exclude (struct passwd *pwent, char **excludes, gboolean is_local)
+{
+	const char * const lockout_passes[] = { "!!", NULL };
+	gint i;
+	
+        if ( ! gdm_setup_config_get_working_bool (GDM_KEY_ALLOW_ROOT) && pwent->pw_uid == 0)
+                return TRUE;
+
+        if ( ! gdm_setup_config_get_working_bool (GDM_KEY_ALLOW_REMOTE_ROOT) && ! is_local && pwent->pw_uid == 0)
+                return TRUE;
+
+	if (pwent->pw_uid < gdm_setup_config_get_working_int (GDM_KEY_MINIMAL_UID))
+		return TRUE;
+
+	for (i=0 ; lockout_passes[i] != NULL ; i++)  {
+		if (strcmp (lockout_passes[i], pwent->pw_passwd) == 0) {
+			return TRUE;
+		}
+	}
+
+	if (excludes != NULL) {
+		for (i=0 ; excludes[i] != NULL ; i++)  {
+			if (g_ascii_strcasecmp (excludes[i],
+						pwent->pw_name) == 0) {
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+static gboolean
+gdm_setup_setup_user (struct passwd *pwent,
+		      GList **users,
+		      GList **users_string,
+		      char **excludes,
+		      char *exclude_user,
+		      int *size_of_users,
+		      gboolean is_local,
+		      gboolean read_faces,
+		      time_t time_started)
+{
+    GdmUser *user;
+    int cnt = 0;
+
+    if (pwent->pw_shell && 
+	gdm_check_shell (pwent->pw_shell) &&
+	!gdm_setup_check_exclude (pwent, excludes, is_local) &&
+	(exclude_user == NULL ||
+	strcmp (ve_sure_string (exclude_user), pwent->pw_name)) != 0) {
+
+	    user = gdm_user_alloc (pwent->pw_name,
+				   pwent->pw_uid,
+				   pwent->pw_dir,
+				   ve_sure_string (pwent->pw_gecos),
+				   NULL, read_faces);
+
+	    if ((user) &&
+		(! g_list_find_custom (*users, user, (GCompareFunc) gdm_user_sort_func))) {
+		cnt++;
+		*users = g_list_insert_sorted (*users, user,
+					       (GCompareFunc) gdm_user_sort_func);
+		*users_string = g_list_prepend (*users_string, g_strdup (pwent->pw_name));
+
+		if (user->picture != NULL) {
+			*size_of_users +=
+				gdk_pixbuf_get_height (user->picture) + 2;
+		} else {
+			*size_of_users += gdm_setup_config_get_int (GDM_KEY_MAX_ICON_HEIGHT);
+		}
+	    }
+
+	    if (cnt > 1000 || time_started + 5 <= time (NULL)) {
+		*users = g_list_append (*users,
+			g_strdup (_("Too many users to list here...")));
+		*users_string = g_list_append (*users_string,
+			g_strdup (_("Too many users to list here...")));
+
+		return (FALSE);
+	    }
+    }
+    return (TRUE);
+}
+
+static void 
+gdm_setup_users_init (GList **users,
+		      GList **users_string,
+		      char *exclude_user,
+		      int *size_of_users,
+		      gboolean is_local,
+		      gboolean read_faces)
+{
+    struct passwd *pwent;
+    char **includes;
+    char **excludes;
+    gboolean found_include = FALSE;
+    int i;
+    time_t time_started;
+    
+    time_started = time (NULL);
+	
+    includes = g_strsplit (gdm_setup_config_get_working_string (GDM_KEY_INCLUDE), ",", 0);
+    for (i=0 ; includes != NULL && includes[i] != NULL ; i++) {
+	g_strstrip (includes[i]);
+        if (includes[i] != NULL)
+           found_include = TRUE;
+    }
+
+    excludes = g_strsplit (gdm_setup_config_get_working_string (GDM_KEY_EXCLUDE), ",", 0);
+    for (i=0 ; excludes != NULL && excludes[i] != NULL ; i++)
+	g_strstrip (excludes[i]);
+
+    if (gdm_setup_config_get_working_bool (GDM_KEY_INCLUDE_ALL) == TRUE) {
+	    setpwent ();
+	    pwent = getpwent ();
+	    while (pwent != NULL) {
+
+		if (! gdm_setup_setup_user (pwent, users, users_string, excludes,
+					    exclude_user, size_of_users, is_local,
+					    read_faces, time_started))
+			break;
+
+		pwent = getpwent ();
+	}
+	endpwent ();
+
+    } else if (found_include == TRUE) {
+	for (i=0 ; includes != NULL && includes[i] != NULL ; i++) {
+		pwent = getpwnam (includes[i]);
+
+		if (pwent != NULL) {
+			if (!gdm_setup_setup_user (pwent, users, users_string, excludes,
+						   exclude_user, size_of_users, is_local,
+						   read_faces, time_started))
+			break;
+
+		}
+	}
+    }
+
+    g_strfreev (includes);
+    g_strfreev (excludes);
+}
+   
 /* Sets up Automatic Login Username and Timed Login User entry comboboxes
  * from the general configuration tab. */
 static void
@@ -2476,13 +2648,13 @@
 	GList *users_string = NULL;
 	GList *li;
 	static gboolean GDM_IS_LOCAL = FALSE;
-	char *selected_user;
+	const char *selected_user;
 	gint size_of_users = 0;
 	int selected = -1;
 	int cnt;
-
+	
 	combobox_store = gtk_list_store_new (USERLIST_NUM_COLUMNS, G_TYPE_STRING);
-	selected_user  = gdm_config_get_string ((gchar *)key);
+	selected_user  = gdm_setup_config_get_working_string (key);
 
 	/* normally empty */
 	users_string = g_list_append (users_string, g_strdup (""));
@@ -2495,8 +2667,8 @@
 	else
 		GDM_IS_LOCAL = TRUE;
 
-	gdm_users_init (&users, &users_string, selected_user, NULL,
-	                &size_of_users, GDM_IS_LOCAL, FALSE);
+	gdm_setup_users_init (&users, &users_string, g_strdup (selected_user), 
+			      &size_of_users, GDM_IS_LOCAL, FALSE);
 
 	users_string = g_list_sort (users_string, users_string_compare_func);
 
@@ -2535,16 +2707,35 @@
 }
 
 static void
+setup_intspin_other (const char *name,
+		     const char *key,
+		     const char *other_name)
+{
+	GtkWidget *spin = glade_xml_get_widget (xml, name);
+	GtkWidget *spin_other = glade_xml_get_widget (xml, other_name);
+	int val = gdm_setup_config_get_int ((gchar *)key);	
+	
+	g_object_set_data_full (G_OBJECT (spin),
+				"key", g_strdup (key),
+				(GDestroyNotify) g_free);
+	
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), val);
+	
+	g_signal_connect (G_OBJECT (spin), "value_changed",
+			  G_CALLBACK (intspin_changed_other), spin_other);	
+}
+
+static void
 setup_intspin (const char *name,
 	       const char *key)
 {
 	GtkWidget *spin = glade_xml_get_widget (xml, name);
-	int val = gdm_config_get_int ((gchar *)key);
-
+	int val = gdm_setup_config_get_int ((gchar *)key);	
+	
 	g_object_set_data_full (G_OBJECT (spin),
 				"key", g_strdup (key),
 				(GDestroyNotify) g_free);
-
+	
 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), val);
 
 	g_signal_connect (G_OBJECT (spin), "value_changed",
@@ -2557,7 +2748,7 @@
 	             const char *key)
 {
 	GtkWidget *spin;
-	int val = gdm_config_get_int ((gchar *)key);
+	int val = gdm_setup_config_get_int ((gchar *)key);
 
 	spin = glade_xml_get_widget (xml_xdmcp, name);
 
@@ -2576,12 +2767,17 @@
 setup_include_exclude (GtkWidget *treeview, const char *key)
 {
 	GtkListStore *face_store = gtk_list_store_new (USERLIST_NUM_COLUMNS,
-		G_TYPE_STRING);
+						       G_TYPE_STRING);
 	GtkTreeIter iter;
 	GtkTreeViewColumn *column;
 	GtkCellRenderer *renderer;
 	char **list;
 	int i;
+	gchar *GdmInclude;
+	gchar *GdmExclude;
+
+	GdmInclude = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_INCLUDE));
+	GdmExclude = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_EXCLUDE));
 
 	column = gtk_tree_view_column_new ();
 
@@ -2609,6 +2805,8 @@
 		gtk_list_store_set(face_store, &iter, USERLIST_NAME, list[i], -1);
 	}
 	g_strfreev (list);
+	g_free (GdmExclude);
+	g_free (GdmInclude);
 
 	return (face_store);
 }
@@ -2619,7 +2817,6 @@
 } FaceType;
 
 typedef struct _FaceCommon {
-	GtkWidget *apply;
 	GtkWidget *include_treeview;
 	GtkWidget *exclude_treeview;
 	GtkListStore *include_store;
@@ -2645,6 +2842,9 @@
 	FaceData *include;
 } FaceApply;
 
+/* Forward declaration */
+static void set_users_data (FaceCommon *fc);
+
 static void
 face_add (FaceData *fd)
 {
@@ -2717,7 +2917,7 @@
 		if (fd->type == INCLUDE) {
 			/* Now the user is valid but his/hers UID might be smaller than the MinimalUID */
 			gint user_uid = gdm_user_uid (text);
-			if (user_uid < gdm_config_get_int (GDM_KEY_MINIMAL_UID)) {
+			if (user_uid < gdm_setup_config_get_working_int (GDM_KEY_MINIMAL_UID)) {
 				GtkWidget *setup_dialog;
 				GtkWidget *dialog;
 				gchar *str;
@@ -2745,8 +2945,8 @@
 			gtk_list_store_set (fd->fc->exclude_store, &iter,
 				USERLIST_NAME, text, -1);
 		}
-		gtk_widget_set_sensitive (fd->fc->apply, TRUE);
-		GdmUserChangesUnsaved = TRUE;
+		set_users_data (fd->fc);
+
 	} else {
 		GtkWidget *setup_dialog;
 		GtkWidget *dialog;
@@ -2780,9 +2980,7 @@
 			GTK_TREE_VIEW (fd->fc->include_treeview));
 
 		if (gtk_tree_selection_get_selected (selection, &(fd->fc->include_model), &iter)) {
-			gtk_list_store_remove (fd->fc->include_store, &iter);
-			gtk_widget_set_sensitive (fd->fc->apply, TRUE);
-			GdmUserChangesUnsaved = TRUE;
+			gtk_list_store_remove (fd->fc->include_store, &iter);			
 		}
 	} else if (fd->type == EXCLUDE) {
 		selection = gtk_tree_view_get_selection (
@@ -2790,10 +2988,10 @@
 
 		if (gtk_tree_selection_get_selected (selection, &(fd->fc->exclude_model), &iter)) {
 			gtk_list_store_remove (fd->fc->exclude_store, &iter);
-			gtk_widget_set_sensitive (fd->fc->apply, TRUE);
-			GdmUserChangesUnsaved = TRUE;
 		}
 	}
+	
+	set_users_data (fd->fc);
 }
 
 static void
@@ -2821,7 +3019,7 @@
 		if (fd->type == INCLUDE) {
 			/* We cant move the users that have uid smaller that MinimalUID */
 			gint user_uid = gdm_user_uid (text);
-			if (user_uid < gdm_config_get_int (GDM_KEY_MINIMAL_UID)) {
+			if (user_uid < gdm_setup_config_get_working_int (GDM_KEY_MINIMAL_UID)) {
 				GtkWidget *setup_dialog;
 				GtkWidget *dialog;
 				gchar *str;
@@ -2851,113 +3049,105 @@
 			gtk_list_store_set (fd->fc->exclude_store, &iter,
 				USERLIST_NAME, text, -1);
 		}
-		gtk_widget_set_sensitive (fd->fc->apply, TRUE);
-		GdmUserChangesUnsaved = TRUE;
+		set_users_data (fd->fc);
 	}
 }
 
-/* Hash key happens to be equal to the config entry key,
-   se we save the value under the key and clean up
-*/
+/* 
+ * Hash key happens to be equal to the config entry key,
+ * so we save the value under the key only if different 
+ * to the existing orginal config value. We also update
+ * the local cache with "new" values rather than poll
+ * the daemon.
+ */
 static gboolean
 unsaved_data_from_hash_table_func (gpointer key, gpointer value, gpointer user_data)
 {
-	gchar *c_key = key;
-        if (strncmp (c_key, GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE, 
-		     strlen (GDM_KEY_CUSTOM_CMD_NO_RESTART_TEMPLATE)) == 0 ||
-	    strncmp (c_key, GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE,
-		     strlen (GDM_KEY_CUSTOM_CMD_IS_PERSISTENT_TEMPLATE)) == 0) {
-		gboolean *p_val = (gboolean*)value;
-		gdm_setup_config_set_bool (c_key, *p_val);
+	GdmConfigValue *defaultval = NULL;
+
+	const gchar *c_key = (const char*)key;
+	const GdmConfigValue *c_value = (const GdmConfigValue*)value;
+	GKeyFile *cfg = (GKeyFile*)g_hash_table_lookup ((GHashTable*)user_data, config_file);
+	GKeyFile *custom_cfg = (GKeyFile*)g_hash_table_lookup ((GHashTable*)user_data, custom_config_file);	        
+	
+	if (!gdm_common_config_get_value (cfg, c_key, &defaultval,
+					  c_value->type, TRUE, NULL)) {
+		/* This is not all that scary - it just means that given
+		   key does not exist in the defaults.conf, or we have
+		   misspelled the key name
+		*/
+		
+		gdm_common_config_set_value (custom_cfg, c_key, c_value);
 	}
-	else
-		gdm_setup_config_set_string (c_key, (gchar*)value);	
+	else {		
+		if (gdm_config_value_compare (c_value, defaultval) == 0) {
+			gdm_common_config_remove_key (custom_cfg, c_key, NULL);			
+		}
+		else {
+			gdm_common_config_set_value (custom_cfg, c_key, c_value);
+		}
+		gdm_config_value_free (defaultval);
+	}				       
 	
-	/* And final cleanup */
-	g_free (value);
-	g_free (key);
-
+	/* since we updating the deamon's configuration lets update the cache too */
+	g_hash_table_insert (GdmCurrentConfigValues, g_strdup (c_key), gdm_config_value_copy (c_value));
+		
 	return TRUE;
 }
 
-/* Go thru and remove each of the hash entries
-   then clean the hash (if not already empty)
-   just in case, then de-sensitise the apply 
-   command changes button
-*/
+/*
+ * We open the config files, save the changes and inform 
+ * the daemon about updating its entire configuration
+ * (well most of it anyway)
+ */
 static void
-command_apply (GtkWidget *button, gpointer data)
+apply_changes (gboolean do_greeters) 
 {
-	const gchar *command = NULL;
-	GtkWidget *cmd_path_entry = NULL;
-	GtkWidget *command_combobox = (GtkWidget*)data;
-	gboolean command_exists = FALSE;
-	gint selected;
-	
-	selected = gtk_combo_box_get_active (GTK_COMBO_BOX (command_combobox));
-	
-	if (last_selected_command < CUSTOM_CMD)
-		cmd_path_entry = glade_xml_get_widget (xml_commands, "hrs_cmd_path_entry");
-	else
-		cmd_path_entry = glade_xml_get_widget (xml_commands, "custom_cmd_path_entry");
+	GKeyFile *cfg;
+	GKeyFile *custom_cfg;
+	GHashTable *cfg_files;
 
-	command = gtk_entry_get_text (GTK_ENTRY (cmd_path_entry));
-	
-	command_exists = ve_string_empty (command) || gdm_working_command_exists (command);
-	
-	if(command_exists)
-		g_hash_table_foreach_remove (GdmCommandChangesUnsaved,
-					     (GHRFunc) unsaved_data_from_hash_table_func, NULL);
-	
-	else {
-		GtkWidget *parent = glade_xml_get_widget (xml_commands, "commands_dialog");
+        cfg = gdm_common_config_load (config_file, NULL);
+	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
 
-		GtkWidget *dialog = hig_dialog_new (GTK_WINDOW (parent),
-						    GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-						    GTK_MESSAGE_ERROR,
-						    GTK_BUTTONS_OK,
-						    _("Invalid command path"),
-						    _("The path you provided for this "
-						      "command is not valid. The changes "
-						      "will not be saved."));
-		gtk_dialog_run (GTK_DIALOG (dialog));
-		gtk_widget_destroy (dialog);
-	}
-	
-	/* Just to make sure */
-	if (g_hash_table_size (GdmCommandChangesUnsaved) != 0)
-		g_hash_table_remove_all (GdmCommandChangesUnsaved);
+	if(cfg != NULL && custom_cfg != NULL)		
+	{
+		cfg_files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify*)g_key_file_free);
+		g_hash_table_insert (cfg_files, g_strdup (config_file), cfg);
+		g_hash_table_insert (cfg_files, g_strdup (custom_config_file), custom_cfg);
+		
+		g_hash_table_foreach_remove (GdmChangesUnsaved, unsaved_data_from_hash_table_func, cfg_files);
 
-	gtk_widget_set_sensitive (button, FALSE);
-	
-	if (selected == last_selected_command)
-		g_signal_emit_by_name (G_OBJECT (command_combobox), "changed");
-	
-	if(command_exists)
-		update_greeters ();
+		gdm_common_config_save (custom_cfg, custom_config_file, NULL);
+		g_hash_table_destroy (cfg_files);
+
+		if (do_greeters)
+			update_greeters ();
+	}
 }
 
 static void
-browser_apply (GtkWidget *button, gpointer data)
+set_users_data (FaceCommon *fc)
 {
-	FaceCommon *fc = data;
 	GString *userlist = g_string_new (NULL);
 	const char *model_text;
-	char *val;
 	GtkTreeIter iter;
 	gboolean valid;
-	gboolean update_greet = FALSE;
 	char *sep = "";
 	gint minimalUID = -1;
 	gboolean any_removed = FALSE;
-	
-	minimalUID = gdm_config_get_int (GDM_KEY_MINIMAL_UID);
-	
+	gchar *GdmInclude;
+	gchar *GdmExclude;
+
+	minimalUID = gdm_setup_config_get_working_int (GDM_KEY_MINIMAL_UID);
+	GdmInclude = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_INCLUDE));
+	GdmExclude = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_EXCLUDE));
+
 	valid = gtk_tree_model_get_iter_first (fc->include_model, &iter);
 	while (valid) {
 		gtk_tree_model_get (fc->include_model, &iter, USERLIST_NAME,
-			 &model_text, -1);
-
+				    &model_text, -1);
+		
 		/* We need to take check that during the time between adding
 		   a user and clicking on the apply button UID has not changed 
 		   If so then the offending users should be removed
@@ -2973,7 +3163,7 @@
 			valid = gtk_tree_model_iter_next (fc->include_model, &iter);
 		}
 	}
-
+	
 	if (any_removed) {
 		GtkWidget *setup_dialog;
 		GtkWidget *dlg;
@@ -2989,57 +3179,43 @@
 				      _("Some of the users had uid lower than "
 					"MinimalUID (Security tab) and "
 					"could not be added."));
-		gtk_dialog_run (GTK_DIALOG (dlg));
-		gtk_widget_destroy (dlg);						
-		
+			gtk_dialog_run (GTK_DIALOG (dlg));
+			gtk_widget_destroy (dlg);						
+			
 	}
-
-	val = gdm_config_get_string (GDM_KEY_INCLUDE);
-
-	if (strcmp (ve_sure_string (val),
-		    ve_sure_string (userlist->str)) != 0) {
+	
+	if (strcmp (ve_sure_string (GdmInclude), ve_sure_string (userlist->str)) != 0)
 		gdm_setup_config_set_string (GDM_KEY_INCLUDE, userlist->str);
-		update_greet = TRUE;
-	}
-
+	
 	g_string_free (userlist, TRUE);
+	g_free (GdmInclude);
 
 	userlist = g_string_new (NULL);
 	sep = "";
 	valid = gtk_tree_model_get_iter_first (fc->exclude_model, &iter);
 	while (valid) {
 		gtk_tree_model_get (fc->exclude_model, &iter, USERLIST_NAME,
-			 &model_text, -1);
-
+				    &model_text, -1);
+		
 		g_string_append (userlist, sep);
 		sep = ",";
 		g_string_append (userlist, model_text);
-
+		
 		valid = gtk_tree_model_iter_next (fc->exclude_model, &iter);
 	}
-
-	val = gdm_config_get_string (GDM_KEY_EXCLUDE);
-
-	if (strcmp (ve_sure_string (val),
-		    ve_sure_string (userlist->str)) != 0) {
+	
+	if (strcmp (ve_sure_string (GdmExclude), ve_sure_string (userlist->str)) != 0)
 		gdm_setup_config_set_string (GDM_KEY_EXCLUDE, userlist->str);
-		update_greet = TRUE;
-	}
-
-	if (update_greet)
-		update_greeters ();
-
+	
 	/* Re-initialize combox with updated userlist. */
-	GdmInclude = gdm_config_get_string (GDM_KEY_INCLUDE);
-	GdmExclude = gdm_config_get_string (GDM_KEY_EXCLUDE);
+	
 	setup_user_combobox_list ("autologin_combo",
 			  GDM_KEY_AUTOMATIC_LOGIN);
 	setup_user_combobox_list ("timedlogin_combo",
 			  GDM_KEY_TIMED_LOGIN);
-	gtk_widget_set_sensitive (button, FALSE);
-
-	GdmUserChangesUnsaved = FALSE;
+	
 	g_string_free (userlist, TRUE);
+	g_free (GdmExclude);
 }
 
 
@@ -3128,7 +3304,6 @@
 	static FaceCommon fc;
 	static FaceData fd_include;
 	static FaceData fd_exclude;
-	static FaceApply face_apply;
 
 	GtkTreeSelection *selection;
 
@@ -3138,7 +3313,6 @@
 	fc.exclude_del       = glade_xml_get_widget (xml, "fb_excludedelete");
 	fc.to_include_button = glade_xml_get_widget (xml, "fb_toinclude");
 	fc.to_exclude_button = glade_xml_get_widget (xml, "fb_toexclude");
-	fc.apply             = glade_xml_get_widget (xml, "fb_faceapply");
 	fc.include_treeview  = glade_xml_get_widget (xml, "fb_include_treeview");
 	fc.exclude_treeview  = glade_xml_get_widget (xml, "fb_exclude_treeview");
 	fc.allusers          = glade_xml_get_widget (xml, "fb_allusers");
@@ -3158,15 +3332,11 @@
 
 	fd_exclude.fc = &fc;
 	fd_exclude.type = EXCLUDE;
-
+	
 	gtk_widget_set_sensitive (fc.include_del, FALSE);
 	gtk_widget_set_sensitive (fc.exclude_del, FALSE);
 	gtk_widget_set_sensitive (fc.to_include_button, FALSE);
 	gtk_widget_set_sensitive (fc.to_exclude_button, FALSE);
-	gtk_widget_set_sensitive (fc.apply, FALSE);
-
-	face_apply.include = &fd_include;
-	face_apply.exclude = &fd_exclude;
 
 	xml_add_users = glade_xml_new (GDM_GLADE_DIR "/gdmsetup.glade", "add_user_dialog", NULL);
 
@@ -3199,68 +3369,47 @@
 	                  G_CALLBACK (browser_move), &fd_include);
 	g_signal_connect (fc.to_exclude_button, "clicked",
 	                  G_CALLBACK (browser_move), &fd_exclude);
-
-	g_signal_connect (fc.apply, "clicked",
-	                  G_CALLBACK (browser_apply), &fc);
 }
 
 static void
-include_all_toggle (GtkWidget *toggle)
-{
-	if (GTK_TOGGLE_BUTTON (toggle)->active)
-		GdmIncludeAll = TRUE;
-	else
-		GdmIncludeAll = FALSE;
-
-	setup_user_combobox_list ("autologin_combo",
-			  GDM_KEY_AUTOMATIC_LOGIN);
-	setup_user_combobox_list ("timedlogin_combo",
-			  GDM_KEY_TIMED_LOGIN);
-}
-
-static gboolean
-greeter_toggle_timeout (GtkWidget *toggle)
+greeter_toggle_toggled (GtkWidget *toggle, gpointer data)
 {
 	const char *key = g_object_get_data (G_OBJECT (toggle), "key");
-	gboolean val = gdm_config_get_bool ((gchar *)key);
-
-	if ( ! bool_equal (val, GTK_TOGGLE_BUTTON (toggle)->active)) {
+	gboolean val = gdm_setup_config_get_working_bool (key);
 	
+	if ( ! bool_equal (val, GTK_TOGGLE_BUTTON (toggle)->active)) {
+		
+		gdm_setup_config_set_bool (key, GTK_TOGGLE_BUTTON (toggle)->active);
+
 		if (strcmp (ve_sure_string (key), GDM_KEY_BACKGROUND_SCALE_TO_FIT) == 0) {
-	
+			
 			if (gtk_notebook_get_current_page (GTK_NOTEBOOK (setup_notebook)) == LOCAL_TAB) {
-
+				
 				GtkWidget *checkbutton;
-		
+				
 				checkbutton = glade_xml_get_widget (xml, "sg_scale_background_remote");
-
+				
 				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton),
 				                              GTK_TOGGLE_BUTTON (toggle)->active);
 			}
 			else {
 				GtkWidget *checkbutton;
-			
+				
 				checkbutton = glade_xml_get_widget (xml, "sg_scale_background");
-
+				
 				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton),
 				                              GTK_TOGGLE_BUTTON (toggle)->active);	
 			}
-		}
-		gdm_setup_config_set_bool (key, GTK_TOGGLE_BUTTON (toggle)->active);
-		update_greeters ();
-
-		if (strcmp (ve_sure_string (key), GDM_KEY_INCLUDE_ALL) == 0) {
-			include_all_toggle (toggle);
-		}
+		}	
+		else if (strcmp (ve_sure_string (key), GDM_KEY_INCLUDE_ALL) == 0) {
+			
+			setup_user_combobox_list ("autologin_combo",
+						  GDM_KEY_AUTOMATIC_LOGIN);
+			setup_user_combobox_list ("timedlogin_combo",
+						  GDM_KEY_TIMED_LOGIN);
+			
+		}		
 	}
-
-	return FALSE;
-}
-
-static void
-greeter_toggle_toggled (GtkWidget *toggle)
-{
-	run_timeout (toggle, 500, greeter_toggle_timeout);
 }
 
 static void
@@ -3276,12 +3425,10 @@
 	} else {
 		gtk_widget_set_sensitive (widget, FALSE);
 	}
-
-	run_timeout (toggle, 500, greeter_toggle_timeout);
 }
 
-static gboolean
-local_background_type_toggle_timeout (GtkWidget *toggle)
+static void
+local_background_type_toggled (GtkWidget *toggle, gpointer data)
 {
 	GtkWidget *color_radiobutton;
 	GtkWidget *image_radiobutton;
@@ -3324,15 +3471,6 @@
 		/* No Background */
 		gdm_setup_config_set_int (GDM_KEY_BACKGROUND_TYPE, 0);
 	}
-		
-	update_greeters ();
-	return FALSE;
-}
-
-static void
-local_background_type_toggled (GtkWidget *toggle)
-{
-	run_timeout (toggle, 200, local_background_type_toggle_timeout);
 }
 
 static void
@@ -3340,7 +3478,7 @@
 		      const char *key)
 {
 	GtkWidget *toggle = glade_xml_get_widget (xml, name);
-	gboolean val = gdm_config_get_bool ((gchar *)key);
+	gboolean val = gdm_setup_config_get_bool ((gchar *)key);
 
 	g_object_set_data_full (G_OBJECT (toggle), "key", g_strdup (key),
 		(GDestroyNotify) g_free);
@@ -3355,7 +3493,7 @@
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (custom), !val);
 
 		g_signal_connect (G_OBJECT (toggle), "toggled",	
-			G_CALLBACK (sensitive_entry_toggled), welcome);
+			G_CALLBACK (sensitive_entry_toggled), welcome);		
 
 	} else if (strcmp ("sg_defaultwelcomeremote", ve_sure_string (name)) == 0) {
 		GtkWidget *welcomeremote = glade_xml_get_widget (xml, "welcomeremote");
@@ -3365,7 +3503,7 @@
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (customremote), !val);
 
 		g_signal_connect (G_OBJECT (toggle), "toggled",	
-			G_CALLBACK (sensitive_entry_toggled), welcomeremote);
+			G_CALLBACK (sensitive_entry_toggled), welcomeremote);		
 	
 	} else if (strcmp ("fb_allusers", ve_sure_string (name)) == 0) {
 
@@ -3386,9 +3524,9 @@
 		g_signal_connect (G_OBJECT (toggle), "toggled",	
 			G_CALLBACK (sensitive_entry_toggled), fb_includeadd);
 		g_signal_connect (G_OBJECT (toggle), "toggled",	
-			G_CALLBACK (list_selection_toggled), fb_includeremove);
+			G_CALLBACK (list_selection_toggled), fb_includeremove);		
 		g_signal_connect (G_OBJECT (toggle), "toggled",	
-			G_CALLBACK (sensitive_entry_toggled), fb_includelabel);
+			G_CALLBACK (sensitive_entry_toggled), fb_includelabel);			
 	}
 	else if (strcmp ("acc_sound_ready", ve_sure_string (name)) == 0) {
 	
@@ -3455,12 +3593,13 @@
 		G_CALLBACK (greeter_toggle_toggled), NULL);
 }
 
-static gboolean
-greeter_color_timeout (GtkWidget *picker)
+static void
+greeter_color_changed (GtkWidget *picker, gpointer data)
 {
 	const char *key = g_object_get_data (G_OBJECT (picker), "key");
 	GdkColor color_val;
-	char *val, *color;
+	GdkColor color_val_other;
+	char *color = NULL;	
 
 	gtk_color_button_get_color (GTK_COLOR_BUTTON (picker), &color_val);
 	
@@ -3473,6 +3612,7 @@
 		} else {
 			colorbutton = glade_xml_get_widget (xml, "remote_background_colorbutton");
 		}
+		gtk_color_button_get_color (GTK_COLOR_BUTTON (colorbutton), &color_val_other);
 		gtk_color_button_set_color (GTK_COLOR_BUTTON (colorbutton), &color_val);
 	}
 	else {
@@ -3483,31 +3623,23 @@
 		} else {
 			colorbutton = glade_xml_get_widget (xml, "local_background_colorbutton");
 		}
+		gtk_color_button_get_color (GTK_COLOR_BUTTON (colorbutton), &color_val_other);
 		gtk_color_button_set_color (GTK_COLOR_BUTTON (colorbutton), &color_val);
 	}
 	
-	color = g_strdup_printf ("#%02x%02x%02x",
-	                         (guint16)color_val.red / 256, 
-	                         (guint16)color_val.green / 256, 
-	                         (guint16)color_val.blue / 256);
-
-	val = gdm_config_get_string ((gchar *)key);
-
-	if (strcmp (ve_sure_string (val), ve_sure_string (color)) != 0) {
-		gdm_setup_config_set_string (key, ve_sure_string (color));
-		update_greeters ();
-	}
-
-	g_free (color);
-
-	return FALSE;
-}
-
-static void
-greeter_color_changed (GtkWidget *picker,
-		       guint r, guint g, guint b, guint a)
-{
-	run_timeout (picker, 500, greeter_color_timeout);
+	if (gdk_color_equal (&color_val, &color_val_other) == FALSE) {
+		gchar *color_upper;
+		
+		color = g_strdup_printf ("#%02x%02x%02x",
+					 (guint16)color_val.red / 256, 
+					 (guint16)color_val.green / 256, 
+					 (guint16)color_val.blue / 256);
+		
+		color_upper = g_ascii_strup (color, strlen (color));
+		gdm_setup_config_set_string (key, ve_sure_string (color_upper));
+		g_free (color_upper);
+		g_free (color);
+	}	
 }
 
 static void
@@ -3515,7 +3647,7 @@
 		     const char *key)
 {
 	GtkWidget *picker = glade_xml_get_widget (xml, name);
-	char *val = gdm_config_get_string ((gchar *)key);
+	const char *val = gdm_setup_config_get_string (key);
 
 	g_object_set_data_full (G_OBJECT (picker),
 				"key", g_strdup (key),
@@ -3544,57 +3676,17 @@
 	gchar *key;
 } ImageData;
 
-/*
- * Do we really want to throw away the user's translations just because they
- * changed the non-translated value?
- */
-static gboolean
-greeter_entry_untranslate_timeout (GtkWidget *entry)
+static void
+greeter_entry_untranslate_changed (GtkWidget *entry, gpointer data)
 {
-	GKeyFile   *custom_cfg;
 	const char *key;
 	const char *text;
-	char       *config_group;
-	char       *config_key;
-	int         i;
-	char       *prefix;
-	char      **keys;
 
-	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
         key = g_object_get_data (G_OBJECT (entry), "key");
 
 	text = gtk_entry_get_text (GTK_ENTRY (entry));
-
-	config_group = config_key = NULL;
-	if (! gdm_common_config_parse_key_string (key, &config_group, &config_key, NULL, NULL)) {
-		goto out;
-	}
-
-	prefix = g_strdup_printf ("%s[", config_key);
-	keys = g_key_file_get_keys (custom_cfg, config_group, NULL, NULL);
-	for (i = 0; keys[i] != NULL; i++) {
-		if (g_str_has_prefix (keys[i], prefix)) {
-			g_key_file_remove_key (custom_cfg, config_group, keys[i], NULL);
-		}
-	}
-	g_strfreev (keys);
-
-	gdm_setup_config_set_string (key, (char *)ve_sure_string (text));
-	update_greeters ();
-
-	gdm_common_config_save (custom_cfg, custom_config_file, NULL);
-
- out:
-	g_key_file_free (custom_cfg);
-
-	return FALSE;
-}
-
-
-static void
-greeter_entry_untranslate_changed (GtkWidget *entry)
-{
-	run_timeout (entry, 500, greeter_entry_untranslate_timeout);
+	gdm_setup_config_set_translated_string (key, (char *)ve_sure_string (text));
+	
 }
 
 static void
@@ -3659,11 +3751,11 @@
 	selected = gtk_combo_box_get_active (GTK_COMBO_BOX (command_combobox));
 	
 	if (selected == HALT_CMD)
-		value = gdm_config_get_string (GDM_KEY_HALT);			
+		value = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_HALT));
 	else if (selected == REBOOT_CMD)
-		value = gdm_config_get_string (GDM_KEY_REBOOT);		
+		value = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_REBOOT));
 	else if (selected == SUSPEND_CMD) 
-		value = gdm_config_get_string (GDM_KEY_SUSPEND);
+		value = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_SUSPEND));
 	else {
 		gchar *key_string;
 		gint i;
@@ -3671,7 +3763,7 @@
 		i = selected - CUSTOM_CMD;
 		
 		key_string = g_strdup_printf("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, i); 
-		value = gdm_config_get_string (key_string);		
+		value = g_strdup (gdm_setup_config_get_working_string (key_string));
 		g_free (key_string);
 	}
 	
@@ -3693,12 +3785,15 @@
 {
 	gchar *filename;
 	gchar *key;
-	gchar *value;
 		
 	filename  = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-	key = g_object_get_data (G_OBJECT (file_chooser), "key");	
-	value     = gdm_config_get_string (key);
-	
+	key = g_object_get_data (G_OBJECT (file_chooser), "key");       
+
+	/* Filename should never be NULL (we made sure of that when we were
+	   setting up file_chooser widget) so we can safely ignore this */
+	if (filename == NULL)
+		return;
+
 	if (strcmp (ve_sure_string (key), GDM_KEY_GLOBAL_FACE_DIR) == 0) {
 		/* we need to append trailing / so it matches the default
 		   config  values. This is not really necessary but makes
@@ -3707,19 +3802,16 @@
 		
 		corr_filename = g_strdup_printf("%s/", ve_sure_string (filename));
 		
-		if (strcmp (ve_sure_string (value), corr_filename) != 0)
-			gdm_setup_config_set_string (key, corr_filename);	
+		gdm_setup_config_set_string (key, corr_filename);	
 		
 		g_free (corr_filename);
 	}
 	else {
 		/* All other cases */
-		if (strcmp (ve_sure_string (value), ve_sure_string (filename)) != 0)
-			gdm_setup_config_set_string (key, ve_sure_string (filename));		
+		gdm_setup_config_set_string (key, ve_sure_string (filename));		
 	}
 	
 	g_free (filename);
-	g_free (value);
 }
 
 static void
@@ -3741,9 +3833,9 @@
 				 const char *key)
 {
 	GtkWidget *entry = glade_xml_get_widget (xml, name);
-	char *val;
+	const char *val;
 
-	val = gdm_config_get_translated_string ((gchar *)key);
+	val = gdm_setup_config_get_translated_string (key);
 
 	g_object_set_data_full (G_OBJECT (entry),
 				"key", g_strdup (key),
@@ -3754,8 +3846,6 @@
 	g_signal_connect (G_OBJECT (entry), "changed",
 			  G_CALLBACK (greeter_entry_untranslate_changed),
 			  NULL);
-
-	g_free (val);
 }
 
 #ifdef HAVE_LIBXDMCP
@@ -3791,45 +3881,6 @@
 }
 #endif
 
-static void
-apply_command_changes (GObject *object, gint response, gpointer command_data)
-{
-	GtkWidget *dialog = command_data;
-	
-	if (g_hash_table_size (GdmCommandChangesUnsaved) != 0 && 
-	    response != GTK_RESPONSE_HELP) {
-
-		GtkWidget *prompt;
-		gint response;
-
-		prompt = hig_dialog_new (GTK_WINDOW (dialog),
-					 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_WARNING,
-					 GTK_BUTTONS_NONE,
-					 _("Apply the changes to commands before closing?"),
-					 _("If you don't apply, the changes made "
-					   "will be disregarded."));
-		
-		gtk_dialog_add_button (GTK_DIALOG (prompt), _("Close _without Applying"), GTK_RESPONSE_CLOSE);
-		gtk_dialog_add_button (GTK_DIALOG (prompt), "gtk-apply", GTK_RESPONSE_APPLY);
-		
-		response = gtk_dialog_run (GTK_DIALOG (prompt));
-		gtk_widget_destroy (prompt);
-		
-		if (response == GTK_RESPONSE_APPLY) {
-			GtkWidget *apply_button;
-
-			apply_button = glade_xml_get_widget (xml_commands, "command_apply_button");
-			g_signal_emit_by_name (G_OBJECT (apply_button), "clicked");
-		}
-		else {
-			/* Just to make sure */
-			if (g_hash_table_size (GdmCommandChangesUnsaved) != 0)
-				g_hash_table_remove_all (GdmCommandChangesUnsaved);
-		}
-	}
-}
-
 /* Make label surrounded by tag (if tag = "tag" add <tag>text</tag>) */
 static void
 glade_helper_tagify_label (GladeXML *xml,
@@ -3857,13 +3908,11 @@
 {
 	static GtkWidget *dialog = NULL;
 	GtkWidget *command_chooser = NULL;
-	gint selected = -1;
 	gint response;
 
 	if (dialog == NULL) {
 
 		GtkWidget *parent;
-		GtkWidget *apply_command_changes_button;
 		gint i;
 
 		xml_commands = glade_xml_new (GDM_GLADE_DIR "/gdmsetup.glade", "commands_dialog", NULL);
@@ -3877,28 +3926,24 @@
 		glade_helper_tagify_label (xml_commands, "hrs_path_label", "small");
 		glade_helper_tagify_label (xml_commands, "custom_path_label", "i");
 		glade_helper_tagify_label (xml_commands, "custom_path_label", "small");
-		glade_helper_tagify_label (xml_commands, "label_label", "i");
-		glade_helper_tagify_label (xml_commands, "label_label", "small");
-		glade_helper_tagify_label (xml_commands, "lrlabel_label", "i");
-		glade_helper_tagify_label (xml_commands, "lrlabel_label", "small");		
-		glade_helper_tagify_label (xml_commands, "text_label", "i");
-		glade_helper_tagify_label (xml_commands, "text_label", "small");
-		glade_helper_tagify_label (xml_commands, "tooltip_label", "i");
-		glade_helper_tagify_label (xml_commands, "tooltip_label", "small");
-		glade_helper_tagify_label (xml_commands, "persistent_label", "i");
-		glade_helper_tagify_label (xml_commands, "persistent_label", "small");
-		glade_helper_tagify_label (xml_commands, "norestart_label", "i");
-		glade_helper_tagify_label (xml_commands, "norestart_label", "small");
+		glade_helper_tagify_label (xml_commands, "custom_label_label", "i");
+		glade_helper_tagify_label (xml_commands, "custom_label_label", "small");
+		glade_helper_tagify_label (xml_commands, "custom_lrlabel_label", "i");
+		glade_helper_tagify_label (xml_commands, "custom_lrlabel_label", "small");		
+		glade_helper_tagify_label (xml_commands, "custom_text_label", "i");
+		glade_helper_tagify_label (xml_commands, "custom_text_label", "small");
+		glade_helper_tagify_label (xml_commands, "custom_tooltip_label", "i");
+		glade_helper_tagify_label (xml_commands, "custom_tooltip_label", "small");
+		glade_helper_tagify_label (xml_commands, "custom_persistent_label", "i");
+		glade_helper_tagify_label (xml_commands, "custom_persistent_label", "small");
+		glade_helper_tagify_label (xml_commands, "custom_norestart_label", "i");
+		glade_helper_tagify_label (xml_commands, "custom_norestart_label", "small");
 	
 		parent = glade_xml_get_widget (xml, "setup_dialog");
 		dialog = glade_xml_get_widget (xml_commands, "commands_dialog");
 		
 		gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (parent));
 		gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
-
-		/* Set up unsaved changes storage container */
-		GdmCommandChangesUnsaved = g_hash_table_new (g_str_hash, g_str_equal);
-				
 		
 		/* Add halt, reboot and suspend commands */
 		gtk_combo_box_append_text (GTK_COMBO_BOX (command_chooser), _("Halt command"));
@@ -3933,42 +3978,37 @@
 		
 		/* Set up append command buttons */
 		setup_general_command_buttons("hrs_command_add", "add_hrs_cmd_button");
-		setup_general_command_buttons("custom_command_add", "add_custom_cmd_button");
-		
-		/* set up apply command changes button */
-		apply_command_changes_button = glade_xml_get_widget (xml_commands, "command_apply_button");
-		g_object_set_data_full (G_OBJECT (apply_command_changes_button), "key",
-					g_strdup ("apply_command_changes"), (GDestroyNotify) g_free);
-		g_signal_connect (G_OBJECT (apply_command_changes_button), "clicked",
-				  G_CALLBACK (command_apply), command_chooser);
-	
-		gtk_widget_set_sensitive (apply_command_changes_button, FALSE);
-		
-						
-		g_signal_connect (G_OBJECT (dialog), "response",
-				  G_CALLBACK (apply_command_changes), dialog);
+		setup_general_command_buttons("custom_command_add", "add_custom_cmd_button");				
+
+		gtk_combo_box_set_active (GTK_COMBO_BOX (command_chooser), HALT_CMD);
 	}
 	else {
 		command_chooser = glade_xml_get_widget (xml_commands, "cmd_type_combobox");
 
-		selected = gtk_combo_box_get_active (GTK_COMBO_BOX (command_chooser));
+		gtk_combo_box_set_active (GTK_COMBO_BOX (command_chooser), last_selected_command);
 		
 	}
 
-	/* Finally lets set our default choice */
-	gtk_combo_box_set_active (GTK_COMBO_BOX (command_chooser), HALT_CMD); 
-	if (selected == last_selected_command)
-		g_signal_emit_by_name (G_OBJECT (command_chooser), "changed");
-
 	do {
 		response = gtk_dialog_run (GTK_DIALOG (dialog));
 		if (response == GTK_RESPONSE_HELP) {
 			g_spawn_command_line_sync ("gnome-open ghelp:gdm", NULL, NULL,
 						   NULL, NULL);
 		}
+		else if (response == GTK_RESPONSE_CLOSE ||
+			 response == GTK_RESPONSE_DELETE_EVENT) {
+			if (validate_command_path_entry (last_selected_command) == FALSE) {
+				/* This is a bit ugly - but we shouldn't
+				   return close/delete when if the user wants
+				   to modify/change the offending command
+				   so GTK_RESPONSE_NONE will do
+				*/
+				response = GTK_RESPONSE_NONE;
+			}
+		}
 	} while (response != GTK_RESPONSE_CLOSE &&
                  response != GTK_RESPONSE_DELETE_EVENT);
-	
+		
 	gtk_widget_hide (dialog);
 }
 
@@ -3985,7 +4025,7 @@
                         const char *key)
 {
 	GtkWidget *combobox = glade_xml_get_widget (xml, name);
-	char *greetval      = g_strdup (gdm_config_get_string ((gchar *)key));
+	char *greetval      = g_strdup (gdm_setup_config_get_string ((gchar *)key));
 
 	if (greetval != NULL &&
 	    strcmp (ve_sure_string (greetval),
@@ -3997,7 +4037,7 @@
 	/* Set initial state of local style combo box. */
 	if (strcmp (ve_sure_string (key), GDM_KEY_GREETER) == 0) {
 
-		gboolean val = gdm_config_get_bool (GDM_KEY_BROWSER);
+		gboolean val = gdm_setup_config_get_bool (GDM_KEY_BROWSER);
 
 		if (strstr (greetval, "/gdmlogin") != NULL) {
 	
@@ -4219,8 +4259,8 @@
 static void
 acc_modules_toggled (GtkWidget *toggle, gpointer data)
 {
-	gboolean add_gtk_modules = gdm_config_get_bool (GDM_KEY_ADD_GTK_MODULES);
-	char *modules_list       = g_strdup (gdm_config_get_string (GDM_KEY_GTK_MODULES_LIST));
+	gboolean add_gtk_modules = gdm_setup_config_get_working_bool (GDM_KEY_ADD_GTK_MODULES);
+	char *modules_list       = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_GTK_MODULES_LIST));
 
 	/* first whack the modules from the list */
 	modules_list = modules_list_remove (modules_list, "gail");
@@ -4251,9 +4291,9 @@
 		add_gtk_modules = FALSE;
 
 	gdm_setup_config_set_string (GDM_KEY_GTK_MODULES_LIST,
-	                      ve_sure_string (modules_list));
+				     modules_list);
 	gdm_setup_config_set_bool (GDM_KEY_ADD_GTK_MODULES,
-	                    add_gtk_modules);
+				   add_gtk_modules);
 
 	g_free (modules_list);
 }
@@ -4290,20 +4330,73 @@
 {
 	gchar *filename;
 	gchar *sound_key;
-	gchar *value;
 		
 	filename  = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
 	sound_key = g_object_get_data (G_OBJECT (file_chooser), "key");	
-	value     = gdm_config_get_string (sound_key);
 	
-	if (strcmp (ve_sure_string (value), ve_sure_string (filename)) != 0) {
-		gdm_setup_config_set_string (sound_key,
-			(char *)ve_sure_string (filename));
-		update_greeters ();
-	}
+	if (filename == NULL)
+		return;
+	
+	gdm_setup_config_set_string (sound_key, (char *)ve_sure_string (filename));
+
 	g_free (filename);
 }
 
+/* We need to make sure that the users in the include list exist
+   and have uid that are higher than MinimalUID. This protects us
+   from invalid data obtained from the config file */
+static gboolean
+gdm_setup_adjust_users_include_list (void)
+{
+	gint GdmMinimalUID;
+	gchar **list;
+	gchar *GdmInclude;
+	gchar *GdmAutoLogin;
+	gchar *GdmTimedLogin;
+	gint i;
+	gboolean ret = FALSE;
+
+	GdmMinimalUID = gdm_setup_config_get_working_int (GDM_KEY_MINIMAL_UID);
+	GdmInclude = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_INCLUDE));
+	GdmAutoLogin = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_AUTOMATIC_LOGIN));
+	GdmTimedLogin = g_strdup (gdm_setup_config_get_working_string (GDM_KEY_TIMED_LOGIN));	
+	
+	list = g_strsplit (GdmInclude, ",", 0);
+	for (i=0; list != NULL && list[i] != NULL; i++) {
+		if (gdm_is_user_valid (list[i]) && gdm_user_uid (list[i]) >= GdmMinimalUID)
+			continue;
+		
+		GdmInclude = strings_list_remove (GdmInclude, list[i], ",");
+		ret = TRUE;
+	}
+	g_strfreev (list);
+		
+	/* Once we corrected the include list we need to save it if
+	   it was modified */	
+	gdm_setup_config_set_string (GDM_KEY_INCLUDE, GdmInclude);
+
+	/* Lets check the auto login and timed login users */
+	if (!ve_string_empty (GdmAutoLogin)) {
+		if (gdm_is_user_valid (GdmAutoLogin) && gdm_user_uid (GdmAutoLogin) < GdmMinimalUID) {
+		gdm_setup_config_set_string (GDM_KEY_AUTOMATIC_LOGIN, "");
+		ret = TRUE;
+		}
+	}
+
+	if (!ve_string_empty (GdmTimedLogin)) {
+		if (gdm_is_user_valid (GdmTimedLogin) && gdm_user_uid (GdmTimedLogin) < GdmMinimalUID) {
+		gdm_setup_config_set_string (GDM_KEY_TIMED_LOGIN, "");
+		ret = TRUE;
+		}
+	}
+	
+	g_free (GdmAutoLogin);
+	g_free (GdmTimedLogin);
+	g_free (GdmInclude);
+	
+	return ret;
+}
+
 static void
 setup_users_tab (void)
 {
@@ -4312,10 +4405,10 @@
 	GtkWidget *default_face_checkbox;
 	GtkWidget *global_face_dir_filechooser;
 	GtkWidget *global_face_dir_checkbox;
-	gchar *filename;
-
-	setup_greeter_toggle ("fb_allusers",
-			      GDM_KEY_INCLUDE_ALL);
+	const gchar *filename;
+	
+	setup_greeter_toggle ("fb_allusers", GDM_KEY_INCLUDE_ALL);
+	
 	setup_face ();
 
 	/* Setup default face */
@@ -4326,11 +4419,11 @@
         gtk_file_filter_add_pixbuf_formats (filter);
         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (default_face_filechooser), filter);
 
-	filename = gdm_config_get_string (GDM_KEY_DEFAULT_FACE);
+	filename = gdm_setup_config_get_string (GDM_KEY_DEFAULT_FACE);
 
 	default_face_checkbox = glade_xml_get_widget (xml, "default_face_checkbutton");
 
-	if (!ve_string_empty (filename) && access (filename, R_OK|X_OK)) {
+	if (!ve_string_empty (filename) && access (filename, R_OK) == 0) {		
 		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (default_face_filechooser),
 					       filename);
 		
@@ -4340,50 +4433,63 @@
 	}	
 	else {
 		gtk_widget_set_sensitive (default_face_filechooser, FALSE);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (default_face_checkbox), FALSE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (default_face_checkbox), FALSE);				
+
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the default_face_ckeckbox 
+		   becomes active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_GLOBAL_FACE_DIR, "");
 	}
 	
 	g_object_set_data_full (G_OBJECT (default_face_filechooser),
 				"key", g_strdup (GDM_KEY_DEFAULT_FACE),
 				(GDestroyNotify) g_free);
-	g_signal_connect (G_OBJECT (default_face_filechooser), "selection-changed",
-			  G_CALLBACK (default_filechooser_response),
-			  NULL);	
-	
+
+
 	g_object_set_data_full (G_OBJECT (default_face_checkbox),
 				"key", g_strdup (GDM_KEY_DEFAULT_FACE),
 				(GDestroyNotify) g_free);       	
 	g_signal_connect (G_OBJECT (default_face_checkbox), "toggled",
 			  G_CALLBACK (toggle_toggled), default_face_checkbox);	
 	g_signal_connect (G_OBJECT (default_face_checkbox), "toggled",
-			  G_CALLBACK (toggle_toggled_sensitivity_positive), default_face_filechooser);			
-	
+			  G_CALLBACK (toggle_toggled_sensitivity_positive), default_face_filechooser);
+	g_signal_connect (G_OBJECT (default_face_filechooser), "selection-changed",
+			  G_CALLBACK (default_filechooser_response),
+			  NULL);			
+		
 	/* Setup global face dir */
-	g_free (filename);		
-	
 	global_face_dir_filechooser = glade_xml_get_widget (xml, "global_face_dir_filechooser");
 
-	filename = gdm_config_get_string (GDM_KEY_GLOBAL_FACE_DIR);
+	filename = gdm_setup_config_get_string (GDM_KEY_GLOBAL_FACE_DIR);
 
 	global_face_dir_checkbox = glade_xml_get_widget (xml, "global_face_dir_checkbutton");
 
 	if (!ve_string_empty (filename) && access (filename, R_OK|X_OK) == 0) {
-		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (global_face_dir_filechooser),
-					       filename);
+		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (global_face_dir_filechooser),
+						     filename);
 		gtk_widget_set_sensitive (global_face_dir_filechooser, TRUE);
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (global_face_dir_checkbox), TRUE);
 	}
 	else {
 		gtk_widget_set_sensitive (global_face_dir_filechooser, FALSE);
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (global_face_dir_checkbox), FALSE);
+
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the global_face_dir_checkbox 
+		   becomes active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_GLOBAL_FACE_DIR, "");		
 	}
        
 
 	g_object_set_data_full (G_OBJECT (global_face_dir_filechooser),
 				"key", g_strdup (GDM_KEY_GLOBAL_FACE_DIR),
-				(GDestroyNotify) g_free);		
-	g_signal_connect (G_OBJECT (global_face_dir_filechooser), "selection-changed",
-			  G_CALLBACK (default_filechooser_response), NULL);
+				(GDestroyNotify) g_free);			
 			
 	g_object_set_data_full (G_OBJECT (global_face_dir_checkbox),
 				"key", g_strdup (GDM_KEY_GLOBAL_FACE_DIR),
@@ -4391,8 +4497,9 @@
 	g_signal_connect (G_OBJECT (global_face_dir_checkbox), "toggled",
 			  G_CALLBACK (toggle_toggled), global_face_dir_checkbox);	
 	g_signal_connect (G_OBJECT (global_face_dir_checkbox), "toggled",
-			  G_CALLBACK (toggle_toggled_sensitivity_positive), global_face_dir_filechooser);				
-	g_free (filename);
+			  G_CALLBACK (toggle_toggled_sensitivity_positive), global_face_dir_filechooser);
+	g_signal_connect (G_OBJECT (global_face_dir_filechooser), "selection-changed",
+			  G_CALLBACK (default_filechooser_response), NULL);
 }
 
 static void
@@ -4411,8 +4518,8 @@
 	gchar *gdm_key_sound_ready;
 	gchar *gdm_key_sound_success;
 	gchar *gdm_key_sound_failure;
-	gchar *modules_list;
-	gchar *value;
+	const gchar *modules_list;
+	const gchar *value;
 	
 	enable_accessible_login = glade_xml_get_widget (xml, "acc_modules");
 
@@ -4426,19 +4533,10 @@
 
 	access_sound_failure_file_chooser = glade_xml_get_widget (xml, "acc_sound_failure_button");
 
-	access_sound_failure_play_button = glade_xml_get_widget (xml, "acc_soundtest_failure_button");
-
-	setup_greeter_toggle ("acc_theme",
-	                      GDM_KEY_ALLOW_GTK_THEME_CHANGE);
-	setup_greeter_toggle ("acc_sound_ready", 
-	                      GDM_KEY_SOUND_ON_LOGIN);
-	setup_greeter_toggle ("acc_sound_success",
-	                      GDM_KEY_SOUND_ON_LOGIN_SUCCESS);
-	setup_greeter_toggle ("acc_sound_failure",
-	                      GDM_KEY_SOUND_ON_LOGIN_FAILURE);
+	access_sound_failure_play_button = glade_xml_get_widget (xml, "acc_soundtest_failure_button");	
 
-	add_gtk_modules = gdm_config_get_bool (GDM_KEY_ADD_GTK_MODULES);
-	modules_list    = gdm_config_get_string (GDM_KEY_GTK_MODULES_LIST);
+	add_gtk_modules = gdm_setup_config_get_bool (GDM_KEY_ADD_GTK_MODULES);
+	modules_list    = gdm_setup_config_get_string (GDM_KEY_GTK_MODULES_LIST);
 
 	if (!(add_gtk_modules &&
 	    modules_list_contains (modules_list, "gail") &&
@@ -4472,39 +4570,73 @@
 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (access_sound_failure_file_chooser), all_sounds_filter);
 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (access_sound_failure_file_chooser), all_files_filter);
 		
-	value = gdm_config_get_string (GDM_KEY_SOUND_ON_LOGIN_FILE);
+	value = gdm_setup_config_get_string (GDM_KEY_SOUND_ON_LOGIN_FILE);
 
-	if (value != NULL && *value != '\0') {
+		
+	if (!ve_string_empty (value) && access (value, R_OK) == 0) {
 		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (access_sound_ready_file_chooser), 
-		                               value);
-	}
-	else {
+		                               value);		
+	} else {
 		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (access_sound_ready_file_chooser),
 		                                     DATADIR"/sounds");
-	}
 
-	value = gdm_config_get_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE);
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the logo_checkbutton 
+		   becomes active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_SOUND_ON_LOGIN_FILE, "");
+		gdm_setup_config_set_bool_cache (GDM_KEY_SOUND_ON_LOGIN, FALSE);
+	}
+	
+	value = gdm_setup_config_get_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE);
 
-	if (value != NULL && *value != '\0') {
+	if (!ve_string_empty (value) && access (value, R_OK) == 0) {
 		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (access_sound_success_file_chooser),
-		                               value);
-	}
-	else {
+		                               value);		
+	} else {
 		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (access_sound_success_file_chooser),
 		                                     DATADIR"/sounds");
+		
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the logo_checkbutton 
+		   becomes active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE, "");
+		gdm_setup_config_set_bool_cache (GDM_KEY_SOUND_ON_LOGIN_SUCCESS, FALSE);
 	}
 	
-	value = gdm_config_get_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE);
+	value = gdm_setup_config_get_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE);
 
-	if (value != NULL && *value != '\0') {
+	if (!ve_string_empty (value) && access (value, R_OK) == 0) {
 		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (access_sound_failure_file_chooser),
 		                               value);
-	} 
-	else {
+	} else {
 		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (access_sound_failure_file_chooser),
 		                                     DATADIR"/sounds");
+		
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the logo_checkbutton 
+		   becomes active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE, "");
+		gdm_setup_config_set_bool_cache (GDM_KEY_SOUND_ON_LOGIN_FAILURE, FALSE);
 	}
-	
+		
+	setup_greeter_toggle ("acc_theme",
+	                      GDM_KEY_ALLOW_GTK_THEME_CHANGE);
+	setup_greeter_toggle ("acc_sound_ready", 
+	                      GDM_KEY_SOUND_ON_LOGIN);
+	setup_greeter_toggle ("acc_sound_success",
+	                      GDM_KEY_SOUND_ON_LOGIN_SUCCESS);
+	setup_greeter_toggle ("acc_sound_failure",
+	                      GDM_KEY_SOUND_ON_LOGIN_FAILURE);
+
 	gdm_key_sound_ready = g_strdup (GDM_KEY_SOUND_ON_LOGIN_FILE);
 	
 	g_object_set_data (G_OBJECT (access_sound_ready_file_chooser), "key",
@@ -4544,7 +4676,7 @@
 	 * we use strdup to build a reasonable value if the configuration value
 	 * is not good.  So use g_strdup here.
 	 */
-	char *theme_dir = g_strdup (gdm_config_get_string (GDM_KEY_GRAPHICAL_THEME_DIR));
+	char *theme_dir = g_strdup (gdm_setup_config_get_string (GDM_KEY_GRAPHICAL_THEME_DIR));
 
 	if (theme_dir == NULL ||
 	    theme_dir[0] == '\0' ||
@@ -4643,7 +4775,7 @@
 		gtk_widget_set_sensitive (delete_button_remote, TRUE);
 	}
 	/* Determine if the theme selected is currently active */
-	GdmGraphicalThemeRand = gdm_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
+	GdmGraphicalThemeRand = gdm_setup_config_get_working_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
 	if (GdmGraphicalThemeRand) {
 		gtk_tree_model_get_value (model, &iter, THEME_COLUMN_SELECTED_LIST, &value);
 	} else {
@@ -4736,6 +4868,7 @@
 	gtk_text_buffer_insert_with_tags_by_name (buffer_remote, &iter_remote,
 	                                          str, -1, "small", NULL);
 	
+	g_free (str);
 	FirstPass = FALSE;
 	g_value_unset (&value);
 }
@@ -4748,7 +4881,7 @@
 	GtkTreeIter *select_iter = NULL;
 	GdkPixbuf *pb = NULL;
 	gchar *markup = NULL;
-	gchar * real_selected_themes = NULL;
+	gchar *real_selected_themes = NULL;
 	
 	while ((dent = readdir (dir)) != NULL) {
 		char *n, *file, *name, *desc, *author, *copyright, *ss;
@@ -4830,6 +4963,7 @@
 				if (gdk_pixbuf_get_width (pb) > 64 ||
 				    gdk_pixbuf_get_height (pb) > 50) {
 					GdkPixbuf *pb2;
+					/* Valgrind thinks there is a memory leak here */
 					pb2 = gdk_pixbuf_scale_simple
 						(pb, 64, 50,
 						 GDK_INTERP_BILINEAR);
@@ -4852,81 +4986,31 @@
 				    THEME_COLUMN_DESCRIPTION, desc,
 				    THEME_COLUMN_AUTHOR, author,
 				    THEME_COLUMN_COPYRIGHT, copyright,
-				    -1);
-
-		if (select_item != NULL &&
-		    strcmp (ve_sure_string (dent->d_name), ve_sure_string (select_item)) == 0) {
-			/* anality */ g_free (select_iter);
-			select_iter = g_new0 (GtkTreeIter, 1);
-			*select_iter = iter;
-		}
-
-		g_free (file);
-		g_free (name);
-		g_free (markup);
-		g_free (desc);
-		g_free (author);
-		g_free (copyright);
-		g_free (ss);
-		g_free (full);
-		g_free (n);
-	}
-
-	g_free (selected_themes);
-	selected_themes = g_strdup (real_selected_themes);
-	g_free (real_selected_themes);
-
-	return select_iter;
-}
-
-static gboolean
-greeter_theme_timeout (GtkWidget *toggle)
-{
-	char *theme;
-	char *themes;
-
-	theme  = gdm_config_get_string (GDM_KEY_GRAPHICAL_THEME);
-	themes = gdm_config_get_string (GDM_KEY_GRAPHICAL_THEMES);
-
-	/* If no checkbox themes selected */
-	if (selected_themes == NULL)
-		selected_themes = "";
-
-	/* If themes have changed from the custom_config file, update it. */
-	if (strcmp (ve_sure_string (theme),
-		ve_sure_string (selected_theme)) != 0) {
-
-		gdm_setup_config_set_string (GDM_KEY_GRAPHICAL_THEME,
-			selected_theme);
-		update_greeters ();
-	}
-
-	if (strcmp (ve_sure_string (themes),
-		ve_sure_string (selected_themes)) != 0) {
-
-		gdm_setup_config_set_string (GDM_KEY_GRAPHICAL_THEMES,
-			selected_themes);
-
-		/* This should only be executed if we dealing with
-		   random theme setting. If no random themes are present and
-		   the random theme option was set to true we force it to be false.
-		   If there is at least one random theme selected and the random 
-		   theme option was false we force it to be true */		
-		if (ve_string_empty (selected_themes) && 
-		    gdm_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND)) {
-			gdm_setup_config_set_bool (GDM_KEY_GRAPHICAL_THEME_RAND, FALSE);
-			GdmRandomFromSelectedChangesWarn = TRUE;
-			
-		} else if (!ve_string_empty (selected_themes) && 
-			   !gdm_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND)) {
-			gdm_setup_config_set_bool (GDM_KEY_GRAPHICAL_THEME_RAND, TRUE);
-			GdmRandomFromSelectedChangesWarn = FALSE;
+				    -1);
+
+		if (select_item != NULL &&
+		    strcmp (ve_sure_string (dent->d_name), ve_sure_string (select_item)) == 0) {
+			/* anality */ g_free (select_iter);
+			select_iter = g_new0 (GtkTreeIter, 1);
+			*select_iter = iter;
 		}
-	       
-		update_greeters ();
+
+		g_free (file);
+		g_free (name);
+		g_free (markup);
+		g_free (desc);
+		g_free (author);
+		g_free (copyright);
+		g_free (ss);
+		g_free (full);
+		g_free (n);
 	}
 
-	return FALSE;
+	g_free (selected_themes);
+	selected_themes = g_strdup (real_selected_themes);
+	g_free (real_selected_themes);
+
+	return select_iter;
 }
 
 static void
@@ -4940,7 +5024,6 @@
 	GtkTreeIter iter;
 	GtkTreePath *path;
 	GtkTreePath *sel_path = gtk_tree_path_new_from_string (path_str);
-	GtkWidget *theme_list = glade_xml_get_widget (xml, "gg_theme_list");
 	GtkWidget *del_button = glade_xml_get_widget (xml, "gg_delete_theme");
 	GtkWidget *del_button_remote = glade_xml_get_widget (xml, "gg_delete_theme_remote");
 	gboolean is_radio;
@@ -5042,7 +5125,31 @@
 	gtk_tree_path_free (path);
 	gtk_tree_path_free (sel_path);
 
-	run_timeout (theme_list, 500, greeter_theme_timeout);
+	/* If no checkbox themes selected */
+	if (selected_themes == NULL)
+		selected_themes = "";
+
+	/* If themes have changed from the custom_config file, update it. */
+	gdm_setup_config_set_string (GDM_KEY_GRAPHICAL_THEME, selected_theme);
+	
+	if (gdm_setup_config_set_string (GDM_KEY_GRAPHICAL_THEMES, selected_themes)) {
+
+		/* This should only be executed if we dealing with
+		   random theme setting. If no random themes are present and
+		   the random theme option was set to true we force it to be false.
+		   If there is at least one random theme selected and the random 
+		   theme option was false we force it to be true */		
+		if (ve_string_empty (selected_themes) && 
+		    gdm_setup_config_get_working_bool (GDM_KEY_GRAPHICAL_THEME_RAND)) {
+			gdm_setup_config_set_bool (GDM_KEY_GRAPHICAL_THEME_RAND, FALSE);
+			GdmRandomFromSelectedChangesWarn = TRUE;
+			
+		} else if (!ve_string_empty (selected_themes) && 
+			   !gdm_setup_config_get_working_bool (GDM_KEY_GRAPHICAL_THEME_RAND)) {
+			gdm_setup_config_set_bool (GDM_KEY_GRAPHICAL_THEME_RAND, TRUE);
+			GdmRandomFromSelectedChangesWarn = FALSE;
+		}
+	}
 }
 
 static gboolean
@@ -5646,7 +5753,7 @@
 		return;
 	}
 
-	GdmGraphicalThemeRand = gdm_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
+	GdmGraphicalThemeRand = gdm_setup_config_get_working_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
 
 	if (GdmGraphicalThemeRand) {
 		gtk_tree_model_get_value (model, &iter,
@@ -5784,8 +5891,286 @@
 	g_free (dir);
 }
 
+/*
+ * Loop through the list of servers and add them
+ * to the local cache
+ */
+static void
+gdm_setup_cache_xservers_locally (void)
+{
+	GSList *li;
+	
+	for (li = xservers; li != NULL; li = li->next) {
+		GdmXserver *svr = li->data;
+		update_xserver_local_cache (svr);
+	}
+}
+
 static gboolean
-xserver_entry_timeout (GtkWidget *entry)
+load_xserver_parameter (GKeyFile *cfg, GKeyFile *custom_cfg, const gchar *key, 
+			GdmConfigValueType type, GdmConfigValue **value) 
+{	
+	GdmConfigValue *tmpval = NULL;
+	GdmConfigValue *tmpval_custom = NULL;
+	GError *error = NULL;
+	
+	if (!gdm_common_config_get_value (cfg, key, &tmpval, type, TRUE, &error)) {
+		if (error) {
+			g_debug ("%s", error->message);
+			g_error_free (error);
+		}
+		return FALSE;
+	}
+	
+	if (gdm_common_config_get_value (custom_cfg, key, &tmpval_custom, type, FALSE, NULL)) {
+		*value = tmpval_custom;
+		gdm_config_value_free (tmpval);
+		return TRUE;
+	}
+
+	*value = tmpval;
+
+	return TRUE;
+}
+
+/* 
+ * This parses the [servers] configuration. It loads all the entries
+ * for a given config file. As we can remove values in the 
+ * default.conf we can only overwrite them with inactive
+ * strings
+ */
+static void
+load_xserver_displays (GKeyFile *cfg, GSList **display_list)
+{
+	gchar **keys = NULL;
+	gint i;
+
+	keys = g_key_file_get_keys (cfg, GDM_KEY_SECTION_SERVERS, NULL, NULL);
+
+	if (keys != NULL) {
+		for (i = 0; keys[i] != NULL; i++) {
+			const gchar *key = keys[i];
+			
+			if (isdigit (*key)) {
+				gchar *fullkey;
+				gchar *value;
+				
+				fullkey = g_strdup_printf ("%s/%s=", GDM_KEY_SECTION_SERVERS, key);
+				if (gdm_common_config_get_string (cfg, fullkey, &value, NULL))					
+					gdm_setup_config_set_string_cache (fullkey, value);
+				
+				g_free (value);
+
+				if (*display_list != NULL &&
+				    g_slist_find (*display_list, fullkey) != NULL) {
+					g_free (fullkey);
+					continue;
+				}
+				
+				*display_list = g_slist_append (*display_list, g_strdup (fullkey));
+				
+				g_free (fullkey);
+			}
+		}
+	}
+	
+	g_strfreev (keys);
+}
+
+static void
+xserver_init_displays_treeview (GSList *displays_keys)
+{
+	GSList *li;
+	
+	/* Get Widgets from glade */
+	GtkWidget *treeview = glade_xml_get_widget (xml_xservers, "xserver_tree_view");
+	GtkWidget *remove_button = glade_xml_get_widget (xml_xservers, "xserver_remove_button");
+	
+	/* create list store */
+	GtkListStore *store = gtk_list_store_new (XSERVER_NUM_COLUMNS,
+						  G_TYPE_INT    /* virtual terminal */,
+						  G_TYPE_STRING /* server type */,
+						  G_TYPE_STRING /* options */);
+
+	/* Read all xservers to start from configuration */		
+
+	for (li = displays_keys; li != NULL; li = li->next) {		
+		GtkTreeIter iter;
+		const gchar *key = li->data;
+		const gchar *value;
+		int vt;
+		gchar *server = NULL;
+		gchar *options;
+		
+		if (sscanf (key, GDM_KEY_SECTION_SERVERS "/%d=", &vt) != 1) 
+			continue;
+			
+		value = gdm_setup_config_get_string (key);
+		server = ve_first_word (value);
+		options = ve_rest (value);
+		
+		gtk_list_store_append (store, &iter);
+		gtk_list_store_set (store, &iter,
+				    XSERVER_COLUMN_VT, vt,
+				    XSERVER_COLUMN_SERVER, server,
+				    XSERVER_COLUMN_OPTIONS, options,
+				    -1);
+		g_free (server);
+	}
+	
+	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
+	                         GTK_TREE_MODEL (store));
+	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
+	gtk_widget_set_sensitive (remove_button, FALSE);
+}
+
+static void
+load_xserver_definitions (GKeyFile *cfg, GKeyFile *custom_cfg)
+{
+	gchar **groups_default = NULL;
+	gchar **groups_custom = NULL;
+	gsize i;
+	GSList *groups = NULL, *li;
+	gsize default_length;
+	gsize custom_length;
+	
+	/* Fill config storage with all present xserver definitions */
+	if (cfg != NULL && custom_cfg != NULL) {
+		groups_default = g_key_file_get_groups (cfg, &default_length);
+		groups_custom  = g_key_file_get_groups (custom_cfg, &custom_length);
+			       
+		for (i = 0; i < default_length; i++) {
+			if (groups_default[i] != NULL) {
+				if (g_slist_find (groups, groups_default[i]) == NULL)
+					groups = g_slist_append (groups, g_strdup (groups_default[i]));
+			}
+		}
+		
+		for (i = 0; i < custom_length; i++) {
+			if (groups_custom[i] != NULL) {
+				if (g_slist_find (groups, groups_custom[i]) == NULL)
+					groups = g_slist_append (groups, g_strdup (groups_custom[i]));
+			}
+		}
+		for (li = groups; li != NULL; li = li->next) {			
+			const gchar *group = li->data;
+			
+			if (strncmp (GDM_KEY_SERVER_PREFIX, ve_sure_string (group), strlen (GDM_KEY_SERVER_PREFIX)) == 0) {
+				gchar *key = NULL;
+				GdmConfigValue *tmpval = NULL;
+
+				GdmXserver *srv = g_new0 (GdmXserver, 1);				
+				
+				srv->id = g_strdup (group + strlen (GDM_KEY_SERVER_PREFIX));
+				
+				key = g_strdup_printf ("%s/%s", group, GDM_KEY_SERVER_NAME);
+				if (!load_xserver_parameter (cfg, custom_cfg, key, GDM_CONFIG_VALUE_STRING, &tmpval)) {
+					g_free (srv);
+					continue;
+				}
+				srv->name = g_strdup (gdm_config_value_get_string (tmpval));
+				gdm_config_value_free (tmpval);
+				g_free (key);				
+				
+				key = g_strdup_printf ("%s/%s", group, GDM_KEY_SERVER_COMMAND);
+				if (!load_xserver_parameter (cfg, custom_cfg, key, GDM_CONFIG_VALUE_STRING, &tmpval)) {
+					g_free (srv);
+					continue;
+				}
+				srv->command = g_strdup (gdm_config_value_get_string (tmpval));
+				gdm_config_value_free (tmpval);
+				g_free (key);
+				
+				key = g_strdup_printf ("%s/%s", group, GDM_KEY_SERVER_FLEXIBLE);
+				if (!load_xserver_parameter (cfg, custom_cfg, key, GDM_CONFIG_VALUE_BOOL, &tmpval)) {
+					g_free (srv);
+					continue;
+				}
+				srv->flexible = gdm_config_value_get_bool (tmpval);
+				gdm_config_value_free (tmpval);
+				g_free (key);
+
+				key = g_strdup_printf ("%s/%s", group, GDM_KEY_SERVER_CHOOSABLE);
+				if (!load_xserver_parameter (cfg, custom_cfg, key, GDM_CONFIG_VALUE_BOOL, &tmpval)) {
+					g_free (srv);
+					continue;
+				}
+				srv->choosable = gdm_config_value_get_bool (tmpval);
+				gdm_config_value_free (tmpval);
+				g_free (key);
+				
+				key = g_strdup_printf ("%s/%s", group, GDM_KEY_SERVER_HANDLED);
+				if (!load_xserver_parameter (cfg, custom_cfg, key, GDM_CONFIG_VALUE_BOOL, &tmpval)) {
+					g_free (srv);
+					continue;
+				}
+				srv->handled = gdm_config_value_get_bool (tmpval);
+				gdm_config_value_free (tmpval);
+				g_free (key);
+
+				key = g_strdup_printf ("%s/%s", group, GDM_KEY_SERVER_CHOOSER);
+				if (!load_xserver_parameter (cfg, custom_cfg, key, GDM_CONFIG_VALUE_BOOL, &tmpval)) {
+					g_free (srv);
+					continue;
+				}
+				srv->chooser = gdm_config_value_get_bool (tmpval);
+				gdm_config_value_free (tmpval);
+				g_free (key);
+				
+				key = g_strdup_printf ("%s/%s", group, GDM_KEY_SERVER_PRIORITY);
+				if (!load_xserver_parameter (cfg, custom_cfg, key, GDM_CONFIG_VALUE_INT, &tmpval)) {
+					g_free (srv);
+					continue;
+				}
+				srv->priority = gdm_config_value_get_int (tmpval);
+				gdm_config_value_free (tmpval);			
+				g_free (key);
+				
+				if (g_slist_find (xservers, srv) == NULL)
+					xservers = g_slist_append (xservers, srv);				
+			}
+		}
+		
+	}
+	
+	/* Lets check if the loading process was successful.
+	   if not and there is no servers loaded then we
+	   need to get them from the daemon, otherwise we 
+	   will end up with an empty list
+	*/
+	if (xservers == NULL)
+		xservers = gdm_config_get_xservers (FALSE);
+		
+	/* Filally lets cache the results locally */
+	gdm_setup_cache_xservers_locally ();
+	
+	g_slist_free (groups);
+	g_strfreev (groups_default);
+	g_strfreev (groups_custom);
+}
+
+static void
+load_xservers (void)
+{
+	GKeyFile *cfg;
+	GKeyFile *custom_cfg;
+	GSList   *displays_keys = NULL;
+	
+	cfg = gdm_common_config_load (config_file, NULL);
+	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
+
+	load_xserver_displays (cfg, &displays_keys);
+	load_xserver_displays (custom_cfg, &displays_keys);
+	xserver_init_displays_treeview (displays_keys);
+	load_xserver_definitions (cfg, custom_cfg);
+
+	g_slist_free (displays_keys);
+	g_key_file_free (custom_cfg);
+	g_key_file_free (cfg);	
+}
+
+static void
+xserver_entry_changed (GtkWidget *entry, gpointer data)
 {
 	GtkWidget *mod_combobox;
 	GSList *li;
@@ -5830,12 +6215,10 @@
 		}
 	}
 	g_free (section);
-
-	return FALSE;
 }
 
-static gboolean
-xserver_priority_timeout (GtkWidget *entry)
+static void
+xserver_priority_changed (GtkWidget *entry, gpointer data)
 {
 	GtkWidget *mod_combobox;
 	GSList *li;
@@ -5867,12 +6250,10 @@
 		}
 	}
 	g_free (section);
-
-	return FALSE;
 }
 
-static gboolean
-xserver_toggle_timeout (GtkWidget *toggle)
+static void
+xserver_toggle_toggled (GtkWidget *toggle, gpointer data)
 {
 	GtkWidget *mod_combobox;
 	const char *key = g_object_get_data (G_OBJECT (toggle), "key");
@@ -5915,26 +6296,6 @@
 		}
 	}
 	g_free (section);
-
-	return FALSE;
-}
-
-static void
-xserver_toggle_toggled (GtkWidget *toggle)
-{
-	run_timeout (toggle, 500, xserver_toggle_timeout);
-}
-
-static void
-xserver_entry_changed (GtkWidget *entry)
-{
-	run_timeout (entry, 500, xserver_entry_timeout);
-}
-
-static void
-xserver_priority_changed (GtkWidget *entry)
-{
-	run_timeout (entry, 500, xserver_priority_timeout);
 }
 
 static void
@@ -5962,45 +6323,15 @@
 }
 
 static void
-xserver_init_server_list ()
-{
-	/* Get Widgets from glade */
-	GtkWidget *treeview = glade_xml_get_widget (xml_xservers, "xserver_tree_view");
-	GtkWidget *remove_button = glade_xml_get_widget (xml_xservers, "xserver_remove_button");
-
-	/* create list store */
-	GtkListStore *store = gtk_list_store_new (XSERVER_NUM_COLUMNS,
-	                            G_TYPE_INT    /* virtual terminal */,
-	                            G_TYPE_STRING /* server type */,
-	                            G_TYPE_STRING /* options */);
-
-	/* Read all xservers to start from configuration */
-	xservers_get_displays (store);
-	gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
-	                         GTK_TREE_MODEL (store));
-	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
-	gtk_widget_set_sensitive (remove_button, FALSE);
-}
-
-static void
-xserver_init_servers ()
-{
-    GtkWidget *remove_button;
-
-    /* Init widget states */
-    xserver_init_server_list();
-
-    remove_button = glade_xml_get_widget (xml_xservers, "xserver_remove_button");
-    gtk_widget_set_sensitive (remove_button, FALSE);
-}
-
-static void
 xserver_row_selected(GtkTreeSelection *selection, gpointer data)
 {
     GtkWidget *remove_button;
-    
+        
     remove_button = glade_xml_get_widget (xml_xservers, "xserver_remove_button");
-    gtk_widget_set_sensitive (remove_button, TRUE);
+    if (gtk_tree_selection_get_selected (selection, NULL, NULL))
+	    gtk_widget_set_sensitive (remove_button, TRUE);
+    else
+	    gtk_widget_set_sensitive (remove_button, FALSE);
 }
 
 /*
@@ -6010,55 +6341,34 @@
 static void
 xserver_remove_display (gpointer data)
 {
-	GtkWidget *treeview, *combo;
+	GtkWidget *treeview;
 	GtkTreeSelection *selection;
 	GtkTreeIter iter;
-	GtkTreeModel *model;
-	gint vt;
-        char vt_value[3];
+	GtkTreeModel *model;       
 
         treeview = glade_xml_get_widget (xml_xservers, "xserver_tree_view");
 
         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
 
 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
-	        GKeyFile *cfg;
-		GKeyFile *custom_cfg;
-		gchar *defaultval;
-		gchar *key;
-
-		cfg = gdm_common_config_load (config_file, NULL);
-		custom_cfg = gdm_common_config_load (custom_config_file, NULL);
-
-		combo = glade_xml_get_widget (xml_add_xservers, "xserver_server_combobox");
+		GtkListStore *store;
+		gchar *key;		
+		gint vt;
+		
+		store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)));
 
 		/* Update config */
 		gtk_tree_model_get (model, &iter, XSERVER_COLUMN_VT, &vt, -1);
-
-		g_snprintf (vt_value,  sizeof (vt_value), "%d", vt);
-		key = g_strconcat (GDM_KEY_SECTION_SERVERS, "/", vt_value, "=", NULL);
-
-		defaultval = NULL;
-		gdm_common_config_get_string (cfg, key, &defaultval, NULL);
-
-		/*
-		 * If the value is in the default config file, set it to inactive in
-		 * the custom config file, else delete it
-		 */
-		if (! ve_string_empty (defaultval)) {
-			gdm_common_config_set_string (custom_cfg, key, "inactive");
-		} else {
-			gdm_common_config_remove_key (custom_cfg, key, NULL);
-		}
-		g_free (defaultval);
-
-		gdm_common_config_save (custom_cfg, custom_config_file, NULL);
-		g_key_file_free (custom_cfg);
-		g_key_file_free (cfg);
-
-		/* Update gdmsetup */
-		xserver_init_server_list ();
+		
+		key = g_strdup_printf (GDM_KEY_SECTION_SERVERS "/%d=", vt);
+		
+		gtk_list_store_remove (store, &iter);
+		
+		gdm_setup_config_set_string (key, "inactive");
+		
+		/* Update gdmsetup */	
 		xserver_update_delete_sensitivity ();
+		g_free (key);
 	}
 }
 
@@ -6066,56 +6376,62 @@
 static void
 xserver_add_display (gpointer data)
 {
-        GKeyFile *cfg;
-        GKeyFile *custom_cfg;
-	GtkWidget *spinner, *combo, *entry, *button;
-	gchar *string;
-	gchar *defaultval;
-	char spinner_value[3], *key;
-
-        cfg = gdm_common_config_load (config_file, NULL);
-	custom_cfg = gdm_common_config_load (custom_config_file, NULL);
-
+	GtkWidget *spinner, *combo, *entry, *button, *treeview;
+	gchar *value;
+	gchar *key;
+	const gchar *server_name;
+	const gchar *options;
+	gint spinner_value;
+	GtkListStore *store;
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+	GdmConfigValue *val;
+	
 	/* Get Widgets from glade */
 	spinner  = glade_xml_get_widget (xml_add_xservers, "xserver_spin_button");
 	entry    = glade_xml_get_widget (xml_add_xservers, "xserver_options_entry");
 	combo    = glade_xml_get_widget (xml_add_xservers, "xserver_server_combobox");
 	button   = glade_xml_get_widget (xml_xservers, "xserver_add_button");
-
+	treeview = glade_xml_get_widget (xml_xservers, "xserver_tree_view");
+	
 	/* String to add to config */
-	g_snprintf (spinner_value,  sizeof (spinner_value), "%d",
-	            gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner)));
-
-	key = g_strconcat (GDM_KEY_SECTION_SERVERS, "/", spinner_value, "=", NULL);
-	if (! ve_string_empty (gtk_entry_get_text (GTK_ENTRY (entry)))) {
-		string = g_strconcat (gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo)),
-		                      " ", gtk_entry_get_text (GTK_ENTRY (entry)),
-		                      NULL);
-	} else {
-		string = g_strdup (gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo)));
-	}
-
-	defaultval = NULL;
-	gdm_common_config_get_string (cfg, key, &defaultval, NULL);
-
-	/* Add to config */
-	if (strcmp (ve_sure_string (defaultval), ve_sure_string (string)) == 0) {
-		gdm_common_config_remove_key (custom_cfg, key, NULL);
+	spinner_value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spinner));
+	
+	key = g_strdup_printf (GDM_KEY_SECTION_SERVERS "/%d=", spinner_value);
+	server_name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (combo));
+	options = gtk_entry_get_text (GTK_ENTRY (entry));
+	
+	if (! ve_string_empty (options)) {
+		value = g_strconcat (server_name, " ", options, NULL);
 	} else {
-		gdm_common_config_set_string (custom_cfg, key, ve_sure_string(string));
-	}
-
-	gdm_common_config_save (custom_cfg, custom_config_file, NULL);
-	g_key_file_free (custom_cfg);
-	g_key_file_free (cfg);
+		value = g_strdup (server_name);
+	}
+	
+	/* Since this value will not exist in the original config
+	   there is no point in polling the daemon for it. We
+	   just add it directly 
+	*/
+	val = gdm_config_value_new (GDM_CONFIG_VALUE_STRING);
+	gdm_config_value_set_string (val, value);
+	gdm_setup_config_set_value (key, val);
+	
+	/* We need to update our treeview model now */	
+	store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)));
+	
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+	
+	if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
+		gtk_list_store_append (store, &iter);
 
-	/* Reinitialize gdmsetup */
-	xserver_init_servers ();
-	xserver_update_delete_sensitivity ();
+	
+	gtk_list_store_set (store, &iter,
+			    XSERVER_COLUMN_VT, spinner_value,
+			    XSERVER_COLUMN_SERVER, server_name,
+			    XSERVER_COLUMN_OPTIONS, ve_sure_string (options),
+			    -1);
 
-	/* Free memory */
-	g_free (defaultval);
-	g_free (string);
+	/* Free memory */		
+	g_free (value);
 	g_free (key);
 }
 
@@ -6193,7 +6509,7 @@
 	      		gtk_tree_model_get (treeview_model, &treeview_iter, XSERVER_COLUMN_VT, &vt, -1);
 	      		if (high_value < vt) {
 				high_value = vt;
-      			}
+      			}			
     		}
 		
 		gtk_spin_button_set_value (GTK_SPIN_BUTTON (vt_spinbutton), ++high_value);
@@ -6355,8 +6671,8 @@
 	GtkTreeViewColumn *column;
 
 	/* Initialize the xserver settings */
+	load_xservers ();
 	xserver_init_definitions();
-	xserver_init_servers();
 
 	/* TODO: In the future, resolution/refresh rate configuration */
 	/* setup_xrandr_support (); */
@@ -6454,7 +6770,9 @@
 	                  G_CALLBACK (xserver_row_selected), NULL);
 	g_signal_connect (G_OBJECT (priority_spinbutton), "value_changed",
 	                  G_CALLBACK (xserver_priority_changed), NULL);
-	
+		
+	gtk_widget_set_sensitive (remove_button, FALSE);
+
 	/* TODO: In the future, allow creation & delection of servers
 	g_signal_connect (create_button, "clicked",
 			  G_CALLBACK (xserver_create), NULL);
@@ -6511,7 +6829,7 @@
 	gint val;
 	
 	radio = glade_xml_get_widget (xml, name);
-	val   = gdm_config_get_int ((gchar *)key);
+	val   = gdm_setup_config_get_int ((gchar *)key);
 	
 	if (val == position)
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
@@ -6757,8 +7075,8 @@
 
 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (theme_list), TRUE);
 
-	selected_theme  = gdm_config_get_string (GDM_KEY_GRAPHICAL_THEME);
-	selected_themes = gdm_config_get_string (GDM_KEY_GRAPHICAL_THEMES);
+	selected_theme  = g_strdup (gdm_setup_config_get_string (GDM_KEY_GRAPHICAL_THEME));
+	selected_themes = g_strdup (gdm_setup_config_get_string (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
@@ -6768,7 +7086,7 @@
 		  slash (/) character in them, so I just made GDM_DELIMITER_THEMES
 		  equal to "/:" instead. */
 
-	GdmGraphicalThemeRand = gdm_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
+	GdmGraphicalThemeRand = gdm_setup_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
 
 	/* create list store */
 	store = gtk_list_store_new (THEME_NUM_COLUMNS,
@@ -6880,19 +7198,77 @@
 	}
 }
 
-static gboolean
-delete_event (GtkWidget *w)
+static void
+check_user_changes (GtkWidget *dialog)
 {
-	timeout_remove_all ();
+
+	/* This is pretty ugly but it is probable
+	   that both events can occur simultaneously.
+	   Then we display two dialogs - one after the other. 
+	   Lets hope that although probable this scenario 
+	   does not arise very often */	
+	if (GdmRandomFromSelectedChangesWarn == TRUE) {
+		
+		GtkWidget *prompt;
+		
+		prompt = hig_dialog_new (GTK_WINDOW (dialog),
+					 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_WARNING,
+					 GTK_BUTTONS_OK,
+					 _("Random theme mode change"),
+					 _("Since no themes were selected in random theme mode"
+					   " switching back to single theme mode."));
+		
+		gtk_dialog_run (GTK_DIALOG (prompt));
+		gtk_widget_destroy (prompt);	
+		
+	}
+	
+	if (g_hash_table_size (GdmChangesUnsaved) != 0) {
+
+		GtkWidget *prompt;
+		gint response;
+
+		prompt = hig_dialog_new (GTK_WINDOW (dialog),
+					 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_WARNING,
+					 GTK_BUTTONS_NONE,
+					 _("Apply the changes before closing?"),
+					 _("If you don't apply, the changes made "
+					   "will be disregarded."));
+
+		gtk_dialog_add_button (GTK_DIALOG (prompt), _("Close _without Applying"), GTK_RESPONSE_CLOSE);
+		gtk_dialog_add_button (GTK_DIALOG (prompt), "gtk-cancel", GTK_RESPONSE_CANCEL); 		
+		gtk_dialog_add_button (GTK_DIALOG (prompt), "gtk-apply", GTK_RESPONSE_APPLY);
+		gtk_dialog_set_default_response (GTK_DIALOG (prompt), GTK_RESPONSE_CANCEL);
+
+		response = gtk_dialog_run (GTK_DIALOG (prompt));
+		gtk_widget_destroy (prompt);
+
+		if (response == GTK_RESPONSE_APPLY) {
+			apply_changes (TRUE);
+		}
+		gtk_main_quit ();
+
+		if (response == GTK_RESPONSE_CANCEL) {
+			gtk_main ();
+		}
+	}
+}
+
+static gboolean
+delete_response (GtkWidget *dlg, GdkEvent *event, gpointer user_data)
+{	
 	gtk_main_quit ();
-	return FALSE;
+	return TRUE;
 }
 
 static void
 dialog_response (GtkWidget *dlg, int response, gpointer data)
 {
+
 	if (response == GTK_RESPONSE_CLOSE) {
-		timeout_remove_all ();
+		check_user_changes (dlg);
 		gtk_main_quit ();
 	} else if (response == GTK_RESPONSE_HELP) {
 		GtkWidget *setup_dialog = glade_xml_get_widget (xml, "setup_dialog");
@@ -6937,102 +7313,68 @@
 					  G_CALLBACK (gtk_widget_destroy),
 					  dlg);
 		gtk_widget_show (dlg);
-	}
-}
-
-static void
-background_filechooser_response (GtkWidget *file_chooser, gpointer data)
-{
-	gchar *filename = NULL;
-	gchar *key;
-	gchar *value;
-				     		
-	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-	key      = g_object_get_data (G_OBJECT (file_chooser), "key");	
-	value    = gdm_config_get_string (key);
+	} else if (response == GTK_RESPONSE_APPLY) {
+		GtkWidget *prompt;
+		gint response;
 
-	/*
-	 * File_name should never be NULL, but something about this GUI causes
-	 * this function to get called on startup and filename=NULL even
-	 * though we set the filename in hookup_*_background.  Resetting the
-	 * value to the default in this case seems to work around this.
-	 */
-	if (filename == NULL && !ve_string_empty (value))
-		filename = g_strdup (value);
+		prompt = hig_dialog_new (GTK_WINDOW (dlg),
+					 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_WARNING,
+					 GTK_BUTTONS_YES_NO,
+					 _("Are you sure you want to apply the changes?"), 
+					 "");
 
-	if (filename != NULL &&
-	   (strcmp (ve_sure_string (value), ve_sure_string (filename)) != 0)) {
-		gchar *old_filename;
-		old_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-
-		if (strcmp (old_filename, filename) == 0)
-			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (file_chooser),
-						       filename);
-		g_free (old_filename);
+		response = gtk_dialog_run (GTK_DIALOG (prompt));
+		gtk_widget_destroy (prompt);
 
-		if (strcmp (ve_sure_string (value), ve_sure_string (filename)) != 0) {
-			gdm_setup_config_set_string (key, (char *)ve_sure_string (filename));
-			update_greeters ();
+		if (response == GTK_RESPONSE_YES) {
+			apply_changes (TRUE);
+			if (g_hash_table_size (GdmChangesUnsaved) == 0) {
+				GtkWidget *apply_button = glade_xml_get_widget (xml, "setup_apply_button");
+				gtk_widget_set_sensitive (apply_button, FALSE);
+			}
+			
 		}
 	}
-	g_free (filename);
 }
 
 static void
-logo_filechooser_response (GtkWidget *file_chooser, gpointer data)
+greeter_filechooser_response (GtkWidget *file_chooser, gpointer data)
 {
 	GtkWidget *image_toggle;
+	GtkWidget *other_file_chooser;
 	gchar *filename;
-	gchar *key;
-	gchar *value;
+	const gchar *key;
+	const gchar *toggle_string;
+	const gchar *other_filechooser_string;
+	const gchar *old_filename;
 	
 	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
 	key      = g_object_get_data (G_OBJECT (file_chooser), "key");	
-	value    = gdm_config_get_string (key);
-	
-	/*
-	 * File_name should never be NULL, but something about this GUI causes
-	 * this function to get called on startup and filename=NULL even
-	 * though we set the filename in hookup_*_background.  Resetting the
-	 * value to the default in this case seems to work around this.
-	 */
-	if (filename == NULL && !ve_string_empty (value))
-		filename = g_strdup (value);
-
-	if (filename == NULL) {
-		value    = gdm_config_get_string (GDM_KEY_CHOOSER_BUTTON_LOGO);
-		if (!ve_string_empty (value))
-			filename = g_strdup (value);
-	}
-
-	if (gtk_notebook_get_current_page (GTK_NOTEBOOK (setup_notebook)) == LOCAL_TAB) {
-		image_toggle = glade_xml_get_widget (xml, "remote_logo_image_checkbutton");
-	} else {
-		image_toggle = glade_xml_get_widget (xml, "remote_logo_image_checkbutton");
-	}
+	toggle_string = g_object_get_data (G_OBJECT (file_chooser), "toggle_string");
+	other_filechooser_string = g_object_get_data (G_OBJECT (file_chooser), "other_filechooser_string");
 
-	if (filename != NULL &&
-	   (strcmp (ve_sure_string (value), ve_sure_string (filename)) != 0)) {
-		gchar *old_filename;
-						      
-		old_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
-
-		if (strcmp (old_filename, filename) != 0)
-			gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (file_chooser),
-						       filename);
-		g_free (old_filename);
-
-		if (GTK_TOGGLE_BUTTON (image_toggle)->active == TRUE) {
-			gdm_setup_config_set_string (key,
-    	                                      (char *)ve_sure_string (filename));
-			update_greeters ();
-		}
+	if (filename == NULL)
+		return;
+	
+	image_toggle = glade_xml_get_widget (xml, toggle_string);
+	other_file_chooser = glade_xml_get_widget (xml, other_filechooser_string);
+		
+	
+	old_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (other_file_chooser));
+	
+	if (strcmp (ve_sure_string (old_filename), filename) != 0) {
+		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (other_file_chooser),
+					       filename);
+		
+		if (GTK_TOGGLE_BUTTON (image_toggle)->active == TRUE)
+			gdm_setup_config_set_string (key, (char *)ve_sure_string (filename));	
 	}
 	g_free (filename);
 }
 
 static GdkPixbuf *
-create_preview_pixbuf (gchar *uri) 
+create_preview_pixbuf (const gchar *uri) 
 {
 	GdkPixbuf *pixbuf = NULL;
 	
@@ -7069,7 +7411,7 @@
 }
 
 static void 
-update_image_preview (GtkFileChooser *chooser) 
+update_image_preview (GtkFileChooser *chooser, gpointer data) 
 {
 	GtkWidget *image;
 	gchar *uri;
@@ -7107,8 +7449,9 @@
 	GtkWidget *image_filechooser;
 	GtkWidget *image_scale_to_fit;
 	GtkWidget *image_preview;
-	gchar *background_filename;
-
+	const gchar *background_filename;
+	gint background_type;
+	
 	color_radiobutton = glade_xml_get_widget (xml, "local_background_color_checkbutton");
 	color_colorbutton = glade_xml_get_widget (xml, "local_background_colorbutton");
 	image_radiobutton = glade_xml_get_widget (xml, "local_background_image_checkbutton");
@@ -7122,7 +7465,7 @@
 			      GDM_KEY_BACKGROUND_SCALE_TO_FIT);
 
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_scale_to_fit), 
-	                              gdm_config_get_bool (GDM_KEY_BACKGROUND_SCALE_TO_FIT));
+	                              gdm_setup_config_get_bool (GDM_KEY_BACKGROUND_SCALE_TO_FIT));
 	
         filter = gtk_file_filter_new ();
         gtk_file_filter_set_name (filter, _("Images"));
@@ -7134,17 +7477,36 @@
         gtk_file_filter_add_pattern(filter, "*");
         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (image_filechooser), filter);
 
-	background_filename = gdm_config_get_string (GDM_KEY_BACKGROUND_IMAGE);
+	background_filename = gdm_setup_config_get_string (GDM_KEY_BACKGROUND_IMAGE);	
+	background_type = gdm_setup_config_get_int (GDM_KEY_BACKGROUND_TYPE);
 
-        if (ve_string_empty (background_filename)) {
-                gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (image_filechooser),
-                        PIXMAPDIR);
+        if (!ve_string_empty (background_filename) && access (background_filename, R_OK) == 0) {
+		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (image_filechooser),
+					       background_filename);                 
 	} else {
-                gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (image_filechooser),
-			background_filename);
+		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (image_filechooser),
+						     PIXMAPDIR);
+		/* Hmm since the file is not available we need to change the 
+		   background type (we can't support images)
+		*/
+		
+		if (background_type == BACKGROUND_IMAGE_AND_COLOR) {
+			background_type = BACKGROUND_COLOR;
+		}
+		else if (background_type == BACKGROUND_IMAGE) {
+			background_type = BACKGROUND_NONE;
+		}
+
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the image_radiobutton becomes
+		   active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_int_cache (GDM_KEY_BACKGROUND_TYPE, background_type);
 	}
 
-	switch (gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE)) {
+	switch (background_type) {
 	
 		case BACKGROUND_IMAGE_AND_COLOR: {
 			/* Image & Color background type */
@@ -7189,9 +7551,9 @@
 	gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (image_filechooser),
 					        FALSE);
 	image_preview = gtk_image_new ();
-	if (!ve_string_empty (background_filename)) {
+	if (!ve_string_empty (background_filename) && access (background_filename, R_OK) == 0) {
 		gtk_image_set_from_pixbuf (GTK_IMAGE (image_preview),
-			create_preview_pixbuf (background_filename));
+					   create_preview_pixbuf (background_filename));
 	}
 	gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (image_filechooser),
 	                                     image_preview);
@@ -7205,7 +7567,11 @@
 	g_object_set_data (G_OBJECT (image_radiobutton), "key",
 	                   GDM_KEY_BACKGROUND_TYPE);
 	g_object_set_data (G_OBJECT (image_filechooser), "key",
-	                   GDM_KEY_BACKGROUND_IMAGE);			   
+	                   GDM_KEY_BACKGROUND_IMAGE);	
+	g_object_set_data_full (G_OBJECT (image_filechooser), "toggle_string", 
+				"local_background_image_checkbutton", (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (image_filechooser), "other_filechooser_string", 
+				"remote_background_image_chooserbutton", (GDestroyNotify) g_free);
 	g_object_set_data (G_OBJECT (image_scale_to_fit), "key",
 	                   GDM_KEY_BACKGROUND_SCALE_TO_FIT);
 
@@ -7220,7 +7586,7 @@
 	g_signal_connect (G_OBJECT (image_radiobutton), "toggled",
 	                  G_CALLBACK (toggle_toggled_sensitivity_positive), image_scale_to_fit);
         g_signal_connect (G_OBJECT (image_filechooser), "selection-changed",
-                          G_CALLBACK (background_filechooser_response), image_filechooser);
+                          G_CALLBACK (greeter_filechooser_response), NULL);
         g_signal_connect (G_OBJECT (image_filechooser), "update-preview",
 			  G_CALLBACK (update_image_preview), NULL);
 }
@@ -7241,10 +7607,12 @@
 	setup_notify_toggle ("local_set_pos_checkbox", GDM_KEY_SET_POSITION);
 
 	/* Setup positionX */
-	setup_intspin ("local_posx_spinbutton", GDM_KEY_POSITION_X);
+	setup_intspin_other ("local_posx_spinbutton", GDM_KEY_POSITION_X, 
+			     "remote_posx_spinbutton");
 
 	/* Setup positionX */
-	setup_intspin ("local_posy_spinbutton", GDM_KEY_POSITION_Y);
+	setup_intspin_other ("local_posy_spinbutton", GDM_KEY_POSITION_Y,
+			     "remote_posy_spinbutton");
 	
 }
 
@@ -7256,7 +7624,7 @@
 	GtkWidget *logo_checkbutton;
 	GtkWidget *logo_button;
 	GtkWidget *image_preview;
-	gchar *logo_filename;
+	const gchar *logo_filename;
 
 	logo_checkbutton = glade_xml_get_widget (xml, "local_logo_image_checkbutton");
 	logo_button = glade_xml_get_widget (xml, "local_logo_image_chooserbutton");
@@ -7274,32 +7642,38 @@
 	gtk_file_filter_add_pattern(filter, "*");
 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (logo_button), filter);
 
-	logo_filename = gdm_config_get_string (GDM_KEY_LOGO);
-
-	if (ve_string_empty (logo_filename)) {
-		logo_filename = gdm_config_get_string (GDM_KEY_CHOOSER_BUTTON_LOGO);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (logo_checkbutton), 
-		                              FALSE);
-		gtk_widget_set_sensitive (logo_button, FALSE);
-	}
-	else {
+	logo_filename = gdm_setup_config_get_string (GDM_KEY_LOGO);
+	
+	if (ve_string_empty (logo_filename))
+		logo_filename = gdm_setup_config_get_string (GDM_KEY_CHOOSER_BUTTON_LOGO);
+	
+	if (!ve_string_empty (logo_filename) && access (logo_filename, R_OK) == 0) {
+		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (logo_button),
+					       logo_filename);
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (logo_checkbutton), 
 		                              TRUE);
 		gtk_widget_set_sensitive (logo_button, TRUE);
-	}
-
-	if (ve_string_empty (logo_filename)) {
-		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (logo_button),
-			PIXMAPDIR);
 	} else {
-		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (logo_button),
-			logo_filename);
-	}
+		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (logo_button),
+						     PIXMAPDIR);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (logo_checkbutton), 
+		                              FALSE);
+		gtk_widget_set_sensitive (logo_button, FALSE);
 
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the logo_checkbutton 
+		   becomes active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_LOGO, "");
+		gdm_setup_config_set_string_cache (GDM_KEY_CHOOSER_BUTTON_LOGO, "");
+	}
+	
 	image_preview = gtk_image_new ();
-	if (!ve_string_empty (logo_filename)) {
+	if (!ve_string_empty (logo_filename) && access (logo_filename, R_OK) == 0) {
 		gtk_image_set_from_pixbuf (GTK_IMAGE (image_preview),
-			create_preview_pixbuf (logo_filename));
+					   create_preview_pixbuf (logo_filename));
 	}
 	gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (logo_button), 
 	                                     image_preview);
@@ -7307,6 +7681,10 @@
 	gtk_widget_show (image_preview); 
 
 	g_object_set_data (G_OBJECT (logo_button), "key", GDM_KEY_LOGO);
+	g_object_set_data_full (G_OBJECT (logo_button), "toggle_string", 
+				"local_logo_image_checkbutton", (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (logo_button), "other_filechooser_string", 
+				"remote_logo_image_chooserbutton", (GDestroyNotify) g_free);
 	g_object_set_data (G_OBJECT (logo_checkbutton), "key", GDM_KEY_LOGO);
 
 	g_signal_connect (G_OBJECT (logo_checkbutton), "toggled", 
@@ -7314,7 +7692,7 @@
 	g_signal_connect (G_OBJECT (logo_checkbutton), "toggled",
 	                  G_CALLBACK (toggle_toggled_sensitivity_positive), logo_button);
         g_signal_connect (G_OBJECT (logo_button), "selection-changed",
-                          G_CALLBACK (logo_filechooser_response), logo_button);
+                          G_CALLBACK (greeter_filechooser_response), NULL);
         g_signal_connect (G_OBJECT (logo_button), "update-preview",
                           G_CALLBACK (update_image_preview), NULL);
 }
@@ -7378,13 +7756,13 @@
 	GList      *tmp;
 	gint       i = 0;
 	gint       active = 0;
-	gchar      *org_val;
+	const gchar      *org_val;
 
 	_gdm_session_list_init (&sessnames, &org_sessions, NULL, NULL);
 	
 	default_session_combobox = glade_xml_get_widget (xml, "default_session_combobox");
 
-	org_val = gdm_config_get_string (GDM_KEY_DEFAULT_SESSION);
+	org_val = gdm_setup_config_get_string (GDM_KEY_DEFAULT_SESSION);
 	
 	for (tmp = org_sessions; tmp != NULL; tmp = tmp->next, i++) {
 		GdmSession *session;
@@ -7444,9 +7822,6 @@
 			  G_CALLBACK (toggle_toggled), default_session_checkbox);
 	g_signal_connect (G_OBJECT (default_session_checkbox), "toggled",
 			  G_CALLBACK (toggle_toggled_sensitivity_positive), default_session_combobox);
-	
-	g_free (org_val);
-	
 }
 
 static void
@@ -7456,8 +7831,8 @@
 	GtkWidget *gtkrc_checkbox;
 	GtkWidget *clock_type_chooser;	
 	GtkWidget *commands_button;
-	gchar *gtkrc_filename;
-	gchar *user_24hr_clock;
+	const gchar *gtkrc_filename;
+	const gchar *user_24hr_clock;
 
 	
 	/* Setup use visual feedback in the passwotrd entry */
@@ -7467,16 +7842,16 @@
 	setup_notify_toggle ("use_circles_passwd_checkbox", GDM_KEY_ENTRY_CIRCLES);
 
 	/* Setup always login current session entry */
-	setup_notify_toggle ("a_login_curr_session_checkbutton", GDM_KEY_ALWAYS_LOGIN_CURRENT_SESSION);
+	setup_notify_toggle ("always_login_curr_session_checkbutton", GDM_KEY_ALWAYS_LOGIN_CURRENT_SESSION);
 
 	/* Setup default session */
 	setup_default_session ();
 	
 	/* Setup GtkRC file path */
-	gtkrc_filechooser = glade_xml_get_widget (xml, "gtkrc_chooserbutton");
-
-	gtkrc_filename = gdm_config_get_string (GDM_KEY_GTKRC);
+	gtkrc_filechooser = glade_xml_get_widget (xml, "gtkrc_filechooserbutton");
 
+	gtkrc_filename = gdm_setup_config_get_string (GDM_KEY_GTKRC);
+	
 	gtkrc_checkbox = glade_xml_get_widget (xml, "gtkrc_checkbutton");
 
 	if (!ve_string_empty (gtkrc_filename) && access (gtkrc_filename, R_OK) == 0) {
@@ -7489,7 +7864,15 @@
 	}
 	else {
 		gtk_widget_set_sensitive (gtkrc_filechooser, FALSE);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtkrc_checkbox), FALSE);	
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtkrc_checkbox), FALSE);
+		
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the gtkrc_checkbox becomes
+		   active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_GTKRC, "");
 	}
 		
 	g_object_set_data_full (G_OBJECT (gtkrc_filechooser),
@@ -7510,18 +7893,17 @@
 	g_signal_connect (G_OBJECT (gtkrc_checkbox), "toggled",
 			  G_CALLBACK (toggle_toggled_sensitivity_positive), gtkrc_filechooser);
 	
-	g_free (gtkrc_filename);
-
-	/* Setup user 24Hr Clock */
+	/* Setup use 24Hr Clock */
 	clock_type_chooser = glade_xml_get_widget (xml, "use_24hr_clock_combobox");
 
-	user_24hr_clock = gdm_config_get_string (GDM_KEY_USE_24_CLOCK);
+	user_24hr_clock = gdm_setup_config_get_string (GDM_KEY_USE_24_CLOCK);
+
 	if (!ve_string_empty (user_24hr_clock)) {
 		if (strcasecmp (ve_sure_string (user_24hr_clock), _("auto")) == 0) {
 			gtk_combo_box_set_active (GTK_COMBO_BOX (clock_type_chooser), CLOCK_AUTO);
 		}
 		else if (strcasecmp (ve_sure_string (user_24hr_clock), _("yes")) == 0) {
-			gtk_combo_box_set_active (GTK_COMBO_BOX (clock_type_chooser), CLOCK_AUTO);
+			gtk_combo_box_set_active (GTK_COMBO_BOX (clock_type_chooser), CLOCK_YES);
 		}
 		else if (strcasecmp (ve_sure_string (user_24hr_clock), _("no")) == 0) {	
 			gtk_combo_box_set_active (GTK_COMBO_BOX (clock_type_chooser), CLOCK_NO);
@@ -7557,8 +7939,9 @@
 	GtkWidget *image_filechooser;
 	GtkWidget *image_scale_to_fit;
 	GtkWidget *image_preview;
-	gchar *background_filename;
-
+	const gchar *background_filename;
+	gint background_type;
+	
 	color_radiobutton = glade_xml_get_widget (xml, "remote_background_color_checkbutton");
 	color_colorbutton = glade_xml_get_widget (xml, "remote_background_colorbutton");
 	image_radiobutton = glade_xml_get_widget (xml, "remote_background_image_checkbutton");
@@ -7575,7 +7958,7 @@
 			      GDM_KEY_BACKGROUND_REMOTE_ONLY_COLOR);
 
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (image_scale_to_fit), 
-	                              gdm_config_get_bool (GDM_KEY_BACKGROUND_SCALE_TO_FIT));
+	                              gdm_setup_config_get_bool (GDM_KEY_BACKGROUND_SCALE_TO_FIT));
 	
         filter = gtk_file_filter_new ();
         gtk_file_filter_set_name (filter, _("Images"));
@@ -7587,17 +7970,37 @@
         gtk_file_filter_add_pattern(filter, "*");
         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (image_filechooser), filter);
 
-	background_filename = gdm_config_get_string (GDM_KEY_BACKGROUND_IMAGE);
-
-        if (ve_string_empty (background_filename)) {
-                gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (image_filechooser),
-                        PIXMAPDIR);
+	background_filename = gdm_setup_config_get_string (GDM_KEY_BACKGROUND_IMAGE);
+	background_type = gdm_setup_config_get_int (GDM_KEY_BACKGROUND_TYPE);
+	
+        if (!ve_string_empty (background_filename) && access (background_filename, R_OK) == 0) {
+		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (image_filechooser),
+					       background_filename);
+                
         } else {
-                gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (image_filechooser),
-			background_filename);
+		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (image_filechooser),
+						     PIXMAPDIR);
+		/* Hmm since the file is not available we need to change the 
+		   background type (we can't support images)
+		*/
+		
+		if (background_type == BACKGROUND_IMAGE_AND_COLOR) {
+			background_type = BACKGROUND_COLOR;
+		}
+		else if (background_type == BACKGROUND_IMAGE) {
+			background_type = BACKGROUND_NONE;
+		}
+
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the image_radiobutton becomes
+		   active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_int_cache (GDM_KEY_BACKGROUND_TYPE, background_type);
 	}
 
-	switch (gdm_config_get_int (GDM_KEY_BACKGROUND_TYPE)) {
+	switch (background_type) {
 	
 		case BACKGROUND_IMAGE_AND_COLOR:	{
 			/* Image & Color background type */
@@ -7642,9 +8045,9 @@
 	gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (image_filechooser),
 					        FALSE);
 	image_preview = gtk_image_new ();
-	if (!ve_string_empty (background_filename)) {
+	if (!ve_string_empty (background_filename) && access (background_filename, R_OK) == 0) {
 	gtk_image_set_from_pixbuf (GTK_IMAGE (image_preview),
-		create_preview_pixbuf (background_filename));
+				   create_preview_pixbuf (background_filename));
 	}
 	gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (image_filechooser), 
 	                                     image_preview);
@@ -7658,7 +8061,11 @@
 	g_object_set_data (G_OBJECT (image_radiobutton), "key",
 	                   GDM_KEY_BACKGROUND_TYPE);
 	g_object_set_data (G_OBJECT (image_filechooser), "key",
-	                   GDM_KEY_BACKGROUND_IMAGE);			   
+	                   GDM_KEY_BACKGROUND_IMAGE);
+	g_object_set_data_full (G_OBJECT (image_filechooser), "toggle_string", 
+				"remote_background_image_checkbutton", (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (image_filechooser), "other_filechooser_string", 
+				"local_background_image_chooserbutton", (GDestroyNotify) g_free);
 	g_object_set_data (G_OBJECT (image_scale_to_fit), "key",
 	                   GDM_KEY_BACKGROUND_SCALE_TO_FIT);
 
@@ -7673,7 +8080,7 @@
 	g_signal_connect (G_OBJECT (image_radiobutton), "toggled",
 	                  G_CALLBACK (toggle_toggled_sensitivity_positive), image_scale_to_fit);
         g_signal_connect (G_OBJECT (image_filechooser), "selection-changed",
-                          G_CALLBACK (background_filechooser_response), image_filechooser);
+                          G_CALLBACK (greeter_filechooser_response), NULL);
         g_signal_connect (G_OBJECT (image_filechooser), "update-preview",
                           G_CALLBACK (update_image_preview), NULL);
 }
@@ -7694,10 +8101,12 @@
 	setup_notify_toggle ("remote_set_pos_checkbox", GDM_KEY_SET_POSITION);
 
 	/* Setup positionX */
-	setup_intspin ("remote_posx_spinbutton", GDM_KEY_POSITION_X);
+	setup_intspin_other ("remote_posx_spinbutton", GDM_KEY_POSITION_X,
+			     "local_posx_spinbutton");
 
 	/* Setup positionX */
-	setup_intspin ("remote_posy_spinbutton", GDM_KEY_POSITION_Y);	
+	setup_intspin_other ("remote_posy_spinbutton", GDM_KEY_POSITION_Y,
+			     "local_posy_spinbutton");	
 }
 
 static void
@@ -7708,7 +8117,7 @@
 	GtkWidget *logo_checkbutton;
 	GtkWidget *logo_button;
 	GtkWidget *image_preview;
-	gchar *logo_filename;
+	const gchar *logo_filename;
 
 	logo_checkbutton = glade_xml_get_widget (xml, "remote_logo_image_checkbutton");
 	logo_button = glade_xml_get_widget (xml, "remote_logo_image_chooserbutton");
@@ -7726,31 +8135,38 @@
 	gtk_file_filter_add_pattern(filter, "*");
 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (logo_button), filter);
 
-	logo_filename = gdm_config_get_string (GDM_KEY_LOGO);
+	logo_filename = gdm_setup_config_get_string (GDM_KEY_LOGO);
 
-	if (ve_string_empty (logo_filename)) {
-		logo_filename = gdm_config_get_string (GDM_KEY_CHOOSER_BUTTON_LOGO);
-
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (logo_checkbutton), 
-		                              FALSE);
-		gtk_widget_set_sensitive (logo_button, FALSE);
-	}
-	else {
+	if (ve_string_empty (logo_filename))
+		logo_filename = gdm_setup_config_get_string (GDM_KEY_CHOOSER_BUTTON_LOGO);
+		
+        if (!ve_string_empty (logo_filename) && access (logo_filename, R_OK) == 0) {
+                gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (logo_button), logo_filename);
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (logo_checkbutton), 
 		                              TRUE);
 		gtk_widget_set_sensitive (logo_button, TRUE);
 	}
+        else {
+		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (logo_button),
+                        PIXMAPDIR);     
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (logo_checkbutton), 
+					      FALSE);
+		gtk_widget_set_sensitive (logo_button, FALSE);
 		
-        if (ve_string_empty (logo_filename))
-                gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (logo_button),
-                        PIXMAPDIR);
-        else
-                gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (logo_button), logo_filename);
+		/* This is a bit of a HACK but it will prevent Apply button
+		   from becomming sensitive when the logo_ckeckbutton becomes
+		   active and then inactive again with filename = None.
+		   The daemon wont care if its invalid file or an empty string
+		   and this just looks neater
+		*/		   
+		gdm_setup_config_set_string_cache (GDM_KEY_LOGO, "");
+		gdm_setup_config_set_string_cache (GDM_KEY_CHOOSER_BUTTON_LOGO, "");
+	}
 
 	image_preview = gtk_image_new ();
-	if (!ve_string_empty (logo_filename)) {
+	if (!ve_string_empty (logo_filename) && access (logo_filename, R_OK) == 0) {
 		gtk_image_set_from_pixbuf (GTK_IMAGE (image_preview),
-			create_preview_pixbuf (logo_filename));
+					   create_preview_pixbuf (logo_filename));
 	}
 	gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (logo_button), 
 	                                     image_preview);
@@ -7759,6 +8175,10 @@
 
 	g_object_set_data (G_OBJECT (logo_button), "key",
 	                   GDM_KEY_LOGO);
+	g_object_set_data_full (G_OBJECT (logo_button), "toggle_string", 
+				"remote_logo_image_checkbutton", (GDestroyNotify) g_free);
+	g_object_set_data_full (G_OBJECT (logo_button), "other_filechooser_string", 
+				"local_logo_image_chooserbutton", (GDestroyNotify) g_free);
 	g_object_set_data (G_OBJECT (logo_checkbutton), "key",
 	                   GDM_KEY_LOGO);
 
@@ -7767,7 +8187,7 @@
 	g_signal_connect (G_OBJECT (logo_checkbutton), "toggled",
 	                  G_CALLBACK (toggle_toggled_sensitivity_positive), logo_button);
         g_signal_connect (G_OBJECT (logo_button), "selection-changed",
-                          G_CALLBACK (logo_filechooser_response), logo_button);
+                          G_CALLBACK (greeter_filechooser_response), NULL);
         g_signal_connect (G_OBJECT (logo_button), "update-preview",
                           G_CALLBACK (update_image_preview), NULL);
 }
@@ -7839,7 +8259,7 @@
 
 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (theme_list), TRUE);
 
-	GdmGraphicalThemeRand = gdm_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
+	GdmGraphicalThemeRand = gdm_setup_config_get_bool (GDM_KEY_GRAPHICAL_THEME_RAND);
 
 	/* Register theme mode combobox */
 	g_object_set_data_full (G_OBJECT (mode_combobox), "key",
@@ -7953,13 +8373,13 @@
 setup_gui (void)
 {
 	GtkWidget *dialog;
-
-	xml = glade_xml_new (GDM_GLADE_DIR "/gdmsetup.glade", "setup_dialog", NULL);
+	
+	if (xml == NULL)
+		xml = glade_xml_new (GDM_GLADE_DIR "/gdmsetup.glade", "setup_dialog", NULL);
 
 	dialog = glade_xml_get_widget (xml, "setup_dialog");
-
 	g_signal_connect (G_OBJECT (dialog), "delete_event",
-			  G_CALLBACK (delete_event), NULL);
+			  G_CALLBACK (delete_response), NULL);
 	g_signal_connect (G_OBJECT (dialog), "response",
 			  G_CALLBACK (dialog_response), NULL);
 
@@ -7991,6 +8411,7 @@
 	glade_helper_tagify_label (xml, "fb_informationlabel", "i");
 	glade_helper_tagify_label (xml, "fb_informationlabel", "small");
 	
+
 	/* Setup preference tabs */
 	setup_general_tab ();
 	setup_local_tab (); 
@@ -8113,76 +8534,10 @@
 	return TRUE;
 }      
 
-static void
-apply_user_changes (GObject *object, gint arg1, gpointer user_data)
-{
-	GtkWidget *dialog = user_data;
-
-
-	/* This is pretty ugly but it is probable
-	   that both events can occur simultaneously.
-	   Then we display two dialogs - one after the other. 
-	   Lets hope that although probable this scenario 
-	   does not araise very often */	
-	if (GdmRandomFromSelectedChangesWarn == TRUE) {
-		
-		GtkWidget *prompt;
-		
-		prompt = hig_dialog_new (GTK_WINDOW (dialog),
-					 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_WARNING,
-					 GTK_BUTTONS_OK,
-					 _("Random theme mode change"),
-					 _("Since no themes were selected in random theme mode"
-					   " switching back to single theme mode."));
-		
-		gtk_dialog_run (GTK_DIALOG (prompt));
-		gtk_widget_destroy (prompt);	
-		
-	}
-	
-	if (GdmUserChangesUnsaved == TRUE) {
-
-		GtkWidget *prompt;
-		gint response;
-
-		prompt = hig_dialog_new (GTK_WINDOW (dialog),
-					 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-					 GTK_MESSAGE_WARNING,
-					 GTK_BUTTONS_NONE,
-					 _("Apply the changes to users before closing?"),
-					 _("If you don't apply, the changes made on "
-					   "the Users tab will be disregarded."));
-
-		gtk_dialog_add_button (GTK_DIALOG (prompt), _("Close _without Applying"), GTK_RESPONSE_CLOSE);
-		gtk_dialog_add_button (GTK_DIALOG (prompt), "gtk-cancel", GTK_RESPONSE_CANCEL); 
-		gtk_dialog_add_button (GTK_DIALOG (prompt), "gtk-apply", GTK_RESPONSE_APPLY);
-
-		response = gtk_dialog_run (GTK_DIALOG (prompt));
-		gtk_widget_destroy (prompt);
-
-		if (response == GTK_RESPONSE_APPLY) {
-			GtkWidget *apply_button;
-
-			apply_button = glade_xml_get_widget (xml, "fb_faceapply");
-			g_signal_emit_by_name (G_OBJECT (apply_button), "clicked");
-		}
-		
-		gtk_main_quit ();
-
-		if (response == GTK_RESPONSE_CANCEL) {
-			gtk_main ();
-		}
-	}
-}
-
 int 
 main (int argc, char *argv[])
 {
 	GtkWidget *dialog;
-	char **list;
-	gint GdmMinimalUID;
-	int i;
 
 	gdm_config_never_cache (TRUE);
 
@@ -8198,7 +8553,7 @@
 	gtk_init (&argc, &argv);
 
 	/* Lets check if gdm daemon is running
-	   if no there is no point in continuing
+	   if not there is no point in continuing
 	*/
 	gdm_running = gdmcomm_check (TRUE);
 	if (gdm_running == FALSE)
@@ -8245,22 +8600,27 @@
 		exit (EXIT_FAILURE);
 	}	
 
+	/* Set up cache for current values */
+	GdmCurrentConfigValues = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify*)gdm_config_value_free);
+	
+	/* Set up unsaved changes storage container */
+	GdmChangesUnsaved = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify*)gdm_config_value_free);
+
 	if (RUNNING_UNDER_GDM) {
-		char *gtkrc;
-		char *theme_name;
+		const char *gtkrc;
+		const char *theme_name;
 
 		/* Set busy cursor */
 		setup_cursor (GDK_WATCH);
 
 		/* parse the given gtk rc first */
-		gtkrc = gdm_config_get_string (GDM_KEY_GTKRC);
+		gtkrc = gdm_setup_config_get_string (GDM_KEY_GTKRC);
 		if ( ! ve_string_empty (gtkrc))
 			gtk_rc_parse (gtkrc);
 
 		theme_name = g_strdup (g_getenv ("GDM_GTK_THEME"));
 		if (ve_string_empty (theme_name)) {
-			g_free (theme_name);
-			theme_name = gdm_config_get_string (GDM_KEY_GTK_THEME);
+			theme_name = gdm_setup_config_get_string (GDM_KEY_GTK_THEME);
 			gdm_set_theme (theme_name);
 		} else {
 			gdm_set_theme (theme_name);
@@ -8297,46 +8657,30 @@
          * XXX: the setup proggie using a greeter config var for it's
 	 * ui?  Say it ain't so.  Our config sections are SUCH A MESS
          */
-	GdmIconMaxHeight   = gdm_config_get_int (GDM_KEY_MAX_ICON_HEIGHT);
-	GdmIconMaxWidth    = gdm_config_get_int (GDM_KEY_MAX_ICON_WIDTH);
-	GdmIncludeAll      = gdm_config_get_bool (GDM_KEY_INCLUDE_ALL);
-	GdmInclude         = gdm_config_get_string (GDM_KEY_INCLUDE);
-	
-	/* We need to make sure that the users in the include list exist
-	   and have uid that are higher than MinimalUID. This protects us
-	   from invalid data obtained from the config file */
-	GdmMinimalUID = gdm_config_get_int (GDM_KEY_MINIMAL_UID);
-	list = g_strsplit (GdmInclude, ",", 0);
-	for (i=0; list != NULL && list[i] != NULL; i++) {
-		if (gdm_is_user_valid (list[i]) && gdm_user_uid (list[i]) >= GdmMinimalUID)
-			continue;
-		
-		GdmInclude = strings_list_remove (GdmInclude, list[i], ",");
-	}
-	g_strfreev (list);
+	GdmIconMaxHeight   = gdm_setup_config_get_int (GDM_KEY_MAX_ICON_HEIGHT);
+	GdmIconMaxWidth    = gdm_setup_config_get_int (GDM_KEY_MAX_ICON_WIDTH);
 
-	GdmExclude         = gdm_config_get_string (GDM_KEY_EXCLUDE);
-	GdmSoundProgram    = gdm_config_get_string (GDM_KEY_SOUND_PROGRAM);
+	GdmSoundProgram    = g_strdup (gdm_setup_config_get_string (GDM_KEY_SOUND_PROGRAM));
 
+	/* Lets check if Include list and auto login and timed login
+	   config values are valid wrt MinimalUID. If not we
+	   adjust them and notify greeters
+	*/
+	xml = glade_xml_new (GDM_GLADE_DIR "/gdmsetup.glade", "setup_dialog", NULL);
+	
+	if (gdm_setup_adjust_users_include_list () == TRUE)
+		apply_changes (TRUE);
+		
 	if (ve_string_empty (GdmSoundProgram) ||
             g_access (GdmSoundProgram, X_OK) != 0) {
 		GdmSoundProgram = NULL;
 	}
-
-        xservers = gdm_config_get_xservers (FALSE);
-
+       
 	/* Done using socket */
-	gdmcomm_comm_bulk_stop ();
+	gdmcomm_comm_bulk_stop ();	
 
-	/* Once we corrected the include list we need to save it if
-	   it was modified */
-	if ( strcmp (ve_sure_string (gdm_config_get_string (GDM_KEY_INCLUDE)), ve_sure_string (GdmInclude)) != 0)
-		gdm_setup_config_set_string (GDM_KEY_INCLUDE, GdmInclude);
-	
 	dialog = setup_gui ();
 
-	g_signal_connect (G_OBJECT (dialog), "response",
-			  G_CALLBACK (apply_user_changes), dialog);
 	gtk_widget_show (dialog);
 
 	if (RUNNING_UNDER_GDM) {
--- gdm2/gui/gdmsetup.glade.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/gui/gdmsetup.glade	2007-07-01 20:17:22.000000000 +0100
@@ -32,7 +32,7 @@
 	  <property name="layout_style">GTK_BUTTONBOX_END</property>
 
 	  <child>
-	    <widget class="GtkButton" id="helpbutton2">
+	    <widget class="GtkButton" id="gdmsetup_helpbutton">
 	      <property name="visible">True</property>
 	      <property name="can_default">True</property>
 	      <property name="can_focus">True</property>
@@ -45,7 +45,21 @@
 	  </child>
 
 	  <child>
-	    <widget class="GtkButton" id="okbutton1">
+	    <widget class="GtkButton" id="setup_apply_button">
+	      <property name="visible">True</property>
+	      <property name="sensitive">False</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-apply</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-10</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="setup_close_button">
 	      <property name="visible">True</property>
 	      <property name="can_default">True</property>
 	      <property name="can_focus">True</property>
@@ -202,7 +216,7 @@
 		  </child>
 
 		  <child>
-		    <widget class="GtkCheckButton" id="a_login_curr_session_checkbutton">
+		    <widget class="GtkCheckButton" id="always_login_curr_session_checkbutton">
 		      <property name="visible">True</property>
 		      <property name="tooltip" translatable="yes">When the user logs in and already has an existing session, they are connected to that session rather than starting a new session.  This only works for sessions running on Virtual Terminals started with gdmflexiserver, and not with XDMCP.</property>
 		      <property name="can_focus">True</property>
@@ -285,7 +299,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkFileChooserButton" id="gtkrc_chooserbutton">
+			    <widget class="GtkFileChooserButton" id="gtkrc_filechooserbutton">
 			      <property name="visible">True</property>
 			      <property name="sensitive">False</property>
 			      <property name="title" translatable="yes">Select Background Image</property>
@@ -1071,7 +1085,7 @@
 					      <property name="update_policy">GTK_UPDATE_ALWAYS</property>
 					      <property name="snap_to_ticks">False</property>
 					      <property name="wrap">False</property>
-					      <property name="adjustment">1 0 100 1 10 10</property>
+					      <property name="adjustment">1 0 3200 1 10 10</property>
 					    </widget>
 					    <packing>
 					      <property name="padding">0</property>
@@ -1117,7 +1131,7 @@
 					      <property name="update_policy">GTK_UPDATE_ALWAYS</property>
 					      <property name="snap_to_ticks">False</property>
 					      <property name="wrap">False</property>
-					      <property name="adjustment">1 0 100 1 10 10</property>
+					      <property name="adjustment">1 0 2400 1 10 10</property>
 					    </widget>
 					    <packing>
 					      <property name="padding">0</property>
@@ -2454,7 +2468,7 @@
 					  <property name="spacing">3</property>
 
 					  <child>
-					    <widget class="GtkHBox" id="remote_background_image_hhox">
+					    <widget class="GtkHBox" id="remote_background_image_hbox">
 					      <property name="visible">True</property>
 					      <property name="homogeneous">False</property>
 					      <property name="spacing">12</property>
@@ -2703,7 +2717,7 @@
 				  </child>
 
 				  <child>
-				    <widget class="GtkVBox" id="vbox144">
+				    <widget class="GtkVBox" id="remote_behaviour_vbox">
 				      <property name="visible">True</property>
 				      <property name="homogeneous">False</property>
 				      <property name="spacing">3</property>
@@ -2970,7 +2984,7 @@
 					      <property name="update_policy">GTK_UPDATE_ALWAYS</property>
 					      <property name="snap_to_ticks">False</property>
 					      <property name="wrap">False</property>
-					      <property name="adjustment">1 0 3000 1 10 10</property>
+					      <property name="adjustment">1 0 3200 1 10 10</property>
 					    </widget>
 					    <packing>
 					      <property name="padding">0</property>
@@ -3016,7 +3030,7 @@
 					      <property name="update_policy">GTK_UPDATE_ALWAYS</property>
 					      <property name="snap_to_ticks">False</property>
 					      <property name="wrap">False</property>
-					      <property name="adjustment">1 0 3000 1 10 10</property>
+					      <property name="adjustment">1 0 2400 1 10 10</property>
 					    </widget>
 					    <packing>
 					      <property name="padding">0</property>
@@ -6195,103 +6209,6 @@
 		      <property name="fill">True</property>
 		    </packing>
 		  </child>
-
-		  <child>
-		    <widget class="GtkHBox" id="hbox217">
-		      <property name="visible">True</property>
-		      <property name="homogeneous">False</property>
-		      <property name="spacing">6</property>
-
-		      <child>
-			<widget class="GtkButton" id="fb_faceapply">
-			  <property name="visible">True</property>
-			  <property name="sensitive">False</property>
-			  <property name="can_focus">True</property>
-			  <property name="relief">GTK_RELIEF_NORMAL</property>
-			  <property name="focus_on_click">True</property>
-
-			  <child>
-			    <widget class="GtkAlignment" id="alignment26">
-			      <property name="visible">True</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xscale">0</property>
-			      <property name="yscale">0</property>
-			      <property name="top_padding">0</property>
-			      <property name="bottom_padding">0</property>
-			      <property name="left_padding">0</property>
-			      <property name="right_padding">0</property>
-
-			      <child>
-				<widget class="GtkHBox" id="hbox218">
-				  <property name="visible">True</property>
-				  <property name="homogeneous">False</property>
-				  <property name="spacing">2</property>
-
-				  <child>
-				    <widget class="GtkImage" id="image25">
-				      <property name="visible">True</property>
-				      <property name="stock">gtk-apply</property>
-				      <property name="icon_size">4</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="GtkLabel" id="label313">
-				      <property name="visible">True</property>
-				      <property name="label" translatable="yes">A_pply User Changes</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>
-				      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-				      <property name="width_chars">-1</property>
-				      <property name="single_line_mode">False</property>
-				      <property name="angle">0</property>
-				    </widget>
-				    <packing>
-				      <property name="padding">0</property>
-				      <property name="expand">False</property>
-				      <property name="fill">False</property>
-				    </packing>
-				  </child>
-				</widget>
-			      </child>
-			    </widget>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="padding">0</property>
-			  <property name="expand">False</property>
-			  <property name="fill">False</property>
-			  <property name="pack_type">GTK_PACK_END</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<placeholder/>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
 		</widget>
 		<packing>
 		  <property name="tab_expand">False</property>
@@ -6364,7 +6281,7 @@
 	  <property name="layout_style">GTK_BUTTONBOX_END</property>
 
 	  <child>
-	    <widget class="GtkButton" id="closebutton2">
+	    <widget class="GtkButton" id="xdmcp_closebutton">
 	      <property name="visible">True</property>
 	      <property name="can_default">True</property>
 	      <property name="can_focus">True</property>
@@ -6911,7 +6828,7 @@
 	  <property name="layout_style">GTK_BUTTONBOX_END</property>
 
 	  <child>
-	    <widget class="GtkButton" id="button1">
+	    <widget class="GtkButton" id="xserver_help_button">
 	      <property name="visible">True</property>
 	      <property name="can_default">True</property>
 	      <property name="can_focus">True</property>
@@ -6924,7 +6841,7 @@
 	  </child>
 
 	  <child>
-	    <widget class="GtkButton" id="closebutton3">
+	    <widget class="GtkButton" id="xserver_close_button">
 	      <property name="visible">True</property>
 	      <property name="can_default">True</property>
 	      <property name="can_focus">True</property>
@@ -8442,7 +8359,7 @@
 	  <property name="layout_style">GTK_BUTTONBOX_END</property>
 
 	  <child>
-	    <widget class="GtkButton" id="button2">
+	    <widget class="GtkButton" id="command_help_button">
 	      <property name="visible">True</property>
 	      <property name="can_default">True</property>
 	      <property name="can_focus">True</property>
@@ -8491,7 +8408,7 @@
 	      <child>
 		<widget class="GtkLabel" id="custom_cmd_note_label">
 		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Note:&lt;/b&gt; You can select different commands from the drop-down list, and modify them through relevant fields located below. To save changes press Apply Command Changes button.</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Note:&lt;/b&gt; You can select different commands from the drop-down list, and modify them through relevant fields located below.</property>
 		  <property name="use_underline">False</property>
 		  <property name="use_markup">True</property>
 		  <property name="justify">GTK_JUSTIFY_FILL</property>
@@ -9315,7 +9232,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkLabel" id="label_label">
+			    <widget class="GtkLabel" id="custom_label_label">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Text to appear on the buttons and menu items</property>
 			      <property name="use_underline">False</property>
@@ -9380,7 +9297,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkLabel" id="lrlabel_label">
+			    <widget class="GtkLabel" id="custom_lrlabel_label">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Text to appear on the radio buttons and list items</property>
 			      <property name="use_underline">False</property>
@@ -9524,7 +9441,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkLabel" id="text_label">
+			    <widget class="GtkLabel" id="custom_text_label">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Text to appear in the warning pop-up dialogs</property>
 			      <property name="use_underline">False</property>
@@ -9668,7 +9585,7 @@
 			  </child>
 
 			  <child>
-			    <widget class="GtkLabel" id="tooltip_label">
+			    <widget class="GtkLabel" id="custom_tooltip_label">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Text to appear on the tooltips</property>
 			      <property name="use_underline">False</property>
@@ -9798,7 +9715,7 @@
 		      </child>
 
 		      <child>
-			<widget class="GtkLabel" id="persistent_label">
+			<widget class="GtkLabel" id="custom_persistent_label">
 			  <property name="visible">True</property>
 			  <property name="label" translatable="yes">Accessible from the outside of the login manager</property>
 			  <property name="use_underline">False</property>
@@ -9919,7 +9836,7 @@
 		      </child>
 
 		      <child>
-			<widget class="GtkLabel" id="norestart_label">
+			<widget class="GtkLabel" id="custom_norestart_label">
 			  <property name="visible">True</property>
 			  <property name="label" translatable="yes">Don't restart the login manager after the execution</property>
 			  <property name="use_underline">False</property>
@@ -9963,103 +9880,6 @@
 	      <property name="fill">False</property>
 	    </packing>
 	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="hbox9921">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkButton" id="command_apply_button">
-		  <property name="visible">True</property>
-		  <property name="sensitive">False</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-
-		  <child>
-		    <widget class="GtkAlignment" id="alignment55">
-		      <property name="visible">True</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xscale">0</property>
-		      <property name="yscale">0</property>
-		      <property name="top_padding">0</property>
-		      <property name="bottom_padding">0</property>
-		      <property name="left_padding">0</property>
-		      <property name="right_padding">0</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox9922">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">2</property>
-
-			  <child>
-			    <widget class="GtkImage" id="image54">
-			      <property name="visible">True</property>
-			      <property name="stock">gtk-apply</property>
-			      <property name="icon_size">4</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="GtkLabel" id="label485">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Apply Co_mmand Changes</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>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-			</widget>
-		      </child>
-		    </widget>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		  <property name="pack_type">GTK_PACK_END</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<placeholder/>
-	      </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>
--- gdm2/gui/gdmuser.h.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/gui/gdmuser.h	2007-06-29 17:39:00.000000000 +0100
@@ -34,11 +34,18 @@
 };
 
 gboolean    gdm_is_user_valid		(const char *username);
+gboolean    gdm_check_shell             (const gchar *usersh);
 gint        gdm_user_uid                (const char *username);
+gint        gdm_user_sort_func          (gpointer d1, gpointer d2);
 const char *get_root_user               (void);
 void        gdm_users_init              (GList **users, GList **users_string,
 					char *exclude_user, GdkPixbuf *defface,
 					int *size_of_users, gboolean is_local,
 					gboolean read_faces);
-
+GdmUser *   gdm_user_alloc              (const gchar *logname,
+					 uid_t uid,
+					 const gchar *homedir,
+					 const char *gecos,
+					 GdkPixbuf *defface,
+					 gboolean read_faces);
 #endif /* GDM_USER_H */
--- gdm2/gui/gdmlogin.c.org	2007-06-30 19:47:17.000000000 +0100
+++ gdm2/gui/gdmlogin.c	2007-07-01 12:56:28.000000000 +0100
@@ -2125,7 +2125,7 @@
 		"<big><big><big>%s</big></big></big>", welcomemsg);
 
 	greeting = gdm_common_expand_text (fullwelcomemsg);
-	gtk_label_set_markup (GTK_LABEL (welcome), greeting);
+	gtk_label_set_markup (GTK_LABEL (welcome), g_strdup (greeting));
 
 	g_free (fullwelcomemsg);
 	g_free (welcomemsg);
@@ -2989,7 +2989,6 @@
 static gboolean
 gdm_reread_config (int sig, gpointer data)
 {
-	gboolean resize = FALSE;
 	gboolean custom_changed = FALSE;
 	gint i;
 
@@ -3074,20 +3073,24 @@
 		gchar *key_string = NULL;
 		key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_TEMPLATE, i);
 		if(gdm_config_reload_string (key_string))
-			custom_changed = TRUE;
-		
+			custom_changed = TRUE;		
+		g_free (key_string);
+
 		key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_LABEL_TEMPLATE, i);
 		if(gdm_config_reload_string (key_string))
 			custom_changed = TRUE;
+		g_free (key_string);
 		
 		key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_LR_LABEL_TEMPLATE, i);
 		if(gdm_config_reload_string (key_string))
 			custom_changed = TRUE;
+		g_free (key_string);
 		
 		key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_TEXT_TEMPLATE, i);
 		if(gdm_config_reload_string (key_string))
 			custom_changed = TRUE;
-        
+		g_free (key_string);
+
 		key_string = g_strdup_printf ("%s%d=", GDM_KEY_CUSTOM_CMD_TOOLTIP_TEMPLATE, i);
 		if(gdm_config_reload_string (key_string))
 			custom_changed = TRUE;
@@ -3111,76 +3114,39 @@
 	    gdm_config_reload_string (GDM_KEY_BACKGROUND_COLOR) ||
 	    gdm_config_reload_int    (GDM_KEY_BACKGROUND_TYPE) ||
 	    gdm_config_reload_bool   (GDM_KEY_BACKGROUND_SCALE_TO_FIT) ||
-	    gdm_config_reload_bool   (GDM_KEY_BACKGROUND_REMOTE_ONLY_COLOR)) {
+	    gdm_config_reload_bool   (GDM_KEY_BACKGROUND_REMOTE_ONLY_COLOR) ||
+	    gdm_config_reload_string (GDM_KEY_LOGO) ||
+	    gdm_config_reload_string (GDM_KEY_USE_24_CLOCK) ||
+	    gdm_config_reload_string (GDM_KEY_WELCOME) ||
+	    gdm_config_reload_bool   (GDM_KEY_DEFAULT_WELCOME) ||
+	    gdm_config_reload_string (GDM_KEY_REMOTE_WELCOME) ||
+            gdm_config_reload_bool   (GDM_KEY_DEFAULT_REMOTE_WELCOME)) {
+
+		/* This is a HACK at best.
+		   For some reason gdmlogin after config update
+		   without restart does not perfom the update
+		   correctly (its usually accompanied by a random
+		   background colour change even if it wasnt requested) 
+		   and stops responding to the update signals (i.e. HUP)
+		   so quick solution is to restart the greeter.
+		   FIXME: Find the real cause of the problem, and
+		   restart the greeter when it is necessary
+		*/
+		   
+		gdm_common_setup_cursor (GDK_WATCH);
 
+		gdm_wm_save_wm_order ();
 		gdm_kill_thingies ();
-		setup_background ();
-		back_prog_launch_after_timeout ();
+		gdmcomm_comm_bulk_stop ();
+
+		_exit (DISPLAY_RESTARTGREETER);
+		return TRUE;		
 	}	
 
 	gdm_config_reload_string (GDM_KEY_SOUND_PROGRAM);
 	gdm_config_reload_bool   (GDM_KEY_SOUND_ON_LOGIN);
 	gdm_config_reload_string (GDM_KEY_SOUND_ON_LOGIN_FILE);
-	gdm_config_reload_string (GDM_KEY_USE_24_CLOCK);
-	update_clock ();
-
-	if (gdm_config_reload_string (GDM_KEY_LOGO)) {
-		GdkPixbuf *pb;
-		gboolean have_logo = FALSE;
-		gchar *gdmlogo;
-		int lw, lh;
-
-		gdmlogo = gdm_config_get_string (GDM_KEY_LOGO);
-
-		if (gdmlogo != NULL) {
-			pb = gdk_pixbuf_new_from_file (gdmlogo, NULL);
-		} else {
-			pb = NULL;
-		}
-
-		if (pb != NULL) {
-			have_logo = TRUE;
-			gtk_image_set_from_pixbuf (GTK_IMAGE (logo_image), pb);
-			lw = gdk_pixbuf_get_width (pb);
-			lh = gdk_pixbuf_get_height (pb);
-			g_object_unref (G_OBJECT (pb));
-		} else {
-			lw = lh = 100;
-		}
-
-		if (lw > gdm_wm_screen.width / 2)
-			lw = gdm_wm_screen.width / 2;
-		else
-			lw = -1;
-		if (lh > (2 * gdm_wm_screen.height) / 3)
-			lh = (2 * gdm_wm_screen.height) / 3;
-		else
-			lh = -1;
-		if (lw > -1 || lh > -1)
-			gtk_widget_set_size_request (logo_image, lw, lh);
-
-		if (have_logo) {
-			gtk_table_set_col_spacings (GTK_TABLE (table), 10);
-			gtk_widget_show (logo_frame);
-		} else {
-			gtk_table_set_col_spacings (GTK_TABLE (table), 0);
-			gtk_widget_hide (logo_frame);
-		}
-
-		resize = TRUE;
-	}
-
-	if (gdm_config_reload_string (GDM_KEY_WELCOME) ||
-            gdm_config_reload_bool   (GDM_KEY_DEFAULT_WELCOME) ||
-            gdm_config_reload_string (GDM_KEY_REMOTE_WELCOME) ||
-            gdm_config_reload_bool   (GDM_KEY_DEFAULT_REMOTE_WELCOME)) {
-
-		gdm_set_welcomemsg ();
-	}
-
-	if (resize)
-		login_window_resize (TRUE /* force */);
-
+	
 	gdmcomm_comm_bulk_stop ();
 
 	return TRUE;
--- gdm2/gui/gdmuser.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/gui/gdmuser.c	2007-06-29 17:39:00.000000000 +0100
@@ -40,7 +40,7 @@
 
 static time_t time_started;
 
-static GdmUser * 
+GdmUser * 
 gdm_user_alloc (const gchar *logname,
 		uid_t uid,
 		const gchar *homedir,
@@ -204,7 +204,7 @@
 	return FALSE;
 }
 
-static gboolean
+gboolean
 gdm_check_shell (const gchar *usersh)
 {
     gint found = 0;
@@ -221,8 +221,8 @@
     return (found);
 }
 
-static gint
-gdm_sort_func (gpointer d1, gpointer d2)
+gint
+gdm_user_sort_func (gpointer d1, gpointer d2)
 {
     GdmUser *a = d1;
     GdmUser *b = d2;
@@ -261,10 +261,10 @@
 				   defface, read_faces);
 
 	    if ((user) &&
-		(! g_list_find_custom (*users, user, (GCompareFunc) gdm_sort_func))) {
+		(! g_list_find_custom (*users, user, (GCompareFunc) gdm_user_sort_func))) {
 		cnt++;
 		*users = g_list_insert_sorted (*users, user,
-		     (GCompareFunc) gdm_sort_func);
+		     (GCompareFunc) gdm_user_sort_func);
 		*users_string = g_list_prepend (*users_string, g_strdup (pwent->pw_name));
 
 		if (user->picture != NULL) {
--- gdm2/gui/gdmconfig.c.org	2007-06-29 17:39:00.000000000 +0100
+++ gdm2/gui/gdmconfig.c	2007-06-29 17:39:00.000000000 +0100
@@ -341,7 +341,7 @@
 	if ( ! result || ve_string_empty (result) ||
 	    strncmp (result, "OK ", 3) != 0) {
 
-		gchar *getdefault;
+		gchar *getdefault, *p;
 
 		/*
 		 * If looking for a translated string, and not found, just return
@@ -357,12 +357,16 @@
 
 		/* Return the compiled in value associated with the key, if available. */
 		getdefault = strchr (key, '=');
-		if (getdefault != NULL)
-			getdefault++;
-
-		temp = g_strdup (getdefault);
+		p = getdefault;
+		if (p != NULL)
+			p++;
+		
+		temp = g_strdup (p);
 
 		gdm_common_error ("Using compiled in value <%s> for <%s>", temp, key);
+
+		g_free (getdefault);
+
 	} else {
 
 		/* skip the "OK " */
