1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun * all copies or substantial portions of the Software.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17*4882a593Smuzhiyun * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun * OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun *
22*4882a593Smuzhiyun * Except as contained in this notice, the name of the copyright holder(s)
23*4882a593Smuzhiyun * and author(s) shall not be used in advertising or otherwise to promote
24*4882a593Smuzhiyun * the sale, use or other dealings in this Software without prior written
25*4882a593Smuzhiyun * authorization from the copyright holder(s) and author(s).
26*4882a593Smuzhiyun */
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
29*4882a593Smuzhiyun #include <xorg-config.h>
30*4882a593Smuzhiyun #endif
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #if defined(_XOPEN_SOURCE) || defined(__sun) && defined(__SVR4)
33*4882a593Smuzhiyun #include <math.h>
34*4882a593Smuzhiyun #else
35*4882a593Smuzhiyun #define _XOPEN_SOURCE /* to get prototype for pow on some systems */
36*4882a593Smuzhiyun #include <math.h>
37*4882a593Smuzhiyun #undef _XOPEN_SOURCE
38*4882a593Smuzhiyun #endif
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #include <X11/X.h>
41*4882a593Smuzhiyun #include "misc.h"
42*4882a593Smuzhiyun #include <X11/Xproto.h>
43*4882a593Smuzhiyun #include "colormapst.h"
44*4882a593Smuzhiyun #include "scrnintstr.h"
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #include "resource.h"
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun #include "xf86.h"
49*4882a593Smuzhiyun #include "xf86_OSproc.h"
50*4882a593Smuzhiyun #include "xf86str.h"
51*4882a593Smuzhiyun #include "micmap.h"
52*4882a593Smuzhiyun #include "xf86RandR12.h"
53*4882a593Smuzhiyun #include "xf86Crtc.h"
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun #ifdef XFreeXDGA
56*4882a593Smuzhiyun #include <X11/extensions/xf86dgaproto.h>
57*4882a593Smuzhiyun #include "dgaproc.h"
58*4882a593Smuzhiyun #endif
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun #include "xf86cmap.h"
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun #define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
63*4882a593Smuzhiyun ((CMapScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, CMapScreenKey))->field)
64*4882a593Smuzhiyun #define SCREEN_EPILOGUE(pScreen, field, wrapper)\
65*4882a593Smuzhiyun ((pScreen)->field = wrapper)
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun #define LOAD_PALETTE(pmap) \
68*4882a593Smuzhiyun ((pmap == GetInstalledmiColormap(pmap->pScreen)) && \
69*4882a593Smuzhiyun ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) || \
70*4882a593Smuzhiyun xf86ScreenToScrn(pmap->pScreen)->vtSema || pScreenPriv->isDGAmode))
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun typedef struct _CMapLink {
73*4882a593Smuzhiyun ColormapPtr cmap;
74*4882a593Smuzhiyun struct _CMapLink *next;
75*4882a593Smuzhiyun } CMapLink, *CMapLinkPtr;
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun typedef struct {
78*4882a593Smuzhiyun CloseScreenProcPtr CloseScreen;
79*4882a593Smuzhiyun CreateColormapProcPtr CreateColormap;
80*4882a593Smuzhiyun DestroyColormapProcPtr DestroyColormap;
81*4882a593Smuzhiyun InstallColormapProcPtr InstallColormap;
82*4882a593Smuzhiyun StoreColorsProcPtr StoreColors;
83*4882a593Smuzhiyun Bool (*EnterVT) (ScrnInfoPtr);
84*4882a593Smuzhiyun Bool (*SwitchMode) (ScrnInfoPtr, DisplayModePtr);
85*4882a593Smuzhiyun int (*SetDGAMode) (ScrnInfoPtr, int, DGADevicePtr);
86*4882a593Smuzhiyun xf86ChangeGammaProc *ChangeGamma;
87*4882a593Smuzhiyun int maxColors;
88*4882a593Smuzhiyun int sigRGBbits;
89*4882a593Smuzhiyun int gammaElements;
90*4882a593Smuzhiyun LOCO *gamma;
91*4882a593Smuzhiyun int *PreAllocIndices;
92*4882a593Smuzhiyun CMapLinkPtr maps;
93*4882a593Smuzhiyun unsigned int flags;
94*4882a593Smuzhiyun Bool isDGAmode;
95*4882a593Smuzhiyun } CMapScreenRec, *CMapScreenPtr;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun typedef struct {
98*4882a593Smuzhiyun int numColors;
99*4882a593Smuzhiyun LOCO *colors;
100*4882a593Smuzhiyun Bool recalculate;
101*4882a593Smuzhiyun int overscan;
102*4882a593Smuzhiyun } CMapColormapRec, *CMapColormapPtr;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun static DevPrivateKeyRec CMapScreenKeyRec;
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun #define CMapScreenKeyRegistered dixPrivateKeyRegistered(&CMapScreenKeyRec)
107*4882a593Smuzhiyun #define CMapScreenKey (&CMapScreenKeyRec)
108*4882a593Smuzhiyun static DevPrivateKeyRec CMapColormapKeyRec;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #define CMapColormapKey (&CMapColormapKeyRec)
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun static void CMapInstallColormap(ColormapPtr);
113*4882a593Smuzhiyun static void CMapStoreColors(ColormapPtr, int, xColorItem *);
114*4882a593Smuzhiyun static Bool CMapCloseScreen(ScreenPtr);
115*4882a593Smuzhiyun static Bool CMapCreateColormap(ColormapPtr);
116*4882a593Smuzhiyun static void CMapDestroyColormap(ColormapPtr);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun static Bool CMapEnterVT(ScrnInfoPtr);
119*4882a593Smuzhiyun static Bool CMapSwitchMode(ScrnInfoPtr, DisplayModePtr);
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun #ifdef XFreeXDGA
122*4882a593Smuzhiyun static int CMapSetDGAMode(ScrnInfoPtr, int, DGADevicePtr);
123*4882a593Smuzhiyun #endif
124*4882a593Smuzhiyun static int CMapChangeGamma(ScrnInfoPtr, Gamma);
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun static void ComputeGamma(ScrnInfoPtr, CMapScreenPtr);
127*4882a593Smuzhiyun static Bool CMapAllocateColormapPrivate(ColormapPtr);
128*4882a593Smuzhiyun static void CMapRefreshColors(ColormapPtr, int, int *);
129*4882a593Smuzhiyun static void CMapSetOverscan(ColormapPtr, int, int *);
130*4882a593Smuzhiyun static void CMapReinstallMap(ColormapPtr);
131*4882a593Smuzhiyun static void CMapUnwrapScreen(ScreenPtr pScreen);
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun Bool
xf86ColormapAllocatePrivates(ScrnInfoPtr pScrn)134*4882a593Smuzhiyun xf86ColormapAllocatePrivates(ScrnInfoPtr pScrn)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&CMapScreenKeyRec, PRIVATE_SCREEN, 0))
137*4882a593Smuzhiyun return FALSE;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&CMapColormapKeyRec, PRIVATE_COLORMAP, 0))
140*4882a593Smuzhiyun return FALSE;
141*4882a593Smuzhiyun return TRUE;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun Bool
xf86HandleColormaps(ScreenPtr pScreen,int maxColors,int sigRGBbits,xf86LoadPaletteProc * loadPalette,xf86SetOverscanProc * setOverscan,unsigned int flags)145*4882a593Smuzhiyun xf86HandleColormaps(ScreenPtr pScreen,
146*4882a593Smuzhiyun int maxColors,
147*4882a593Smuzhiyun int sigRGBbits,
148*4882a593Smuzhiyun xf86LoadPaletteProc * loadPalette,
149*4882a593Smuzhiyun xf86SetOverscanProc * setOverscan, unsigned int flags)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
152*4882a593Smuzhiyun ColormapPtr pDefMap = NULL;
153*4882a593Smuzhiyun CMapScreenPtr pScreenPriv;
154*4882a593Smuzhiyun LOCO *gamma;
155*4882a593Smuzhiyun int *indices;
156*4882a593Smuzhiyun int elements;
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun if (!maxColors || !sigRGBbits ||
159*4882a593Smuzhiyun (!loadPalette && !xf86_crtc_supports_gamma(pScrn)))
160*4882a593Smuzhiyun return FALSE;
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun elements = 1 << sigRGBbits;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun if (!(gamma = xallocarray(elements, sizeof(LOCO))))
165*4882a593Smuzhiyun return FALSE;
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun if (!(indices = xallocarray(maxColors, sizeof(int)))) {
168*4882a593Smuzhiyun free(gamma);
169*4882a593Smuzhiyun return FALSE;
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (!(pScreenPriv = malloc(sizeof(CMapScreenRec)))) {
173*4882a593Smuzhiyun free(gamma);
174*4882a593Smuzhiyun free(indices);
175*4882a593Smuzhiyun return FALSE;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, &CMapScreenKeyRec, pScreenPriv);
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun pScreenPriv->CloseScreen = pScreen->CloseScreen;
181*4882a593Smuzhiyun pScreenPriv->CreateColormap = pScreen->CreateColormap;
182*4882a593Smuzhiyun pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
183*4882a593Smuzhiyun pScreenPriv->InstallColormap = pScreen->InstallColormap;
184*4882a593Smuzhiyun pScreenPriv->StoreColors = pScreen->StoreColors;
185*4882a593Smuzhiyun pScreen->CloseScreen = CMapCloseScreen;
186*4882a593Smuzhiyun pScreen->CreateColormap = CMapCreateColormap;
187*4882a593Smuzhiyun pScreen->DestroyColormap = CMapDestroyColormap;
188*4882a593Smuzhiyun pScreen->InstallColormap = CMapInstallColormap;
189*4882a593Smuzhiyun pScreen->StoreColors = CMapStoreColors;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun pScrn->LoadPalette = loadPalette;
192*4882a593Smuzhiyun pScrn->SetOverscan = setOverscan;
193*4882a593Smuzhiyun pScreenPriv->maxColors = maxColors;
194*4882a593Smuzhiyun pScreenPriv->sigRGBbits = sigRGBbits;
195*4882a593Smuzhiyun pScreenPriv->gammaElements = elements;
196*4882a593Smuzhiyun pScreenPriv->gamma = gamma;
197*4882a593Smuzhiyun pScreenPriv->PreAllocIndices = indices;
198*4882a593Smuzhiyun pScreenPriv->maps = NULL;
199*4882a593Smuzhiyun pScreenPriv->flags = flags;
200*4882a593Smuzhiyun pScreenPriv->isDGAmode = FALSE;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun pScreenPriv->EnterVT = pScrn->EnterVT;
203*4882a593Smuzhiyun pScreenPriv->SwitchMode = pScrn->SwitchMode;
204*4882a593Smuzhiyun pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
205*4882a593Smuzhiyun pScreenPriv->ChangeGamma = pScrn->ChangeGamma;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun if (!(flags & CMAP_LOAD_EVEN_IF_OFFSCREEN)) {
208*4882a593Smuzhiyun pScrn->EnterVT = CMapEnterVT;
209*4882a593Smuzhiyun if ((flags & CMAP_RELOAD_ON_MODE_SWITCH) && pScrn->SwitchMode)
210*4882a593Smuzhiyun pScrn->SwitchMode = CMapSwitchMode;
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun #ifdef XFreeXDGA
213*4882a593Smuzhiyun pScrn->SetDGAMode = CMapSetDGAMode;
214*4882a593Smuzhiyun #endif
215*4882a593Smuzhiyun pScrn->ChangeGamma = CMapChangeGamma;
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun ComputeGamma(pScrn, pScreenPriv);
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /* get the default map */
220*4882a593Smuzhiyun dixLookupResourceByType((void **) &pDefMap, pScreen->defColormap,
221*4882a593Smuzhiyun RT_COLORMAP, serverClient, DixInstallAccess);
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun if (!CMapAllocateColormapPrivate(pDefMap)) {
224*4882a593Smuzhiyun CMapUnwrapScreen(pScreen);
225*4882a593Smuzhiyun return FALSE;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun if (xf86_crtc_supports_gamma(pScrn)) {
229*4882a593Smuzhiyun pScrn->LoadPalette = xf86RandR12LoadPalette;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun if (!xf86RandR12InitGamma(pScrn, elements)) {
232*4882a593Smuzhiyun CMapUnwrapScreen(pScreen);
233*4882a593Smuzhiyun return FALSE;
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /* Force the initial map to be loaded */
238*4882a593Smuzhiyun SetInstalledmiColormap(pScreen, NULL);
239*4882a593Smuzhiyun CMapInstallColormap(pDefMap);
240*4882a593Smuzhiyun return TRUE;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun /**** Screen functions ****/
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun static Bool
CMapCloseScreen(ScreenPtr pScreen)246*4882a593Smuzhiyun CMapCloseScreen(ScreenPtr pScreen)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun CMapUnwrapScreen(pScreen);
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun return (*pScreen->CloseScreen) (pScreen);
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun static Bool
CMapColormapUseMax(VisualPtr pVisual,CMapScreenPtr pScreenPriv)254*4882a593Smuzhiyun CMapColormapUseMax(VisualPtr pVisual, CMapScreenPtr pScreenPriv)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun if (pVisual->nplanes > 16)
257*4882a593Smuzhiyun return TRUE;
258*4882a593Smuzhiyun return ((1 << pVisual->nplanes) > pScreenPriv->maxColors);
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun static Bool
CMapAllocateColormapPrivate(ColormapPtr pmap)262*4882a593Smuzhiyun CMapAllocateColormapPrivate(ColormapPtr pmap)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
265*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pmap->pScreen->devPrivates,
266*4882a593Smuzhiyun CMapScreenKey);
267*4882a593Smuzhiyun CMapColormapPtr pColPriv;
268*4882a593Smuzhiyun CMapLinkPtr pLink;
269*4882a593Smuzhiyun int numColors;
270*4882a593Smuzhiyun LOCO *colors;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun if (CMapColormapUseMax(pmap->pVisual, pScreenPriv))
273*4882a593Smuzhiyun numColors = pmap->pVisual->ColormapEntries;
274*4882a593Smuzhiyun else
275*4882a593Smuzhiyun numColors = 1 << pmap->pVisual->nplanes;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun if (!(colors = xallocarray(numColors, sizeof(LOCO))))
278*4882a593Smuzhiyun return FALSE;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun if (!(pColPriv = malloc(sizeof(CMapColormapRec)))) {
281*4882a593Smuzhiyun free(colors);
282*4882a593Smuzhiyun return FALSE;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun dixSetPrivate(&pmap->devPrivates, CMapColormapKey, pColPriv);
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun pColPriv->numColors = numColors;
288*4882a593Smuzhiyun pColPriv->colors = colors;
289*4882a593Smuzhiyun pColPriv->recalculate = TRUE;
290*4882a593Smuzhiyun pColPriv->overscan = -1;
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun /* add map to list */
293*4882a593Smuzhiyun pLink = malloc(sizeof(CMapLink));
294*4882a593Smuzhiyun if (pLink) {
295*4882a593Smuzhiyun pLink->cmap = pmap;
296*4882a593Smuzhiyun pLink->next = pScreenPriv->maps;
297*4882a593Smuzhiyun pScreenPriv->maps = pLink;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun return TRUE;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun static Bool
CMapCreateColormap(ColormapPtr pmap)304*4882a593Smuzhiyun CMapCreateColormap(ColormapPtr pmap)
305*4882a593Smuzhiyun {
306*4882a593Smuzhiyun ScreenPtr pScreen = pmap->pScreen;
307*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
308*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
309*4882a593Smuzhiyun Bool ret = FALSE;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun pScreen->CreateColormap = pScreenPriv->CreateColormap;
312*4882a593Smuzhiyun if ((*pScreen->CreateColormap) (pmap)) {
313*4882a593Smuzhiyun if (CMapAllocateColormapPrivate(pmap))
314*4882a593Smuzhiyun ret = TRUE;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun pScreen->CreateColormap = CMapCreateColormap;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun return ret;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun static void
CMapDestroyColormap(ColormapPtr cmap)322*4882a593Smuzhiyun CMapDestroyColormap(ColormapPtr cmap)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun ScreenPtr pScreen = cmap->pScreen;
325*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
326*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
327*4882a593Smuzhiyun CMapColormapPtr pColPriv =
328*4882a593Smuzhiyun (CMapColormapPtr) dixLookupPrivate(&cmap->devPrivates, CMapColormapKey);
329*4882a593Smuzhiyun CMapLinkPtr prevLink = NULL, pLink = pScreenPriv->maps;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun if (pColPriv) {
332*4882a593Smuzhiyun free(pColPriv->colors);
333*4882a593Smuzhiyun free(pColPriv);
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* remove map from list */
337*4882a593Smuzhiyun while (pLink) {
338*4882a593Smuzhiyun if (pLink->cmap == cmap) {
339*4882a593Smuzhiyun if (prevLink)
340*4882a593Smuzhiyun prevLink->next = pLink->next;
341*4882a593Smuzhiyun else
342*4882a593Smuzhiyun pScreenPriv->maps = pLink->next;
343*4882a593Smuzhiyun free(pLink);
344*4882a593Smuzhiyun break;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun prevLink = pLink;
347*4882a593Smuzhiyun pLink = pLink->next;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun if (pScreenPriv->DestroyColormap) {
351*4882a593Smuzhiyun pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
352*4882a593Smuzhiyun (*pScreen->DestroyColormap) (cmap);
353*4882a593Smuzhiyun pScreen->DestroyColormap = CMapDestroyColormap;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun static void
CMapStoreColors(ColormapPtr pmap,int ndef,xColorItem * pdefs)358*4882a593Smuzhiyun CMapStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun ScreenPtr pScreen = pmap->pScreen;
361*4882a593Smuzhiyun VisualPtr pVisual = pmap->pVisual;
362*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
363*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
364*4882a593Smuzhiyun int *indices = pScreenPriv->PreAllocIndices;
365*4882a593Smuzhiyun int num = ndef;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun /* At the moment this isn't necessary since there's nobody below us */
368*4882a593Smuzhiyun pScreen->StoreColors = pScreenPriv->StoreColors;
369*4882a593Smuzhiyun (*pScreen->StoreColors) (pmap, ndef, pdefs);
370*4882a593Smuzhiyun pScreen->StoreColors = CMapStoreColors;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun /* should never get here for these */
373*4882a593Smuzhiyun if ((pVisual->class == TrueColor) ||
374*4882a593Smuzhiyun (pVisual->class == StaticColor) || (pVisual->class == StaticGray))
375*4882a593Smuzhiyun return;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun if (pVisual->class == DirectColor) {
378*4882a593Smuzhiyun CMapColormapPtr pColPriv =
379*4882a593Smuzhiyun (CMapColormapPtr) dixLookupPrivate(&pmap->devPrivates,
380*4882a593Smuzhiyun CMapColormapKey);
381*4882a593Smuzhiyun int i;
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun if (CMapColormapUseMax(pVisual, pScreenPriv)) {
384*4882a593Smuzhiyun int index;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun num = 0;
387*4882a593Smuzhiyun while (ndef--) {
388*4882a593Smuzhiyun if (pdefs[ndef].flags & DoRed) {
389*4882a593Smuzhiyun index = (pdefs[ndef].pixel & pVisual->redMask) >>
390*4882a593Smuzhiyun pVisual->offsetRed;
391*4882a593Smuzhiyun i = num;
392*4882a593Smuzhiyun while (i--)
393*4882a593Smuzhiyun if (indices[i] == index)
394*4882a593Smuzhiyun break;
395*4882a593Smuzhiyun if (i == -1)
396*4882a593Smuzhiyun indices[num++] = index;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun if (pdefs[ndef].flags & DoGreen) {
399*4882a593Smuzhiyun index = (pdefs[ndef].pixel & pVisual->greenMask) >>
400*4882a593Smuzhiyun pVisual->offsetGreen;
401*4882a593Smuzhiyun i = num;
402*4882a593Smuzhiyun while (i--)
403*4882a593Smuzhiyun if (indices[i] == index)
404*4882a593Smuzhiyun break;
405*4882a593Smuzhiyun if (i == -1)
406*4882a593Smuzhiyun indices[num++] = index;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun if (pdefs[ndef].flags & DoBlue) {
409*4882a593Smuzhiyun index = (pdefs[ndef].pixel & pVisual->blueMask) >>
410*4882a593Smuzhiyun pVisual->offsetBlue;
411*4882a593Smuzhiyun i = num;
412*4882a593Smuzhiyun while (i--)
413*4882a593Smuzhiyun if (indices[i] == index)
414*4882a593Smuzhiyun break;
415*4882a593Smuzhiyun if (i == -1)
416*4882a593Smuzhiyun indices[num++] = index;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun else {
422*4882a593Smuzhiyun /* not really as overkill as it seems */
423*4882a593Smuzhiyun num = pColPriv->numColors;
424*4882a593Smuzhiyun for (i = 0; i < pColPriv->numColors; i++)
425*4882a593Smuzhiyun indices[i] = i;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun else {
429*4882a593Smuzhiyun while (ndef--)
430*4882a593Smuzhiyun indices[ndef] = pdefs[ndef].pixel;
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun
433*4882a593Smuzhiyun CMapRefreshColors(pmap, num, indices);
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun static void
CMapInstallColormap(ColormapPtr pmap)437*4882a593Smuzhiyun CMapInstallColormap(ColormapPtr pmap)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun ScreenPtr pScreen = pmap->pScreen;
440*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
441*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun if (pmap == GetInstalledmiColormap(pmap->pScreen))
444*4882a593Smuzhiyun return;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun pScreen->InstallColormap = pScreenPriv->InstallColormap;
447*4882a593Smuzhiyun (*pScreen->InstallColormap) (pmap);
448*4882a593Smuzhiyun pScreen->InstallColormap = CMapInstallColormap;
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun /* Important. We let the lower layers, namely DGA,
451*4882a593Smuzhiyun overwrite the choice of Colormap to install */
452*4882a593Smuzhiyun if (GetInstalledmiColormap(pmap->pScreen))
453*4882a593Smuzhiyun pmap = GetInstalledmiColormap(pmap->pScreen);
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
456*4882a593Smuzhiyun (pmap->pVisual->class == TrueColor) &&
457*4882a593Smuzhiyun CMapColormapUseMax(pmap->pVisual, pScreenPriv))
458*4882a593Smuzhiyun return;
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun if (LOAD_PALETTE(pmap))
461*4882a593Smuzhiyun CMapReinstallMap(pmap);
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun /**** ScrnInfoRec functions ****/
465*4882a593Smuzhiyun
466*4882a593Smuzhiyun static Bool
CMapEnterVT(ScrnInfoPtr pScrn)467*4882a593Smuzhiyun CMapEnterVT(ScrnInfoPtr pScrn)
468*4882a593Smuzhiyun {
469*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
470*4882a593Smuzhiyun Bool ret;
471*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
472*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun pScrn->EnterVT = pScreenPriv->EnterVT;
475*4882a593Smuzhiyun ret = (*pScreenPriv->EnterVT) (pScrn);
476*4882a593Smuzhiyun pScreenPriv->EnterVT = pScrn->EnterVT;
477*4882a593Smuzhiyun pScrn->EnterVT = CMapEnterVT;
478*4882a593Smuzhiyun if (ret) {
479*4882a593Smuzhiyun if (GetInstalledmiColormap(pScreen))
480*4882a593Smuzhiyun CMapReinstallMap(GetInstalledmiColormap(pScreen));
481*4882a593Smuzhiyun return TRUE;
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun return FALSE;
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun static Bool
CMapSwitchMode(ScrnInfoPtr pScrn,DisplayModePtr mode)487*4882a593Smuzhiyun CMapSwitchMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
490*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
491*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if ((*pScreenPriv->SwitchMode) (pScrn, mode)) {
494*4882a593Smuzhiyun if (GetInstalledmiColormap(pScreen))
495*4882a593Smuzhiyun CMapReinstallMap(GetInstalledmiColormap(pScreen));
496*4882a593Smuzhiyun return TRUE;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun return FALSE;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun #ifdef XFreeXDGA
502*4882a593Smuzhiyun static int
CMapSetDGAMode(ScrnInfoPtr pScrn,int num,DGADevicePtr dev)503*4882a593Smuzhiyun CMapSetDGAMode(ScrnInfoPtr pScrn, int num, DGADevicePtr dev)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
506*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
507*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
508*4882a593Smuzhiyun int ret;
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun ret = (*pScreenPriv->SetDGAMode) (pScrn, num, dev);
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun pScreenPriv->isDGAmode = DGAActive(pScrn->scrnIndex);
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun if (!pScreenPriv->isDGAmode && GetInstalledmiColormap(pScreen)
515*4882a593Smuzhiyun && xf86ScreenToScrn(pScreen)->vtSema)
516*4882a593Smuzhiyun CMapReinstallMap(GetInstalledmiColormap(pScreen));
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun return ret;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun #endif
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun /**** Utilities ****/
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun static void
CMapReinstallMap(ColormapPtr pmap)525*4882a593Smuzhiyun CMapReinstallMap(ColormapPtr pmap)
526*4882a593Smuzhiyun {
527*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
528*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pmap->pScreen->devPrivates,
529*4882a593Smuzhiyun CMapScreenKey);
530*4882a593Smuzhiyun CMapColormapPtr cmapPriv =
531*4882a593Smuzhiyun (CMapColormapPtr) dixLookupPrivate(&pmap->devPrivates, CMapColormapKey);
532*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pmap->pScreen);
533*4882a593Smuzhiyun int i = cmapPriv->numColors;
534*4882a593Smuzhiyun int *indices = pScreenPriv->PreAllocIndices;
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun while (i--)
537*4882a593Smuzhiyun indices[i] = i;
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun if (cmapPriv->recalculate)
540*4882a593Smuzhiyun CMapRefreshColors(pmap, cmapPriv->numColors, indices);
541*4882a593Smuzhiyun else {
542*4882a593Smuzhiyun (*pScrn->LoadPalette) (pScrn, cmapPriv->numColors,
543*4882a593Smuzhiyun indices, cmapPriv->colors, pmap->pVisual);
544*4882a593Smuzhiyun if (pScrn->SetOverscan) {
545*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
546*4882a593Smuzhiyun ErrorF("SetOverscan() called from CMapReinstallMap\n");
547*4882a593Smuzhiyun #endif
548*4882a593Smuzhiyun pScrn->SetOverscan(pScrn, cmapPriv->overscan);
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun cmapPriv->recalculate = FALSE;
553*4882a593Smuzhiyun }
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun static void
CMapRefreshColors(ColormapPtr pmap,int defs,int * indices)556*4882a593Smuzhiyun CMapRefreshColors(ColormapPtr pmap, int defs, int *indices)
557*4882a593Smuzhiyun {
558*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
559*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pmap->pScreen->devPrivates,
560*4882a593Smuzhiyun CMapScreenKey);
561*4882a593Smuzhiyun CMapColormapPtr pColPriv =
562*4882a593Smuzhiyun (CMapColormapPtr) dixLookupPrivate(&pmap->devPrivates, CMapColormapKey);
563*4882a593Smuzhiyun VisualPtr pVisual = pmap->pVisual;
564*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pmap->pScreen);
565*4882a593Smuzhiyun int numColors, i;
566*4882a593Smuzhiyun LOCO *gamma, *colors;
567*4882a593Smuzhiyun EntryPtr entry;
568*4882a593Smuzhiyun int reds, greens, blues, maxValue, index, shift;
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun numColors = pColPriv->numColors;
571*4882a593Smuzhiyun shift = 16 - pScreenPriv->sigRGBbits;
572*4882a593Smuzhiyun maxValue = (1 << pScreenPriv->sigRGBbits) - 1;
573*4882a593Smuzhiyun gamma = pScreenPriv->gamma;
574*4882a593Smuzhiyun colors = pColPriv->colors;
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun reds = pVisual->redMask >> pVisual->offsetRed;
577*4882a593Smuzhiyun greens = pVisual->greenMask >> pVisual->offsetGreen;
578*4882a593Smuzhiyun blues = pVisual->blueMask >> pVisual->offsetBlue;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun switch (pVisual->class) {
581*4882a593Smuzhiyun case StaticGray:
582*4882a593Smuzhiyun for (i = 0; i < numColors; i++) {
583*4882a593Smuzhiyun index = (i + 1) * maxValue / numColors;
584*4882a593Smuzhiyun colors[i].red = gamma[index].red;
585*4882a593Smuzhiyun colors[i].green = gamma[index].green;
586*4882a593Smuzhiyun colors[i].blue = gamma[index].blue;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun break;
589*4882a593Smuzhiyun case TrueColor:
590*4882a593Smuzhiyun if (CMapColormapUseMax(pVisual, pScreenPriv)) {
591*4882a593Smuzhiyun for (i = 0; i <= reds; i++)
592*4882a593Smuzhiyun colors[i].red = gamma[i * maxValue / reds].red;
593*4882a593Smuzhiyun for (i = 0; i <= greens; i++)
594*4882a593Smuzhiyun colors[i].green = gamma[i * maxValue / greens].green;
595*4882a593Smuzhiyun for (i = 0; i <= blues; i++)
596*4882a593Smuzhiyun colors[i].blue = gamma[i * maxValue / blues].blue;
597*4882a593Smuzhiyun break;
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun for (i = 0; i < numColors; i++) {
600*4882a593Smuzhiyun colors[i].red = gamma[((i >> pVisual->offsetRed) & reds) *
601*4882a593Smuzhiyun maxValue / reds].red;
602*4882a593Smuzhiyun colors[i].green = gamma[((i >> pVisual->offsetGreen) & greens) *
603*4882a593Smuzhiyun maxValue / greens].green;
604*4882a593Smuzhiyun colors[i].blue = gamma[((i >> pVisual->offsetBlue) & blues) *
605*4882a593Smuzhiyun maxValue / blues].blue;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun break;
608*4882a593Smuzhiyun case StaticColor:
609*4882a593Smuzhiyun case PseudoColor:
610*4882a593Smuzhiyun case GrayScale:
611*4882a593Smuzhiyun for (i = 0; i < defs; i++) {
612*4882a593Smuzhiyun index = indices[i];
613*4882a593Smuzhiyun entry = (EntryPtr) &pmap->red[index];
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun if (entry->fShared) {
616*4882a593Smuzhiyun colors[index].red =
617*4882a593Smuzhiyun gamma[entry->co.shco.red->color >> shift].red;
618*4882a593Smuzhiyun colors[index].green =
619*4882a593Smuzhiyun gamma[entry->co.shco.green->color >> shift].green;
620*4882a593Smuzhiyun colors[index].blue =
621*4882a593Smuzhiyun gamma[entry->co.shco.blue->color >> shift].blue;
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun else {
624*4882a593Smuzhiyun colors[index].red = gamma[entry->co.local.red >> shift].red;
625*4882a593Smuzhiyun colors[index].green =
626*4882a593Smuzhiyun gamma[entry->co.local.green >> shift].green;
627*4882a593Smuzhiyun colors[index].blue = gamma[entry->co.local.blue >> shift].blue;
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun break;
631*4882a593Smuzhiyun case DirectColor:
632*4882a593Smuzhiyun if (CMapColormapUseMax(pVisual, pScreenPriv)) {
633*4882a593Smuzhiyun for (i = 0; i < defs; i++) {
634*4882a593Smuzhiyun index = indices[i];
635*4882a593Smuzhiyun if (index <= reds)
636*4882a593Smuzhiyun colors[index].red =
637*4882a593Smuzhiyun gamma[pmap->red[index].co.local.red >> shift].red;
638*4882a593Smuzhiyun if (index <= greens)
639*4882a593Smuzhiyun colors[index].green =
640*4882a593Smuzhiyun gamma[pmap->green[index].co.local.green >> shift].green;
641*4882a593Smuzhiyun if (index <= blues)
642*4882a593Smuzhiyun colors[index].blue =
643*4882a593Smuzhiyun gamma[pmap->blue[index].co.local.blue >> shift].blue;
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun break;
647*4882a593Smuzhiyun }
648*4882a593Smuzhiyun for (i = 0; i < defs; i++) {
649*4882a593Smuzhiyun index = indices[i];
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun colors[index].red = gamma[pmap->red[(index >> pVisual->
652*4882a593Smuzhiyun offsetRed) & reds].co.local.
653*4882a593Smuzhiyun red >> shift].red;
654*4882a593Smuzhiyun colors[index].green =
655*4882a593Smuzhiyun gamma[pmap->green[(index >> pVisual->offsetGreen) & greens].co.
656*4882a593Smuzhiyun local.green >> shift].green;
657*4882a593Smuzhiyun colors[index].blue =
658*4882a593Smuzhiyun gamma[pmap->blue[(index >> pVisual->offsetBlue) & blues].co.
659*4882a593Smuzhiyun local.blue >> shift].blue;
660*4882a593Smuzhiyun }
661*4882a593Smuzhiyun break;
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun if (LOAD_PALETTE(pmap))
665*4882a593Smuzhiyun (*pScrn->LoadPalette) (pScrn, defs, indices, colors, pmap->pVisual);
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun if (pScrn->SetOverscan)
668*4882a593Smuzhiyun CMapSetOverscan(pmap, defs, indices);
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
672*4882a593Smuzhiyun static Bool
CMapCompareColors(LOCO * color1,LOCO * color2)673*4882a593Smuzhiyun CMapCompareColors(LOCO * color1, LOCO * color2)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun /* return TRUE if the color1 is "closer" to black than color2 */
676*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
677*4882a593Smuzhiyun ErrorF("#%02x%02x%02x vs #%02x%02x%02x (%d vs %d)\n",
678*4882a593Smuzhiyun color1->red, color1->green, color1->blue,
679*4882a593Smuzhiyun color2->red, color2->green, color2->blue,
680*4882a593Smuzhiyun color1->red + color1->green + color1->blue,
681*4882a593Smuzhiyun color2->red + color2->green + color2->blue);
682*4882a593Smuzhiyun #endif
683*4882a593Smuzhiyun return (color1->red + color1->green + color1->blue <
684*4882a593Smuzhiyun color2->red + color2->green + color2->blue);
685*4882a593Smuzhiyun }
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun static void
CMapSetOverscan(ColormapPtr pmap,int defs,int * indices)688*4882a593Smuzhiyun CMapSetOverscan(ColormapPtr pmap, int defs, int *indices)
689*4882a593Smuzhiyun {
690*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
691*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pmap->pScreen->devPrivates,
692*4882a593Smuzhiyun CMapScreenKey);
693*4882a593Smuzhiyun CMapColormapPtr pColPriv =
694*4882a593Smuzhiyun (CMapColormapPtr) dixLookupPrivate(&pmap->devPrivates, CMapColormapKey);
695*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pmap->pScreen);
696*4882a593Smuzhiyun VisualPtr pVisual = pmap->pVisual;
697*4882a593Smuzhiyun int i;
698*4882a593Smuzhiyun LOCO *colors;
699*4882a593Smuzhiyun int index;
700*4882a593Smuzhiyun Bool newOverscan = FALSE;
701*4882a593Smuzhiyun int overscan, tmpOverscan;
702*4882a593Smuzhiyun
703*4882a593Smuzhiyun colors = pColPriv->colors;
704*4882a593Smuzhiyun overscan = pColPriv->overscan;
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun /*
707*4882a593Smuzhiyun * Search for a new overscan index in the following cases:
708*4882a593Smuzhiyun *
709*4882a593Smuzhiyun * - The index hasn't yet been initialised. In this case search
710*4882a593Smuzhiyun * for an index that is black or a close match to black.
711*4882a593Smuzhiyun *
712*4882a593Smuzhiyun * - The colour of the old index is changed. In this case search
713*4882a593Smuzhiyun * all indices for a black or close match to black.
714*4882a593Smuzhiyun *
715*4882a593Smuzhiyun * - The colour of the old index wasn't black. In this case only
716*4882a593Smuzhiyun * search the indices that were changed for a better match to black.
717*4882a593Smuzhiyun */
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun switch (pVisual->class) {
720*4882a593Smuzhiyun case StaticGray:
721*4882a593Smuzhiyun case TrueColor:
722*4882a593Smuzhiyun /* Should only come here once. Initialise the overscan index to 0 */
723*4882a593Smuzhiyun overscan = 0;
724*4882a593Smuzhiyun newOverscan = TRUE;
725*4882a593Smuzhiyun break;
726*4882a593Smuzhiyun case StaticColor:
727*4882a593Smuzhiyun /*
728*4882a593Smuzhiyun * Only come here once, but search for the overscan in the same way
729*4882a593Smuzhiyun * as for the other cases.
730*4882a593Smuzhiyun */
731*4882a593Smuzhiyun case DirectColor:
732*4882a593Smuzhiyun case PseudoColor:
733*4882a593Smuzhiyun case GrayScale:
734*4882a593Smuzhiyun if (overscan < 0 || overscan > pScreenPriv->maxColors - 1) {
735*4882a593Smuzhiyun /* Uninitialised */
736*4882a593Smuzhiyun newOverscan = TRUE;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun else {
739*4882a593Smuzhiyun /* Check if the overscan was changed */
740*4882a593Smuzhiyun for (i = 0; i < defs; i++) {
741*4882a593Smuzhiyun index = indices[i];
742*4882a593Smuzhiyun if (index == overscan) {
743*4882a593Smuzhiyun newOverscan = TRUE;
744*4882a593Smuzhiyun break;
745*4882a593Smuzhiyun }
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun }
748*4882a593Smuzhiyun if (newOverscan) {
749*4882a593Smuzhiyun /* The overscan is either uninitialised or it has been changed */
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun if (overscan < 0 || overscan > pScreenPriv->maxColors - 1)
752*4882a593Smuzhiyun tmpOverscan = pScreenPriv->maxColors - 1;
753*4882a593Smuzhiyun else
754*4882a593Smuzhiyun tmpOverscan = overscan;
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun /* search all entries for a close match to black */
757*4882a593Smuzhiyun for (i = pScreenPriv->maxColors - 1; i >= 0; i--) {
758*4882a593Smuzhiyun if (colors[i].red == 0 && colors[i].green == 0 &&
759*4882a593Smuzhiyun colors[i].blue == 0) {
760*4882a593Smuzhiyun overscan = i;
761*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
762*4882a593Smuzhiyun ErrorF("Black found at index 0x%02x\n", i);
763*4882a593Smuzhiyun #endif
764*4882a593Smuzhiyun break;
765*4882a593Smuzhiyun }
766*4882a593Smuzhiyun else {
767*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
768*4882a593Smuzhiyun ErrorF("0x%02x: ", i);
769*4882a593Smuzhiyun #endif
770*4882a593Smuzhiyun if (CMapCompareColors(&colors[i], &colors[tmpOverscan])) {
771*4882a593Smuzhiyun tmpOverscan = i;
772*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
773*4882a593Smuzhiyun ErrorF("possible \"Black\" at index 0x%02x\n", i);
774*4882a593Smuzhiyun #endif
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun }
777*4882a593Smuzhiyun }
778*4882a593Smuzhiyun if (i < 0)
779*4882a593Smuzhiyun overscan = tmpOverscan;
780*4882a593Smuzhiyun }
781*4882a593Smuzhiyun else {
782*4882a593Smuzhiyun /* Check of the old overscan wasn't black */
783*4882a593Smuzhiyun if (colors[overscan].red != 0 || colors[overscan].green != 0 ||
784*4882a593Smuzhiyun colors[overscan].blue != 0) {
785*4882a593Smuzhiyun int oldOverscan = tmpOverscan = overscan;
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun /* See of there is now a better match */
788*4882a593Smuzhiyun for (i = 0; i < defs; i++) {
789*4882a593Smuzhiyun index = indices[i];
790*4882a593Smuzhiyun if (colors[index].red == 0 && colors[index].green == 0 &&
791*4882a593Smuzhiyun colors[index].blue == 0) {
792*4882a593Smuzhiyun overscan = index;
793*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
794*4882a593Smuzhiyun ErrorF("Black found at index 0x%02x\n", index);
795*4882a593Smuzhiyun #endif
796*4882a593Smuzhiyun break;
797*4882a593Smuzhiyun }
798*4882a593Smuzhiyun else {
799*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
800*4882a593Smuzhiyun ErrorF("0x%02x: ", index);
801*4882a593Smuzhiyun #endif
802*4882a593Smuzhiyun if (CMapCompareColors(&colors[index],
803*4882a593Smuzhiyun &colors[tmpOverscan])) {
804*4882a593Smuzhiyun tmpOverscan = index;
805*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
806*4882a593Smuzhiyun ErrorF("possible \"Black\" at index 0x%02x\n",
807*4882a593Smuzhiyun index);
808*4882a593Smuzhiyun #endif
809*4882a593Smuzhiyun }
810*4882a593Smuzhiyun }
811*4882a593Smuzhiyun }
812*4882a593Smuzhiyun if (i == defs)
813*4882a593Smuzhiyun overscan = tmpOverscan;
814*4882a593Smuzhiyun if (overscan != oldOverscan)
815*4882a593Smuzhiyun newOverscan = TRUE;
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun }
818*4882a593Smuzhiyun break;
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun if (newOverscan) {
821*4882a593Smuzhiyun pColPriv->overscan = overscan;
822*4882a593Smuzhiyun if (LOAD_PALETTE(pmap)) {
823*4882a593Smuzhiyun #ifdef DEBUGOVERSCAN
824*4882a593Smuzhiyun ErrorF("SetOverscan() called from CmapSetOverscan\n");
825*4882a593Smuzhiyun #endif
826*4882a593Smuzhiyun pScrn->SetOverscan(pScrn, overscan);
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun }
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun static void
CMapUnwrapScreen(ScreenPtr pScreen)832*4882a593Smuzhiyun CMapUnwrapScreen(ScreenPtr pScreen)
833*4882a593Smuzhiyun {
834*4882a593Smuzhiyun CMapScreenPtr pScreenPriv =
835*4882a593Smuzhiyun (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates, CMapScreenKey);
836*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun pScreen->CloseScreen = pScreenPriv->CloseScreen;
839*4882a593Smuzhiyun pScreen->CreateColormap = pScreenPriv->CreateColormap;
840*4882a593Smuzhiyun pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
841*4882a593Smuzhiyun pScreen->InstallColormap = pScreenPriv->InstallColormap;
842*4882a593Smuzhiyun pScreen->StoreColors = pScreenPriv->StoreColors;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun pScrn->EnterVT = pScreenPriv->EnterVT;
845*4882a593Smuzhiyun pScrn->SwitchMode = pScreenPriv->SwitchMode;
846*4882a593Smuzhiyun pScrn->SetDGAMode = pScreenPriv->SetDGAMode;
847*4882a593Smuzhiyun pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
848*4882a593Smuzhiyun
849*4882a593Smuzhiyun free(pScreenPriv->gamma);
850*4882a593Smuzhiyun free(pScreenPriv->PreAllocIndices);
851*4882a593Smuzhiyun free(pScreenPriv);
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun static void
ComputeGamma(ScrnInfoPtr pScrn,CMapScreenPtr priv)855*4882a593Smuzhiyun ComputeGamma(ScrnInfoPtr pScrn, CMapScreenPtr priv)
856*4882a593Smuzhiyun {
857*4882a593Smuzhiyun int elements = priv->gammaElements - 1;
858*4882a593Smuzhiyun double RedGamma, GreenGamma, BlueGamma;
859*4882a593Smuzhiyun int i;
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun #ifndef DONT_CHECK_GAMMA
862*4882a593Smuzhiyun /* This check is to catch drivers that are not initialising pScrn->gamma */
863*4882a593Smuzhiyun if (pScrn->gamma.red < GAMMA_MIN || pScrn->gamma.red > GAMMA_MAX ||
864*4882a593Smuzhiyun pScrn->gamma.green < GAMMA_MIN || pScrn->gamma.green > GAMMA_MAX ||
865*4882a593Smuzhiyun pScrn->gamma.blue < GAMMA_MIN || pScrn->gamma.blue > GAMMA_MAX) {
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 0,
868*4882a593Smuzhiyun "The %s driver didn't call xf86SetGamma() to initialise\n"
869*4882a593Smuzhiyun "\tthe gamma values.\n", pScrn->driverName);
870*4882a593Smuzhiyun xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 0,
871*4882a593Smuzhiyun "PLEASE FIX THE `%s' DRIVER!\n",
872*4882a593Smuzhiyun pScrn->driverName);
873*4882a593Smuzhiyun pScrn->gamma.red = 1.0;
874*4882a593Smuzhiyun pScrn->gamma.green = 1.0;
875*4882a593Smuzhiyun pScrn->gamma.blue = 1.0;
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun #endif
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun RedGamma = 1.0 / (double) pScrn->gamma.red;
880*4882a593Smuzhiyun GreenGamma = 1.0 / (double) pScrn->gamma.green;
881*4882a593Smuzhiyun BlueGamma = 1.0 / (double) pScrn->gamma.blue;
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun for (i = 0; i <= elements; i++) {
884*4882a593Smuzhiyun if (RedGamma == 1.0)
885*4882a593Smuzhiyun priv->gamma[i].red = i;
886*4882a593Smuzhiyun else
887*4882a593Smuzhiyun priv->gamma[i].red = (CARD16) (pow((double) i / (double) elements,
888*4882a593Smuzhiyun RedGamma) * (double) elements +
889*4882a593Smuzhiyun 0.5);
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun if (GreenGamma == 1.0)
892*4882a593Smuzhiyun priv->gamma[i].green = i;
893*4882a593Smuzhiyun else
894*4882a593Smuzhiyun priv->gamma[i].green = (CARD16) (pow((double) i / (double) elements,
895*4882a593Smuzhiyun GreenGamma) *
896*4882a593Smuzhiyun (double) elements + 0.5);
897*4882a593Smuzhiyun
898*4882a593Smuzhiyun if (BlueGamma == 1.0)
899*4882a593Smuzhiyun priv->gamma[i].blue = i;
900*4882a593Smuzhiyun else
901*4882a593Smuzhiyun priv->gamma[i].blue = (CARD16) (pow((double) i / (double) elements,
902*4882a593Smuzhiyun BlueGamma) * (double) elements +
903*4882a593Smuzhiyun 0.5);
904*4882a593Smuzhiyun }
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun int
CMapChangeGamma(ScrnInfoPtr pScrn,Gamma gamma)908*4882a593Smuzhiyun CMapChangeGamma(ScrnInfoPtr pScrn, Gamma gamma)
909*4882a593Smuzhiyun {
910*4882a593Smuzhiyun int ret = Success;
911*4882a593Smuzhiyun ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
912*4882a593Smuzhiyun CMapColormapPtr pColPriv;
913*4882a593Smuzhiyun CMapScreenPtr pScreenPriv;
914*4882a593Smuzhiyun CMapLinkPtr pLink;
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun /* Is this sufficient checking ? */
917*4882a593Smuzhiyun if (!CMapScreenKeyRegistered)
918*4882a593Smuzhiyun return BadImplementation;
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun pScreenPriv = (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
921*4882a593Smuzhiyun CMapScreenKey);
922*4882a593Smuzhiyun if (!pScreenPriv)
923*4882a593Smuzhiyun return BadImplementation;
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun if (gamma.red < GAMMA_MIN || gamma.red > GAMMA_MAX ||
926*4882a593Smuzhiyun gamma.green < GAMMA_MIN || gamma.green > GAMMA_MAX ||
927*4882a593Smuzhiyun gamma.blue < GAMMA_MIN || gamma.blue > GAMMA_MAX)
928*4882a593Smuzhiyun return BadValue;
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun pScrn->gamma.red = gamma.red;
931*4882a593Smuzhiyun pScrn->gamma.green = gamma.green;
932*4882a593Smuzhiyun pScrn->gamma.blue = gamma.blue;
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun ComputeGamma(pScrn, pScreenPriv);
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun /* mark all colormaps on this screen */
937*4882a593Smuzhiyun pLink = pScreenPriv->maps;
938*4882a593Smuzhiyun while (pLink) {
939*4882a593Smuzhiyun pColPriv = (CMapColormapPtr) dixLookupPrivate(&pLink->cmap->devPrivates,
940*4882a593Smuzhiyun CMapColormapKey);
941*4882a593Smuzhiyun pColPriv->recalculate = TRUE;
942*4882a593Smuzhiyun pLink = pLink->next;
943*4882a593Smuzhiyun }
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun if (GetInstalledmiColormap(pScreen) &&
946*4882a593Smuzhiyun ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
947*4882a593Smuzhiyun pScrn->vtSema || pScreenPriv->isDGAmode)) {
948*4882a593Smuzhiyun ColormapPtr pMap = GetInstalledmiColormap(pScreen);
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
951*4882a593Smuzhiyun (pMap->pVisual->class == TrueColor) &&
952*4882a593Smuzhiyun CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun /* if the current map doesn't have a palette look
955*4882a593Smuzhiyun for another map to change the gamma on. */
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun pLink = pScreenPriv->maps;
958*4882a593Smuzhiyun while (pLink) {
959*4882a593Smuzhiyun if (pLink->cmap->pVisual->class == PseudoColor)
960*4882a593Smuzhiyun break;
961*4882a593Smuzhiyun pLink = pLink->next;
962*4882a593Smuzhiyun }
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun if (pLink) {
965*4882a593Smuzhiyun /* need to trick CMapRefreshColors() into thinking
966*4882a593Smuzhiyun this is the currently installed map */
967*4882a593Smuzhiyun SetInstalledmiColormap(pScreen, pLink->cmap);
968*4882a593Smuzhiyun CMapReinstallMap(pLink->cmap);
969*4882a593Smuzhiyun SetInstalledmiColormap(pScreen, pMap);
970*4882a593Smuzhiyun }
971*4882a593Smuzhiyun }
972*4882a593Smuzhiyun else
973*4882a593Smuzhiyun CMapReinstallMap(pMap);
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
977*4882a593Smuzhiyun if (pScrn->ChangeGamma)
978*4882a593Smuzhiyun ret = pScrn->ChangeGamma(pScrn, gamma);
979*4882a593Smuzhiyun pScrn->ChangeGamma = CMapChangeGamma;
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun return ret;
982*4882a593Smuzhiyun }
983*4882a593Smuzhiyun
984*4882a593Smuzhiyun static void
ComputeGammaRamp(CMapScreenPtr priv,unsigned short * red,unsigned short * green,unsigned short * blue)985*4882a593Smuzhiyun ComputeGammaRamp(CMapScreenPtr priv,
986*4882a593Smuzhiyun unsigned short *red,
987*4882a593Smuzhiyun unsigned short *green, unsigned short *blue)
988*4882a593Smuzhiyun {
989*4882a593Smuzhiyun int elements = priv->gammaElements;
990*4882a593Smuzhiyun LOCO *entry = priv->gamma;
991*4882a593Smuzhiyun int shift = 16 - priv->sigRGBbits;
992*4882a593Smuzhiyun
993*4882a593Smuzhiyun while (elements--) {
994*4882a593Smuzhiyun entry->red = *(red++) >> shift;
995*4882a593Smuzhiyun entry->green = *(green++) >> shift;
996*4882a593Smuzhiyun entry->blue = *(blue++) >> shift;
997*4882a593Smuzhiyun entry++;
998*4882a593Smuzhiyun }
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun
1001*4882a593Smuzhiyun int
xf86ChangeGammaRamp(ScreenPtr pScreen,int size,unsigned short * red,unsigned short * green,unsigned short * blue)1002*4882a593Smuzhiyun xf86ChangeGammaRamp(ScreenPtr pScreen,
1003*4882a593Smuzhiyun int size,
1004*4882a593Smuzhiyun unsigned short *red,
1005*4882a593Smuzhiyun unsigned short *green, unsigned short *blue)
1006*4882a593Smuzhiyun {
1007*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1008*4882a593Smuzhiyun CMapColormapPtr pColPriv;
1009*4882a593Smuzhiyun CMapScreenPtr pScreenPriv;
1010*4882a593Smuzhiyun CMapLinkPtr pLink;
1011*4882a593Smuzhiyun
1012*4882a593Smuzhiyun if (!CMapScreenKeyRegistered)
1013*4882a593Smuzhiyun return BadImplementation;
1014*4882a593Smuzhiyun
1015*4882a593Smuzhiyun pScreenPriv = (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
1016*4882a593Smuzhiyun CMapScreenKey);
1017*4882a593Smuzhiyun if (!pScreenPriv)
1018*4882a593Smuzhiyun return BadImplementation;
1019*4882a593Smuzhiyun
1020*4882a593Smuzhiyun if (pScreenPriv->gammaElements != size)
1021*4882a593Smuzhiyun return BadValue;
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun ComputeGammaRamp(pScreenPriv, red, green, blue);
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun /* mark all colormaps on this screen */
1026*4882a593Smuzhiyun pLink = pScreenPriv->maps;
1027*4882a593Smuzhiyun while (pLink) {
1028*4882a593Smuzhiyun pColPriv = (CMapColormapPtr) dixLookupPrivate(&pLink->cmap->devPrivates,
1029*4882a593Smuzhiyun CMapColormapKey);
1030*4882a593Smuzhiyun pColPriv->recalculate = TRUE;
1031*4882a593Smuzhiyun pLink = pLink->next;
1032*4882a593Smuzhiyun }
1033*4882a593Smuzhiyun
1034*4882a593Smuzhiyun if (GetInstalledmiColormap(pScreen) &&
1035*4882a593Smuzhiyun ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
1036*4882a593Smuzhiyun pScrn->vtSema || pScreenPriv->isDGAmode)) {
1037*4882a593Smuzhiyun ColormapPtr pMap = GetInstalledmiColormap(pScreen);
1038*4882a593Smuzhiyun
1039*4882a593Smuzhiyun if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
1040*4882a593Smuzhiyun (pMap->pVisual->class == TrueColor) &&
1041*4882a593Smuzhiyun CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun /* if the current map doesn't have a palette look
1044*4882a593Smuzhiyun for another map to change the gamma on. */
1045*4882a593Smuzhiyun
1046*4882a593Smuzhiyun pLink = pScreenPriv->maps;
1047*4882a593Smuzhiyun while (pLink) {
1048*4882a593Smuzhiyun if (pLink->cmap->pVisual->class == PseudoColor)
1049*4882a593Smuzhiyun break;
1050*4882a593Smuzhiyun pLink = pLink->next;
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun
1053*4882a593Smuzhiyun if (pLink) {
1054*4882a593Smuzhiyun /* need to trick CMapRefreshColors() into thinking
1055*4882a593Smuzhiyun this is the currently installed map */
1056*4882a593Smuzhiyun SetInstalledmiColormap(pScreen, pLink->cmap);
1057*4882a593Smuzhiyun CMapReinstallMap(pLink->cmap);
1058*4882a593Smuzhiyun SetInstalledmiColormap(pScreen, pMap);
1059*4882a593Smuzhiyun }
1060*4882a593Smuzhiyun }
1061*4882a593Smuzhiyun else
1062*4882a593Smuzhiyun CMapReinstallMap(pMap);
1063*4882a593Smuzhiyun }
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun return Success;
1066*4882a593Smuzhiyun }
1067*4882a593Smuzhiyun
1068*4882a593Smuzhiyun int
xf86GetGammaRampSize(ScreenPtr pScreen)1069*4882a593Smuzhiyun xf86GetGammaRampSize(ScreenPtr pScreen)
1070*4882a593Smuzhiyun {
1071*4882a593Smuzhiyun CMapScreenPtr pScreenPriv;
1072*4882a593Smuzhiyun
1073*4882a593Smuzhiyun if (!CMapScreenKeyRegistered)
1074*4882a593Smuzhiyun return 0;
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun pScreenPriv = (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
1077*4882a593Smuzhiyun CMapScreenKey);
1078*4882a593Smuzhiyun if (!pScreenPriv)
1079*4882a593Smuzhiyun return 0;
1080*4882a593Smuzhiyun
1081*4882a593Smuzhiyun return pScreenPriv->gammaElements;
1082*4882a593Smuzhiyun }
1083*4882a593Smuzhiyun
1084*4882a593Smuzhiyun int
xf86GetGammaRamp(ScreenPtr pScreen,int size,unsigned short * red,unsigned short * green,unsigned short * blue)1085*4882a593Smuzhiyun xf86GetGammaRamp(ScreenPtr pScreen,
1086*4882a593Smuzhiyun int size,
1087*4882a593Smuzhiyun unsigned short *red,
1088*4882a593Smuzhiyun unsigned short *green, unsigned short *blue)
1089*4882a593Smuzhiyun {
1090*4882a593Smuzhiyun CMapScreenPtr pScreenPriv;
1091*4882a593Smuzhiyun LOCO *entry;
1092*4882a593Smuzhiyun int shift, sigbits;
1093*4882a593Smuzhiyun
1094*4882a593Smuzhiyun if (!CMapScreenKeyRegistered)
1095*4882a593Smuzhiyun return BadImplementation;
1096*4882a593Smuzhiyun
1097*4882a593Smuzhiyun pScreenPriv = (CMapScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
1098*4882a593Smuzhiyun CMapScreenKey);
1099*4882a593Smuzhiyun if (!pScreenPriv)
1100*4882a593Smuzhiyun return BadImplementation;
1101*4882a593Smuzhiyun
1102*4882a593Smuzhiyun if (size > pScreenPriv->gammaElements)
1103*4882a593Smuzhiyun return BadValue;
1104*4882a593Smuzhiyun
1105*4882a593Smuzhiyun entry = pScreenPriv->gamma;
1106*4882a593Smuzhiyun sigbits = pScreenPriv->sigRGBbits;
1107*4882a593Smuzhiyun
1108*4882a593Smuzhiyun while (size--) {
1109*4882a593Smuzhiyun *red = entry->red << (16 - sigbits);
1110*4882a593Smuzhiyun *green = entry->green << (16 - sigbits);
1111*4882a593Smuzhiyun *blue = entry->blue << (16 - sigbits);
1112*4882a593Smuzhiyun shift = sigbits;
1113*4882a593Smuzhiyun while (shift < 16) {
1114*4882a593Smuzhiyun *red |= *red >> shift;
1115*4882a593Smuzhiyun *green |= *green >> shift;
1116*4882a593Smuzhiyun *blue |= *blue >> shift;
1117*4882a593Smuzhiyun shift += sigbits;
1118*4882a593Smuzhiyun }
1119*4882a593Smuzhiyun red++;
1120*4882a593Smuzhiyun green++;
1121*4882a593Smuzhiyun blue++;
1122*4882a593Smuzhiyun entry++;
1123*4882a593Smuzhiyun }
1124*4882a593Smuzhiyun
1125*4882a593Smuzhiyun return Success;
1126*4882a593Smuzhiyun }
1127*4882a593Smuzhiyun
1128*4882a593Smuzhiyun int
xf86ChangeGamma(ScreenPtr pScreen,Gamma gamma)1129*4882a593Smuzhiyun xf86ChangeGamma(ScreenPtr pScreen, Gamma gamma)
1130*4882a593Smuzhiyun {
1131*4882a593Smuzhiyun ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1132*4882a593Smuzhiyun
1133*4882a593Smuzhiyun if (pScrn->ChangeGamma)
1134*4882a593Smuzhiyun return (*pScrn->ChangeGamma) (pScrn, gamma);
1135*4882a593Smuzhiyun
1136*4882a593Smuzhiyun return BadImplementation;
1137*4882a593Smuzhiyun }
1138