diff -up gnome-desktop-2.21.90/configure.in.add-randr-12 gnome-desktop-2.21.90/configure.in
--- gnome-desktop-2.21.90/configure.in.add-randr-12 2008-01-27 18:48:13.000000000 -0500
+++ gnome-desktop-2.21.90/configure.in 2008-01-29 03:27:34.000000000 -0500
@@ -51,10 +51,10 @@ AC_SUBST(GNOME_MICRO)
AC_SUBST(GNOME_DISTRIBUTOR)
AC_SUBST(GNOME_DATE)
-GNOME_COMMON_INIT
-GNOME_DEBUG_CHECK
-GNOME_COMPILE_WARNINGS([maximum])
-GNOME_MAINTAINER_MODE_DEFINES
+#GNOME_COMMON_INIT
+#GNOME_DEBUG_CHECK
+#GNOME_COMPILE_WARNINGS([maximum])
+#GNOME_MAINTAINER_MODE_DEFINES
# As a special favour for vuntz, support --disable-deprecations
diff -up gnome-desktop-2.21.90/libgnome-desktop/libgnomeui/Makefile.am.add-randr-12 gnome-desktop-2.21.90/libgnome-desktop/libgnomeui/Makefile.am
--- gnome-desktop-2.21.90/libgnome-desktop/libgnomeui/Makefile.am.add-randr-12 2008-01-27 18:44:20.000000000 -0500
+++ gnome-desktop-2.21.90/libgnome-desktop/libgnomeui/Makefile.am 2008-01-29 03:27:34.000000000 -0500
@@ -2,4 +2,5 @@ libgnomeui_desktopdir = $(includedir)/gn
libgnomeui_desktop_HEADERS = \
gnome-ditem-edit.h \
gnome-hint.h \
- gnome-bg.h
+ gnome-bg.h \
+ randrwrap.h
diff -up /dev/null gnome-desktop-2.21.90/libgnome-desktop/libgnomeui/randrwrap.h
--- /dev/null 2008-01-30 11:34:25.225700292 -0500
+++ gnome-desktop-2.21.90/libgnome-desktop/libgnomeui/randrwrap.h 2008-01-31 14:56:02.000000000 -0500
@@ -0,0 +1,93 @@
+#ifndef I_KNOW_THIS_IS_UNSTABLE_AND_ONLY_IN_FEDORA
+#error This is not yet for general consumption.
+#endif
+
+#ifndef RANDR_WRAP_H
+#define RANDR_WRAP_H
+
+#include <glib.h>
+#include <gdk/gdk.h>
+
+typedef struct RWScreen RWScreen;
+typedef struct RWOutput RWOutput;
+typedef struct RWCrtc RWCrtc;
+typedef struct RWMode RWMode;
+
+typedef void (* RWScreenChanged) (RWScreen *screen, gpointer data);
+
+typedef enum
+{
+ RW_ROTATE_0,
+ RW_ROTATE_90,
+ RW_ROTATE_180,
+ RW_ROTATE_270
+} RWRotation;
+
+/* RWScreen */
+RWScreen * rw_screen_new (GdkScreen *screen,
+ RWScreenChanged callback,
+ gpointer data);
+RWOutput ** rw_screen_list_outputs (RWScreen *screen);
+RWCrtc ** rw_screen_list_crtcs (RWScreen *screen);
+RWMode ** rw_screen_list_modes (RWScreen *screen);
+void rw_screen_set_size (RWScreen *screen,
+ int width,
+ int height,
+ int mm_width,
+ int mm_height);
+RWCrtc * rw_screen_get_crtc_by_id (RWScreen *screen,
+ guint32 id);
+void rw_screen_refresh (RWScreen *screen);
+RWOutput * rw_screen_get_output_by_id (RWScreen *screen,
+ guint32 id);
+RWOutput * rw_screen_get_output_by_name (RWScreen *screen,
+ const char *name);
+void rw_screen_get_ranges (RWScreen *screen,
+ int *min_width,
+ int *max_width,
+ int *min_height,
+ int *max_height);
+
+/* RWOutput */
+guint32 rw_output_get_id (RWOutput *output);
+const char * rw_output_get_name (RWOutput *output);
+gboolean rw_output_is_connected (RWOutput *output);
+int rw_output_get_size_inches (RWOutput *output);
+int rw_output_get_width_mm (RWOutput *outout);
+int rw_output_get_height_mm (RWOutput *output);
+const guint8 *rw_output_get_edid_data (RWOutput *output);
+RWCrtc ** rw_output_get_possible_crtcs (RWOutput *output);
+RWMode * rw_output_get_current_mode (RWOutput *output);
+RWCrtc * rw_output_get_crtc (RWOutput *output);
+void rw_output_get_position (RWOutput *output,
+ int *x,
+ int *y);
+gboolean rw_output_can_clone (RWOutput *output,
+ RWOutput *clone);
+RWMode ** rw_output_list_modes (RWOutput *output);
+RWMode * rw_output_get_preferred_mode (RWOutput *output);
+gboolean rw_output_supports_mode (RWOutput *output,
+ RWMode *mode);
+
+/* RWMode */
+guint32 rw_mode_get_id (RWMode *mode);
+guint rw_mode_get_width (RWMode *mode);
+guint rw_mode_get_height (RWMode *mode);
+int rw_mode_get_freq (RWMode *mode);
+
+/* RWCrtc */
+guint32 rw_crtc_get_id (RWCrtc *crtc);
+gboolean rw_crtc_set_config (RWCrtc *crtc,
+ int x,
+ int y,
+ RWMode *mode,
+ RWOutput **outputs,
+ int n_outputs);
+gboolean rw_crtc_can_drive_output (RWCrtc *crtc,
+ RWOutput *output);
+RWMode * rw_crtc_get_current_mode (RWCrtc *crtc);
+void rw_crtc_get_position (RWCrtc *crtc,
+ int *x,
+ int *y);
+
+#endif
diff -up /dev/null gnome-desktop-2.21.90/libgnome-desktop/randrwrap.c
--- /dev/null 2008-01-30 11:34:25.225700292 -0500
+++ gnome-desktop-2.21.90/libgnome-desktop/randrwrap.c 2008-01-31 14:56:02.000000000 -0500
@@ -0,0 +1,968 @@
+#define I_KNOW_THIS_IS_UNSTABLE_AND_ONLY_IN_FEDORA
+#include "libgnomeui/randrwrap.h"
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+
+struct RWScreen
+{
+ GdkScreen * gdk_screen;
+ GdkWindow * gdk_root;
+ Display * xdisplay;
+ Screen * xscreen;
+ Window xroot;
+
+ int min_width;
+ int max_width;
+ int min_height;
+ int max_height;
+
+ RWScreenChanged callback;
+ gpointer data;
+
+ XRRScreenResources *resources;
+
+ RWOutput ** outputs;
+ RWCrtc ** crtcs;
+ RWMode ** modes;
+
+ int randr_event_base;
+};
+
+struct RWOutput
+{
+ RWScreen * screen;
+ RROutput id;
+
+ char * name;
+ RWCrtc * current_crtc;
+ gboolean connected;
+ gulong width_mm;
+ gulong height_mm;
+ RWCrtc ** possible_crtcs;
+ RWOutput ** clones;
+ RWMode ** modes;
+ int n_preferred;
+ guint8 * edid_data;
+};
+
+struct RWCrtc
+{
+ RWScreen * screen;
+ RRCrtc id;
+
+ RWMode * current_mode;
+ RWOutput ** current_outputs;
+ RWOutput ** possible_outputs;
+ int x;
+ int y;
+};
+
+struct RWMode
+{
+ RWScreen * screen;
+ RRMode id;
+ char * name;
+ int width;
+ int height;
+ int freq; /* in mHz */
+};
+
+/* RWCrtc */
+static RWCrtc * crtc_new (RWScreen *screen,
+ RRCrtc id);
+static void crtc_free (RWCrtc *crtc);
+static void crtc_initialize (RWCrtc *crtc,
+ XRRScreenResources *res);
+
+
+/* RWOutput */
+static RWOutput *output_new (RWScreen *screen,
+ RROutput id);
+static void output_initialize (RWOutput *output,
+ XRRScreenResources *res);
+static void output_free (RWOutput *output);
+
+
+/* RWMode */
+static RWMode * mode_new (RWScreen *screen,
+ RRMode id);
+static void mode_initialize (RWMode *mode,
+ XRRModeInfo *info);
+static void mode_free (RWMode *mode);
+
+
+/* Screen */
+static RWOutput *
+rw_output_by_id (RWScreen *screen, RROutput id)
+{
+ RWOutput **output;
+
+ for (output = screen->outputs; *output; ++output)
+ {
+ if ((*output)->id == id)
+ return *output;
+ }
+
+ return NULL;
+}
+
+static RWCrtc *
+crtc_by_id (RWScreen *screen, RRCrtc id)
+{
+ RWCrtc **crtc;
+
+ for (crtc = screen->crtcs; *crtc; ++crtc)
+ {
+ if ((*crtc)->id == id)
+ return *crtc;
+ }
+
+ return NULL;
+}
+
+static RWMode *
+mode_by_id (RWScreen *screen, RRMode id)
+{
+ RWMode **mode;
+
+ for (mode = screen->modes; *mode; ++mode)
+ {
+ if ((*mode)->id == id)
+ return *mode;
+ }
+
+ return NULL;
+}
+
+static void
+screen_free_resources (RWScreen *screen)
+{
+ RWOutput **output;
+ RWCrtc **crtc;
+ RWMode **mode;
+
+ if (screen->resources)
+ {
+ XRRFreeScreenResources (screen->resources);
+
+ screen->resources = NULL;
+ }
+
+ if (screen->outputs)
+ {
+ for (output = screen->outputs; *output; ++output)
+ output_free (*output);
+ g_free (screen->outputs);
+ }
+
+ if (screen->crtcs)
+ {
+ for (crtc = screen->crtcs; *crtc; ++crtc)
+ crtc_free (*crtc);
+ g_free (screen->crtcs);
+ }
+
+ if (screen->modes)
+ {
+ for (mode = screen->modes; *mode; ++mode)
+ mode_free (*mode);
+ g_free (screen->modes);
+ }
+}
+
+static void
+screen_update (RWScreen *screen,
+ gboolean call_callback)
+{
+ XRRScreenResources *resources;
+
+ g_return_if_fail (screen != NULL);
+
+ XRRGetScreenSizeRange (screen->xdisplay, screen->xroot,
+ &(screen->min_width),
+ &(screen->min_height),
+ &(screen->max_width),
+ &(screen->max_height));
+
+#if 0
+ g_print ("ranges: %d - %d; %d - %d\n",
+ screen->min_width, screen->max_width,
+ screen->min_height, screen->max_height);
+#endif
+
+ resources = XRRGetScreenResources (screen->xdisplay, screen->xroot);
+
+ if (resources)
+ {
+ int i;
+ GPtrArray *a;
+ RWCrtc **crtc;
+ RWOutput **output;
+
+ screen_free_resources (screen);
+
+ screen->resources = resources;
+
+ /* We create all the structures before initializing them, so
+ * that they can refer to each other.
+ */
+ a = g_ptr_array_new ();
+ for (i = 0; i < resources->ncrtc; ++i)
+ {
+ RWCrtc *crtc = crtc_new (screen, resources->crtcs[i]);
+
+ g_ptr_array_add (a, crtc);
+ }
+ g_ptr_array_add (a, NULL);
+ screen->crtcs = (RWCrtc **)g_ptr_array_free (a, FALSE);
+
+ a = g_ptr_array_new ();
+ for (i = 0; i < resources->noutput; ++i)
+ {
+ RWOutput *output = output_new (screen, resources->outputs[i]);
+
+ g_ptr_array_add (a, output);
+ }
+ g_ptr_array_add (a, NULL);
+ screen->outputs = (RWOutput **)g_ptr_array_free (a, FALSE);
+
+ a = g_ptr_array_new ();
+ for (i = 0; i < resources->nmode; ++i)
+ {
+ RWMode *mode = mode_new (screen, resources->modes[i].id);
+
+ g_ptr_array_add (a, mode);
+ }
+ g_ptr_array_add (a, NULL);
+ screen->modes = (RWMode **)g_ptr_array_free (a, FALSE);
+
+ /* Initialize */
+ for (crtc = screen->crtcs; *crtc; ++crtc)
+ crtc_initialize (*crtc, resources);
+
+ for (output = screen->outputs; *output; ++output)
+ output_initialize (*output, resources);
+
+ for (i = 0; i < resources->nmode; ++i)
+ {
+ RWMode *mode = mode_by_id (screen, resources->modes[i].id);
+
+ mode_initialize (mode, &(resources->modes[i]));
+ }
+ }
+
+ if (call_callback && screen->callback)
+ screen->callback (screen, screen->data);
+}
+
+static GdkFilterReturn
+screen_on_event (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ RWScreen *screen = data;
+ XEvent *e = xevent;
+
+ if (e->type - screen->randr_event_base == RRNotify)
+ {
+ /* FIXME: we probably need to be more discriminating in
+ * what causes 'changed' events
+ */
+ screen_update (screen, TRUE);
+ }
+
+ /* Pass the event on to GTK+ */
+ return GDK_FILTER_CONTINUE;
+}
+
+RWScreen *
+rw_screen_new (GdkScreen *gdk_screen,
+ RWScreenChanged callback,
+ gpointer data)
+{
+ Display *dpy = GDK_SCREEN_XDISPLAY (gdk_screen);
+ int event_base;
+ int ignore;
+
+ if (XRRQueryExtension (dpy, &event_base, &ignore))
+ {
+ RWScreen *screen = g_new0 (RWScreen, 1);
+
+ screen->gdk_screen = gdk_screen;
+ screen->gdk_root = gdk_screen_get_root_window (gdk_screen);
+ screen->xroot = gdk_x11_drawable_get_xid (screen->gdk_root);
+ screen->xdisplay = dpy;
+ screen->xscreen = gdk_x11_screen_get_xscreen (screen->gdk_screen);
+
+ screen->callback = callback;
+ screen->data = data;
+
+ screen->randr_event_base = event_base;
+
+ screen->outputs = NULL;
+ screen->crtcs = NULL;
+ screen->modes = NULL;
+
+ screen_update (screen, FALSE);
+
+ XRRSelectInput (screen->xdisplay,
+ screen->xroot,
+ RRScreenChangeNotifyMask |
+ RRCrtcChangeNotifyMask |
+ RROutputPropertyNotifyMask);
+
+ gdk_x11_register_standard_event_type (
+ gdk_screen_get_display (gdk_screen),
+ event_base,
+ RRNotify + 1);
+
+ gdk_window_add_filter (screen->gdk_root, screen_on_event, screen);
+ return screen;
+ }
+
+ return NULL;
+}
+
+void
+rw_screen_set_size (RWScreen *screen,
+ int width,
+ int height,
+ int mm_width,
+ int mm_height)
+{
+ g_return_if_fail (screen != NULL);
+
+ XRRSetScreenSize (screen->xdisplay, screen->xroot,
+ width, height, mm_width, mm_height);
+}
+
+void
+rw_screen_get_ranges (RWScreen *screen,
+ int *min_width,
+ int *max_width,
+ int *min_height,
+ int *max_height)
+{
+ g_return_if_fail (screen != NULL);
+
+ if (min_width)
+ *min_width = screen->min_width;
+
+ if (max_width)
+ *max_width = screen->max_width;
+
+ if (min_height)
+ *min_height = screen->min_height;
+
+ if (max_height)
+ *max_height = screen->max_height;
+}
+
+void
+rw_screen_refresh (RWScreen *screen)
+{
+ screen_update (screen, TRUE);
+}
+
+RWMode **
+rw_screen_list_modes (RWScreen *screen)
+{
+ return screen->modes;
+}
+
+RWCrtc **
+rw_screen_list_crtcs (RWScreen *screen)
+{
+ return screen->crtcs;
+}
+
+RWOutput **
+rw_screen_list_outputs (RWScreen *screen)
+{
+ return screen->outputs;
+}
+
+RWCrtc *
+rw_screen_get_crtc_by_id (RWScreen *screen,
+ guint32 id)
+{
+ int i;
+
+ for (i = 0; screen->crtcs[i] != NULL; ++i)
+ {
+ if (screen->crtcs[i]->id == id)
+ return screen->crtcs[i];
+ }
+
+ return NULL;
+}
+
+RWOutput *
+rw_screen_get_output_by_id (RWScreen *screen,
+ guint32 id)
+{
+ int i;
+
+ for (i = 0; screen->outputs[i] != NULL; ++i)
+ {
+ if (screen->outputs[i]->id == id)
+ return screen->outputs[i];
+ }
+
+ return NULL;
+}
+
+/* RWOutput */
+static RWOutput *
+output_new (RWScreen *screen, RROutput id)
+{
+ RWOutput *output = g_new0 (RWOutput, 1);
+
+ output->id = id;
+ output->screen = screen;
+
+ return output;
+}
+
+static guint8 *
+get_property (Display *dpy,
+ RROutput output,
+ Atom atom,
+ int *len)
+{
+ unsigned char *prop;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+ Atom actual_type;
+ guint8 *result;
+
+ XRRGetOutputProperty (dpy, output, atom,
+ 0, 100, False, False,
+ AnyPropertyType,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, &prop);
+
+ if (actual_type == XA_INTEGER && actual_format == 8)
+ {
+ result = g_memdup (prop, nitems);
+ if (len)
+ *len = nitems;
+ }
+ else
+ {
+ result = NULL;
+ }
+
+ XFree (prop);
+
+ return result;
+}
+
+static guint8 *
+read_edid_data (RWOutput *output)
+{
+ Atom edid_atom = XInternAtom (output->screen->xdisplay, "EDID_DATA", FALSE);
+ guint8 *result;
+ int len;
+
+ result = get_property (output->screen->xdisplay, output->id, edid_atom, &len);
+
+ if (result)
+ {
+ if (len == 128)
+ return result;
+ else
+ g_free (result);
+ }
+
+ return NULL;
+}
+
+static void
+output_initialize (RWOutput *output, XRRScreenResources *res)
+{
+ XRROutputInfo *info = XRRGetOutputInfo (
+ output->screen->xdisplay, res, output->id);
+ GPtrArray *a;
+ int i;
+
+ if (!info)
+ {
+ /* FIXME */
+ return;
+ }
+
+ output->name = g_strdup (info->name); /* FIXME: what is nameLen used for? */
+ output->current_crtc = crtc_by_id (output->screen, info->crtc);
+ output->width_mm = info->mm_width;
+ output->height_mm = info->mm_height;
+ output->connected = (info->connection == RR_Connected);
+
+ /* Possible crtcs */
+ a = g_ptr_array_new ();
+
+ for (i = 0; i < info->ncrtc; ++i)
+ {
+ RWCrtc *crtc = crtc_by_id (output->screen, info->crtcs[i]);
+
+ if (crtc)
+ g_ptr_array_add (a, crtc);
+ }
+ g_ptr_array_add (a, NULL);
+ output->possible_crtcs = (RWCrtc **)g_ptr_array_free (a, FALSE);
+
+ /* Clones */
+ a = g_ptr_array_new ();
+ for (i = 0; i < info->nclone; ++i)
+ {
+ RWOutput *output = rw_output_by_id (output->screen, info->clones[i]);
+
+ if (output)
+ g_ptr_array_add (a, output);
+ }
+ g_ptr_array_add (a, NULL);
+ output->clones = (RWOutput **)g_ptr_array_free (a, FALSE);
+
+ /* Modes */
+ a = g_ptr_array_new ();
+ for (i = 0; i < info->nmode; ++i)
+ {
+ RWMode *mode = mode_by_id (output->screen, info->modes[i]);
+
+ if (mode)
+ g_ptr_array_add (a, mode);
+ }
+ g_ptr_array_add (a, NULL);
+ output->modes = (RWMode **)g_ptr_array_free (a, FALSE);
+
+ output->n_preferred = info->npreferred;
+
+ /* Edid data */
+ output->edid_data = read_edid_data (output);
+
+ XRRFreeOutputInfo (info);
+}
+
+static void
+output_free (RWOutput *output)
+{
+ g_free (output);
+}
+
+guint32
+rw_output_get_id (RWOutput *output)
+{
+ return output->id;
+}
+
+const guint8 *
+rw_output_get_edid_data (RWOutput *output)
+{
+ return output->edid_data;
+}
+
+RWOutput *
+rw_screen_get_output_by_name (RWScreen *screen,
+ const char *name)
+{
+ int i;
+
+ for (i = 0; screen->outputs[i] != NULL; ++i)
+ {
+ RWOutput *output = screen->outputs[i];
+
+ if (strcmp (output->name, name) == 0)
+ return output;
+ }
+
+ return NULL;
+}
+
+RWCrtc *
+rw_output_get_crtc (RWOutput *output)
+{
+ return output->current_crtc;
+}
+
+RWMode *
+rw_output_get_current_mode (RWOutput *output)
+{
+ RWCrtc *crtc;
+
+ g_return_val_if_fail (output != NULL, NULL);
+
+ if ((crtc = rw_output_get_crtc (output)))
+ return rw_crtc_get_current_mode (crtc);
+
+ return NULL;
+}
+
+void
+rw_output_get_position (RWOutput *output,
+ int *x,
+ int *y)
+{
+ RWCrtc *crtc;
+
+ g_return_if_fail (output != NULL);
+
+ if ((crtc = rw_output_get_crtc (output)))
+ rw_crtc_get_position (crtc, x, y);
+}
+
+const char *
+rw_output_get_name (RWOutput *output)
+{
+ return output->name;
+}
+
+int
+rw_output_get_width_mm (RWOutput *output)
+{
+ return output->width_mm;
+}
+
+int
+rw_output_get_height_mm (RWOutput *output)
+{
+ return output->height_mm;
+}
+
+RWMode *
+rw_output_get_preferred_mode (RWOutput *output)
+{
+ if (output->n_preferred)
+ return output->modes[0];
+
+ return NULL;
+}
+
+RWMode **
+rw_output_list_modes (RWOutput *output)
+{
+ return output->modes;
+}
+
+gboolean
+rw_output_is_connected (RWOutput *output)
+{
+ return output->connected;
+}
+
+gboolean
+rw_output_supports_mode (RWOutput *output,
+ RWMode *mode)
+{
+ int i;
+
+ g_return_val_if_fail (output != NULL, FALSE);
+ g_return_val_if_fail (mode != NULL, FALSE);
+
+ for (i = 0; output->modes[i] != NULL; ++i)
+ {
+ if (output->modes[i] == mode)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean
+rw_output_can_clone (RWOutput *output,
+ RWOutput *clone)
+{
+ int i;
+
+ g_return_val_if_fail (output != NULL, FALSE);
+ g_return_val_if_fail (clone != NULL, FALSE);
+
+ for (i = 0; output->clones[i] != NULL; ++i)
+ {
+ if (output->clones[i] == clone)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* RWCrtc */
+gboolean
+rw_crtc_set_config (RWCrtc *crtc,
+ int x,
+ int y,
+ RWMode *mode,
+ RWOutput **outputs,
+ int n_outputs)
+{
+ RWScreen *screen;
+ GArray *output_ids;
+ int i;
+
+ g_return_val_if_fail (crtc != NULL, FALSE);
+ g_return_val_if_fail (mode != NULL || outputs == NULL || n_outputs == 0, FALSE);
+
+ screen = crtc->screen;
+
+ if (mode)
+ {
+#if 0
+ g_print ("x: %d mode->width: %d max width: %d\n", x, mode->width, screen->max_width);
+#endif
+ g_return_val_if_fail (x + mode->width <= screen->max_width, FALSE);
+ g_return_val_if_fail (y + mode->height <= screen->max_height, FALSE);
+ }
+
+ output_ids = g_array_new (FALSE, FALSE, sizeof (RROutput));
+
+ if (outputs)
+ {
+ for (i = 0; i < n_outputs; ++i)
+ g_array_append_val (output_ids, outputs[i]->id);
+ }
+
+ XRRSetCrtcConfig (screen->xdisplay, screen->resources, crtc->id,
+ CurrentTime,
+ x, y,
+ mode? mode->id : None, RR_Rotate_0,
+ (RROutput *)output_ids->data,
+ output_ids->len);
+
+ g_array_free (output_ids, TRUE);
+
+ return TRUE;
+}
+
+RWMode *
+rw_crtc_get_current_mode (RWCrtc *crtc)
+{
+ g_return_val_if_fail (crtc != NULL, NULL);
+
+ return crtc->current_mode;
+}
+
+guint32
+rw_crtc_get_id (RWCrtc *crtc)
+{
+ g_return_val_if_fail (crtc != NULL, 0);
+
+ return crtc->id;
+}
+
+gboolean
+rw_crtc_can_drive_output (RWCrtc *crtc,
+ RWOutput *output)
+{
+ int i;
+
+ g_return_val_if_fail (crtc != NULL, FALSE);
+ g_return_val_if_fail (output != NULL, FALSE);
+
+ for (i = 0; crtc->possible_outputs[i] != NULL; ++i)
+ {
+ if (crtc->possible_outputs[i] == output)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* FIXME: merge with get_mode()? */
+void
+rw_crtc_get_position (RWCrtc *crtc,
+ int *x,
+ int *y)
+{
+ g_return_if_fail (crtc != NULL);
+
+ if (x)
+ *x = crtc->x;
+
+ if (y)
+ *y = crtc->y;
+}
+
+static RWCrtc *
+crtc_new (RWScreen *screen, RROutput id)
+{
+ RWCrtc *crtc = g_new0 (RWCrtc, 1);
+
+ crtc->id = id;
+ crtc->screen = screen;
+
+ return crtc;
+}
+
+static void
+crtc_initialize (RWCrtc *crtc, XRRScreenResources *res)
+{
+ XRRCrtcInfo *info = XRRGetCrtcInfo (crtc->screen->xdisplay, res, crtc->id);
+ GPtrArray *a;
+ int i;
+
+ if (!info)
+ {
+ /* FIXME: We need to reaquire the screen resources */
+ return;
+ }
+
+ /* RWMode */
+ crtc->current_mode = mode_by_id (crtc->screen, info->mode);
+
+ crtc->x = info->x;
+ crtc->y = info->y;
+
+ /* Current outputs */
+ a = g_ptr_array_new ();
+ for (i = 0; i < info->noutput; ++i)
+ {
+ RWOutput *output = rw_output_by_id (crtc->screen, info->outputs[i]);
+
+ if (output)
+ g_ptr_array_add (a, output);
+ }
+ g_ptr_array_add (a, NULL);
+ crtc->current_outputs = (RWOutput **)g_ptr_array_free (a, FALSE);
+
+ /* Possible outputs */
+ a = g_ptr_array_new ();
+ for (i = 0; i < info->npossible; ++i)
+ {
+ RWOutput *output = rw_output_by_id (crtc->screen, info->possible[i]);
+
+ if (output)
+ g_ptr_array_add (a, output);
+ }
+ g_ptr_array_add (a, NULL);
+ crtc->possible_outputs = (RWOutput **)g_ptr_array_free (a, FALSE);
+
+ XRRFreeCrtcInfo (info);
+}
+
+static void
+crtc_free (RWCrtc *crtc)
+{
+ g_free (crtc->current_outputs);
+ g_free (crtc->possible_outputs);
+ g_free (crtc);
+}
+
+/* RWMode */
+static RWMode *
+mode_new (RWScreen *screen, RRMode id)
+{
+ RWMode *mode = g_new0 (RWMode, 1);
+
+ mode->id = id;
+ mode->screen = screen;
+
+ return mode;
+}
+
+guint32
+rw_mode_get_id (RWMode *mode)
+{
+ return mode->id;
+}
+
+guint
+rw_mode_get_width (RWMode *mode)
+{
+ return mode->width;
+}
+
+int
+rw_mode_get_freq (RWMode *mode)
+{
+ return (mode->freq) / 1000;
+}
+
+guint
+rw_mode_get_height (RWMode *mode)
+{
+ return mode->height;
+}
+
+static void
+mode_initialize (RWMode *mode, XRRModeInfo *info)
+{
+ mode->name = g_strdup (info->name);
+ mode->width = info->width;
+ mode->height = info->height;
+ mode->freq = ((info->dotClock / (double)info->hTotal) / info->vTotal + 0.5) * 1000;
+}
+
+static void
+mode_free (RWMode *mode)
+{
+ g_free (mode->name);
+ g_free (mode);
+}
+
+
+#ifdef INCLUDE_MAIN
+static void
+on_screen_changed (RWScreen *screen, gpointer data)
+{
+ g_print ("Changed\n");
+}
+
+static gboolean
+do_refresh (gpointer data)
+{
+ RWScreen *screen = data;
+
+ rw_screen_refresh (screen);
+
+ return TRUE;
+}
+
+int
+main (int argc, char **argv)
+{
+ int i;
+
+ gtk_init (&argc, &argv);
+
+ RWScreen *screen = rw_screen_new (gdk_screen_get_default(),
+ on_screen_changed,
+ NULL);
+
+ for (i = 0; screen->crtcs[i]; ++i)
+ {
+ RWCrtc *crtc = screen->crtcs[i];
+
+ if (crtc->current_mode)
+ {
+ g_print ("CRTC %p: (%d %d %d %d)\n",
+ crtc, crtc->x, crtc->y,
+ crtc->current_mode->width, crtc->current_mode->height);
+ }
+ else
+ {
+ g_print ("CRTC %p: turned off\n", crtc);
+ }
+ }
+
+ for (i = 0; screen->outputs[i]; ++i)
+ {
+ RWOutput *output = screen->outputs[i];
+
+ g_print ("Output %s currently", output->name);
+
+ if (!output->current_crtc)
+ g_print (" turned off\n");
+ else
+ g_print (" driven by CRTC %p\n", output->current_crtc);
+ }
+
+ g_timeout_add (500, do_refresh, screen);
+
+ gtk_main ();
+
+ return 0;
+}
+#endif
diff -up gnome-desktop-2.21.90/libgnome-desktop/Makefile.am.add-randr-12 gnome-desktop-2.21.90/libgnome-desktop/Makefile.am
--- gnome-desktop-2.21.90/libgnome-desktop/Makefile.am.add-randr-12 2008-01-27 18:44:20.000000000 -0500
+++ gnome-desktop-2.21.90/libgnome-desktop/Makefile.am 2008-01-29 03:27:34.000000000 -0500
@@ -20,7 +20,8 @@ libgnome_desktop_2_la_SOURCES = \
gnome-desktop-item.c \
gnome-ditem-edit.c \
gnome-hint.c \
- gnome-bg.c
+ gnome-bg.c \
+ randrwrap.c
libgnome_desktop_2_la_LIBADD = \
$(XLIB_LIBS) \