ba02439
From feaa2623530296ccb783b63ec7b06105f0795af9 Mon Sep 17 00:00:00 2001
ba02439
From: Adam Jackson <ajax@redhat.com>
ba02439
Date: Wed, 15 Apr 2009 15:50:18 -0400
ba02439
Subject: [PATCH] Hook up RANDR gamma to xf86vm
ba02439
ba02439
---
ba02439
 hw/xfree86/common/xf86RandR.c  |    1 +
ba02439
 hw/xfree86/common/xf86cmap.c   |   13 ++++++++-
ba02439
 hw/xfree86/modes/xf86RandR12.c |   55 ++++++++++++++++++++++++++++++++++++++++
ba02439
 3 files changed, 67 insertions(+), 2 deletions(-)
ba02439
ba02439
diff --git a/hw/xfree86/common/xf86RandR.c b/hw/xfree86/common/xf86RandR.c
ba02439
index de2f78c..58e5cc5 100644
ba02439
--- a/hw/xfree86/common/xf86RandR.c
ba02439
+++ b/hw/xfree86/common/xf86RandR.c
ba02439
@@ -30,6 +30,7 @@
ba02439
 #include "mibank.h"
ba02439
 #include "globals.h"
ba02439
 #include "xf86.h"
ba02439
+#include "xf86str.h"
ba02439
 #include "xf86Priv.h"
ba02439
 #include "xf86DDC.h"
ba02439
 #include "mipointer.h"
