d6abca6
diff -up gnome-screensaver-2.28.0/src/gs-fade.c.xrandr-gamma gnome-screensaver-2.28.0/src/gs-fade.c
d6abca6
--- gnome-screensaver-2.28.0/src/gs-fade.c.xrandr-gamma	2009-08-19 19:19:14.000000000 -0400
d6abca6
+++ gnome-screensaver-2.28.0/src/gs-fade.c	2009-10-22 14:04:06.740384504 -0400
d6abca6
@@ -40,22 +40,19 @@
d6abca6
 #include "gs-fade.h"
d6abca6
 #include "gs-debug.h"
d6abca6
 
d6abca6
+#define GNOME_DESKTOP_USE_UNSTABLE_API
d6abca6
+
d6abca6
+#include "libgnomeui/gnome-rr.h"
d6abca6
+
d6abca6
 /* XFree86 4.x+ Gamma fading */
d6abca6
 
d6abca6
+
d6abca6
 #ifdef HAVE_XF86VMODE_GAMMA
d6abca6
 
d6abca6
 #include <X11/extensions/xf86vmode.h>
d6abca6
 
d6abca6
 #define XF86_MIN_GAMMA  0.1
d6abca6
 
d6abca6
-typedef struct {
d6abca6
-        XF86VidModeGamma vmg;
d6abca6
-        int              size;
d6abca6
-        unsigned short  *r;
d6abca6
-        unsigned short  *g;
d6abca6
-        unsigned short  *b;
d6abca6
-} xf86_gamma_info;
d6abca6
-
d6abca6
 #endif /* HAVE_XF86VMODE_GAMMA */
d6abca6
 
d6abca6
 static void     gs_fade_class_init (GSFadeClass *klass);
