1/*
2 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Thomas Roell not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Thomas Roell makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as is" without express or implied warranty.
13 *
14 * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 */
23
24
25#ifdef HAVE_XORG_CONFIG_H
26#include <xorg-config.h>
27#endif
28
29#include <X11/X.h>
30#include <X11/Xproto.h>
31#include "windowstr.h"
32#include "compiler.h"
33#include "mipointer.h"
34#include "micmap.h"
35
36#include "xf86.h"
37#include "vgaHW.h"
38
39#include <X11/extensions/xf86dgaproto.h>
40#include "dgaproc.h"
41
42
43#define NOMAPYET        (ColormapPtr) 0
44
45int
46vgaListInstalledColormaps(pScreen, pmaps)
47     ScreenPtr	pScreen;
48     Colormap	*pmaps;
49{
50  /* By the time we are processing requests, we can guarantee that there
51   * is always a colormap installed */
52
53  *pmaps = GetInstalledmiColormap(pScreen)->mid;
54  return 1;
55}
56
57int
58vgaGetInstalledColormaps(pScreen, pmaps)
59     ScreenPtr		pScreen;
60     ColormapPtr	*pmaps;
61{
62  /* By the time we are processing requests, we can guarantee that there
63   * is always a colormap installed */
64
65  *pmaps = GetInstalledmiColormap(pScreen);
66  return 1;
67}
68
69int vgaCheckColorMap(ColormapPtr pmap)
70{
71  return (pmap != GetInstalledmiColormap(pmap->pScreen));
72}
73
74
75void
76vgaStoreColors(pmap, ndef, pdefs)
77     ColormapPtr	pmap;
78     int		ndef;
79     xColorItem	        *pdefs;
80{
81    int		i;
82    unsigned char *cmap, *tmp = NULL;
83    xColorItem	directDefs[256];
84    Bool          new_overscan = FALSE;
85    Bool	writeColormap;
86
87    /* This can get called before the ScrnInfoRec is installed so we
88       can't rely on getting it with XF86SCRNINFO() */
89    int scrnIndex = pmap->pScreen->myNum;
90    ScrnInfoPtr scrninfp = xf86Screens[scrnIndex];
91    vgaHWPtr hwp = VGAHWPTR(scrninfp);
92
93    unsigned char overscan = hwp->ModeReg.Attribute[OVERSCAN];
94    unsigned char tmp_overscan = 0;
95
96    if (vgaCheckColorMap(pmap))
97        return;
98
99    if ((pmap->pVisual->class | DynamicClass) == DirectColor)
100    {
101        ndef = miExpandDirectColors (pmap, ndef, pdefs, directDefs);
102        pdefs = directDefs;
103    }
104
105    writeColormap = scrninfp->vtSema;
106    if (DGAAvailable(scrnIndex))
107    {
108	writeColormap = writeColormap ||
109			(DGAGetDirectMode(scrnIndex) &&
110			 !(DGAGetFlags(scrnIndex) & XF86DGADirectColormap)) ||
111			(DGAGetFlags(scrnIndex) & XF86DGAHasColormap);
112    }
113
114    if (writeColormap)
115	hwp->enablePalette(hwp);
116
117    for(i = 0; i < ndef; i++)
118    {
119        if (pdefs[i].pixel == overscan)
120	{
121	    new_overscan = TRUE;
122	}
123        cmap = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
124	if (scrninfp->rgbBits == 8) {
125            cmap[0] = pdefs[i].red   >> 8;
126            cmap[1] = pdefs[i].green >> 8;
127            cmap[2] = pdefs[i].blue  >> 8;
128        }
129        else {
130            cmap[0] = pdefs[i].red   >> 10;
131            cmap[1] = pdefs[i].green >> 10;
132            cmap[2] = pdefs[i].blue  >> 10;
133        }
134#if 0
135	if (clgd6225Lcd)
136	{
137		/* The LCD doesn't like white */
138		if (cmap[0] == 63) cmap[0]= 62;
139		if (cmap[1] == 63) cmap[1]= 62;
140		if (cmap[2] == 63) cmap[2]= 62;
141	}
142#endif
143
144        if (writeColormap)
145	{
146	    if (hwp->ShowOverscan && i == 255)
147		continue;
148	    hwp->writeDacWriteAddr(hwp, pdefs[i].pixel);
149	    DACDelay(hwp);
150	    hwp->writeDacData(hwp, cmap[0]);
151	    DACDelay(hwp);
152	    hwp->writeDacData(hwp, cmap[1]);
153	    DACDelay(hwp);
154	    hwp->writeDacData(hwp, cmap[2]);
155	    DACDelay(hwp);
156	}
157    }
158    if (new_overscan && !hwp->ShowOverscan)
159    {
160	new_overscan = FALSE;
161        for(i = 0; i < ndef; i++)
162        {
163            if (pdefs[i].pixel == overscan)
164	    {
165	        if ((pdefs[i].red != 0) ||
166	            (pdefs[i].green != 0) ||
167	            (pdefs[i].blue != 0))
168	        {
169	            new_overscan = TRUE;
170		    tmp_overscan = overscan;
171        	    tmp = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
172	        }
173	        break;
174	    }
175        }
176        if (new_overscan)
177        {
178            /*
179             * Find a black pixel, or the nearest match.
180             */
181            for (i=255; i >= 0; i--)
182	    {
183                cmap = &(hwp->ModeReg.DAC[i*3]);
184	        if ((cmap[0] == 0) && (cmap[1] == 0) && (cmap[2] == 0))
185	        {
186	            overscan = i;
187	            break;
188	        }
189	        else
190	        {
191	            if ((cmap[0] < tmp[0]) &&
192		        (cmap[1] < tmp[1]) && (cmap[2] < tmp[2]))
193	            {
194		        tmp = cmap;
195		        tmp_overscan = i;
196	            }
197	        }
198	    }
199	    if (i < 0)
200	    {
201	        overscan = tmp_overscan;
202	    }
203	    hwp->ModeReg.Attribute[OVERSCAN] = overscan;
204            if (writeColormap)
205	    {
206	      hwp->writeAttr(hwp, OVERSCAN, overscan);
207	    }
208        }
209    }
210
211    if (writeColormap)
212	hwp->disablePalette(hwp);
213}
214
215
216void
217vgaInstallColormap(pmap)
218     ColormapPtr	pmap;
219{
220  ColormapPtr oldmap = GetInstalledmiColormap(pmap->pScreen);
221  int         entries;
222  Pixel *     ppix;
223  xrgb *      prgb;
224  xColorItem *defs;
225  int         i;
226
227
228  if (pmap == oldmap)
229    return;
230
231  if ((pmap->pVisual->class | DynamicClass) == DirectColor)
232    entries = (pmap->pVisual->redMask |
233	       pmap->pVisual->greenMask |
234	       pmap->pVisual->blueMask) + 1;
235  else
236    entries = pmap->pVisual->ColormapEntries;
237
238  ppix = (Pixel *)malloc( entries * sizeof(Pixel));
239  prgb = (xrgb *)malloc( entries * sizeof(xrgb));
240  defs = (xColorItem *)malloc(entries * sizeof(xColorItem));
241
242  if ( oldmap != NOMAPYET)
243    WalkTree( pmap->pScreen, TellLostMap, &oldmap->mid);
244
245  SetInstalledmiColormap(pmap->pScreen, pmap);
246
247  for ( i=0; i<entries; i++) ppix[i] = i;
248
249  QueryColors(pmap, entries, ppix, prgb, serverClient);
250
251  for ( i=0; i<entries; i++) /* convert xrgbs to xColorItems */
252    {
253      defs[i].pixel = ppix[i];
254      defs[i].red = prgb[i].red;
255      defs[i].green = prgb[i].green;
256      defs[i].blue = prgb[i].blue;
257      defs[i].flags =  DoRed|DoGreen|DoBlue;
258    }
259  pmap->pScreen->StoreColors(pmap, entries, defs);
260
261  WalkTree(pmap->pScreen, TellGainedMap, &pmap->mid);
262
263  free(ppix);
264  free(prgb);
265  free(defs);
266}
267
268
269void
270vgaUninstallColormap(pmap)
271     ColormapPtr pmap;
272{
273
274  ColormapPtr defColormap;
275
276  if ( pmap != GetInstalledmiColormap(pmap->pScreen))
277    return;
278
279  dixLookupResourceByType((pointer *)&defColormap, pmap->pScreen->defColormap,
280			  RT_COLORMAP, serverClient, DixInstallAccess);
281
282  if (defColormap == GetInstalledmiColormap(pmap->pScreen))
283    return;
284
285  (*pmap->pScreen->InstallColormap) (defColormap);
286}
287
288
289void
290vgaHandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp)
291{
292  if (scrnp->bitsPerPixel > 1) {
293     if (scrnp->bitsPerPixel <= 8) { /* For 8bpp SVGA and VGA16 */
294        pScreen->InstallColormap = vgaInstallColormap;
295        pScreen->UninstallColormap = vgaUninstallColormap;
296        pScreen->ListInstalledColormaps = vgaListInstalledColormaps;
297        pScreen->StoreColors = vgaStoreColors;
298    }
299  }
300}
301
302