Index: libgnome-desktop/libgnomeui/gnome-rr-config.h
===================================================================
--- libgnome-desktop/libgnomeui/gnome-rr-config.h	(revision 5225)
+++ libgnome-desktop/libgnomeui/gnome-rr-config.h	(working copy)
@@ -75,5 +75,13 @@
 gboolean        gnome_rr_config_apply_stored (GnomeRRScreen  *screen);
 gboolean        gnome_rr_config_applicable   (GnomeRRConfig  *configuration,
 					      GnomeRRScreen  *screen);
+gboolean        gnome_rr_config_check_desired (GnomeRRConfig *config);
 
+gboolean        gnome_rr_config_save_to_file (GnomeRRConfig *configuration,
+                        GError **err, gchar *filename);
+gboolean        gnome_rr_config_save_desired (GnomeRRConfig *configuration,
+                        GError **err);
+void            remove_desired_settings      (void);
+void            compute_virtual_size_for_configuration (GnomeRRConfig *config,
+                          int *ret_width, int *ret_height);
 #endif
Index: libgnome-desktop/gnome-rr-config.c
===================================================================
--- libgnome-desktop/gnome-rr-config.c	(revision 5225)
+++ libgnome-desktop/gnome-rr-config.c	(working copy)
@@ -32,6 +32,7 @@
 #include "edid.h"
 
 #define CONFIG_BASENAME "monitors.xml"
+#define CONFIG_DESIRED_BASENAME "monitors.xml.desired"
 
 /* In version 0 of the config file format, we had several <configuration> toplevel elements
  * and no explicit version number.  So, the filed looked like
@@ -864,11 +865,61 @@
 }
 
 static gchar *
+get_desired_config_filename (void)
+{
+    return g_build_filename (g_get_user_config_dir (), CONFIG_DESIRED_BASENAME, NULL);
+}
+
+static gchar *
 get_config_filename (void)
 {
     return g_build_filename (g_get_user_config_dir (), CONFIG_BASENAME, NULL);
 }
 
+static GnomeRRConfig **
+desired_configurations_read (GError **error)
+{
+    char *filename;
+    GnomeRRConfig **configs;
+    GError *err;
+
+    /* Try the desired configuration file... */
+
+    filename = get_desired_config_filename ();
+    
+    g_print("desired is = %s\n", filename);
+    
+    err = NULL;
+    
+    g_print("reading configuration...\n");
+    configs = configurations_read_from_file (filename, &err);
+
+    g_free (filename);
+    
+    g_print("done\n");
+    if (err)
+    {
+        if (g_error_matches (err, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+        {
+            
+            g_print("error MATCHES");
+            g_error_free (err);
+            
+            /* Okay, so try the old configuration file */
+            filename = get_config_filename ();
+            configs = configurations_read_from_file (filename, error);
+            g_free (filename);
+        }
+        else
+        {
+            g_print("error does NOT MATCH");
+            g_propagate_error (error, err);
+        }
+    }
+    
+    return configs;
+}
+
 static const char *
 get_rotation_name (GnomeRRRotation r)
 {
@@ -989,14 +1040,13 @@
     }
 }
 
-
 gboolean
-gnome_rr_config_save (GnomeRRConfig *configuration, GError **err)
+gnome_rr_config_save_to_file (GnomeRRConfig *configuration, GError **err, gchar *filename)
 {
     GnomeRRConfig **configurations;
     GString *output = g_string_new("");
     int i;
-    gchar *filename;
+    
     gboolean result;
 
     configurations = configurations_read (NULL); /* NULL-GError */
@@ -1018,7 +1068,7 @@
 
     g_string_append_printf (output, "</monitors>\n");
 
-    filename = get_config_filename ();
+    
     result = g_file_set_contents (filename, output->str, -1, err);
     g_free (filename);
 
@@ -1036,6 +1086,35 @@
     return result;
 }
 
+gboolean
+gnome_rr_config_save (GnomeRRConfig *configuration, GError **err)
+{
+    gchar *filename;
+    filename = get_config_filename ();
+    
+    return(gnome_rr_config_save_to_file(configuration, err, filename));
+}
+
+gboolean
+gnome_rr_config_save_desired (GnomeRRConfig *configuration, GError **err)
+{
+    gchar *filename;
+    filename = get_desired_config_filename ();
+    
+    return(gnome_rr_config_save_to_file(configuration, err, filename));
+}
+
+void remove_desired_settings(void)
+{
+    gchar *filename;
+    filename = get_desired_config_filename ();
+    if (g_file_test (filename, G_FILE_TEST_EXISTS))
+        g_unlink (filename);
+
+    g_free (filename);
+
+}
+
 static gboolean
 apply_configuration (GnomeRRConfig *conf, GnomeRRScreen *screen)
 {
@@ -1062,23 +1141,127 @@
     return FALSE;
 }
 
