Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / vgahw / vgaCmap.c
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 #ifdef HAVE_XORG_CONFIG_H
25 #include <xorg-config.h>
26 #endif
27
28 #include <X11/X.h>
29 #include <X11/Xproto.h>
30 #include "windowstr.h"
31 #include "compiler.h"
32 #include "mipointer.h"
33 #include "micmap.h"
34
35 #include "xf86.h"
36 #include "vgaHW.h"
37
38 #include <X11/extensions/xf86dgaproto.h>
39 #include "dgaproc.h"
40
41 #define NOMAPYET (ColormapPtr) 0
42
43 int
44 vgaListInstalledColormaps(pScreen, pmaps)
45 ScreenPtr pScreen;
46 Colormap *pmaps;
47 {
48 /* By the time we are processing requests, we can guarantee that there
49 * is always a colormap installed */
50
51 *pmaps = GetInstalledmiColormap(pScreen)->mid;
52 return 1;
53 }
54
55 int
56 vgaGetInstalledColormaps(pScreen, pmaps)
57 ScreenPtr pScreen;
58 ColormapPtr *pmaps;
59 {
60 /* By the time we are processing requests, we can guarantee that there
61 * is always a colormap installed */
62
63 *pmaps = GetInstalledmiColormap(pScreen);
64 return 1;
65 }
66
67 int
68 vgaCheckColorMap(ColormapPtr pmap)
69 {
70 return (pmap != GetInstalledmiColormap(pmap->pScreen));
71 }
72
73 void
74 vgaStoreColors(pmap, ndef, pdefs)
75 ColormapPtr pmap;
76 int ndef;
77 xColorItem *pdefs;
78 {
79 int i;
80 unsigned char *cmap, *tmp = NULL;
81 xColorItem directDefs[256];
82 Bool new_overscan = FALSE;
83 Bool writeColormap;
84 int scrnIndex = pmap->pScreen->myNum;
85 ScrnInfoPtr scrninfp = xf86ScreenToScrn(pmap->pScreen);
86 vgaHWPtr hwp = VGAHWPTR(scrninfp);
87
88 unsigned char overscan = hwp->ModeReg.Attribute[OVERSCAN];
89 unsigned char tmp_overscan = 0;
90
91 if (vgaCheckColorMap(pmap))
92 return;
93
94 if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
95 ndef = miExpandDirectColors(pmap, ndef, pdefs, directDefs);
96 pdefs = directDefs;
97 }
98
99 writeColormap = scrninfp->vtSema;
100 if (DGAScreenAvailable(pmap->pScreen)) {
101 writeColormap = writeColormap ||
102 (DGAGetDirectMode(scrnIndex) &&
103 !(DGAGetFlags(scrnIndex) & XF86DGADirectColormap)) ||
104 (DGAGetFlags(scrnIndex) & XF86DGAHasColormap);
105 }
106
107 if (writeColormap)
108 hwp->enablePalette(hwp);
109
110 for (i = 0; i < ndef; i++) {
111 if (pdefs[i].pixel == overscan) {
112 new_overscan = TRUE;
113 }
114 cmap = &(hwp->ModeReg.DAC[pdefs[i].pixel * 3]);
115 if (scrninfp->rgbBits == 8) {
116 cmap[0] = pdefs[i].red >> 8;
117 cmap[1] = pdefs[i].green >> 8;
118 cmap[2] = pdefs[i].blue >> 8;
119 }
120 else {
121 cmap[0] = pdefs[i].red >> 10;
122 cmap[1] = pdefs[i].green >> 10;
123 cmap[2] = pdefs[i].blue >> 10;
124 }
125 #if 0
126 if (clgd6225Lcd) {
127 /* The LCD doesn't like white */
128 if (cmap[0] == 63)
129 cmap[0] = 62;
130 if (cmap[1] == 63)
131 cmap[1] = 62;
132 if (cmap[2] == 63)
133 cmap[2] = 62;
134 }
135 #endif
136
137 if (writeColormap) {
138 if (hwp->ShowOverscan && i == 255)
139 continue;
140 hwp->writeDacWriteAddr(hwp, pdefs[i].pixel);
141 DACDelay(hwp);
142 hwp->writeDacData(hwp, cmap[0]);
143 DACDelay(hwp);
144 hwp->writeDacData(hwp, cmap[1]);
145 DACDelay(hwp);
146 hwp->writeDacData(hwp, cmap[2]);
147 DACDelay(hwp);
148 }
149 }
150 if (new_overscan && !hwp->ShowOverscan) {
151 new_overscan = FALSE;
152 for (i = 0; i < ndef; i++) {
153 if (pdefs[i].pixel == overscan) {
154 if ((pdefs[i].red != 0) ||
155 (pdefs[i].green != 0) || (pdefs[i].blue != 0)) {
156 new_overscan = TRUE;
157 tmp_overscan = overscan;
158 tmp = &(hwp->ModeReg.DAC[pdefs[i].pixel * 3]);
159 }
160 break;
161 }
162 }
163 if (new_overscan) {
164 /*
165 * Find a black pixel, or the nearest match.
166 */
167 for (i = 255; i >= 0; i--) {
168 cmap = &(hwp->ModeReg.DAC[i * 3]);
169 if ((cmap[0] == 0) && (cmap[1] == 0) && (cmap[2] == 0)) {
170 overscan = i;
171 break;
172 }
173 else {
174 if ((cmap[0] < tmp[0]) &&
175 (cmap[1] < tmp[1]) && (cmap[2] < tmp[2])) {
176 tmp = cmap;
177 tmp_overscan = i;
178 }
179 }
180 }
181 if (i < 0) {
182 overscan = tmp_overscan;
183 }
184 hwp->ModeReg.Attribute[OVERSCAN] = overscan;
185 if (writeColormap) {
186 hwp->writeAttr(hwp, OVERSCAN, overscan);
187 }
188 }
189 }
190
191 if (writeColormap)
192 hwp->disablePalette(hwp);
193 }
194
195 void
196 vgaInstallColormap(pmap)
197 ColormapPtr pmap;
198 {
199 ColormapPtr oldmap = GetInstalledmiColormap(pmap->pScreen);
200 int entries;
201 Pixel *ppix;
202 xrgb *prgb;
203 xColorItem *defs;
204 int i;
205
206 if (pmap == oldmap)
207 return;
208
209 if ((pmap->pVisual->class | DynamicClass) == DirectColor)
210 entries = (pmap->pVisual->redMask |
211 pmap->pVisual->greenMask | pmap->pVisual->blueMask) + 1;
212 else
213 entries = pmap->pVisual->ColormapEntries;
214
215 ppix = (Pixel *) malloc(entries * sizeof(Pixel));
216 prgb = (xrgb *) malloc(entries * sizeof(xrgb));
217 defs = (xColorItem *) malloc(entries * sizeof(xColorItem));
218
219 if (oldmap != NOMAPYET)
220 WalkTree(pmap->pScreen, TellLostMap, &oldmap->mid);
221
222 SetInstalledmiColormap(pmap->pScreen, pmap);
223
224 for (i = 0; i < entries; i++)
225 ppix[i] = i;
226
227 QueryColors(pmap, entries, ppix, prgb, serverClient);
228
229 for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
230 defs[i].pixel = ppix[i];
231 defs[i].red = prgb[i].red;
232 defs[i].green = prgb[i].green;
233 defs[i].blue = prgb[i].blue;
234 defs[i].flags = DoRed | DoGreen | DoBlue;
235 }
236 pmap->pScreen->StoreColors(pmap, entries, defs);
237
238 WalkTree(pmap->pScreen, TellGainedMap, &pmap->mid);
239
240 free(ppix);
241 free(prgb);
242 free(defs);
243 }
244
245 void
246 vgaUninstallColormap(pmap)
247 ColormapPtr pmap;
248 {
249
250 ColormapPtr defColormap;
251
252 if (pmap != GetInstalledmiColormap(pmap->pScreen))
253 return;
254
255 dixLookupResourceByType((pointer *) &defColormap,
256 pmap->pScreen->defColormap, RT_COLORMAP,
257 serverClient, DixInstallAccess);
258
259 if (defColormap == GetInstalledmiColormap(pmap->pScreen))
260 return;
261
262 (*pmap->pScreen->InstallColormap) (defColormap);
263 }
264
265 void
266 vgaHandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp)
267 {
268 if (scrnp->bitsPerPixel > 1) {
269 if (scrnp->bitsPerPixel <= 8) { /* For 8bpp SVGA and VGA16 */
270 pScreen->InstallColormap = vgaInstallColormap;
271 pScreen->UninstallColormap = vgaUninstallColormap;
272 pScreen->ListInstalledColormaps = vgaListInstalledColormaps;
273 pScreen->StoreColors = vgaStoreColors;
274 }
275 }
276 }