[gnome-desktop] Turn GnomeRRConfig and GnomeOutputInfo into GObjects



commit 139ac9d3510767444e425366594f7e7e6bb5c1f8
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Thu Nov 4 17:17:22 2010 +0100

    Turn GnomeRRConfig and GnomeOutputInfo into GObjects
    
    For easier binding and introspectability, rework GnomeRRConfig and
    GnomeOutputInfo to be GObjects (GInitables, actually) instead of
    boxed types. This commit *does* break API, as previous API just
    accessed fields in the public structs, while now everything has been
    moved to private structures and accessors must be used.
    Also, rework GnomeRRLabeler to use both a public and a private structure,
    so that gobject-introspection can find instance/class sizes.
    Modifications to gnome-control-center and gnome-settings-daemon will
    follow.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=630913

 libgnome-desktop/Makefile.am            |    1 +
 libgnome-desktop/gnome-rr-config.c      |  800 +++++++++++++++---------------
 libgnome-desktop/gnome-rr-config.h      |  182 ++++----
 libgnome-desktop/gnome-rr-labeler.c     |  169 ++++---
 libgnome-desktop/gnome-rr-labeler.h     |   14 +-
 libgnome-desktop/gnome-rr-output-info.c |  246 ++++++++++
 libgnome-desktop/gnome-rr-private.h     |   31 ++
 libgnome-desktop/gnome-rr.c             |   25 +-
 libgnome-desktop/gnome-rr.h             |   20 +-
 9 files changed, 914 insertions(+), 574 deletions(-)
---
diff --git a/libgnome-desktop/Makefile.am b/libgnome-desktop/Makefile.am
index b8c6a39..8d8b74a 100644
--- a/libgnome-desktop/Makefile.am
+++ b/libgnome-desktop/Makefile.am
@@ -22,6 +22,7 @@ introspection_sources = 		\
 	display-name.c			\
 	gnome-rr.c			\
 	gnome-rr-config.c		\
+	gnome-rr-output-info.c		\
 	gnome-rr-labeler.c		\
 	edid-parse.c
 
diff --git a/libgnome-desktop/gnome-rr-config.c b/libgnome-desktop/gnome-rr-config.c
index 2a8a84f..25b0545 100644
--- a/libgnome-desktop/gnome-rr-config.c
+++ b/libgnome-desktop/gnome-rr-config.c
@@ -1,6 +1,8 @@
 /* gnome-rr-config.c
+ * -*- c-basic-offset: 4 -*-
  *
  * Copyright 2007, 2008, Red Hat, Inc.
+ * Copyright 2010 Giovanni Campagna
  * 
  * This file is part of the Gnome Library.
  * 
@@ -34,7 +36,6 @@
 #include <X11/Xlib.h>
 #include <gdk/gdkx.h>
 
-#undef GNOME_DISABLE_DEPRECATED
 #include "gnome-rr-config.h"
 
 #include "edid.h"
@@ -79,16 +80,21 @@ typedef struct CrtcAssignment CrtcAssignment;
 static gboolean         crtc_assignment_apply (CrtcAssignment   *assign,
 					       guint32           timestamp,
 					       GError          **error);
-static CrtcAssignment  *crtc_assignment_new   (GnomeRRScreen    *screen,
-					       GnomeOutputInfo **outputs,
-					       GError          **error);
+static CrtcAssignment  *crtc_assignment_new   (GnomeRRScreen      *screen,
+					       GnomeRROutputInfo **outputs,
+					       GError            **error);
 static void             crtc_assignment_free  (CrtcAssignment   *assign);
-static void             output_free           (GnomeOutputInfo  *output);
-static GnomeOutputInfo *output_copy           (const GnomeOutputInfo  *output);
-static GnomeRRConfig *  gnome_rr_config_copy (const GnomeRRConfig *config);
 
-G_DEFINE_BOXED_TYPE (GnomeOutputInfo, gnome_rr_output_info, output_copy, output_free)
-G_DEFINE_BOXED_TYPE (GnomeRRConfig, gnome_rr_config, gnome_rr_config_copy, gnome_rr_config_free)
+enum {
+  PROP_0,
+  PROP_CURRENT,
+  PROP_SCREEN,
+  PROP_LAST
+};
+
+static void gnome_rr_config_initable_iface_init (GInitableIface *iface);
+G_DEFINE_TYPE_WITH_CODE (GnomeRRConfig, gnome_rr_config, G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gnome_rr_config_initable_iface_init))
 
 typedef struct Parser Parser;
 
@@ -96,7 +102,7 @@ typedef struct Parser Parser;
 struct Parser
 {
     int			config_file_version;
-    GnomeOutputInfo *	output;
+    GnomeRROutputInfo *	output;
     GnomeRRConfig *	configuration;
     GPtrArray *		outputs;
     GPtrArray *		configurations;
@@ -171,38 +177,38 @@ handle_start_element (GMarkupParseContext *context,
 	int i;
 	g_assert (parser->output == NULL);
 
-	parser->output = g_new0 (GnomeOutputInfo, 1);
-	parser->output->rotation = 0;
+	parser->output = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL);
+	parser->output->priv->rotation = 0;
 	
 	for (i = 0; attr_names[i] != NULL; ++i)
 	{
 	    if (strcmp (attr_names[i], "name") == 0)
 	    {
-		parser->output->name = g_strdup (attr_values[i]);
+		parser->output->priv->name = g_strdup (attr_values[i]);
 		break;
 	    }
 	}
 
-	if (!parser->output->name)
+	if (!parser->output->priv->name)
 	{
 	    /* This really shouldn't happen, but it's better to make
 	     * something up than to crash later.
 	     */
 	    g_warning ("Malformed monitor configuration file");
 	    
-	    parser->output->name = g_strdup ("default");
+	    parser->output->priv->name = g_strdup ("default");
 	}	