d6abca6
@@ -64,6 +61,31 @@ static void     gs_fade_finalize   (GObj
d6abca6
 
d6abca6
 #define GS_FADE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_FADE, GSFadePrivate))
d6abca6
 
d6abca6
+struct GSGammaInfo {
d6abca6
+        int              size;
d6abca6
+        unsigned short  *r;
d6abca6
+        unsigned short  *g;
d6abca6
+        unsigned short  *b;
d6abca6
+};
d6abca6
+
d6abca6
+struct GSFadeScreenPrivate
d6abca6
+{
d6abca6
+        int fade_type;
d6abca6
+        int num_ramps;
d6abca6
+        /* one per crtc in randr mode */
d6abca6
+        struct GSGammaInfo *info;
d6abca6
+        /* one per screen in theory */
d6abca6
+        GnomeRRScreen    *rrscreen;
d6abca6
+#ifdef HAVE_XF86VMODE_GAMMA
d6abca6
+        /* one per screen also */
d6abca6
+        XF86VidModeGamma vmg;
d6abca6
+#endif /* HAVE_XF86VMODE_GAMMA */
d6abca6
+        gboolean (*fade_setup) (GSFade *fade, int screen);
d6abca6
+        gboolean (*fade_set_alpha_gamma) (GSFade *fade,
d6abca6
+                                          int screen, gdouble alpha);
d6abca6
+        void (*fade_finish) (GSFade *fade, int screen);
d6abca6
+};
d6abca6
+        
d6abca6
 struct GSFadePrivate
d6abca6
 {
d6abca6
         guint            enabled : 1;
d6abca6
@@ -78,14 +100,9 @@ struct GSFadePrivate
d6abca6
         gdouble          alpha_per_iter;
d6abca6
         gdouble          current_alpha;
d6abca6
 
d6abca6
-        int              fade_type;
d6abca6
-
d6abca6
         int              num_screens;
d6abca6
 
d6abca6
-#ifdef HAVE_XF86VMODE_GAMMA
d6abca6
-        xf86_gamma_info *gamma_info;
d6abca6
-#endif /* HAVE_XF86VMODE_GAMMA */
d6abca6
-
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
 };
d6abca6
 
d6abca6
 enum {
d6abca6
@@ -96,7 +113,8 @@ enum {
d6abca6
 enum {
d6abca6
         FADE_TYPE_NONE,
d6abca6
         FADE_TYPE_GAMMA_NUMBER,
d6abca6
-        FADE_TYPE_GAMMA_RAMP
d6abca6
+        FADE_TYPE_GAMMA_RAMP,
d6abca6
+        FADE_TYPE_XRANDR,
d6abca6
 };
d6abca6
 
d6abca6
 static guint         signals [LAST_SIGNAL] = { 0, };
d6abca6
@@ -149,10 +167,16 @@ safe_XF86VidModeQueryVersion (Display *d
d6abca6
 
d6abca6
 static gboolean
d6abca6
 xf86_whack_gamma (int              screen,
d6abca6
-                  xf86_gamma_info *info,
d6abca6
+                  struct GSFadeScreenPrivate *screen_priv,
d6abca6
                   float            ratio)
d6abca6
 {
d6abca6
         Bool status;
d6abca6
+        struct GSGammaInfo *gamma_info;
d6abca6
+
d6abca6
+        gamma_info = screen_priv->info;
d6abca6
+
d6abca6
+        if (!gamma_info)
d6abca6
+                return FALSE;
d6abca6
 
d6abca6
         if (ratio < 0) {
d6abca6
                 ratio = 0;
d6abca6
@@ -161,14 +185,14 @@ xf86_whack_gamma (int              scree
d6abca6
                 ratio = 1;
d6abca6
         }
d6abca6
 
d6abca6
-        if (info->size == 0) {
d6abca6
+        if (gamma_info->size == 0) {
d6abca6
                 /* we only have a gamma number, not a ramp. */
d6abca6
 
d6abca6
                 XF86VidModeGamma g2;
d6abca6
 
d6abca6
-                g2.red   = info->vmg.red   * ratio;
d6abca6
-                g2.green = info->vmg.green * ratio;
d6abca6
-                g2.blue  = info->vmg.blue  * ratio;
d6abca6
+                g2.red   = screen_priv->vmg.red   * ratio;
d6abca6
+                g2.green = screen_priv->vmg.green * ratio;
d6abca6
+                g2.blue  = screen_priv->vmg.blue  * ratio;
d6abca6
 
d6abca6
                 if (g2.red < XF86_MIN_GAMMA) {
d6abca6
                         g2.red = XF86_MIN_GAMMA;
d6abca6
@@ -187,21 +211,21 @@ xf86_whack_gamma (int              scree
d6abca6
                 unsigned short *r, *g, *b;
d6abca6
                 int i;
d6abca6
 
d6abca6
-                r = g_new0 (unsigned short, info->size);
d6abca6
-                g = g_new0 (unsigned short, info->size);
d6abca6
-                b = g_new0 (unsigned short, info->size);
d6abca6
-
d6abca6
-                for (i = 0; i < info->size; i++) {
d6abca6
-                        r[i] = info->r[i] * ratio;
d6abca6
-                        g[i] = info->g[i] * ratio;
d6abca6
-                        b[i] = info->b[i] * ratio;
d6abca6
+                r = g_new0 (unsigned short, gamma_info->size);
d6abca6
+                g = g_new0 (unsigned short, gamma_info->size);
d6abca6
+                b = g_new0 (unsigned short, gamma_info->size);
d6abca6
+
d6abca6
+                for (i = 0; i < gamma_info->size; i++) {
d6abca6
+                        r[i] = gamma_info->r[i] * ratio;
d6abca6
+                        g[i] = gamma_info->g[i] * ratio;
d6abca6
+                        b[i] = gamma_info->b[i] * ratio;
d6abca6
                 }
d6abca6
 
d6abca6
-                status = XF86VidModeSetGammaRamp (GDK_DISPLAY (), screen, info->size, r, g, b);
d6abca6
+                status = XF86VidModeSetGammaRamp (GDK_DISPLAY (), screen, gamma_info->size, r, g, b);
d6abca6
 
d6abca6
-                free (r);
d6abca6
-                free (g);
d6abca6
-                free (b);
d6abca6
+                g_free (r);
d6abca6
+                g_free (g);
d6abca6
+                g_free (b);
d6abca6
 
d6abca6
 # else  /* !HAVE_XF86VMODE_GAMMA_RAMP */
d6abca6
                 abort ();
d6abca6
@@ -223,44 +247,6 @@ xf86_whack_gamma (int              scree
d6abca6
 # define XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR 2
d6abca6
 # define XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR 1
d6abca6
 
d6abca6
-static int
d6abca6
-check_gamma_extension (void)
d6abca6
-{
d6abca6
-#ifdef HAVE_XF86VMODE_GAMMA
d6abca6
-        int      event;
d6abca6
-        int      error;
d6abca6
-        int      major;
d6abca6
-        int      minor;
d6abca6
-        gboolean res;
d6abca6
-
d6abca6
-        res = XF86VidModeQueryExtension (GDK_DISPLAY (), &event, &error);
d6abca6
-        if (! res) {
d6abca6
-                return FADE_TYPE_NONE;  /* display doesn't have the extension. */
d6abca6
-        }
d6abca6
-
d6abca6
-        res = safe_XF86VidModeQueryVersion (GDK_DISPLAY (), &major, &minor);
d6abca6
-        if (! res) {
d6abca6
-                return FADE_TYPE_NONE;  /* unable to get version number? */
d6abca6
-        }
d6abca6
-
d6abca6
-        if (major < XF86_VIDMODE_GAMMA_MIN_MAJOR ||
d6abca6
-            (major == XF86_VIDMODE_GAMMA_MIN_MAJOR &&
d6abca6
-             minor < XF86_VIDMODE_GAMMA_MIN_MINOR)) {
d6abca6
-                return FADE_TYPE_NONE;  /* extension is too old for gamma. */
d6abca6
-        }
d6abca6
-
d6abca6
-        if (major < XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR ||
d6abca6
-            (major == XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR &&
d6abca6
-             minor < XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR)) {
d6abca6
-                return FADE_TYPE_GAMMA_NUMBER;  /* extension is too old for gamma ramps. */
d6abca6
-        }
d6abca6
-
d6abca6
-        /* Copacetic */
d6abca6
-        return FADE_TYPE_GAMMA_RAMP;
d6abca6
-#else
d6abca6
-        return FADE_TYPE_NONE;
d6abca6
-#endif /* HAVE_XF86VMODE_GAMMA */
d6abca6
-}
d6abca6
 
d6abca6
 gboolean
d6abca6
 gs_fade_get_enabled (GSFade *fade)
d6abca6
@@ -282,86 +268,80 @@ gs_fade_set_enabled (GSFade  *fade,
d6abca6
 }
d6abca6
 
d6abca6
 static gboolean
d6abca6
-gamma_info_init (GSFade *fade)
d6abca6
+gamma_fade_setup (GSFade *fade, int screen_idx)
d6abca6
 {
d6abca6
 #ifdef HAVE_XF86VMODE_GAMMA
d6abca6
-        int              screen;
d6abca6
-        xf86_gamma_info *info;
d6abca6
         gboolean         res;
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+
d6abca6
+        screen_priv = &fade->priv->screen_priv[screen_idx];
d6abca6
+
d6abca6
+        if (screen_priv->info)
d6abca6
+                return TRUE;
d6abca6
 
d6abca6
 # ifndef HAVE_XF86VMODE_GAMMA_RAMP
d6abca6
-        if (FADE_TYPE_GAMMA_RAMP == fade->priv->fade_type) {
d6abca6
+        if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type) {
d6abca6
                 /* server is newer than client! */
d6abca6
-                fade->priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
+                screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
         }
d6abca6
 # endif
d6abca6
 
d6abca6
-        if (fade->priv->gamma_info != NULL) {
d6abca6
-                return TRUE;
d6abca6
-        }
d6abca6
-
d6abca6
-        info = g_new0 (xf86_gamma_info, fade->priv->num_screens);
d6abca6
-        fade->priv->gamma_info = info;
d6abca6
-
d6abca6
-        /* Get the current gamma maps for all screens.
d6abca6
-           Bug out and return -1 if we can't get them for some screen.
d6abca6
-        */
d6abca6
-        for (screen = 0; screen < fade->priv->num_screens; screen++) {
d6abca6
-
d6abca6
 # ifdef HAVE_XF86VMODE_GAMMA_RAMP
d6abca6
+        
d6abca6
+        screen_priv->info = g_new0(struct GSGammaInfo, 1);
d6abca6
+        screen_priv->num_ramps = 1;
d6abca6
+
d6abca6
+        if (FADE_TYPE_GAMMA_RAMP == screen_priv->fade_type) {
d6abca6
+                /* have ramps */
d6abca6
+
d6abca6
+                res = XF86VidModeGetGammaRampSize (GDK_DISPLAY (), screen_idx, &screen_priv->info->size);
d6abca6
+                if (!res || screen_priv->info->size <= 0) {
d6abca6
+                        screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
+                        goto test_number;
d6abca6
+                }
d6abca6
 
d6abca6
-                if (FADE_TYPE_GAMMA_RAMP == fade->priv->fade_type) {
d6abca6
-                        /* have ramps */
d6abca6
+                screen_priv->info->r = g_new0 (unsigned short, screen_priv->info->size);
d6abca6
+                screen_priv->info->g = g_new0 (unsigned short, screen_priv->info->size);
d6abca6
+                screen_priv->info->b = g_new0 (unsigned short, screen_priv->info->size);
d6abca6
+
d6abca6
+                if (! (screen_priv->info->r && screen_priv->info->g && screen_priv->info->b)) {
d6abca6
+                        screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
+                        goto test_number;
d6abca6
+                }
d6abca6
 
d6abca6
-                        res = XF86VidModeGetGammaRampSize (GDK_DISPLAY (), screen, &info [screen].size);
d6abca6
-                        if (! res || info [screen].size <= 0) {
d6abca6
-                                fade->priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
-                                goto test_number;
d6abca6
-                        }
d6abca6
-
d6abca6
-                        info [screen].r = g_new0 (unsigned short, info[screen].size);
d6abca6
-                        info [screen].g = g_new0 (unsigned short, info[screen].size);
d6abca6
-                        info [screen].b = g_new0 (unsigned short, info[screen].size);
d6abca6
-
d6abca6
-                        if (! (info [screen].r && info [screen].g && info [screen].b)) {
d6abca6
-                                fade->priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
-                                goto test_number;
d6abca6
-                        }
d6abca6
-
d6abca6
-                        res = XF86VidModeGetGammaRamp (GDK_DISPLAY (),
d6abca6
-                                                       screen,
d6abca6
-                                                       info [screen].size,
d6abca6
-                                                       info [screen].r,
d6abca6
-                                                       info [screen].g,
d6abca6
-                                                       info [screen].b);
d6abca6
-                        if (! res) {
d6abca6
-                                fade->priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
-                                goto test_number;
d6abca6
-                        }
d6abca6
-                        gs_debug ("Initialized gamma ramp fade");
d6abca6
+                res = XF86VidModeGetGammaRamp (GDK_DISPLAY (),
d6abca6
+                                               screen_idx,
d6abca6
+                                               screen_priv->info->size,
d6abca6
+                                               screen_priv->info->r,
d6abca6
+                                               screen_priv->info->g,
d6abca6
+                                               screen_priv->info->b);
d6abca6
+                if (! res) {
d6abca6
+                        screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
+                        goto test_number;
d6abca6
                 }
d6abca6
+                gs_debug ("Initialized gamma ramp fade");
d6abca6
+        }
d6abca6
 # endif /* HAVE_XF86VMODE_GAMMA_RAMP */
d6abca6
 
d6abca6
  test_number:
d6abca6
-                if (FADE_TYPE_GAMMA_NUMBER == fade->priv->fade_type) {
d6abca6
-                        /* only have gamma parameter, not ramps. */
d6abca6
-
d6abca6
-                        res = XF86VidModeGetGamma (GDK_DISPLAY (), screen, &info [screen].vmg);
d6abca6
-                        if (! res) {
d6abca6
-                                fade->priv->fade_type = FADE_TYPE_NONE;
d6abca6
-                                goto test_none;
d6abca6
-                        }
d6abca6
-                        gs_debug ("Initialized gamma fade for screen %d: %f %f %f",
d6abca6
-                                  screen,
d6abca6
-                                  info [screen].vmg.red,
d6abca6
-                                  info [screen].vmg.green,
d6abca6
-                                  info [screen].vmg.blue);
d6abca6
+        if (FADE_TYPE_GAMMA_NUMBER == screen_priv->fade_type) {
d6abca6
+                /* only have gamma parameter, not ramps. */
d6abca6
+                
d6abca6
+                res = XF86VidModeGetGamma (GDK_DISPLAY (), screen_idx, &screen_priv->vmg);
d6abca6
+                if (! res) {
d6abca6
+                        screen_priv->fade_type = FADE_TYPE_NONE;
d6abca6
+                        goto test_none;
d6abca6
                 }
d6abca6
-
d6abca6
+                gs_debug ("Initialized gamma fade for screen %d: %f %f %f",
d6abca6
+                          screen_idx,
d6abca6
+                          screen_priv->vmg.red,
d6abca6
+                          screen_priv->vmg.green,
d6abca6
+                          screen_priv->vmg.blue);
d6abca6
+        }
d6abca6
+        
d6abca6
  test_none:
d6abca6
-                if (FADE_TYPE_NONE == fade->priv->fade_type) {
d6abca6
-                        goto FAIL;
d6abca6
-                }
d6abca6
+        if (FADE_TYPE_NONE == screen_priv->fade_type) {
d6abca6
+                goto FAIL;
d6abca6
         }
d6abca6
 
d6abca6
         return TRUE;
d6abca6
@@ -369,76 +349,263 @@ gamma_info_init (GSFade *fade)
d6abca6
 
d6abca6
 #endif /* HAVE_XF86VMODE_GAMMA */
d6abca6
 
d6abca6
-return FALSE;
d6abca6
+        return FALSE;
d6abca6
 }
d6abca6
 
d6abca6
 static void
d6abca6
-gamma_info_free (GSFade *fade)
d6abca6
+screen_fade_finish (GSFade *fade, int screen_idx)
d6abca6
 {
d6abca6
-#ifdef HAVE_XF86VMODE_GAMMA
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+        int i;
d6abca6
+        screen_priv = &fade->priv->screen_priv[screen_idx];
d6abca6
 
d6abca6
-        if (fade->priv->gamma_info) {
d6abca6
-                int screen;
d6abca6
+        if (!screen_priv->info)
d6abca6
+                return;
d6abca6
 
d6abca6
-                for (screen = 0; screen < fade->priv->num_screens; screen++) {
d6abca6
-                        if (fade->priv->gamma_info [screen].r) {
d6abca6
-                                g_free (fade->priv->gamma_info[screen].r);
d6abca6
-                        }
d6abca6
-                        if (fade->priv->gamma_info [screen].g) {
d6abca6
-                                g_free (fade->priv->gamma_info[screen].g);
d6abca6
-                        }
d6abca6
-                        if (fade->priv->gamma_info [screen].b) {
d6abca6
-                                g_free (fade->priv->gamma_info[screen].b);
d6abca6
-                        }
d6abca6
-                }
d6abca6
+        for (i = 0; i < screen_priv->num_ramps; i++) {
d6abca6
+                if (screen_priv->info[i].r)
d6abca6
+                        g_free (screen_priv->info[i].r);
d6abca6
+                if (screen_priv->info[i].g)
d6abca6
+                        g_free (screen_priv->info[i].g);
d6abca6
+                if (screen_priv->info[i].b)
d6abca6
+                        g_free (screen_priv->info[i].b);
d6abca6
+        }
d6abca6
+                
d6abca6
+        g_free (screen_priv->info);
d6abca6
+        screen_priv->info = NULL;
d6abca6
+        screen_priv->num_ramps = 0;
d6abca6
+}
d6abca6
 
d6abca6
-                g_free (fade->priv->gamma_info);
d6abca6
-                fade->priv->gamma_info = NULL;
d6abca6
-        }
d6abca6
+static gboolean
d6abca6
+gamma_fade_set_alpha_gamma (GSFade *fade,
d6abca6
+                            int screen_idx,
d6abca6
+                            gdouble alpha)
d6abca6
+{
d6abca6
+#ifdef HAVE_XF86VMODE_GAMMA
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+        gboolean res;
d6abca6
 
d6abca6
+        screen_priv = &fade->priv->screen_priv[screen_idx];
d6abca6
+        res = xf86_whack_gamma (screen_idx, screen_priv, alpha);
d6abca6
+
d6abca6
+        return TRUE;
d6abca6
+#else
d6abca6
+        return FALSE;
d6abca6
 #endif /* HAVE_XF86VMODE_GAMMA */
d6abca6
 }
d6abca6
 
d6abca6
-static gboolean
d6abca6
-gs_fade_set_alpha_gamma (GSFade *fade,
d6abca6
-                         gdouble alpha)
d6abca6
+static void
d6abca6
+check_gamma_extension (GSFade *fade, int screen_idx)
d6abca6
 {
d6abca6
 #ifdef HAVE_XF86VMODE_GAMMA
d6abca6
-        int      screen;
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+        int      event;
d6abca6
+        int      error;
d6abca6
+        int      major;
d6abca6
+        int      minor;
d6abca6
         gboolean res;
d6abca6
 
d6abca6
-        if (fade->priv->gamma_info != NULL) {
d6abca6
-                for (screen = 0; screen < fade->priv->num_screens; screen++) {
d6abca6
-                        res = xf86_whack_gamma (screen, &fade->priv->gamma_info [screen], alpha);
d6abca6
-                }
d6abca6
+        screen_priv = &fade->priv->screen_priv[screen_idx];
d6abca6
+
d6abca6
+        res = XF86VidModeQueryExtension (GDK_DISPLAY (), &event, &error);
d6abca6
+        if (! res)
d6abca6
+                goto fade_none;
d6abca6
+
d6abca6
+        res = safe_XF86VidModeQueryVersion (GDK_DISPLAY (), &major, &minor);
d6abca6
+        if (! res)
d6abca6
+                goto fade_none;
d6abca6
+
d6abca6
+        if (major < XF86_VIDMODE_GAMMA_MIN_MAJOR ||
d6abca6
+            (major == XF86_VIDMODE_GAMMA_MIN_MAJOR &&
d6abca6
+             minor < XF86_VIDMODE_GAMMA_MIN_MINOR))
d6abca6
+                goto fade_none;
d6abca6
+
d6abca6
+        screen_priv->fade_setup = gamma_fade_setup;
d6abca6
+        screen_priv->fade_finish = screen_fade_finish;
d6abca6
+        screen_priv->fade_set_alpha_gamma = gamma_fade_set_alpha_gamma;
d6abca6
+        
d6abca6
+        if (major < XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR ||
d6abca6
+            (major == XF86_VIDMODE_GAMMA_RAMP_MIN_MAJOR &&
d6abca6
+             minor < XF86_VIDMODE_GAMMA_RAMP_MIN_MINOR)) {
d6abca6
+                screen_priv->fade_type = FADE_TYPE_GAMMA_NUMBER;
d6abca6
+                return;
d6abca6
         }
d6abca6
 
d6abca6
+        /* Copacetic */
d6abca6
+        screen_priv->fade_type = FADE_TYPE_GAMMA_RAMP;
d6abca6
+        return;
d6abca6
+ fade_none:
d6abca6
+#endif
d6abca6
+        screen_priv->fade_type = FADE_TYPE_NONE;
d6abca6
+}
d6abca6
+
d6abca6
+/* Xrandr support */
d6abca6
+
d6abca6
+static gboolean xrandr_fade_setup (GSFade *fade, int screen_idx)
d6abca6
+{
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+        GnomeRRCrtc *crtc;
d6abca6
+        GnomeRRCrtc **crtcs;
d6abca6
+        int crtc_count = 0;
d6abca6
+        struct GSGammaInfo *info;
d6abca6
+        gboolean res;
d6abca6
+
d6abca6
+        screen_priv = &fade->priv->screen_priv[screen_idx];
d6abca6
+
d6abca6
+        if (screen_priv->info)
d6abca6
+                return TRUE;
d6abca6
+
d6abca6
+        /* refresh the screen info */
d6abca6
+        gnome_rr_screen_refresh (screen_priv->rrscreen, NULL);
d6abca6
+
d6abca6
+        crtcs = gnome_rr_screen_list_crtcs (screen_priv->rrscreen);
d6abca6
+        while (*crtcs) {
d6abca6
+                crtc_count++;
d6abca6
+                crtcs++;
d6abca6
+        };
d6abca6
+
d6abca6
+        screen_priv->info = g_new0 (struct GSGammaInfo, crtc_count);
d6abca6
+        screen_priv->num_ramps = crtc_count;
d6abca6
+
d6abca6
+        crtc_count = 0;
d6abca6
+        crtcs = gnome_rr_screen_list_crtcs (screen_priv->rrscreen);
d6abca6
+        while (*crtcs)
d6abca6
+        {
d6abca6
+                crtc = *crtcs;
d6abca6
+
d6abca6
+                info = &screen_priv->info[crtc_count];
d6abca6
+
d6abca6
+                /* if no mode ignore crtc */
d6abca6
+                if (!gnome_rr_crtc_get_current_mode (crtc)) {
d6abca6
+			info->size = 0;
d6abca6
+			info->r = NULL;
d6abca6
+			info->g = NULL;
d6abca6
+			info->b = NULL;
d6abca6
+                }
d6abca6
+		else {
d6abca6
+                	res = gnome_rr_crtc_get_gamma (crtc, &info->size,
d6abca6
+                          	                       &info->r, &info->g,
d6abca6
+                                	               &info->b);
d6abca6
+                	if (res == FALSE)
d6abca6
+                        	goto fail;
d6abca6
+		}
d6abca6
+
d6abca6
+                crtcs++;
d6abca6
+                crtc_count++;
d6abca6
+        }
d6abca6
         return TRUE;
d6abca6
-#else
d6abca6
+ fail:
d6abca6
         return FALSE;
d6abca6
-#endif /* HAVE_XF86VMODE_GAMMA */
d6abca6
+}
d6abca6
+
d6abca6
+static void xrandr_crtc_whack_gamma (GnomeRRCrtc *crtc,
d6abca6
+                                     struct GSGammaInfo *gamma_info,
d6abca6
+                                     float            ratio)
d6abca6
+{
d6abca6
+        unsigned short *r, *g, *b;
d6abca6
+        int i;
d6abca6
+
d6abca6
+        if (gamma_info->size == 0)
d6abca6
+                return;
d6abca6
+
d6abca6
+        if (ratio < 0) {
d6abca6
+                ratio = 0;
d6abca6
+        }
d6abca6
+        if (ratio > 1) {
d6abca6
+                ratio = 1;
d6abca6
+        }
d6abca6
+
d6abca6
+        r = g_new0 (unsigned short, gamma_info->size);
d6abca6
+        g = g_new0 (unsigned short, gamma_info->size);
d6abca6
+        b = g_new0 (unsigned short, gamma_info->size);
d6abca6
+
d6abca6
+        for (i = 0; i < gamma_info->size; i++) {
d6abca6
+                r[i] = gamma_info->r[i] * ratio;
d6abca6
+                g[i] = gamma_info->g[i] * ratio;
d6abca6
+                b[i] = gamma_info->b[i] * ratio;
d6abca6
+        }
d6abca6
+
d6abca6
+        gnome_rr_crtc_set_gamma (crtc, gamma_info->size,
d6abca6
+                                 r, g, b);
d6abca6
+        g_free (r);
d6abca6
+        g_free (g);
d6abca6
+        g_free (b);
d6abca6
+}
d6abca6
+
d6abca6
+static gboolean xrandr_fade_set_alpha_gamma (GSFade *fade,
d6abca6
+                                             int screen_idx,
d6abca6
+                                             gdouble alpha)
d6abca6
+{
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+        struct GSGammaInfo *info;
d6abca6
+        GnomeRRCrtc **crtcs;
d6abca6
+        int i;
d6abca6
+
d6abca6
+        screen_priv = &fade->priv->screen_priv[screen_idx];
d6abca6
+
d6abca6
+        if (!screen_priv->info)
d6abca6
+                return FALSE;
d6abca6
+
d6abca6
+        crtcs = gnome_rr_screen_list_crtcs (screen_priv->rrscreen);
d6abca6
+        i = 0;
d6abca6
+
d6abca6
+        while (*crtcs)
d6abca6
+        {
d6abca6
+                info = &screen_priv->info[i];
d6abca6
+                xrandr_crtc_whack_gamma (*crtcs, info, alpha);
d6abca6
+                i++;
d6abca6
+                crtcs++;
d6abca6
+        }
d6abca6
+        return TRUE;
d6abca6
+}
d6abca6
+
d6abca6
+static void
d6abca6
+check_randr_extension (GSFade *fade, int screen_idx)
d6abca6
+{
d6abca6
+        GdkDisplay *display = gdk_display_get_default ();
d6abca6
+        GdkScreen *screen = gdk_display_get_screen (display, screen_idx);
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+
d6abca6
+        screen_priv = &fade->priv->screen_priv[screen_idx];
d6abca6
+
d6abca6
+        screen_priv->rrscreen = gnome_rr_screen_new (screen,
d6abca6
+                                                     NULL,
d6abca6
+                                                     NULL,
d6abca6
+                                                     NULL);
d6abca6
+        if (!screen_priv->rrscreen) {
d6abca6
+                screen_priv->fade_type = FADE_TYPE_NONE;
d6abca6
+                return;
d6abca6
+        }
d6abca6
+
d6abca6
+        screen_priv->fade_type = FADE_TYPE_XRANDR;
d6abca6
+        screen_priv->fade_setup = xrandr_fade_setup;
d6abca6
+        screen_priv->fade_finish = screen_fade_finish;
d6abca6
+        screen_priv->fade_set_alpha_gamma = xrandr_fade_set_alpha_gamma;
d6abca6
 }
d6abca6
 
d6abca6
 static gboolean
d6abca6
 gs_fade_set_alpha (GSFade *fade,
d6abca6
                    gdouble alpha)
d6abca6
 {
d6abca6
-        gboolean ret;
d6abca6
+        gboolean ret = FALSE;
d6abca6
+        int i;
d6abca6
 
d6abca6
-        switch (fade->priv->fade_type) {
d6abca6
-        case FADE_TYPE_GAMMA_RAMP:
d6abca6
-        case FADE_TYPE_GAMMA_NUMBER:
d6abca6
-                ret = gs_fade_set_alpha_gamma (fade, alpha);
d6abca6
-                break;
d6abca6
-        case FADE_TYPE_NONE:
d6abca6
-                ret = FALSE;
d6abca6
-                break;
d6abca6
-        default:
d6abca6
-                g_warning ("Unknown fade type");
d6abca6
-                ret = FALSE;
d6abca6
-                break;
d6abca6
+        for (i = 0; i < fade->priv->num_screens; i++) {
d6abca6
+                switch (fade->priv->screen_priv[i].fade_type) {
d6abca6
+                case FADE_TYPE_GAMMA_RAMP:
d6abca6
+                case FADE_TYPE_GAMMA_NUMBER:
d6abca6
+                case FADE_TYPE_XRANDR:
d6abca6
+                        ret = fade->priv->screen_priv[i].fade_set_alpha_gamma (fade, i, alpha);
d6abca6
+                        break;
d6abca6
+                case FADE_TYPE_NONE:
d6abca6
+                        ret = FALSE;
d6abca6
+                        break;
d6abca6
+                default:
d6abca6
+                        g_warning ("Unknown fade type");
d6abca6
+                        ret = FALSE;
d6abca6
+                        break;
d6abca6
+                }
d6abca6
         }
d6abca6
-
d6abca6
         return ret;
d6abca6
 }
d6abca6
 
d6abca6
@@ -527,10 +694,18 @@ gs_fade_start (GSFade *fade,
d6abca6
 {
d6abca6
         guint steps_per_sec = 30;
d6abca6
         guint msecs_per_step;
d6abca6
+        struct GSFadeScreenPrivate *screen_priv;
d6abca6
+        gboolean active_fade, res;
d6abca6
+        int i;
d6abca6
 
d6abca6
         g_return_if_fail (GS_IS_FADE (fade));
d6abca6
 
d6abca6
-        gamma_info_init (fade);
d6abca6
+        for (i = 0; i < fade->priv->num_screens; i++) {
d6abca6
+                screen_priv = &fade->priv->screen_priv[i];
d6abca6
+                res = screen_priv->fade_setup (fade, i);
d6abca6
+                if (res == FALSE)
d6abca6
+                        return;
d6abca6
+        }
d6abca6
 
d6abca6
         if (fade->priv->timer_id > 0) {
d6abca6
                 gs_fade_stop (fade);
d6abca6
@@ -540,7 +715,13 @@ gs_fade_start (GSFade *fade,
d6abca6
 
d6abca6
         gs_fade_set_timeout (fade, timeout);
d6abca6
 
d6abca6
-        if (fade->priv->fade_type != FADE_TYPE_NONE) {
d6abca6
+        active_fade = FALSE;
d6abca6
+        for (i = 0; i < fade->priv->num_screens; i++) {
d6abca6
+                screen_priv = &fade->priv->screen_priv[i];
d6abca6
+                if (screen_priv->fade_type != FADE_TYPE_NONE)
d6abca6
+                        active_fade = TRUE;
d6abca6
+        }
d6abca6
+        if (active_fade) {
d6abca6
                 guint num_steps;
d6abca6
 
d6abca6
                 num_steps = (fade->priv->timeout / 1000) * steps_per_sec;
d6abca6
@@ -639,6 +820,7 @@ gs_fade_sync (GSFade        *fade,
d6abca6
 void
d6abca6
 gs_fade_reset (GSFade *fade)
d6abca6
 {
d6abca6
+        int i;
d6abca6
         g_return_if_fail (GS_IS_FADE (fade));
d6abca6
 
d6abca6
         gs_debug ("Resetting fade");
d6abca6
@@ -651,7 +833,8 @@ gs_fade_reset (GSFade *fade)
d6abca6
 
d6abca6
         gs_fade_set_alpha (fade, fade->priv->current_alpha);
d6abca6
 
d6abca6
-        gamma_info_free (fade);
d6abca6
+        for (i = 0; i < fade->priv->num_screens; i++)
d6abca6
+                fade->priv->screen_priv[i].fade_finish (fade, i);
d6abca6
 }
d6abca6
 
d6abca6
 static void
d6abca6
@@ -679,28 +862,31 @@ static void
d6abca6
 gs_fade_init (GSFade *fade)
d6abca6
 {
d6abca6
         GdkDisplay *display;
d6abca6
+        int i;
d6abca6
 
d6abca6
         fade->priv = GS_FADE_GET_PRIVATE (fade);
d6abca6
 
d6abca6
         fade->priv->timeout = 1000;
d6abca6
         fade->priv->current_alpha = 1.0;
d6abca6
 
d6abca6
-        fade->priv->fade_type = check_gamma_extension ();
d6abca6
-
d6abca6
-        gs_debug ("Fade type: %d", fade->priv->fade_type);
d6abca6
-
d6abca6
         display = gdk_display_get_default ();
d6abca6
         fade->priv->num_screens = gdk_display_get_n_screens (display);
d6abca6
 
d6abca6
-#ifdef HAVE_XF86VMODE_GAMMA
d6abca6
-        fade->priv->gamma_info = NULL;
d6abca6
-#endif
d6abca6
+        fade->priv->screen_priv = g_new0 (struct GSFadeScreenPrivate, fade->priv->num_screens);
d6abca6
+
d6abca6
+        for (i = 0; i < fade->priv->num_screens; i++) {
d6abca6
+                check_randr_extension (fade, i);
d6abca6
+                if (!fade->priv->screen_priv[i].fade_type)
d6abca6
+                        check_gamma_extension (fade, i);
d6abca6
+                gs_debug ("Fade type: %d", fade->priv->screen_priv[i].fade_type);
d6abca6
+        }
d6abca6
 }
d6abca6
 
d6abca6
 static void
d6abca6
 gs_fade_finalize (GObject *object)
d6abca6
 {
d6abca6
         GSFade *fade;
d6abca6
+        int i;
d6abca6
 
d6abca6
         g_return_if_fail (object != NULL);
d6abca6
         g_return_if_fail (GS_IS_FADE (object));
d6abca6
@@ -709,8 +895,20 @@ gs_fade_finalize (GObject *object)
d6abca6
 
d6abca6
         g_return_if_fail (fade->priv != NULL);
d6abca6
 
d6abca6
-        gamma_info_free (fade);
d6abca6
+        for (i = 0; i < fade->priv->num_screens; i++)
d6abca6
+                fade->priv->screen_priv[i].fade_finish(fade, i);
d6abca6
 
d6abca6
+        if (fade->priv->screen_priv) {
d6abca6
+                for (i = 0; i < fade->priv->num_screens; i++) {
d6abca6
+                        if (!fade->priv->screen_priv[i].rrscreen)
d6abca6
+                                continue;
d6abca6
+                        gnome_rr_screen_destroy (fade->priv->screen_priv[i].rrscreen);
d6abca6
+                }
d6abca6
+                                
d6abca6
+                g_free (fade->priv->screen_priv);
d6abca6
+                fade->priv->screen_priv = NULL;
d6abca6
+        }
d6abca6
+                
d6abca6
         G_OBJECT_CLASS (gs_fade_parent_class)->finalize (object);
d6abca6
 }
d6abca6