Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / vgahw / vgaCmap.c
CommitLineData
a09e091a
JB
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
43int
44vgaListInstalledColormaps(pScreen, pmaps)
45ScreenPtr pScreen;
46Colormap *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
55int
56vgaGetInstalledColormaps(pScreen, pmaps)
57ScreenPtr pScreen;
58ColormapPtr *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
67int
68vgaCheckColorMap(ColormapPtr pmap)
69{
70 return (pmap != GetInstalledmiColormap(pmap->pScreen));
71}
72
73void
74vgaStoreColors(pmap, ndef, pdefs)
75ColormapPtr pmap;
76int ndef;
77xColorItem *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
195void
196vgaInstallColormap(pmap)
197ColormapPtr 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
245void
246vgaUninstallColormap(pmap)
247ColormapPtr 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
265void
266vgaHandleColormaps(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}