ba02439
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
ba02439
--- a/hw/xfree86/common/xf86cmap.c
ba02439
+++ b/hw/xfree86/common/xf86cmap.c
ba02439
@@ -84,6 +84,7 @@ typedef struct {
ba02439
   Bool				(*EnterVT)(int, int);
ba02439
   Bool				(*SwitchMode)(int, DisplayModePtr, int);
ba02439
   int				(*SetDGAMode)(int, int, DGADevicePtr);
ba02439
+  xf86ChangeGammaProc		*ChangeGamma;
ba02439
   int				maxColors;
ba02439
   int				sigRGBbits;
ba02439
   int				gammaElements;
ba02439
@@ -190,6 +191,7 @@ _X_EXPORT Bool xf86HandleColormaps(
ba02439
     pScreenPriv->EnterVT = pScrn->EnterVT;
ba02439
     pScreenPriv->SwitchMode = pScrn->SwitchMode;
ba02439
     pScreenPriv->SetDGAMode = pScrn->SetDGAMode;    
ba02439
+    pScreenPriv->ChangeGamma = pScrn->ChangeGamma;
ba02439
 
ba02439
     if (!(flags & CMAP_LOAD_EVEN_IF_OFFSCREEN)) {
ba02439
 	pScrn->EnterVT = CMapEnterVT;
ba02439
@@ -819,6 +821,7 @@ CMapUnwrapScreen(ScreenPtr pScreen)
ba02439
     pScrn->EnterVT = pScreenPriv->EnterVT; 
ba02439
     pScrn->SwitchMode = pScreenPriv->SwitchMode; 
ba02439
     pScrn->SetDGAMode = pScreenPriv->SetDGAMode; 
ba02439
+    pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
ba02439
 
ba02439
     xfree(pScreenPriv->gamma);
ba02439
     xfree(pScreenPriv->PreAllocIndices);
ba02439
@@ -884,6 +887,7 @@ CMapChangeGamma(
ba02439
    int index,
ba02439
    Gamma gamma
ba02439
 ){
ba02439
+    int ret = Success;
ba02439
     ScrnInfoPtr pScrn = xf86Screens[index];
ba02439
     ScreenPtr pScreen = pScrn->pScreen;
ba02439
     CMapColormapPtr pColPriv;
ba02439
@@ -949,7 +953,12 @@ CMapChangeGamma(
ba02439
 	    CMapReinstallMap(pMap);
ba02439
     }
ba02439
 
ba02439
-    return Success;
ba02439
+    pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
ba02439
+    if (pScrn->ChangeGamma)
ba02439
+	ret = pScrn->ChangeGamma(index, gamma);
ba02439
+    pScrn->ChangeGamma = CMapChangeGamma;
ba02439
+
ba02439
+    return ret;
ba02439
 }
ba02439
 
ba02439
 
ba02439
@@ -1108,5 +1117,5 @@ xf86ChangeGamma(
ba02439
     if(pScrn->ChangeGamma)
ba02439
 	return (*pScrn->ChangeGamma)(pScreen->myNum, gamma);
ba02439
 
ba02439
-    return Success; /* Success? */
ba02439
+    return BadImplementation;
ba02439
 }
ba02439
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
ba02439
--- a/hw/xfree86/modes/xf86RandR12.c
ba02439
+++ b/hw/xfree86/modes/xf86RandR12.c
ba02439
@@ -1647,6 +1647,60 @@ xf86RandR13SetPanning (ScreenPtr           pScreen,
ba02439
     }
ba02439
 }
ba02439
 
ba02439
+/*
ba02439
+ * Compatibility with XF86VidMode's gamma changer.  This necessarily clobbers
ba02439
+ * any per-crtc setup.  You asked for it...
ba02439
+ */
ba02439
+
ba02439
+static void
ba02439
+gamma_to_ramp(float gamma, CARD16 *ramp, int size)
ba02439
+{
ba02439
+    int i;
ba02439
+
ba02439
+    for (i = 0; i < size; i++) {
ba02439
+	if (gamma == 1.0)
ba02439
+	    ramp[i] = i << 8;
ba02439
+	else
ba02439
+	    ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), gamma)
ba02439
+			       * (double)(size - 1) * 256);
ba02439
+    }
ba02439
+}
ba02439
+
ba02439
+static int
ba02439
+xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
ba02439
+{
ba02439
+    int i, size = 0;
ba02439
+    CARD16 *points, *red, *green, *blue;
ba02439
+    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
ba02439
+    rrScrPrivPtr rp = rrGetScrPriv(pScrn->pScreen);
494d02e
+
ba02439
+    for (i = 0; i < rp->numCrtcs; i++)
ba02439
+	size = max(size, rp->crtcs[i]->gammaSize);
ba02439
+
ba02439
+    if (!size)
ba02439
+	return Success;
ba02439
+
ba02439
+    points = xcalloc(size, 3 * sizeof(CARD16));
ba02439
+    if (!points)
ba02439
+	return BadAlloc;
ba02439
+
ba02439
+    red = points;
ba02439
+    green = points + size;
ba02439
+    blue = points + 2 * size;
ba02439
+
ba02439
+    for (i = 0; i < rp->numCrtcs; i++) {
ba02439
+	gamma_to_ramp(gamma.red, red, rp->crtcs[i]->gammaSize);
ba02439
+	gamma_to_ramp(gamma.green, green, rp->crtcs[i]->gammaSize);
ba02439
+	gamma_to_ramp(gamma.blue, blue, rp->crtcs[i]->gammaSize);
ba02439
+	RRCrtcGammaSet(rp->crtcs[i], red, green, blue);
ba02439
+	memset(points, 0, 3 * size * sizeof(CARD16));
ba02439
+    }
ba02439
+
ba02439
+    xfree(points);
ba02439
+
ba02439
+    return Success;
ba02439
+}
ba02439
+
ba02439
 static Bool
ba02439
 xf86RandR12Init12 (ScreenPtr pScreen)
ba02439
 {
ba02439
@@ -1667,6 +1721,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
ba02439
     rp->rrModeDestroy = xf86RandR12ModeDestroy;
ba02439
     rp->rrSetConfig = NULL;
ba02439
     pScrn->PointerMoved = xf86RandR12PointerMoved;
ba02439
+    pScrn->ChangeGamma = xf86RandR12ChangeGamma;
ba02439
     if (!xf86RandR12CreateObjects12 (pScreen))
ba02439
 	return FALSE;
ba02439
 
ba02439
-- 
ba02439
1.6.2.2
ba02439