-	parser->output->connected = FALSE;
-	parser->output->on = FALSE;
-	parser->output->primary = FALSE;
+	parser->output->priv->connected = FALSE;
+	parser->output->priv->on = FALSE;
+	parser->output->priv->primary = FALSE;
     }
     else if (strcmp (name, "configuration") == 0)
     {
 	g_assert (parser->configuration == NULL);
 	
-	parser->configuration = g_new0 (GnomeRRConfig, 1);
-	parser->configuration->clone = FALSE;
-	parser->configuration->outputs = NULL;
+	parser->configuration = g_object_new (GNOME_TYPE_RR_CONFIG, NULL);
+	parser->configuration->priv->clone = FALSE;
+	parser->configuration->priv->outputs = NULL;
     }
     else if (strcmp (name, "monitors") == 0)
     {
@@ -232,8 +238,8 @@ handle_end_element (GMarkupParseContext *context,
     if (strcmp (name, "output") == 0)
     {
 	/* If no rotation properties were set, just use GNOME_RR_ROTATION_0 */
-	if (parser->output->rotation == 0)
-	    parser->output->rotation = GNOME_RR_ROTATION_0;
+	if (parser->output->priv->rotation == 0)
+	    parser->output->priv->rotation = GNOME_RR_ROTATION_0;
 	
 	g_ptr_array_add (parser->outputs, parser->output);
 
@@ -242,8 +248,8 @@ handle_end_element (GMarkupParseContext *context,
     else if (strcmp (name, "configuration") == 0)
     {
 	g_ptr_array_add (parser->outputs, NULL);
-	parser->configuration->outputs =
-	    (GnomeOutputInfo **)g_ptr_array_free (parser->outputs, FALSE);
+	parser->configuration->priv->outputs =
+	    (GnomeRROutputInfo **)g_ptr_array_free (parser->outputs, FALSE);
 	parser->outputs = g_ptr_array_new ();
 	g_ptr_array_add (parser->configurations, parser->configuration);
 	parser->configuration = NULL;
@@ -265,96 +271,96 @@ handle_text (GMarkupParseContext *context,
     
     if (stack_is (parser, "vendor", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->connected = TRUE;
+	parser->output->priv->connected = TRUE;
 	
-	strncpy (parser->output->vendor, text, 3);
-	parser->output->vendor[3] = 0;
+	strncpy ((gchar*) parser->output->priv->vendor, text, 3);
+	parser->output->priv->vendor[3] = 0;
     }
     else if (stack_is (parser, "clone", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
 	if (strcmp (text, "yes") == 0)
-	    parser->configuration->clone = TRUE;
+	    parser->configuration->priv->clone = TRUE;
     }
     else if (stack_is (parser, "product", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->connected = TRUE;
+	parser->output->priv->connected = TRUE;
 
-	parser->output->product = parse_int (text);
+	parser->output->priv->product = parse_int (text);
     }
     else if (stack_is (parser, "serial", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->connected = TRUE;
+	parser->output->priv->connected = TRUE;
 
-	parser->output->serial = parse_uint (text);
+	parser->output->priv->serial = parse_uint (text);
     }
     else if (stack_is (parser, "width", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->on = TRUE;
+	parser->output->priv->on = TRUE;
 
-	parser->output->width = parse_int (text);
+	parser->output->priv->width = parse_int (text);
     }
     else if (stack_is (parser, "x", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->on = TRUE;
+	parser->output->priv->on = TRUE;
 
-	parser->output->x = parse_int (text);
+	parser->output->priv->x = parse_int (text);
     }
     else if (stack_is (parser, "y", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->on = TRUE;
+	parser->output->priv->on = TRUE;
 
-	parser->output->y = parse_int (text);
+	parser->output->priv->y = parse_int (text);
     }
     else if (stack_is (parser, "height", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->on = TRUE;
+	parser->output->priv->on = TRUE;
 
-	parser->output->height = parse_int (text);
+	parser->output->priv->height = parse_int (text);
     }
     else if (stack_is (parser, "rate", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
-	parser->output->on = TRUE;
+	parser->output->priv->on = TRUE;
 
-	parser->output->rate = parse_int (text);
+	parser->output->priv->rate = parse_int (text);
     }
     else if (stack_is (parser, "rotation", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
 	if (strcmp (text, "normal") == 0)
 	{
-	    parser->output->rotation |= GNOME_RR_ROTATION_0;
+	    parser->output->priv->rotation |= GNOME_RR_ROTATION_0;
 	}
 	else if (strcmp (text, "left") == 0)
 	{
-	    parser->output->rotation |= GNOME_RR_ROTATION_90;
+	    parser->output->priv->rotation |= GNOME_RR_ROTATION_90;
 	}
 	else if (strcmp (text, "upside_down") == 0)
 	{
-	    parser->output->rotation |= GNOME_RR_ROTATION_180;
+	    parser->output->priv->rotation |= GNOME_RR_ROTATION_180;
 	}
 	else if (strcmp (text, "right") == 0)
 	{
-	    parser->output->rotation |= GNOME_RR_ROTATION_270;
+	    parser->output->priv->rotation |= GNOME_RR_ROTATION_270;
 	}
     }
     else if (stack_is (parser, "reflect_x", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
 	if (strcmp (text, "yes") == 0)
 	{
-	    parser->output->rotation |= GNOME_RR_REFLECT_X;
+	    parser->output->priv->rotation |= GNOME_RR_REFLECT_X;
 	}
     }
     else if (stack_is (parser, "reflect_y", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
 	if (strcmp (text, "yes") == 0)
 	{
-	    parser->output->rotation |= GNOME_RR_REFLECT_Y;
+	    parser->output->priv->rotation |= GNOME_RR_REFLECT_Y;
 	}
     }
     else if (stack_is (parser, "primary", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
     {
 	if (strcmp (text, "yes") == 0)
 	{
-	    parser->output->primary = TRUE;
+	    parser->output->priv->primary = TRUE;
 	}
     }
     else
@@ -372,16 +378,16 @@ parser_free (Parser *parser)
     g_assert (parser != NULL);
 
     if (parser->output)
-	output_free (parser->output);
+	g_object_unref (parser->output);
 
     if (parser->configuration)
-	gnome_rr_config_free (parser->configuration);
+	g_object_unref (parser->configuration);
 
     for (i = 0; i < parser->outputs->len; ++i)
     {
-	GnomeOutputInfo *output = parser->outputs->pdata[i];
+	GnomeRROutputInfo *output = parser->outputs->pdata[i];
 
-	output_free (output);
+	g_object_unref (output);
     }
 
     g_ptr_array_free (parser->outputs, TRUE);
@@ -390,7 +396,7 @@ parser_free (Parser *parser)
     {
 	GnomeRRConfig *config = parser->configurations->pdata[i];
 
-	gnome_rr_config_free (config);
+	g_object_unref (config);
     }
 
     g_ptr_array_free (parser->configurations, TRUE);
@@ -441,10 +447,58 @@ out:
     return result;
 }
 
-GnomeRRConfig *
-gnome_rr_config_new_current (GnomeRRScreen *screen)
+static void
+gnome_rr_config_init (GnomeRRConfig *self)
+{
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_CONFIG, GnomeRRConfigPrivate);
+
+    self->priv->current = FALSE;
+    self->priv->clone = FALSE;
+    self->priv->screen = NULL;
+    self->priv->outputs = NULL;
+}
+
+static void
+gnome_rr_config_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *property)
+{
+    GnomeRRConfig *self = GNOME_RR_CONFIG (gobject);
+
+    switch (property_id) {
+	case PROP_CURRENT:
+	    self->priv->current = g_value_get_boolean (value);
+	    return;
+	case PROP_SCREEN:
+	    self->priv->screen = g_value_dup_object (value);
+	    return;
+	default:
+	    G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property);
+    }
+}
+
+static void
+gnome_rr_config_finalize (GObject *gobject)
+{
+    GnomeRRConfig *self = GNOME_RR_CONFIG (gobject);
+
+    if (self->priv->screen)
+	g_object_unref (self->priv->screen);
+
+    if (self->priv->outputs) {
+	int i;
+
+        for (i = 0; self->priv->outputs[i] != NULL; i++) {
+	    GnomeRROutputInfo *output = self->priv->outputs[i];
+	    g_object_unref (output);
+	}
+	g_free (self->priv->outputs);
+    }
+
+    G_OBJECT_CLASS (gnome_rr_config_parent_class)->finalize (gobject);
+}
+
+static gboolean
+config_init_current (GnomeRRConfig *config)
 {
-    GnomeRRConfig *config = g_new0 (GnomeRRConfig, 1);
     GPtrArray *a = g_ptr_array_new ();
     GnomeRROutput **rr_outputs;
     int i;
@@ -452,31 +506,29 @@ gnome_rr_config_new_current (GnomeRRScreen *screen)
     int clone_height = -1;
     int last_x;
 
-    g_return_val_if_fail (screen != NULL, NULL);
+    rr_outputs = gnome_rr_screen_list_outputs (config->priv->screen);
 
-    rr_outputs = gnome_rr_screen_list_outputs (screen);
-
-    config->clone = FALSE;
+    config->priv->clone = FALSE;
     
     for (i = 0; rr_outputs[i] != NULL; ++i)
     {
 	GnomeRROutput *rr_output = rr_outputs[i];
-	GnomeOutputInfo *output = g_new0 (GnomeOutputInfo, 1);
+	GnomeRROutputInfo *output = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL);
 	GnomeRRMode *mode = NULL;
 	const guint8 *edid_data = gnome_rr_output_get_edid_data (rr_output);
 	GnomeRRCrtc *crtc;
 
-	output->name = g_strdup (gnome_rr_output_get_name (rr_output));
-	output->connected = gnome_rr_output_is_connected (rr_output);
+	output->priv->name = g_strdup (gnome_rr_output_get_name (rr_output));
+	output->priv->connected = gnome_rr_output_is_connected (rr_output);
 
-	if (!output->connected)
+	if (!output->priv->connected)
 	{
-	    output->x = -1;
-	    output->y = -1;
-	    output->width = -1;
-	    output->height = -1;
-	    output->rate = -1;
-	    output->rotation = GNOME_RR_ROTATION_0;
+	    output->priv->x = -1;
+	    output->priv->y = -1;
+	    output->priv->width = -1;
+	    output->priv->height = -1;
+	    output->priv->rate = -1;
+	    output->priv->rotation = GNOME_RR_ROTATION_0;
 	}
 	else
 	{
@@ -487,24 +539,24 @@ gnome_rr_config_new_current (GnomeRRScreen *screen)
 
 	    if (info)
 	    {
-		memcpy (output->vendor, info->manufacturer_code,
-			sizeof (output->vendor));
+		memcpy (output->priv->vendor, info->manufacturer_code,
+			sizeof (output->priv->vendor));
 		
-		output->product = info->product_code;
-		output->serial = info->serial_number;
-		output->aspect = info->aspect_ratio;
+		output->priv->product = info->product_code;
+		output->priv->serial = info->serial_number;
+		output->priv->aspect = info->aspect_ratio;
 	    }
 	    else
 	    {
-		strcpy (output->vendor, "???");
-		output->product = 0;
-		output->serial = 0;
+		strcpy (output->priv->vendor, "???");
+		output->priv->product = 0;
+		output->priv->serial = 0;
 	    }
 
 	    if (gnome_rr_output_is_laptop (rr_output))
-		output->display_name = g_strdup (_("Laptop"));
+		output->priv->display_name = g_strdup (_("Laptop"));
 	    else
-		output->display_name = make_display_name (info);
+		output->priv->display_name = make_display_name (info);
 		
 	    g_free (info);
 		
@@ -513,28 +565,28 @@ gnome_rr_config_new_current (GnomeRRScreen *screen)
 	    
 	    if (crtc && mode)
 	    {
-		output->on = TRUE;
+		output->priv->on = TRUE;
 		
-		gnome_rr_crtc_get_position (crtc, &output->x, &output->y);
-		output->width = gnome_rr_mode_get_width (mode);
-		output->height = gnome_rr_mode_get_height (mode);
-		output->rate = gnome_rr_mode_get_freq (mode);
-		output->rotation = gnome_rr_crtc_get_current_rotation (crtc);
+		gnome_rr_crtc_get_position (crtc, &output->priv->x, &output->priv->y);
+		output->priv->width = gnome_rr_mode_get_width (mode);
+		output->priv->height = gnome_rr_mode_get_height (mode);
+		output->priv->rate = gnome_rr_mode_get_freq (mode);
+		output->priv->rotation = gnome_rr_crtc_get_current_rotation (crtc);
 
-		if (output->x == 0 && output->y == 0) {
+		if (output->priv->x == 0 && output->priv->y == 0) {
 			if (clone_width == -1) {
-				clone_width = output->width;
-				clone_height = output->height;
-			} else if (clone_width == output->width &&
-				   clone_height == output->height) {
-				config->clone = TRUE;
+				clone_width = output->priv->width;
+				clone_height = output->priv->height;
+			} else if (clone_width == output->priv->width &&
+				   clone_height == output->priv->height) {
+				config->priv->clone = TRUE;
 			}
 		}
 	    }
 	    else
 	    {
-		output->on = FALSE;
-		config->clone = FALSE;
+		output->priv->on = FALSE;
+		config->priv->clone = FALSE;
 	    }
 
 	    /* Get preferred size for the monitor */
@@ -560,117 +612,160 @@ gnome_rr_config_new_current (GnomeRRScreen *screen)
 	    
 	    if (mode)
 	    {
-		output->pref_width = gnome_rr_mode_get_width (mode);
-		output->pref_height = gnome_rr_mode_get_height (mode);
+		output->priv->pref_width = gnome_rr_mode_get_width (mode);
+		output->priv->pref_height = gnome_rr_mode_get_height (mode);
 	    }
 	    else
 	    {
 		/* Pick some random numbers. This should basically never happen */
-		output->pref_width = 1024;
-		output->pref_height = 768;
+		output->priv->pref_width = 1024;
+		output->priv->pref_height = 768;
 	    }
 	}
 
-        output->primary = gnome_rr_output_get_is_primary (rr_output);
+        output->priv->primary = gnome_rr_output_get_is_primary (rr_output);
  
 	g_ptr_array_add (a, output);
     }
 
     g_ptr_array_add (a, NULL);
     
-    config->outputs = (GnomeOutputInfo **)g_ptr_array_free (a, FALSE);
+    config->priv->outputs = (GnomeRROutputInfo **)g_ptr_array_free (a, FALSE);
 
     /* Walk the outputs computing the right-most edge of all
      * lit-up displays
      */
     last_x = 0;
-    for (i = 0; config->outputs[i] != NULL; ++i)
+    for (i = 0; config->priv->outputs[i] != NULL; ++i)
     {
-	GnomeOutputInfo *output = config->outputs[i];
+	GnomeRROutputInfo *output = config->priv->outputs[i];
 
-	if (output->on)
+	if (output->priv->on)
 	{
-	    last_x = MAX (last_x, output->x + output->width);
+	    last_x = MAX (last_x, output->priv->x + output->priv->width);
 	}
     }
 
     /* Now position all off displays to the right of the
      * on displays
      */
-    for (i = 0; config->outputs[i] != NULL; ++i)
+    for (i = 0; config->priv->outputs[i] != NULL; ++i)
     {
-	GnomeOutputInfo *output = config->outputs[i];
+	GnomeRROutputInfo *output = config->priv->outputs[i];
 
-	if (output->connected && !output->on)
+	if (output->priv->connected && !output->priv->on)
 	{
-	    output->x = last_x;
-	    last_x = output->x + output->width;
+	    output->priv->x = last_x;
+	    last_x = output->priv->x + output->priv->width;
 	}
     }
     
     g_assert (gnome_rr_config_match (config, config));
-    
-    return config;
+
+    return TRUE;
 }
 
-static void
-output_free (GnomeOutputInfo *output)
+static gboolean
+config_init_stored (GnomeRRConfig *result, const char *filename, GError **error)
 {
-    if (output->display_name)
-	g_free (output->display_name);
+    GnomeRRConfig *current;
+    GnomeRRConfig **configs;
+    gboolean found = FALSE;
 
-    if (output->name)
-	g_free (output->name);
-    
-    g_free (output);
-}
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-static GnomeOutputInfo *
-output_copy (const GnomeOutputInfo *output)
-{
-    GnomeOutputInfo *copy = g_new0 (GnomeOutputInfo, 1);
+    current = gnome_rr_config_new_current (result->priv->screen, error);
+
+    configs = configurations_read_from_file (filename, error);
+
+    if (configs)
+    {
+	int i;
+
+	for (i = 0; configs[i] != NULL; ++i)
+	{
+	    if (gnome_rr_config_match (configs[i], current))
+	    {
+		int j;
+		GPtrArray *array;
+		result->priv->clone = configs[i]->priv->clone;
+
+		array = g_ptr_array_new ();
+		for (j = 0; configs[i]->priv->outputs[j] != NULL; j++) {
+		    g_ptr_array_add (array, configs[i]->priv->outputs[i]);
+		}
+		g_ptr_array_add (array, NULL);
+		result->priv->outputs = (GnomeRROutputInfo **) g_ptr_array_free (array, FALSE);
 
-    *copy = *output;
+		found = TRUE;
+		break;
+	    }
+	    g_object_unref (configs[i]);
+	}
+	g_free (configs);
 
-    copy->name = g_strdup (output->name);
-    copy->display_name = g_strdup (output->display_name);
+	if (!found)
+	    g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG,
+			 _("none of the saved display configurations matched the active configuration"));
+    }
 
-    return copy;
+    g_object_unref (current);
+    return found;
 }
 
-static void
-outputs_free (GnomeOutputInfo **outputs)
+static gboolean
+gnome_rr_config_initable_init (GInitable* initable, GCancellable* cancellable, GError** error)
 {
-    int i;
+    GnomeRRConfig *self = GNOME_RR_CONFIG (initable);
 
-    g_assert (outputs != NULL);
+    if (self->priv->current) {
+	return config_init_current (self);
+    } else {
+	gchar *filename;
+	gboolean retval;
 
-    for (i = 0; outputs[i] != NULL; ++i)
-	output_free (outputs[i]);
+	filename = gnome_rr_config_get_intended_filename ();
+	retval = config_init_stored (self, filename, error);
 
-    g_free (outputs);
+	g_free (filename);
+	return retval;
+    }
 }
 
-void
-gnome_rr_config_free (GnomeRRConfig *config)
+static void
+gnome_rr_config_initable_iface_init (GInitableIface *iface)
 {
-    g_return_if_fail (config != NULL);
-    outputs_free (config->outputs);
-    
-    g_free (config);
+    iface->init = gnome_rr_config_initable_init;
 }
 
 static void
-configurations_free (GnomeRRConfig **configurations)
+gnome_rr_config_class_init (GnomeRRConfigClass *klass)
 {
-    int i;
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
-    g_assert (configurations != NULL);
+    g_type_class_add_private (klass, sizeof (GnomeRROutputInfoPrivate));
 
-    for (i = 0; configurations[i] != NULL; ++i)
-	gnome_rr_config_free (configurations[i]);
+    gobject_class->set_property = gnome_rr_config_set_property;
+    gobject_class->finalize = gnome_rr_config_finalize;
 
-    g_free (configurations);
+    g_object_class_install_property (gobject_class, PROP_CURRENT,
+				     g_param_spec_boolean ("current", "Current", "If this is current screen configuration", FALSE,
+							   G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+    g_object_class_install_property (gobject_class, PROP_SCREEN,
+				     g_param_spec_object ("screen", "Screen", "The GnomeRRScreen this config applies to", GNOME_TYPE_RR_SCREEN,
+							  G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
+}
+
+GnomeRRConfig *
+gnome_rr_config_new_current (GnomeRRScreen *screen, GError **error)
+{
+    return g_initable_new (GNOME_TYPE_RR_CONFIG, NULL, error, "screen", screen, "current", TRUE, NULL);
+}
+
+GnomeRRConfig *
+gnome_rr_config_new_stored (GnomeRRScreen *screen, GError **error)
+{
+    return g_initable_new (GNOME_TYPE_RR_CONFIG, NULL, error, "screen", screen, "current", FALSE, NULL);
 }
 
 static gboolean
@@ -715,75 +810,75 @@ out:
 }
 
 static gboolean
-output_match (GnomeOutputInfo *output1, GnomeOutputInfo *output2)
+output_match (GnomeRROutputInfo *output1, GnomeRROutputInfo *output2)
 {
-    g_assert (output1 != NULL);
-    g_assert (output2 != NULL);
+    g_assert (GNOME_IS_RR_OUTPUT_INFO (output1));
+    g_assert (GNOME_IS_RR_OUTPUT_INFO (output2));
 
-    if (strcmp (output1->name, output2->name) != 0)
+    if (strcmp (output1->priv->name, output2->priv->name) != 0)
 	return FALSE;
 
-    if (strcmp (output1->vendor, output2->vendor) != 0)
+    if (strcmp (output1->priv->vendor, output2->priv->vendor) != 0)
 	return FALSE;
 
-    if (output1->product != output2->product)
+    if (output1->priv->product != output2->priv->product)
 	return FALSE;
 
-    if (output1->serial != output2->serial)
+    if (output1->priv->serial != output2->priv->serial)
 	return FALSE;
 
-    if (output1->connected != output2->connected)
+    if (output1->priv->connected != output2->priv->connected)
 	return FALSE;
     
     return TRUE;
 }
 
 static gboolean
-output_equal (GnomeOutputInfo *output1, GnomeOutputInfo *output2)
+output_equal (GnomeRROutputInfo *output1, GnomeRROutputInfo *output2)
 {
-    g_assert (output1 != NULL);
-    g_assert (output2 != NULL);
+    g_assert (GNOME_IS_RR_OUTPUT_INFO (output1));
+    g_assert (GNOME_IS_RR_OUTPUT_INFO (output2));
 
     if (!output_match (output1, output2))
 	return FALSE;
 
-    if (output1->on != output2->on)
+    if (output1->priv->on != output2->priv->on)
 	return FALSE;
 
-    if (output1->on)
+    if (output1->priv->on)
     {
-	if (output1->width != output2->width)
+	if (output1->priv->width != output2->priv->width)
 	    return FALSE;
 	
-	if (output1->height != output2->height)
+	if (output1->priv->height != output2->priv->height)
 	    return FALSE;
 	
-	if (output1->rate != output2->rate)
+	if (output1->priv->rate != output2->priv->rate)
 	    return FALSE;
 	
-	if (output1->x != output2->x)
+	if (output1->priv->x != output2->priv->x)
 	    return FALSE;
 	
-	if (output1->y != output2->y)
+	if (output1->priv->y != output2->priv->y)
 	    return FALSE;
 	
-	if (output1->rotation != output2->rotation)
+	if (output1->priv->rotation != output2->priv->rotation)
 	    return FALSE;
     }
 
     return TRUE;
 }
 
-static GnomeOutputInfo *
+static GnomeRROutputInfo *
 find_output (GnomeRRConfig *config, const char *name)
 {
     int i;
 
-    for (i = 0; config->outputs[i] != NULL; ++i)
+    for (i = 0; config->priv->outputs[i] != NULL; ++i)
     {
-	GnomeOutputInfo *output = config->outputs[i];
+	GnomeRROutputInfo *output = config->priv->outputs[i];
 	
-	if (strcmp (name, output->name) == 0)
+	if (strcmp (name, output->priv->name) == 0)
 	    return output;
     }
 
@@ -797,13 +892,15 @@ gboolean
 gnome_rr_config_match (GnomeRRConfig *c1, GnomeRRConfig *c2)
 {
     int i;
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (c1), FALSE);
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (c2), FALSE);
 
-    for (i = 0; c1->outputs[i] != NULL; ++i)
+    for (i = 0; c1->priv->outputs[i] != NULL; ++i)
     {
-	GnomeOutputInfo *output1 = c1->outputs[i];
-	GnomeOutputInfo *output2;
+	GnomeRROutputInfo *output1 = c1->priv->outputs[i];
+	GnomeRROutputInfo *output2;
 
-	output2 = find_output (c2, output1->name);
+	output2 = find_output (c2, output1->priv->name);
 	if (!output2 || !output_match (output1, output2))
 	    return FALSE;
     }
@@ -819,13 +916,15 @@ gnome_rr_config_equal (GnomeRRConfig  *c1,
 		       GnomeRRConfig  *c2)
 {
     int i;
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (c1), FALSE);
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (c2), FALSE);
 
-    for (i = 0; c1->outputs[i] != NULL; ++i)
+    for (i = 0; c1->priv->outputs[i] != NULL; ++i)
     {
-	GnomeOutputInfo *output1 = c1->outputs[i];
-	GnomeOutputInfo *output2;
+	GnomeRROutputInfo *output1 = c1->priv->outputs[i];
+	GnomeRROutputInfo *output2;
 
-	output2 = find_output (c2, output1->name);
+	output2 = find_output (c2, output1->priv->name);
 	if (!output2 || !output_equal (output1, output2))
 	    return FALSE;
     }
@@ -833,34 +932,39 @@ gnome_rr_config_equal (GnomeRRConfig  *c1,
     return TRUE;
 }
 
-static GnomeOutputInfo **
+static GnomeRROutputInfo **
 make_outputs (GnomeRRConfig *config)
 {
     GPtrArray *outputs;
-    GnomeOutputInfo *first_on;
+    GnomeRROutputInfo *first_on;
     int i;
 
     outputs = g_ptr_array_new ();
 
     first_on = NULL;
     
-    for (i = 0; config->outputs[i] != NULL; ++i)
+    for (i = 0; config->priv->outputs[i] != NULL; ++i)
     {
-	GnomeOutputInfo *old = config->outputs[i];
-	GnomeOutputInfo *new = output_copy (old);
-
-	if (old->on && !first_on)
+	GnomeRROutputInfo *old = config->priv->outputs[i];
+	GnomeRROutputInfo *new = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL);
+	*(new->priv) = *(old->priv);
+	if (old->priv->name)
+	    new->priv->name = g_strdup (old->priv->name);
+	if (old->priv->display_name)
+	    new->priv->display_name = g_strdup (old->priv->display_name);
+
+	if (old->priv->on && !first_on)
 	    first_on = old;
 	
-	if (config->clone && new->on)
+	if (config->priv->clone && new->priv->on)
 	{
 	    g_assert (first_on);
 
-	    new->width = first_on->width;
-	    new->height = first_on->height;
-	    new->rotation = first_on->rotation;
-	    new->x = 0;
-	    new->y = 0;
+	    new->priv->width = first_on->priv->width;
+	    new->priv->height = first_on->priv->height;
+	    new->priv->rotation = first_on->priv->rotation;
+	    new->priv->x = 0;
+	    new->priv->y = 0;
 	}
 
 	g_ptr_array_add (outputs, new);
@@ -868,7 +972,7 @@ make_outputs (GnomeRRConfig *config)
 
     g_ptr_array_add (outputs, NULL);
 
-    return (GnomeOutputInfo **)g_ptr_array_free (outputs, FALSE);
+    return (GnomeRROutputInfo **)g_ptr_array_free (outputs, FALSE);
 }
 
 gboolean
@@ -876,11 +980,13 @@ gnome_rr_config_applicable (GnomeRRConfig  *configuration,
 			    GnomeRRScreen  *screen,
 			    GError        **error)
 {
-    GnomeOutputInfo **outputs;
+    GnomeRROutputInfo **outputs;
     CrtcAssignment *assign;
     gboolean result;
+    int i;
 
-    g_return_val_if_fail (configuration != NULL, FALSE);
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (configuration), FALSE);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), FALSE);
     g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
     outputs = make_outputs (configuration);
@@ -896,7 +1002,9 @@ gnome_rr_config_applicable (GnomeRRConfig  *configuration,
 	result = FALSE;
     }
 
-    outputs_free (outputs);
+    for (i = 0; outputs[i] != NULL; i++) {
+	 g_object_unref (outputs[i]);
+    }
 
     return result;
 }
@@ -964,46 +1072,46 @@ emit_configuration (GnomeRRConfig *config,
 
     g_string_append_printf (string, "  <configuration>\n");
 
-    g_string_append_printf (string, "      <clone>%s</clone>\n", yes_no (config->clone));
+    g_string_append_printf (string, "      <clone>%s</clone>\n", yes_no (config->priv->clone));
     
-    for (j = 0; config->outputs[j] != NULL; ++j)
+    for (j = 0; config->priv->outputs[j] != NULL; ++j)
     {
-	GnomeOutputInfo *output = config->outputs[j];
+	GnomeRROutputInfo *output = config->priv->outputs[j];
 	
 	g_string_append_printf (
-	    string, "      <output name=\"%s\">\n", output->name);
+	    string, "      <output name=\"%s\">\n", output->priv->name);
 	
-	if (output->connected && *output->vendor != '\0')
+	if (output->priv->connected && *output->priv->vendor != '\0')
 	{
 	    g_string_append_printf (
-		string, "          <vendor>%s</vendor>\n", output->vendor);
+		string, "          <vendor>%s</vendor>\n", output->priv->vendor);
 	    g_string_append_printf (
-		string, "          <product>0x%04x</product>\n", output->product);
+		string, "          <product>0x%04x</product>\n", output->priv->product);
 	    g_string_append_printf (
-		string, "          <serial>0x%08x</serial>\n", output->serial);
+		string, "          <serial>0x%08x</serial>\n", output->priv->serial);
 	}
 	
 	/* An unconnected output which is on does not make sense */
-	if (output->connected && output->on)
+	if (output->priv->connected && output->priv->on)
 	{
 	    g_string_append_printf (
-		string, "          <width>%d</width>\n", output->width);
+		string, "          <width>%d</width>\n", output->priv->width);
 	    g_string_append_printf (
-		string, "          <height>%d</height>\n", output->height);
+		string, "          <height>%d</height>\n", output->priv->height);
 	    g_string_append_printf (
-		string, "          <rate>%d</rate>\n", output->rate);
+		string, "          <rate>%d</rate>\n", output->priv->rate);
 	    g_string_append_printf (
-		string, "          <x>%d</x>\n", output->x);
+		string, "          <x>%d</x>\n", output->priv->x);
 	    g_string_append_printf (
-		string, "          <y>%d</y>\n", output->y);
+		string, "          <y>%d</y>\n", output->priv->y);
 	    g_string_append_printf (
-		string, "          <rotation>%s</rotation>\n", get_rotation_name (output->rotation));
+		string, "          <rotation>%s</rotation>\n", get_rotation_name (output->priv->rotation));
 	    g_string_append_printf (
-		string, "          <reflect_x>%s</reflect_x>\n", get_reflect_x (output->rotation));
+		string, "          <reflect_x>%s</reflect_x>\n", get_reflect_x (output->priv->rotation));
 	    g_string_append_printf (
-		string, "          <reflect_y>%s</reflect_y>\n", get_reflect_y (output->rotation));
+		string, "          <reflect_y>%s</reflect_y>\n", get_reflect_y (output->priv->rotation));
             g_string_append_printf (
-                string, "          <primary>%s</primary>\n", yes_no (output->primary));
+                string, "          <primary>%s</primary>\n", yes_no (output->priv->primary));
 	}
 	
 	g_string_append_printf (string, "      </output>\n");
@@ -1023,37 +1131,37 @@ gnome_rr_config_sanitize (GnomeRRConfig *config)
      * make sure the configuration starts at (0, 0)
      */
     x_offset = y_offset = G_MAXINT;
-    for (i = 0; config->outputs[i]; ++i)
+    for (i = 0; config->priv->outputs[i]; ++i)
     {
-	GnomeOutputInfo *output = config->outputs[i];
+	GnomeRROutputInfo *output = config->priv->outputs[i];
 
-	if (output->on)
+	if (output->priv->on)
 	{
-	    x_offset = MIN (x_offset, output->x);
-	    y_offset = MIN (y_offset, output->y);
+	    x_offset = MIN (x_offset, output->priv->x);
+	    y_offset = MIN (y_offset, output->priv->y);
 	}
     }
 
-    for (i = 0; config->outputs[i]; ++i)
+    for (i = 0; config->priv->outputs[i]; ++i)
     {
-	GnomeOutputInfo *output = config->outputs[i];
+	GnomeRROutputInfo *output = config->priv->outputs[i];
 	
-	if (output->on)
+	if (output->priv->on)
 	{
-	    output->x -= x_offset;
-	    output->y -= y_offset;
+	    output->priv->x -= x_offset;
+	    output->priv->y -= y_offset;
 	}
     }
 
     /* Only one primary, please */
     found = FALSE;
-    for (i = 0; config->outputs[i]; ++i)
+    for (i = 0; config->priv->outputs[i]; ++i)
     {
-        if (config->outputs[i]->primary)
+        if (config->priv->outputs[i]->priv->primary)
         {
             if (found)
             {
-                config->outputs[i]->primary = FALSE;
+                config->priv->outputs[i]->priv->primary = FALSE;
             }
             else
             {
@@ -1074,7 +1182,7 @@ gnome_rr_config_save (GnomeRRConfig *configuration, GError **error)
     gchar *backup_filename;
     gboolean result;
 
-    g_return_val_if_fail (configuration != NULL, FALSE);
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (configuration), FALSE);
     g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
     output = g_string_new ("");
@@ -1092,9 +1200,10 @@ gnome_rr_config_save (GnomeRRConfig *configuration, GError **error)
 	{
 	    if (!gnome_rr_config_match (configurations[i], configuration))
 		emit_configuration (configurations[i], output);
+	    g_object_unref (configurations[i]);
 	}
 
-	configurations_free (configurations);
+	g_free (configurations);
     }
 
     emit_configuration (configuration, output);
@@ -1115,89 +1224,6 @@ gnome_rr_config_save (GnomeRRConfig *configuration, GError **error)
     return result;
 }
 
-static GnomeRRConfig *
-gnome_rr_config_copy (const GnomeRRConfig *config)
-{
-    GnomeRRConfig *copy = g_new0 (GnomeRRConfig, 1);
-    int i;
-    GPtrArray *array = g_ptr_array_new ();
-
-    copy->clone = config->clone;
-    
-    for (i = 0; config->outputs[i] != NULL; ++i)
-	g_ptr_array_add (array, output_copy (config->outputs[i]));
-
-    g_ptr_array_add (array, NULL);
-    copy->outputs = (GnomeOutputInfo **)g_ptr_array_free (array, FALSE);
-
-    return copy;
-}
-
-static GnomeRRConfig *
-config_new_stored (GnomeRRScreen *screen, const char *filename, GError **error)
-{
-    GnomeRRConfig *current;
-    GnomeRRConfig **configs;
-    GnomeRRConfig *result;
-
-    g_return_val_if_fail (screen != NULL, NULL);
-    g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-    
-    current = gnome_rr_config_new_current (screen);
-    
-    configs = configurations_read_from_file (filename, error);
-
-    result = NULL;
-    if (configs)
-    {
-	int i;
-	
-	for (i = 0; configs[i] != NULL; ++i)
-	{
-	    if (gnome_rr_config_match (configs[i], current))
-	    {
-		result = gnome_rr_config_copy (configs[i]);
-		break;
-	    }
-	}
-
-	if (result == NULL)
-	    g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG,
-			 _("none of the saved display configurations matched the active configuration"));
-
-	configurations_free (configs);
-    }
-
-    gnome_rr_config_free (current);
-    
-    return result;
-}
-
-GnomeRRConfig *
-gnome_rr_config_new_stored (GnomeRRScreen *screen, GError **error)
-{
-    char *intended_filename;
-    GnomeRRConfig *config;
-
-    intended_filename = gnome_rr_config_get_intended_filename ();
-
-    config = config_new_stored (screen, intended_filename, error);
-
-    g_free (intended_filename);
-
-    return config;
-}
-
-#ifndef GNOME_DISABLE_DEPRECATED_SOURCE
-gboolean
-gnome_rr_config_apply (GnomeRRConfig *config,
-		       GnomeRRScreen *screen,
-		       GError       **error)
-{
-    return gnome_rr_config_apply_with_time (config, screen, GDK_CURRENT_TIME, error);
-}
-#endif
-
 gboolean
 gnome_rr_config_apply_with_time (GnomeRRConfig *config,
 				 GnomeRRScreen *screen,
@@ -1205,14 +1231,20 @@ gnome_rr_config_apply_with_time (GnomeRRConfig *config,
 				 GError       **error)
 {
     CrtcAssignment *assignment;
-    GnomeOutputInfo **outputs;
+    GnomeRROutputInfo **outputs;
     gboolean result = FALSE;
+    int i;
+
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (config), FALSE);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), FALSE);
 
     outputs = make_outputs (config);
 
     assignment = crtc_assignment_new (screen, outputs, error);
 
-    outputs_free (outputs);
+    for (i = 0; outputs[i] != NULL; i++)
+	g_object_unref (outputs[i]);
+    g_free (outputs);
     
     if (assignment)
     {
@@ -1227,74 +1259,6 @@ gnome_rr_config_apply_with_time (GnomeRRConfig *config,
     return result;
 }
 
-#ifndef GNOME_DISABLE_DEPRECATED_SOURCE
-/**
- * gnome_rr_config_apply_stored:
- * @screen: A #GnomeRRScreen
- * @error: Location to store error, or %NULL
- *
- * See the documentation for gnome_rr_config_apply_from_filename().  This
- * function simply calls that other function with a filename of
- * gnome_rr_config_get_intended_filename().
- *
- * Deprecated: 2.26: Use gnome_rr_config_apply_from_filename() instead and pass it
- * the filename from gnome_rr_config_get_intended_filename().
- */
-gboolean
-gnome_rr_config_apply_stored (GnomeRRScreen *screen, GError **error)
-{
-    char *filename;
-    gboolean result;
-
-    filename = gnome_rr_config_get_intended_filename ();
-    result = gnome_rr_config_apply_from_filename_with_time (screen, filename, GDK_CURRENT_TIME, error);
-    g_free (filename);
-
-    return result;
-}
-#endif
-
-#ifndef GNOME_DISABLE_DEPRECATED_SOURCE
-/* gnome_rr_config_apply_from_filename:
- * @screen: A #GnomeRRScreen
- * @filename: Path of the file to look in for stored RANDR configurations.
- * @error: Location to store error, or %NULL
- *
- * First, this function refreshes the @screen to match the current RANDR
- * configuration from the X server.  Then, it tries to load the file in
- * @filename and looks for suitable matching RANDR configurations in the file;
- * if one is found, that configuration will be applied to the current set of
- * RANDR outputs.
- *
- * Typically, @filename is the result of gnome_rr_config_get_intended_filename() or
- * gnome_rr_config_get_backup_filename().
- *
- * Returns: TRUE if the RANDR configuration was loaded and applied from
- * $(XDG_CONFIG_HOME)/monitors.xml, or FALSE otherwise:
- *
- * If the current RANDR configuration could not be refreshed, the @error will
- * have a domain of #GNOME_RR_ERROR and a corresponding error code.
- *
- * If the file in question is loaded successfully but the configuration cannot
- * be applied, the @error will have a domain of #GNOME_RR_ERROR.  Note that an
- * error code of #GNOME_RR_ERROR_NO_MATCHING_CONFIG is not a real error; it
- * simply means that there were no stored configurations that match the current
- * set of RANDR outputs.
- *
- * If the file in question cannot be loaded, the @error will have a domain of
- * #G_FILE_ERROR.  Note that an error code of G_FILE_ERROR_NOENT is not really
- * an error, either; it means that there was no stored configuration file and so
- * nothing is changed.
- *
- * @Deprecated: 2.28: use gnome_rr_config_apply_from_filename_with_time() instead.
- */
-gboolean
-gnome_rr_config_apply_from_filename (GnomeRRScreen *screen, const char *filename, GError **error)
-{
-    return gnome_rr_config_apply_from_filename_with_time (screen, filename, GDK_CURRENT_TIME, error);
-}
-#endif
-
 /* gnome_rr_config_apply_from_filename_with_time:
  * @screen: A #GnomeRRScreen
  * @filename: Path of the file to look in for stored RANDR configurations.
@@ -1333,7 +1297,7 @@ gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen *screen, const char
     GnomeRRConfig *stored;
     GError *my_error;
 
-    g_return_val_if_fail (screen != NULL, FALSE);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), FALSE);
     g_return_val_if_fail (filename != NULL, FALSE);
     g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
@@ -1347,24 +1311,60 @@ gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen *screen, const char
 	    /* This means the screen didn't change, so just proceed */
     }
 
-    stored = config_new_stored (screen, filename, error);
+    stored = g_object_new (GNOME_TYPE_RR_CONFIG, "screen", screen, "current", FALSE, NULL);
 
-    if (stored)
+    if (config_init_stored (stored, filename, error))
     {
 	gboolean result;
 
 	result = gnome_rr_config_apply_with_time (stored, screen, timestamp, error);
 
-	gnome_rr_config_free (stored);
-	
+	g_object_unref (stored);
 	return result;
     }
     else
     {
+	g_object_unref (stored);
 	return FALSE;
     }
 }
 
