initial commit
[profile/ivi/xorg-x11-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
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
45 int
46 vgaListInstalledColormaps(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
57 int
58 vgaGetInstalledColormaps(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
69 int vgaCheckColorMap(ColormapPtr pmap)
70 {
71   return (pmap != GetInstalledmiColormap(pmap->pScreen));
72 }
73
74
75 void
76 vgaStoreColors(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
216 void
217 vgaInstallColormap(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
269 void
270 vgaUninstallColormap(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
289 void
290 vgaHandleColormaps(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