+void
+compute_virtual_size_for_configuration (GnomeRRConfig *config, int *ret_width, int *ret_height)
+{
+    int i;
+    int width, height;
+
+    width = height = 0;
+
+    for (i = 0; config->outputs[i] != NULL; i++)
+    {
+	GnomeOutputInfo *output;
+
+	output = config->outputs[i];
+
+	if (output->on)
+	{
+	    width = MAX (width, output->x + output->width);
+	    height = MAX (height, output->y + output->height);
+	}
+    }
+
+    *ret_width = width;
+    *ret_height = height;
+}
+
+static gboolean
+check_framebuffer_size (GnomeRRConfig *config, GnomeRRScreen *screen)
+{
+    int req_width, req_height;
+    int min_width, max_width;
+    int min_height, max_height;
+    
+    /* Put the desired configuration 
+     * instead of app->current_configuration
+     */
+    compute_virtual_size_for_configuration (config, &req_width, &req_height);
+    
+    /* Put screen 
+     * instead of app->screen
+     */
+    gnome_rr_screen_get_ranges (screen, &min_width, &max_width, &min_height, &max_height);
+
+#if 0
+    g_print ("X Server supports:\n");
+    g_print ("min_width = %d, max_width = %d\n", min_width, max_width);
+    g_print ("min_height = %d, max_height = %d\n", min_height, max_height);
+
+    g_print ("Requesting size of %dx%d\n", req_width, req_height);
+#endif
+
+    if (!(min_width <= req_width && req_width <= max_width
+	  && min_height <= req_height && req_height <= max_height))
+        return FALSE;
+    else
+        return TRUE;
+}
+
 gboolean
 gnome_rr_config_apply_stored (GnomeRRScreen *screen)
 {
     GnomeRRConfig **configs;
+    GnomeRRConfig **desired_configs;
     GnomeRRConfig *current;
     GnomeRRConfig *found;
+    GnomeRRConfig *desired_found;
     gboolean result = TRUE;
 
     if (!screen)
 	return FALSE;
 
+    /* Look for the desired settings and try to load that
+     * instead.
+     * Then remove such settings.
+     * else read the usual configuration
+     */
+    
+    desired_configs = desired_configurations_read (NULL); /* NULL-GError */
+    
     configs = configurations_read (NULL); /* NULL-GError */
 
     gnome_rr_screen_refresh (screen);
     
     current = gnome_rr_config_new_current (screen);
 
+    if (desired_configs)/* desired settings available */
+    {
+	if ((desired_found = gnome_rr_config_find (desired_configs, current)))
+	{/* desired settings available and applicable */
+	    
+	    /* Check framebuffer size. Do not apply
+	     * the settings if the fb is not big
+	     * enough
+	     */
+	    if (check_framebuffer_size (desired_found, screen))
+	    {
+	        apply_configuration (desired_found, screen);
+            
+            /* result's default value is TRUE therefore
+             * we set it to FALSE here (so that it's
+             * clear that the desired settings were
+             * applied) then, after the next check we
+             * set it to TRUE again. A bit confusing but
+             * there might be a reason behind having
+             * TRUE as result's default value.
+             */
+            result = FALSE;
+            /* Try to save the desired settings to the default
+             * settings file
+             */
+            GError *err = NULL;
+            gnome_rr_config_sanitize (desired_found);
+            gnome_rr_config_save (desired_found, &err);
+        }
+	}
+	
+	configurations_free (desired_configs);
+	remove_desired_settings();
+    }
+    
+    if (result)/* no desired settings */
+    {
     if (configs)
     {
 	if ((found = gnome_rr_config_find (configs, current)))
@@ -1094,13 +1277,15 @@
 	
 	configurations_free (configs);
     }
+    }
+    else/* applied desired settings */
+        result = TRUE;
 	
     gnome_rr_config_free (current);
 
     return result;
 }
 
-
 /*
  * CRTC assignment
  */