+/**
+ * gnome_rr_config_get_outputs:
+ *
+ * Returns: (array zero-terminated=1) (element-type GnomeDesktop.RROutputInfo) (transfer none): the output configuration for this #GnomeRRConfig
+ */
+GnomeRROutputInfo **
+gnome_rr_config_get_outputs (GnomeRRConfig *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (self), NULL);
+
+    return self->priv->outputs;
+}
+
+/**
+ * gnome_rr_config_get_clone:
+ *
+ * Returns: whether at least two outputs are at (0, 0) offset and they
+ * have the same width/height.  Those outputs are of course connected and on
+ * (i.e. they have a CRTC assigned).
+ */
+gboolean
+gnome_rr_config_get_clone (GnomeRRConfig *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_CONFIG (self), FALSE);
+
+    return self->priv->clone;
+}
+
+void
+gnome_rr_config_set_clone (GnomeRRConfig *self, gboolean clone)
+{
+    g_return_if_fail (GNOME_IS_RR_CONFIG (self));
+
+    self->priv->clone = clone;
+}
+
 /*
  * CRTC assignment
  */
@@ -1607,12 +1607,12 @@ accumulate_error (GString *accumulated_error, GError *error)
  */
 static gboolean
 real_assign_crtcs (GnomeRRScreen *screen,
-		   GnomeOutputInfo **outputs,
+		   GnomeRROutputInfo **outputs,
 		   CrtcAssignment *assignment,
 		   GError **error)
 {
     GnomeRRCrtc **crtcs = gnome_rr_screen_list_crtcs (screen);
-    GnomeOutputInfo *output;
+    GnomeRROutputInfo *output;
     int i;
     gboolean tried_mode;
     GError *my_error;
@@ -1624,7 +1624,7 @@ real_assign_crtcs (GnomeRRScreen *screen,
 	return TRUE;
 
     /* It is always allowed for an output to be turned off */
-    if (!output->on)
+    if (!output->priv->on)
     {
 	return real_assign_crtcs (screen, outputs + 1, assignment, error);
     }
@@ -1648,7 +1648,7 @@ real_assign_crtcs (GnomeRRScreen *screen,
 	 */
 	for (pass = 0; pass < 2; ++pass)
 	{
-	    GnomeRROutput *gnome_rr_output = gnome_rr_screen_get_output_by_name (screen, output->name);
+	    GnomeRROutput *gnome_rr_output = gnome_rr_screen_get_output_by_name (screen, output->priv->name);
 	    GnomeRRMode **modes = gnome_rr_output_list_modes (gnome_rr_output);
 	    int j;
 
@@ -1667,21 +1667,21 @@ real_assign_crtcs (GnomeRRScreen *screen,
 					_("CRTC %d: trying mode %dx%d %dHz with output at %dx%d %dHz (pass %d)\n"),
 					crtc_id,
 					mode_width, mode_height, mode_freq,
-					output->width, output->height, output->rate,
+					output->priv->width, output->priv->height, output->priv->rate,
 					pass);
 
-		if (mode_width == output->width	&&
-		    mode_height == output->height &&
-		    (pass == 1 || mode_freq == output->rate))
+		if (mode_width == output->priv->width	&&
+		    mode_height == output->priv->height &&
+		    (pass == 1 || mode_freq == output->priv->rate))
 		{
 		    tried_mode = TRUE;
 
 		    my_error = NULL;
 		    if (crtc_assignment_assign (
 			    assignment, crtc, modes[j],
-			    output->x, output->y,
-			    output->rotation,
-                            output->primary,
+			    output->priv->x, output->priv->y,
+			    output->priv->rotation,
+                            output->priv->primary,
 			    gnome_rr_output,
 			    &my_error))
 		    {
@@ -1769,7 +1769,7 @@ get_required_virtual_size (CrtcAssignment *assign, int *width, int *height)
 }
 
 static CrtcAssignment *
-crtc_assignment_new (GnomeRRScreen *screen, GnomeOutputInfo **outputs, GError **error)
+crtc_assignment_new (GnomeRRScreen *screen, GnomeRROutputInfo **outputs, GError **error)
 {
     CrtcAssignment *assignment = g_new0 (CrtcAssignment, 1);
 
diff --git a/libgnome-desktop/gnome-rr-config.h b/libgnome-desktop/gnome-rr-config.h
index cdd537e..de060ed 100644
--- a/libgnome-desktop/gnome-rr-config.h
+++ b/libgnome-desktop/gnome-rr-config.h
@@ -1,6 +1,8 @@
 /* gnome-rr-config.h
+ * -*- c-basic-offset: 4 -*-
  *
  * Copyright 2007, 2008, Red Hat, Inc.
+ * Copyright 2010 Giovanni Campagna
  * 
  * This file is part of the Gnome Library.
  * 
@@ -29,108 +31,114 @@
 #endif
 
 #include <glib.h>
+#include <glib-object.h>
 #include <libgnome-desktop/gnome-rr.h>
 
-typedef struct GnomeOutputInfo GnomeOutputInfo;
-typedef struct GnomeRRConfig GnomeRRConfig;
+typedef struct GnomeRROutputInfoPrivate GnomeRROutputInfoPrivate;
+typedef struct GnomeRRConfigPrivate GnomeRRConfigPrivate;
 
-/* FIXME:
- *
- * This structure is a Frankenstein monster where all of the fields
- * are generated by the system, but some of them can be changed by
- * the client.
- */
+typedef struct
+{
+    GObject parent;
 
-struct GnomeOutputInfo
+    /*< private >*/
+    GnomeRROutputInfoPrivate *priv;
+} GnomeRROutputInfo;
+
+typedef struct
 {
-    char *		name;
-
-    gboolean		on; /* whether there is a CRTC assigned to this output (i.e. a signal is being sent to it) */
-    int			width;
-    int			height;
-    int			rate;
-    int			x;
-    int			y;
-    GnomeRRRotation	rotation;
-
-    gboolean		connected; /* whether the output is physically connected to a monitor */
-    char		vendor[4];
-    guint		product;
-    guint		serial;
-    double		aspect;
-    int			pref_width;
-    int			pref_height;
-    char *		display_name;
-    gboolean            primary;
-
-    gpointer		user_data;
-};
-
-#define GNOME_RR_TYPE_OUTPUT_INFO    (gnome_rr_output_info_get_type())
-#define GNOME_RR_TYPE_CONFIG         (gnome_rr_config_get_type())
+    GObjectClass parent_class;
+} GnomeRROutputInfoClass;
+
+#define GNOME_TYPE_RR_OUTPUT_INFO                  (gnome_rr_output_info_get_type())
+#define GNOME_RR_OUTPUT_INFO(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfo))
+#define GNOME_IS_RR_OUTPUT_INFO(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_OUTPUT_INFO))
+#define GNOME_RR_OUTPUT_INFO_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfoClass))
+#define GNOME_IS_RR_OUTPUT_INFO_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_OUTPUT_INFO))
+#define GNOME_RR_OUTPUT_INFO_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfoClass))
+
 GType gnome_rr_output_info_get_type (void);
-GType gnome_rr_config_get_type (void);
 
-struct GnomeRRConfig
-{
-    /* "clone" means that at least two outputs are at (0, 0) offset and they
-     * have the same width/height.  Those outputs are of course connected and on
-     * (i.e. they have a CRTC assigned).
-     */
-    gboolean		clone;
-    
-    GnomeOutputInfo **	outputs;
-};
-
-GnomeRRConfig  *gnome_rr_config_new_current  (GnomeRRScreen  *screen);
-GnomeRRConfig  *gnome_rr_config_new_stored   (GnomeRRScreen  *screen,
-					      GError        **error);
-void            gnome_rr_config_free         (GnomeRRConfig  *configuration);
-gboolean        gnome_rr_config_match        (GnomeRRConfig  *config1,
-					      GnomeRRConfig  *config2);
-gboolean        gnome_rr_config_equal	     (GnomeRRConfig  *config1,
-					      GnomeRRConfig  *config2);
-gboolean        gnome_rr_config_save         (GnomeRRConfig  *configuration,
-					      GError        **error);
-void            gnome_rr_config_sanitize     (GnomeRRConfig  *configuration);
-
-#ifndef GNOME_DISABLE_DEPRECATED
-gboolean	gnome_rr_config_apply        (GnomeRRConfig  *configuration,
-					      GnomeRRScreen  *screen,
-					      GError        **error);
-#endif
+char *gnome_rr_output_info_get_name (GnomeRROutputInfo *self);
 
-gboolean	gnome_rr_config_apply_with_time (GnomeRRConfig  *configuration,
-						 GnomeRRScreen  *screen,
-						 guint32         timestamp,
-						 GError        **error);
+gboolean gnome_rr_output_info_get_active (GnomeRROutputInfo *self);
+void     gnome_rr_output_info_set_active (GnomeRROutputInfo *self, gboolean active);
 
-#ifndef GNOME_DISABLE_DEPRECATED
-gboolean        gnome_rr_config_apply_stored (GnomeRRScreen  *screen,
-					      GError        **error);
-#endif
+void gnome_rr_output_info_get_geometry (GnomeRROutputInfo *self, int *x, int *y, int *width, int *height);
+void gnome_rr_output_info_set_geometry (GnomeRROutputInfo *self, int  x, int  y, int  width, int  height);
+
+int  gnome_rr_output_info_get_refresh_rate (GnomeRROutputInfo *self);
+void gnome_rr_output_info_set_refresh_rate (GnomeRROutputInfo *self, int rate);
+
+GnomeRRRotation gnome_rr_output_info_get_rotation (GnomeRROutputInfo *self);
+void            gnome_rr_output_info_set_rotation (GnomeRROutputInfo *self, GnomeRRRotation rotation);
 
-#ifndef GNOME_DISABLE_DEPRECATED
-gboolean        gnome_rr_config_apply_from_filename (GnomeRRScreen  *screen,
-						     const char     *filename,
+gboolean gnome_rr_output_info_get_connected    (GnomeRROutputInfo *self);
+void     gnome_rr_output_info_get_vendor       (GnomeRROutputInfo *self, gchar* vendor);
+guint    gnome_rr_output_info_get_product      (GnomeRROutputInfo *self);
+guint    gnome_rr_output_info_get_serial       (GnomeRROutputInfo *self);
+double   gnome_rr_output_info_get_aspect_ratio (GnomeRROutputInfo *self);
+char    *gnome_rr_output_info_get_display_name (GnomeRROutputInfo *self);
+
+gboolean gnome_rr_output_info_get_primary (GnomeRROutputInfo *self);
+void     gnome_rr_output_info_set_primary (GnomeRROutputInfo *self, gboolean primary);
+
+int gnome_rr_output_info_get_preferred_width  (GnomeRROutputInfo *self);
+int gnome_rr_output_info_get_preferred_height (GnomeRROutputInfo *self);
+
+typedef struct
+{
+    GObject parent;
+
+    /*< private >*/
+    GnomeRRConfigPrivate *priv;
+} GnomeRRConfig;
+
+typedef struct
+{
+    GObjectClass parent_class;
+} GnomeRRConfigClass;
+
+#define GNOME_TYPE_RR_CONFIG                  (gnome_rr_config_get_type())
+#define GNOME_RR_CONFIG(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_CONFIG, GnomeRRConfig))
+#define GNOME_IS_RR_CONFIG(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_CONFIG))
+#define GNOME_RR_CONFIG_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_CONFIG, GnomeRRConfigClass))
+#define GNOME_IS_RR_CONFIG_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_CONFIG))
+#define GNOME_RR_CONFIG_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_CONFIG, GnomeRRConfigClass))
+
+GType               gnome_rr_config_get_type     (void);
+
+GnomeRRConfig      *gnome_rr_config_new_current  (GnomeRRScreen  *screen,
+						  GError        **error);
+GnomeRRConfig      *gnome_rr_config_new_stored   (GnomeRRScreen  *screen,
+						  GError        **error);
+gboolean            gnome_rr_config_match        (GnomeRRConfig  *config1,
+						  GnomeRRConfig  *config2);
+gboolean            gnome_rr_config_equal	 (GnomeRRConfig  *config1,
+						  GnomeRRConfig  *config2);
+gboolean            gnome_rr_config_save         (GnomeRRConfig  *configuration,
+						  GError        **error);
+void                gnome_rr_config_sanitize     (GnomeRRConfig  *configuration);
+
+gboolean	    gnome_rr_config_apply_with_time (GnomeRRConfig  *configuration,
+						     GnomeRRScreen  *screen,
+						     guint32         timestamp,
 						     GError        **error);
-#endif
 
-gboolean        gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen  *screen,
-							       const char     *filename,
-							       guint32         timestamp,
-							       GError        **error);
+gboolean            gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen  *screen,
+								   const char     *filename,
+								   guint32         timestamp,
+								   GError        **error);
+
+gboolean            gnome_rr_config_applicable   (GnomeRRConfig  *configuration,
+						  GnomeRRScreen  *screen,
+						  GError        **error);
 
-gboolean        gnome_rr_config_applicable   (GnomeRRConfig  *configuration,
-					      GnomeRRScreen  *screen,
-					      GError        **error);
+gboolean            gnome_rr_config_get_clone    (GnomeRRConfig  *configuration);
+void                gnome_rr_config_set_clone    (GnomeRRConfig  *configuration, gboolean clone);
+GnomeRROutputInfo **gnome_rr_config_get_outputs  (GnomeRRConfig  *configuration);
 
 char *gnome_rr_config_get_backup_filename (void);
 char *gnome_rr_config_get_intended_filename (void);
 
-/* A utility function that isn't really in the spirit of this file, but I don't
- * don't know a better place for it.
- */
-GnomeRRMode **gnome_rr_create_clone_modes (GnomeRRScreen *screen);
-
 #endif
diff --git a/libgnome-desktop/gnome-rr-labeler.c b/libgnome-desktop/gnome-rr-labeler.c
index 1de4569..87dc43b 100644
--- a/libgnome-desktop/gnome-rr-labeler.c
+++ b/libgnome-desktop/gnome-rr-labeler.c
@@ -29,7 +29,6 @@
 
 #include <config.h>
 #include <glib/gi18n-lib.h>
-#include "gnome-rr-labeler.h"
 #include <gtk/gtk.h>
 
 #include <X11/Xproto.h>
@@ -38,9 +37,9 @@
 #include <X11/Xatom.h>
 #include <gdk/gdkx.h>
 
-struct _GnomeRRLabeler {
-	GObject parent;
+#include "gnome-rr-labeler.h"
 
+struct _GnomeRRLabelerPrivate {
 	GnomeRRConfig *config;
 
 	int num_outputs;
@@ -52,14 +51,17 @@ struct _GnomeRRLabeler {
 	Atom        workarea_atom;
 };
 
-struct _GnomeRRLabelerClass {
-	GObjectClass parent_class;
+enum {
+	PROP_0,
+	PROP_CONFIG,
+	PROP_LAST
 };
 
 G_DEFINE_TYPE (GnomeRRLabeler, gnome_rr_labeler, G_TYPE_OBJECT);
 
 static void gnome_rr_labeler_finalize (GObject *object);
 static void create_label_windows (GnomeRRLabeler *labeler);
+static void setup_from_config (GnomeRRLabeler *labeler);
 
 static gboolean
 get_work_area (GnomeRRLabeler *labeler,
@@ -78,16 +80,16 @@ get_work_area (GnomeRRLabeler *labeler,
 	int             disp_screen;
 	Display        *display;
 
-	display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (labeler->screen));
+	display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (labeler->priv->screen));
 	workarea = XInternAtom (display, "_NET_WORKAREA", True);
 
-	disp_screen = GDK_SCREEN_XNUMBER (labeler->screen);
+	disp_screen = GDK_SCREEN_XNUMBER (labeler->priv->screen);
 
 	/* Defaults in case of error */
 	rect->x = 0;
 	rect->y = 0;
-	rect->width = gdk_screen_get_width (labeler->screen);
-	rect->height = gdk_screen_get_height (labeler->screen);
+	rect->width = gdk_screen_get_width (labeler->priv->screen);
+	rect->height = gdk_screen_get_height (labeler->priv->screen);
 
 	if (workarea == None)
 		return FALSE;
@@ -135,7 +137,7 @@ screen_xevent_filter (GdkXEvent      *xevent,
 	xev = (XEvent *) xevent;
 
 	if (xev->type == PropertyNotify &&
-	    xev->xproperty.atom == labeler->workarea_atom) {
+	    xev->xproperty.atom == labeler->priv->workarea_atom) {
 		/* update label positions */
 		gnome_rr_labeler_hide (labeler);
 		create_label_windows (labeler);
@@ -149,25 +151,62 @@ gnome_rr_labeler_init (GnomeRRLabeler *labeler)
 {
 	GdkWindow *gdkwindow;
 
-	labeler->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
-					      "_NET_WORKAREA",
-					      True);
+	labeler->priv = G_TYPE_INSTANCE_GET_PRIVATE (labeler, GNOME_TYPE_RR_LABELER, GnomeRRLabelerPrivate);
+
+	labeler->priv->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
+						    "_NET_WORKAREA",
+						    True);
 
-	labeler->screen = gdk_screen_get_default ();
+	labeler->priv->screen = gdk_screen_get_default ();
 	/* code is not really designed to handle multiple screens so *shrug* */
-	gdkwindow = gdk_screen_get_root_window (labeler->screen);
+	gdkwindow = gdk_screen_get_root_window (labeler->priv->screen);
 	gdk_window_add_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler);
 	gdk_window_set_events (gdkwindow, gdk_window_get_events (gdkwindow) | GDK_PROPERTY_CHANGE_MASK);
 }
 
 static void
-gnome_rr_labeler_class_init (GnomeRRLabelerClass *class)
+gnome_rr_labeler_set_property (GObject *gobject, guint property_id, const GValue *value, GParamSpec *param_spec)
+{
+	GnomeRRLabeler *self = GNOME_RR_LABELER (gobject);
+
+	switch (property_id) {
+	case PROP_CONFIG:
+		self->priv->config = GNOME_RR_CONFIG (g_value_get_object (value));
+		return;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, param_spec);
+	}
+}
+
+static GObject *
+gnome_rr_labeler_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)
+{
+	GnomeRRLabeler *self = (GnomeRRLabeler*) G_OBJECT_CLASS (gnome_rr_labeler_parent_class)->constructor (type, n_construct_properties, construct_properties);
+
+	setup_from_config (self);
+
+	return (GObject*) self;
+}
+
+static void
+gnome_rr_labeler_class_init (GnomeRRLabelerClass *klass)
 {
 	GObjectClass *object_class;
 
-	object_class = (GObjectClass *) class;
+	g_type_class_add_private (klass, sizeof (GnomeRRLabelerPrivate));
+
+	object_class = (GObjectClass *) klass;
 
+	object_class->set_property = gnome_rr_labeler_set_property;
 	object_class->finalize = gnome_rr_labeler_finalize;
+	object_class->constructor = gnome_rr_labeler_constructor;
+
+	g_object_class_install_property (object_class, PROP_CONFIG, g_param_spec_object ("config",
+											 "Configuration",
+											 "RandR configuration to label",
+											 GNOME_TYPE_RR_CONFIG,
+											 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+											 G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
 }
 
 static void
@@ -178,21 +217,19 @@ gnome_rr_labeler_finalize (GObject *object)
 
 	labeler = GNOME_RR_LABELER (object);
 
-	gdkwindow = gdk_screen_get_root_window (labeler->screen);
+	gdkwindow = gdk_screen_get_root_window (labeler->priv->screen);
 	gdk_window_remove_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler);
 
-	/* We don't destroy the labeler->config (a GnomeRRConfig*) here; let our
-	 * caller do that instead.
-	 */
+	if (labeler->priv->config != NULL) {
+		g_object_unref (labeler->priv->config);
+	}
 
-	if (labeler->windows != NULL) {
+	if (labeler->priv->windows != NULL) {
 		gnome_rr_labeler_hide (labeler);
-		g_free (labeler->windows);
-		labeler->windows = NULL;
+		g_free (labeler->priv->windows);
 	}
 
-	g_free (labeler->palette);
-	labeler->palette = NULL;
+	g_free (labeler->priv->palette);
 
 	G_OBJECT_CLASS (gnome_rr_labeler_parent_class)->finalize (object);
 }
@@ -201,8 +238,9 @@ static int
 count_outputs (GnomeRRConfig *config)
 {
 	int i;
+	GnomeRROutputInfo **outputs = gnome_rr_config_get_outputs (config);
 
-	for (i = 0; config->outputs[i] != NULL; i++)
+	for (i = 0; outputs[i] != NULL; i++)
 		;
 
 	return i;
@@ -223,26 +261,26 @@ make_palette (GnomeRRLabeler *labeler)
 	double end_hue;
 	int i;
 
-	g_assert (labeler->num_outputs > 0);
+	g_assert (labeler->priv->num_outputs > 0);
 
-	labeler->palette = g_new (GdkColor, labeler->num_outputs);
+	labeler->priv->palette = g_new (GdkColor, labeler->priv->num_outputs);
 
 	start_hue = 0.0; /* red */
 	end_hue   = 2.0/3; /* blue */
 
-	for (i = 0; i < labeler->num_outputs; i++) {
+	for (i = 0; i < labeler->priv->num_outputs; i++) {
 		double h, s, v;
 		double r, g, b;
 
-		h = start_hue + (end_hue - start_hue) / labeler->num_outputs * i;
+		h = start_hue + (end_hue - start_hue) / labeler->priv->num_outputs * i;
 		s = 1.0 / 3;
 		v = 1.0;
 
 		gtk_hsv_to_rgb (h, s, v, &r, &g, &b);
 
-		labeler->palette[i].red   = (int) (65535 * r + 0.5);
-		labeler->palette[i].green = (int) (65535 * g + 0.5);
-		labeler->palette[i].blue  = (int) (65535 * b + 0.5);
+		labeler->priv->palette[i].red   = (int) (65535 * r + 0.5);
+		labeler->priv->palette[i].green = (int) (65535 * g + 0.5);
+		labeler->priv->palette[i].blue  = (int) (65535 * b + 0.5);
 	}
 }
 
@@ -293,8 +331,8 @@ position_window (GnomeRRLabeler  *labeler,
 	int             monitor_num;
 
 	get_work_area (labeler, &workarea);
-	monitor_num = gdk_screen_get_monitor_at_point (labeler->screen, x, y);
-	gdk_screen_get_monitor_geometry (labeler->screen,
+	monitor_num = gdk_screen_get_monitor_at_point (labeler->priv->screen, x, y);
+	gdk_screen_get_monitor_geometry (labeler->priv->screen,
                                          monitor_num,
                                          &monitor);
 	gdk_rectangle_intersect (&monitor, &workarea, &workarea);
@@ -303,13 +341,14 @@ position_window (GnomeRRLabeler  *labeler,
 }
 
 static GtkWidget *
-create_label_window (GnomeRRLabeler *labeler, GnomeOutputInfo *output, GdkColor *color)
+create_label_window (GnomeRRLabeler *labeler, GnomeRROutputInfo *output, GdkColor *color)
 {
 	GtkWidget *window;
 	GtkWidget *widget;
 	char *str;
 	const char *display_name;
 	GdkColor black = { 0, 0, 0, 0 };
+	int x,y;
 
 	window = gtk_window_new (GTK_WINDOW_POPUP);
 	gtk_widget_set_app_paintable (window, TRUE);
@@ -325,7 +364,7 @@ create_label_window (GnomeRRLabeler *labeler, GnomeOutputInfo *output, GdkColor
 	g_signal_connect (window, "draw",
 			  G_CALLBACK (label_window_draw_event_cb), labeler);
 
-	if (labeler->config->clone) {
+	if (gnome_rr_config_get_clone (labeler->priv->config)) {
 		/* Keep this string in sync with gnome-control-center/capplets/display/xrandr-capplet.c:get_display_name() */
 
 		/* Translators:  this is the feature where what you see on your laptop's
@@ -335,7 +374,7 @@ create_label_window (GnomeRRLabeler *labeler, GnomeOutputInfo *output, GdkColor
 		 */
 		display_name = _("Mirror Screens");
 	} else
-		display_name = output->display_name;
+		display_name = gnome_rr_output_info_get_display_name (output);
 
 	str = g_strdup_printf ("<b>%s</b>", display_name);
 	widget = gtk_label_new (NULL);
@@ -351,7 +390,8 @@ create_label_window (GnomeRRLabeler *labeler, GnomeOutputInfo *output, GdkColor
 	gtk_container_add (GTK_CONTAINER (window), widget);
 
 	/* Should we center this at the top edge of the monitor, instead of using the upper-left corner? */
-	position_window (labeler, window, output->x, output->y);
+	gnome_rr_output_info_get_geometry (output, &x, &y, NULL, NULL);
+	position_window (labeler, window, x, y);
 
 	gtk_widget_show_all (window);
 
@@ -363,26 +403,29 @@ create_label_windows (GnomeRRLabeler *labeler)
 {
 	int i;
 	gboolean created_window_for_clone;
+	GnomeRROutputInfo **outputs;
 
-	labeler->windows = g_new (GtkWidget *, labeler->num_outputs);
+	labeler->priv->windows = g_new (GtkWidget *, labeler->priv->num_outputs);
 
 	created_window_for_clone = FALSE;
 
-	for (i = 0; i < labeler->num_outputs; i++) {
-		if (!created_window_for_clone && labeler->config->outputs[i]->on) {
-			labeler->windows[i] = create_label_window (labeler, labeler->config->outputs[i], labeler->palette + i);
+	outputs = gnome_rr_config_get_outputs (labeler->priv->config);
+
+	for (i = 0; i < labeler->priv->num_outputs; i++) {
+		if (!created_window_for_clone && gnome_rr_output_info_get_active (outputs[i])) {
+			labeler->priv->windows[i] = create_label_window (labeler, outputs[i], labeler->priv->palette + i);
 
-			if (labeler->config->clone)
+			if (gnome_rr_config_get_clone (labeler->priv->config))
 				created_window_for_clone = TRUE;
 		} else
-			labeler->windows[i] = NULL;
+			labeler->priv->windows[i] = NULL;
 	}
 }
 
 static void
 setup_from_config (GnomeRRLabeler *labeler)
 {
-	labeler->num_outputs = count_outputs (labeler->config);
+	labeler->priv->num_outputs = count_outputs (labeler->priv->config);
 
 	make_palette (labeler);
 
@@ -392,16 +435,9 @@ setup_from_config (GnomeRRLabeler *labeler)
 GnomeRRLabeler *
 gnome_rr_labeler_new (GnomeRRConfig *config)
 {
-	GnomeRRLabeler *labeler;
-
-	g_return_val_if_fail (config != NULL, NULL);
-
-	labeler = g_object_new (GNOME_TYPE_RR_LABELER, NULL);
-	labeler->config = config;
+	g_return_val_if_fail (GNOME_IS_RR_CONFIG (config), NULL);
 
-	setup_from_config (labeler);
-
-	return labeler;
+	return g_object_new (GNOME_TYPE_RR_LABELER, "config", config, NULL);
 }
 
 void
@@ -411,25 +447,28 @@ gnome_rr_labeler_hide (GnomeRRLabeler *labeler)
 
 	g_return_if_fail (GNOME_IS_RR_LABELER (labeler));
 
-	for (i = 0; i < labeler->num_outputs; i++)
-		if (labeler->windows[i] != NULL) {
-			gtk_widget_destroy (labeler->windows[i]);
-			labeler->windows[i] = NULL;
+	for (i = 0; i < labeler->priv->num_outputs; i++)
+		if (labeler->priv->windows[i] != NULL) {
+			gtk_widget_destroy (labeler->priv->windows[i]);
+			labeler->priv->windows[i] = NULL;
 		}
 }
 
 void
-gnome_rr_labeler_get_color_for_output (GnomeRRLabeler *labeler, GnomeOutputInfo *output, GdkColor *color_out)
+gnome_rr_labeler_get_color_for_output (GnomeRRLabeler *labeler, GnomeRROutputInfo *output, GdkColor *color_out)
 {
 	int i;
+	GnomeRROutputInfo **outputs;
 
 	g_return_if_fail (GNOME_IS_RR_LABELER (labeler));
-	g_return_if_fail (output != NULL);
+	g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (output));
 	g_return_if_fail (color_out != NULL);
 
-	for (i = 0; i < labeler->num_outputs; i++)
-		if (labeler->config->outputs[i] == output) {
-			*color_out = labeler->palette[i];
+	outputs = gnome_rr_config_get_outputs (labeler->priv->config);
+
+	for (i = 0; i < labeler->priv->num_outputs; i++)
+		if (outputs[i] == output) {
+			*color_out = labeler->priv->palette[i];
 			return;
 		}
 
diff --git a/libgnome-desktop/gnome-rr-labeler.h b/libgnome-desktop/gnome-rr-labeler.h
index b62e38b..155731c 100644
--- a/libgnome-desktop/gnome-rr-labeler.h
+++ b/libgnome-desktop/gnome-rr-labeler.h
@@ -41,6 +41,18 @@
 
 typedef struct _GnomeRRLabeler GnomeRRLabeler;
 typedef struct _GnomeRRLabelerClass GnomeRRLabelerClass;
+typedef struct _GnomeRRLabelerPrivate GnomeRRLabelerPrivate;
+
+struct _GnomeRRLabeler {
+	GObject parent;
+
+	/*< private >*/
+	GnomeRRLabelerPrivate *priv;
+};
+
+struct _GnomeRRLabelerClass {
+	GObjectClass parent_class;
+};
 
 GType gnome_rr_labeler_get_type (void);
 
@@ -48,6 +60,6 @@ GnomeRRLabeler *gnome_rr_labeler_new (GnomeRRConfig *config);
 
 void gnome_rr_labeler_hide (GnomeRRLabeler *labeler);
 
-void gnome_rr_labeler_get_color_for_output (GnomeRRLabeler *labeler, GnomeOutputInfo *output, GdkColor *color_out);
+void gnome_rr_labeler_get_color_for_output (GnomeRRLabeler *labeler, GnomeRROutputInfo *output, GdkColor *color_out);
 
 #endif
diff --git a/libgnome-desktop/gnome-rr-output-info.c b/libgnome-desktop/gnome-rr-output-info.c
new file mode 100644
index 0000000..fedb9bb
--- /dev/null
+++ b/libgnome-desktop/gnome-rr-output-info.c
@@ -0,0 +1,246 @@
+/* gnome-rr-output-info.c
+ * -*- c-basic-offset: 4 -*-
+ *
+ * Copyright 2010 Giovanni Campagna
+ *
+ * This file is part of the Gnome Desktop Library.
+ *
+ * The Gnome Desktop Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the Gnome Desktop Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+
+#include <config.h>
+
+#include "gnome-rr-config.h"
+
+#include "edid.h"
+#include "gnome-rr-private.h"
+
+G_DEFINE_TYPE (GnomeRROutputInfo, gnome_rr_output_info, G_TYPE_OBJECT)
+
+static void
+gnome_rr_output_info_init (GnomeRROutputInfo *self)
+{
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_OUTPUT_INFO, GnomeRROutputInfoPrivate);
+
+    self->priv->name = NULL;
+    self->priv->on = FALSE;
+    self->priv->display_name = NULL;
+}
+
+static void
+gnome_rr_output_info_finalize (GObject *gobject)
+{
+    GnomeRROutputInfo *self = GNOME_RR_OUTPUT_INFO (gobject);
+
+    g_free (self->priv->name);
+    g_free (self->priv->display_name);
+
+    G_OBJECT_CLASS (gnome_rr_output_info_parent_class)->finalize (gobject);
+}
+
+static void
+gnome_rr_output_info_class_init (GnomeRROutputInfoClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+    g_type_class_add_private (klass, sizeof (GnomeRROutputInfoPrivate));
+
+    gobject_class->finalize = gnome_rr_output_info_finalize;
+}
+
+/**
+ * gnome_rr_output_info_get_name:
+ *
+ * Returns: (transfer none): the output name
+ */
+char *gnome_rr_output_info_get_name (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), NULL);
+
+    return self->priv->name;
+}
+
+/**
+ * gnome_rr_output_info_get_active:
+ *
+ * Returns: whether there is a CRTC assigned to this output (i.e. a signal is being sent to it)
+ */
+gboolean gnome_rr_output_info_get_active (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), FALSE);
+
+    return self->priv->on;
+}
+
+void gnome_rr_output_info_set_active (GnomeRROutputInfo *self, gboolean active)
+{
+    g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+
+    self->priv->on = active;
+}
+
+/**
+ * gnome_rr_output_info_get_geometry:
+ *
+ * @self: a #GnomeRROutputInfo
+ * @x: (out) (allow-none):
+ * @y: (out) (allow-none):
+ * @width: (out) (allow-none):
+ * @height: (out) (allow-none):
+ */
+void gnome_rr_output_info_get_geometry (GnomeRROutputInfo *self, int *x, int *y, int *width, int *height)
+{
+    g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+
+    if (x)
+	*x = self->priv->x;
+    if (y)
+	*y = self->priv->y;
+    if (width)
+	*width = self->priv->width;
+    if (height)
+	*height = self->priv->height;
+}
+
+void gnome_rr_output_info_set_geometry (GnomeRROutputInfo *self, int  x, int  y, int  width, int  height)
+{
+    g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+
+    self->priv->x = x;
+    self->priv->y = y;
+    self->priv->width = width;
+    self->priv->height = height;
+}
+
+int gnome_rr_output_info_get_refresh_rate (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+
+    return self->priv->rate;
+}
+
+void gnome_rr_output_info_set_refresh_rate (GnomeRROutputInfo *self, int rate)
+{
+    g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+
+    self->priv->rate = rate;
+}
+
+GnomeRRRotation gnome_rr_output_info_get_rotation (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), GNOME_RR_ROTATION_0);
+
+    return self->priv->rotation;
+}
+
+void gnome_rr_output_info_set_rotation (GnomeRROutputInfo *self, GnomeRRRotation rotation)
+{
+    g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+
+    self->priv->rotation = rotation;
+}
+
+/**
+ * gnome_rr_output_info_get_connected:
+ *
+ * Returns: whether the output is physically connected to a monitor
+ */
+gboolean gnome_rr_output_info_get_connected (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), FALSE);
+
+    return self->priv->connected;
+}
+
+/**
+ * gnome_rr_output_info_get_vendor:
+ *
+ * @self: a #GnomeRROutputInfo
+ * @vendor: (out caller-allocates) (array fixed-size=4):
+ */
+void gnome_rr_output_info_get_vendor (GnomeRROutputInfo *self, gchar* vendor)
+{
+    g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+    g_return_if_fail (vendor != NULL);
+
+    vendor[0] = self->priv->vendor[0];
+    vendor[1] = self->priv->vendor[1];
+    vendor[2] = self->priv->vendor[2];
+    vendor[3] = self->priv->vendor[3];
+}
+
+guint gnome_rr_output_info_get_product (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+
+    return self->priv->product;
+}
+
+guint gnome_rr_output_info_get_serial (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+
+    return self->priv->serial;
+}
+
+double gnome_rr_output_info_get_aspect_ratio (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+
+    return self->priv->aspect;
+}
+
+/**
+ * gnome_rr_output_info_get_display_name:
+ *
+ * Returns: (transfer none): the display name of this output
+ */
+char *gnome_rr_output_info_get_display_name (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), NULL);
+
+    return self->priv->display_name;
+}
+
+gboolean gnome_rr_output_info_get_primary (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), FALSE);
+
+    return self->priv->primary;
+}
+
+void gnome_rr_output_info_set_primary (GnomeRROutputInfo *self, gboolean primary)
+{
+    g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
+
+    self->priv->primary = primary;
+}
+
+int gnome_rr_output_info_get_preferred_width (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+
+    return self->priv->pref_width;
+}
+
+int gnome_rr_output_info_get_preferred_height (GnomeRROutputInfo *self)
+{
+    g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+
+    return self->priv->pref_height;
+}
diff --git a/libgnome-desktop/gnome-rr-private.h b/libgnome-desktop/gnome-rr-private.h
index cfa84e3..5113a12 100644
--- a/libgnome-desktop/gnome-rr-private.h
+++ b/libgnome-desktop/gnome-rr-private.h
@@ -47,4 +47,35 @@ struct GnomeRRScreenPrivate
     Atom                        connector_type_atom;
 };
 
+struct GnomeRROutputInfoPrivate
+{
+    char *		name;
+
+    gboolean		on;
+    int			width;
+    int			height;
+    int			rate;
+    int			x;
+    int			y;
+    GnomeRRRotation	rotation;
+
+    gboolean		connected;
+    gchar		vendor[4];
+    guint		product;
+    guint		serial;
+    double		aspect;
+    int			pref_width;
+    int			pref_height;
+    char *		display_name;
+    gboolean            primary;
+};
+
+struct GnomeRRConfigPrivate
+{
+  gboolean clone;
+  gboolean current;
+  GnomeRRScreen *screen;
+  GnomeRROutputInfo **outputs;
+};
+
 #endif
diff --git a/libgnome-desktop/gnome-rr.c b/libgnome-desktop/gnome-rr.c
index 568acd3..7d03565 100644
--- a/libgnome-desktop/gnome-rr.c
+++ b/libgnome-desktop/gnome-rr.c
@@ -39,6 +39,7 @@
 
 #undef GNOME_DISABLE_DEPRECATED
 #include "gnome-rr.h"
+#include "gnome-rr-config.h"
 
 #include "private.h"
 #include "gnome-rr-private.h"
@@ -792,7 +793,7 @@ gnome_rr_screen_class_init (GnomeRRScreenClass *klass)
 void
 gnome_rr_screen_init (GnomeRRScreen *self)
 {
-    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_RR_TYPE_SCREEN, GnomeRRScreenPrivate);
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_SCREEN, GnomeRRScreenPrivate);
 
     self->priv->gdk_screen = NULL;
     self->priv->gdk_root = NULL;
@@ -823,7 +824,7 @@ gnome_rr_screen_new (GdkScreen *screen,
 		     GError **error)
 {
     _gnome_desktop_init_i18n ();
-    GnomeRRScreen *self = g_initable_new (GNOME_RR_TYPE_SCREEN, NULL, error, "gdk-screen", screen, NULL);
+    GnomeRRScreen *self = g_initable_new (GNOME_TYPE_RR_SCREEN, NULL, error, "gdk-screen", screen, NULL);
     if (self && callback) {
         g_signal_connect (self, "screen-changed", G_CALLBACK (callback), data);
     }
@@ -849,7 +850,7 @@ gnome_rr_screen_set_size (GnomeRRScreen *screen,
 			  int       mm_width,
 			  int       mm_height)
 {
-    g_return_if_fail (GNOME_RR_IS_SCREEN (screen));
+    g_return_if_fail (GNOME_IS_RR_SCREEN (screen));
 
 #ifdef HAVE_RANDR
     gdk_error_trap_push ();
@@ -876,7 +877,7 @@ gnome_rr_screen_get_ranges (GnomeRRScreen *screen,
 			    int           *min_height,
 			    int	          *max_height)
 {
-    g_return_if_fail (GNOME_RR_IS_SCREEN (screen));
+    g_return_if_fail (GNOME_IS_RR_SCREEN (screen));
     
     if (min_width)
 	*min_width = screen->priv->info->min_width;
@@ -908,7 +909,7 @@ gnome_rr_screen_get_timestamps (GnomeRRScreen *screen,
 				guint32       *change_timestamp_ret,
 				guint32       *config_timestamp_ret)
 {
-    g_return_if_fail (GNOME_RR_IS_SCREEN (screen));
+    g_return_if_fail (GNOME_IS_RR_SCREEN (screen));
 
 #ifdef HAVE_RANDR
     if (change_timestamp_ret)
@@ -1006,7 +1007,7 @@ gnome_rr_screen_refresh (GnomeRRScreen *screen,
 GnomeRRMode **
 gnome_rr_screen_list_modes (GnomeRRScreen *screen)
 {
-    g_return_val_if_fail (GNOME_RR_IS_SCREEN (screen), NULL);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL);
     g_return_val_if_fail (screen->priv->info != NULL, NULL);
     
     return screen->priv->info->modes;
@@ -1022,7 +1023,7 @@ gnome_rr_screen_list_modes (GnomeRRScreen *screen)
 GnomeRRMode **
 gnome_rr_screen_list_clone_modes   (GnomeRRScreen *screen)
 {
-    g_return_val_if_fail (GNOME_RR_IS_SCREEN (screen), NULL);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL);
     g_return_val_if_fail (screen->priv->info != NULL, NULL);
 
     return screen->priv->info->clone_modes;
@@ -1038,7 +1039,7 @@ gnome_rr_screen_list_clone_modes   (GnomeRRScreen *screen)
 GnomeRRCrtc **
 gnome_rr_screen_list_crtcs (GnomeRRScreen *screen)
 {
-    g_return_val_if_fail (GNOME_RR_IS_SCREEN (screen), NULL);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL);
     g_return_val_if_fail (screen->priv->info != NULL, NULL);
     
     return screen->priv->info->crtcs;
@@ -1054,7 +1055,7 @@ gnome_rr_screen_list_crtcs (GnomeRRScreen *screen)
 GnomeRROutput **
 gnome_rr_screen_list_outputs (GnomeRRScreen *screen)
 {
-    g_return_val_if_fail (GNOME_RR_IS_SCREEN (screen), NULL);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL);
     g_return_val_if_fail (screen->priv->info != NULL, NULL);
     
     return screen->priv->info->outputs;
@@ -1071,7 +1072,7 @@ gnome_rr_screen_get_crtc_by_id (GnomeRRScreen *screen,
 {
     int i;
     
-    g_return_val_if_fail (GNOME_RR_IS_SCREEN (screen), NULL);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL);
     g_return_val_if_fail (screen->priv->info != NULL, NULL);
     
     for (i = 0; screen->priv->info->crtcs[i] != NULL; ++i)
@@ -1094,7 +1095,7 @@ gnome_rr_screen_get_output_by_id (GnomeRRScreen *screen,
 {
     int i;
     
-    g_return_val_if_fail (GNOME_RR_IS_SCREEN (screen), NULL);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL);
     g_return_val_if_fail (screen->priv->info != NULL, NULL);
     
     for (i = 0; screen->priv->info->outputs[i] != NULL; ++i)
@@ -1389,7 +1390,7 @@ gnome_rr_screen_get_output_by_name (GnomeRRScreen *screen,
 {
     int i;
     
-    g_return_val_if_fail (GNOME_RR_IS_SCREEN (screen), NULL);
+    g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), NULL);
     g_return_val_if_fail (screen->priv->info != NULL, NULL);
     
     for (i = 0; screen->priv->info->outputs[i] != NULL; ++i)
diff --git a/libgnome-desktop/gnome-rr.h b/libgnome-desktop/gnome-rr.h
index e305921..4880add 100644
--- a/libgnome-desktop/gnome-rr.h
+++ b/libgnome-desktop/gnome-rr.h
@@ -76,16 +76,16 @@ typedef enum {
 
 #define GNOME_RR_CONNECTOR_TYPE_PANEL "Panel"  /* This is a laptop's built-in LCD */
 
-#define GNOME_RR_TYPE_SCREEN                  (gnome_rr_screen_get_type())
-#define GNOME_RR_SCREEN(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_RR_TYPE_SCREEN, GnomeRRScreen))
-#define GNOME_RR_IS_SCREEN(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_RR_TYPE_SCREEN))
-#define GNOME_RR_SCREEN_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_RR_TYPE_SCREEN, GnomeRRScreenClass))
-#define GNOME_RR_IS_SCREEN_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_RR_TYPE_SCREEN))
-#define GNOME_RR_SCREEN_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_RR_TYPE_SCREEN, GnomeRRScreenClass))
+#define GNOME_TYPE_RR_SCREEN                  (gnome_rr_screen_get_type())
+#define GNOME_RR_SCREEN(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_RR_SCREEN, GnomeRRScreen))
+#define GNOME_IS_RR_SCREEN(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_RR_SCREEN))
+#define GNOME_RR_SCREEN_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_RR_SCREEN, GnomeRRScreenClass))
+#define GNOME_IS_RR_SCREEN_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_RR_SCREEN))
+#define GNOME_RR_SCREEN_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_RR_SCREEN, GnomeRRScreenClass))
 
-#define GNOME_RR_TYPE_OUTPUT (gnome_rr_output_get_type())
-#define GNOME_RR_TYPE_CRTC   (gnome_rr_crtc_get_type())
-#define GNOME_RR_TYPE_MODE   (gnome_rr_mode_get_type())
+#define GNOME_TYPE_RR_OUTPUT (gnome_rr_output_get_type())
+#define GNOME_TYPE_RR_CRTC   (gnome_rr_crtc_get_type())
+#define GNOME_TYPE_RR_MODE   (gnome_rr_mode_get_type())
 
 GType gnome_rr_screen_get_type (void);
 GType gnome_rr_output_get_type (void);
@@ -127,6 +127,8 @@ void            gnome_rr_screen_get_timestamps     (GnomeRRScreen         *scree
 void            gnome_rr_screen_set_primary_output (GnomeRRScreen         *screen,
                                                     GnomeRROutput         *output);
 
+GnomeRRMode   **gnome_rr_screen_create_clone_modes (GnomeRRScreen *screen);
+
 /* GnomeRROutput */
 guint32         gnome_rr_output_get_id             (GnomeRROutput         *output);
 const char *    gnome_rr_output_get_name           (GnomeRROutput         *output);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]