summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/common/xf86RandR.c1
-rw-r--r--hw/xfree86/common/xf86cmap.c13
-rw-r--r--hw/xfree86/modes/xf86RandR12.c55
3 files changed, 67 insertions, 2 deletions
diff --git a/hw/xfree86/common/xf86RandR.c b/hw/xfree86/common/xf86RandR.c
index 0e06de661..02dcc34b4 100644
--- a/hw/xfree86/common/xf86RandR.c
+++ b/hw/xfree86/common/xf86RandR.c
@@ -30,6 +30,7 @@
#include "mibank.h"
#include "globals.h"
#include "xf86.h"
+#include "xf86str.h"
#include "xf86Priv.h"
#include "xf86DDC.h"
#include "mipointer.h"
diff --git a/hw/xfree86/common/xf86cmap.c b/hw/xfree86/common/xf86cmap.c
index 316470df4..a627b5315 100644
--- a/hw/xfree86/common/xf86cmap.c
+++ b/hw/xfree86/common/xf86cmap.c
@@ -85,6 +85,7 @@ typedef struct {
Bool (*EnterVT)(int, int);
Bool (*SwitchMode)(int, DisplayModePtr, int);
int (*SetDGAMode)(int, int, DGADevicePtr);
+ xf86ChangeGammaProc *ChangeGamma;
int maxColors;
int sigRGBbits;
int gammaElements;
@@ -195,6 +196,7 @@ Bool xf86HandleColormaps(
pScreenPriv->EnterVT = pScrn->EnterVT;
pScreenPriv->SwitchMode = pScrn->SwitchMode;
pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
+ pScreenPriv->ChangeGamma = pScrn->ChangeGamma;
if (!(flags & CMAP_LOAD_EVEN_IF_OFFSCREEN)) {
pScrn->EnterVT = CMapEnterVT;
@@ -824,6 +826,7 @@ CMapUnwrapScreen(ScreenPtr pScreen)
pScrn->EnterVT = pScreenPriv->EnterVT;
pScrn->SwitchMode = pScreenPriv->SwitchMode;
pScrn->SetDGAMode = pScreenPriv->SetDGAMode;
+ pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
xfree(pScreenPriv->gamma);
xfree(pScreenPriv->PreAllocIndices);
@@ -889,6 +892,7 @@ CMapChangeGamma(
int index,
Gamma gamma
){
+ int ret = Success;
ScrnInfoPtr pScrn = xf86Screens[index];
ScreenPtr pScreen = pScrn->pScreen;
CMapColormapPtr pColPriv;
@@ -954,7 +958,12 @@ CMapChangeGamma(
CMapReinstallMap(pMap);
}
- return Success;
+ pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
+ if (pScrn->ChangeGamma)
+ ret = pScrn->ChangeGamma(index, gamma);
+ pScrn->ChangeGamma = CMapChangeGamma;
+
+ return ret;
}
@@ -1113,5 +1122,5 @@ xf86ChangeGamma(
if(pScrn->ChangeGamma)
return (*pScrn->ChangeGamma)(pScreen->myNum, gamma);
- return Success; /* Success? */
+ return BadImplementation;
}
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index ac066a85f..f941a3b4a 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1689,6 +1689,60 @@ xf86RandR13SetPanning (ScreenPtr pScreen,
}
}
+/*
+ * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers
+ * any per-crtc setup. You asked for it...
+ */
+
+static void
+gamma_to_ramp(float gamma, CARD16 *ramp, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (gamma == 1.0)
+ ramp[i] = i << 8;
+ else
+ ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), gamma)
+ * (double)(size - 1) * 256);
+ }
+}
+
+static int
+xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
+{
+ int i, size = 0;
+ CARD16 *points, *red, *green, *blue;
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ rrScrPrivPtr rp = rrGetScrPriv(pScrn->pScreen);
+
+ for (i = 0; i < rp->numCrtcs; i++)
+ size = max(size, rp->crtcs[i]->gammaSize);
+
+ if (!size)
+ return Success;
+
+ points = xcalloc(size, 3 * sizeof(CARD16));
+ if (!points)
+ return BadAlloc;
+
+ red = points;
+ green = points + size;
+ blue = points + 2 * size;
+
+ for (i = 0; i < rp->numCrtcs; i++) {
+ gamma_to_ramp(gamma.red, red, rp->crtcs[i]->gammaSize);
+ gamma_to_ramp(gamma.green, green, rp->crtcs[i]->gammaSize);
+ gamma_to_ramp(gamma.blue, blue, rp->crtcs[i]->gammaSize);
+ RRCrtcGammaSet(rp->crtcs[i], red, green, blue);
+ memset(points, 0, 3 * size * sizeof(CARD16));
+ }
+
+ xfree(points);
+
+ return Success;
+}
+
static Bool
xf86RandR12Init12 (ScreenPtr pScreen)
{
@@ -1710,6 +1764,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
rp->rrModeDestroy = xf86RandR12ModeDestroy;
rp->rrSetConfig = NULL;
pScrn->PointerMoved = xf86RandR12PointerMoved;
+ pScrn->ChangeGamma = xf86RandR12ChangeGamma;
if (!xf86RandR12CreateObjects12 (pScreen))
return FALSE;