xref: /OK3568_Linux_fs/external/xserver/hw/xwin/wincmap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *Permission is hereby granted, free of charge, to any person obtaining
5*4882a593Smuzhiyun  * a copy of this software and associated documentation files (the
6*4882a593Smuzhiyun  *"Software"), to deal in the Software without restriction, including
7*4882a593Smuzhiyun  *without limitation the rights to use, copy, modify, merge, publish,
8*4882a593Smuzhiyun  *distribute, sublicense, and/or sell copies of the Software, and to
9*4882a593Smuzhiyun  *permit persons to whom the Software is furnished to do so, subject to
10*4882a593Smuzhiyun  *the following conditions:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  *The above copyright notice and this permission notice shall be
13*4882a593Smuzhiyun  *included in all copies or substantial portions of the Software.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16*4882a593Smuzhiyun  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17*4882a593Smuzhiyun  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18*4882a593Smuzhiyun  *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19*4882a593Smuzhiyun  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20*4882a593Smuzhiyun  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21*4882a593Smuzhiyun  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  *Except as contained in this notice, the name of the XFree86 Project
24*4882a593Smuzhiyun  *shall not be used in advertising or otherwise to promote the sale, use
25*4882a593Smuzhiyun  *or other dealings in this Software without prior written authorization
26*4882a593Smuzhiyun  *from the XFree86 Project.
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * Authors:	Dakshinamurthy Karra
29*4882a593Smuzhiyun  *		Suhaib M Siddiqi
30*4882a593Smuzhiyun  *		Peter Busch
31*4882a593Smuzhiyun  *		Harold L Hunt II
32*4882a593Smuzhiyun  */
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #ifdef HAVE_XWIN_CONFIG_H
35*4882a593Smuzhiyun #include <xwin-config.h>
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun #include "win.h"
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /*
40*4882a593Smuzhiyun  * Local prototypes
41*4882a593Smuzhiyun  */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun static int
44*4882a593Smuzhiyun  winListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps);
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun static void
47*4882a593Smuzhiyun  winStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun static void
50*4882a593Smuzhiyun  winInstallColormap(ColormapPtr pmap);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun static void
53*4882a593Smuzhiyun  winUninstallColormap(ColormapPtr pmap);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun static void
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun winResolveColor(unsigned short *pred,
58*4882a593Smuzhiyun                 unsigned short *pgreen,
59*4882a593Smuzhiyun                 unsigned short *pblue, VisualPtr pVisual);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun static Bool
62*4882a593Smuzhiyun  winCreateColormap(ColormapPtr pmap);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun static void
65*4882a593Smuzhiyun  winDestroyColormap(ColormapPtr pmap);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun static Bool
68*4882a593Smuzhiyun  winGetPaletteDIB(ScreenPtr pScreen, ColormapPtr pcmap);
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun static Bool
71*4882a593Smuzhiyun  winGetPaletteDD(ScreenPtr pScreen, ColormapPtr pcmap);
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun  * Set screen functions for colormaps
75*4882a593Smuzhiyun  */
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun void
winSetColormapFunctions(ScreenPtr pScreen)78*4882a593Smuzhiyun winSetColormapFunctions(ScreenPtr pScreen)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun     pScreen->CreateColormap = winCreateColormap;
81*4882a593Smuzhiyun     pScreen->DestroyColormap = winDestroyColormap;
82*4882a593Smuzhiyun     pScreen->InstallColormap = winInstallColormap;
83*4882a593Smuzhiyun     pScreen->UninstallColormap = winUninstallColormap;
84*4882a593Smuzhiyun     pScreen->ListInstalledColormaps = winListInstalledColormaps;
85*4882a593Smuzhiyun     pScreen->StoreColors = winStoreColors;
86*4882a593Smuzhiyun     pScreen->ResolveColor = winResolveColor;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun /* See Porting Layer Definition - p. 30 */
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun  * Walk the list of installed colormaps, filling the pmaps list
92*4882a593Smuzhiyun  * with the resource ids of the installed maps, and return
93*4882a593Smuzhiyun  * a count of the total number of installed maps.
94*4882a593Smuzhiyun  */
95*4882a593Smuzhiyun static int
winListInstalledColormaps(ScreenPtr pScreen,Colormap * pmaps)96*4882a593Smuzhiyun winListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun     winScreenPriv(pScreen);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun     /*
101*4882a593Smuzhiyun      * There will only be one installed colormap, so we only need
102*4882a593Smuzhiyun      * to return one id, and the count of installed maps will always
103*4882a593Smuzhiyun      * be one.
104*4882a593Smuzhiyun      */
105*4882a593Smuzhiyun     *pmaps = pScreenPriv->pcmapInstalled->mid;
106*4882a593Smuzhiyun     return 1;
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun /* See Porting Layer Definition - p. 30 */
110*4882a593Smuzhiyun /* See Programming Windows - p. 663 */
111*4882a593Smuzhiyun static void
winInstallColormap(ColormapPtr pColormap)112*4882a593Smuzhiyun winInstallColormap(ColormapPtr pColormap)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun     ScreenPtr pScreen = pColormap->pScreen;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun     winScreenPriv(pScreen);
117*4882a593Smuzhiyun     ColormapPtr oldpmap = pScreenPriv->pcmapInstalled;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun #if CYGDEBUG
120*4882a593Smuzhiyun     winDebug("winInstallColormap\n");
121*4882a593Smuzhiyun #endif
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun     /* Did the colormap actually change? */
124*4882a593Smuzhiyun     if (pColormap != oldpmap) {
125*4882a593Smuzhiyun #if CYGDEBUG
126*4882a593Smuzhiyun         winDebug("winInstallColormap - Colormap has changed, attempt "
127*4882a593Smuzhiyun                  "to install.\n");
128*4882a593Smuzhiyun #endif
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun         /* Was there a previous colormap? */
131*4882a593Smuzhiyun         if (oldpmap != (ColormapPtr) None) {
132*4882a593Smuzhiyun             /* There was a previous colormap; tell clients it is gone */
133*4882a593Smuzhiyun             WalkTree(pColormap->pScreen, TellLostMap, (char *) &oldpmap->mid);
134*4882a593Smuzhiyun         }
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun         /* Install new colormap */
137*4882a593Smuzhiyun         pScreenPriv->pcmapInstalled = pColormap;
138*4882a593Smuzhiyun         WalkTree(pColormap->pScreen, TellGainedMap, (char *) &pColormap->mid);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun         /* Call the engine specific colormap install procedure */
141*4882a593Smuzhiyun         if (!((*pScreenPriv->pwinInstallColormap) (pColormap))) {
142*4882a593Smuzhiyun             winErrorFVerb(2,
143*4882a593Smuzhiyun                           "winInstallColormap - Screen specific colormap install "
144*4882a593Smuzhiyun                           "procedure failed.  Continuing, but colors may be "
145*4882a593Smuzhiyun                           "messed up from now on.\n");
146*4882a593Smuzhiyun         }
147*4882a593Smuzhiyun     }
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun     /* Save a pointer to the newly installed colormap */
150*4882a593Smuzhiyun     pScreenPriv->pcmapInstalled = pColormap;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /* See Porting Layer Definition - p. 30 */
154*4882a593Smuzhiyun static void
winUninstallColormap(ColormapPtr pmap)155*4882a593Smuzhiyun winUninstallColormap(ColormapPtr pmap)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun     winScreenPriv(pmap->pScreen);
158*4882a593Smuzhiyun     ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun #if CYGDEBUG
161*4882a593Smuzhiyun     winDebug("winUninstallColormap\n");
162*4882a593Smuzhiyun #endif
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun     /* Is the colormap currently installed? */
165*4882a593Smuzhiyun     if (pmap != curpmap) {
166*4882a593Smuzhiyun         /* Colormap not installed, nothing to do */
167*4882a593Smuzhiyun         return;
168*4882a593Smuzhiyun     }
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun     /* Clear the installed colormap flag */
171*4882a593Smuzhiyun     pScreenPriv->pcmapInstalled = NULL;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun     /*
174*4882a593Smuzhiyun      * NOTE: The default colormap does not get "uninstalled" before
175*4882a593Smuzhiyun      * it is destroyed.
176*4882a593Smuzhiyun      */
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun     /* Install the default cmap in place of the cmap to be uninstalled */
179*4882a593Smuzhiyun     if (pmap->mid != pmap->pScreen->defColormap) {
180*4882a593Smuzhiyun         dixLookupResourceByType((void *) &curpmap, pmap->pScreen->defColormap,
181*4882a593Smuzhiyun                                 RT_COLORMAP, NullClient, DixUnknownAccess);
182*4882a593Smuzhiyun         (*pmap->pScreen->InstallColormap) (curpmap);
183*4882a593Smuzhiyun     }
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun /* See Porting Layer Definition - p. 30 */
187*4882a593Smuzhiyun static void
winStoreColors(ColormapPtr pmap,int ndef,xColorItem * pdefs)188*4882a593Smuzhiyun winStoreColors(ColormapPtr pmap, int ndef, xColorItem * pdefs)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun     ScreenPtr pScreen = pmap->pScreen;
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun     winScreenPriv(pScreen);
193*4882a593Smuzhiyun     winCmapPriv(pmap);
194*4882a593Smuzhiyun     int i;
195*4882a593Smuzhiyun     unsigned short nRed, nGreen, nBlue;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun #if CYGDEBUG
198*4882a593Smuzhiyun     if (ndef != 1)
199*4882a593Smuzhiyun         winDebug("winStoreColors - ndef: %d\n", ndef);
200*4882a593Smuzhiyun #endif
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun     /* Save the new colors in the colormap privates */
203*4882a593Smuzhiyun     for (i = 0; i < ndef; ++i) {
204*4882a593Smuzhiyun         /* Adjust the colors from the X color spec to the Windows color spec */
205*4882a593Smuzhiyun         nRed = pdefs[i].red >> 8;
206*4882a593Smuzhiyun         nGreen = pdefs[i].green >> 8;
207*4882a593Smuzhiyun         nBlue = pdefs[i].blue >> 8;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun         /* Copy the colors to a palette entry table */
210*4882a593Smuzhiyun         pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed;
211*4882a593Smuzhiyun         pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen;
212*4882a593Smuzhiyun         pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun         /* Copy the colors to a RGBQUAD table */
215*4882a593Smuzhiyun         pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed;
216*4882a593Smuzhiyun         pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen;
217*4882a593Smuzhiyun         pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun #if CYGDEBUG
220*4882a593Smuzhiyun         winDebug("winStoreColors - nRed %d nGreen %d nBlue %d\n",
221*4882a593Smuzhiyun                  nRed, nGreen, nBlue);
222*4882a593Smuzhiyun #endif
223*4882a593Smuzhiyun     }
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun     /* Call the engine specific store colors procedure */
226*4882a593Smuzhiyun     if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs))) {
227*4882a593Smuzhiyun         winErrorFVerb(2,
228*4882a593Smuzhiyun                       "winStoreColors - Engine cpecific color storage procedure "
229*4882a593Smuzhiyun                       "failed.  Continuing, but colors may be messed up from now "
230*4882a593Smuzhiyun                       "on.\n");
231*4882a593Smuzhiyun     }
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun /* See Porting Layer Definition - p. 30 */
235*4882a593Smuzhiyun static void
winResolveColor(unsigned short * pred,unsigned short * pgreen,unsigned short * pblue,VisualPtr pVisual)236*4882a593Smuzhiyun winResolveColor(unsigned short *pred,
237*4882a593Smuzhiyun                 unsigned short *pgreen,
238*4882a593Smuzhiyun                 unsigned short *pblue, VisualPtr pVisual)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun #if CYGDEBUG
241*4882a593Smuzhiyun     winDebug("winResolveColor ()\n");
242*4882a593Smuzhiyun #endif
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun     miResolveColor(pred, pgreen, pblue, pVisual);
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun /* See Porting Layer Definition - p. 29 */
248*4882a593Smuzhiyun static Bool
winCreateColormap(ColormapPtr pmap)249*4882a593Smuzhiyun winCreateColormap(ColormapPtr pmap)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun     winPrivCmapPtr pCmapPriv = NULL;
252*4882a593Smuzhiyun     ScreenPtr pScreen = pmap->pScreen;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun     winScreenPriv(pScreen);
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun #if CYGDEBUG
257*4882a593Smuzhiyun     winDebug("winCreateColormap\n");
258*4882a593Smuzhiyun #endif
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun     /* Allocate colormap privates */
261*4882a593Smuzhiyun     if (!winAllocateCmapPrivates(pmap)) {
262*4882a593Smuzhiyun         ErrorF("winCreateColorma - Couldn't allocate cmap privates\n");
263*4882a593Smuzhiyun         return FALSE;
264*4882a593Smuzhiyun     }
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun     /* Get a pointer to the newly allocated privates */
267*4882a593Smuzhiyun     pCmapPriv = winGetCmapPriv(pmap);
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun     /*
270*4882a593Smuzhiyun      * FIXME: This is some evil hackery to help in handling some X clients
271*4882a593Smuzhiyun      * that expect the top pixel to be white.  This "help" only lasts until
272*4882a593Smuzhiyun      * some client overwrites the top colormap entry.
273*4882a593Smuzhiyun      *
274*4882a593Smuzhiyun      * We don't want to actually allocate the top entry, as that causes
275*4882a593Smuzhiyun      * problems with X clients that need 7 planes (128 colors) in the default
276*4882a593Smuzhiyun      * colormap, such as Magic 7.1.
277*4882a593Smuzhiyun      */
278*4882a593Smuzhiyun     pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255;
279*4882a593Smuzhiyun     pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255;
280*4882a593Smuzhiyun     pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255;
281*4882a593Smuzhiyun     pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255;
282*4882a593Smuzhiyun     pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255;
283*4882a593Smuzhiyun     pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun     /* Call the engine specific colormap initialization procedure */
286*4882a593Smuzhiyun     if (!((*pScreenPriv->pwinCreateColormap) (pmap))) {
287*4882a593Smuzhiyun         ErrorF("winCreateColormap - Engine specific colormap creation "
288*4882a593Smuzhiyun                "procedure failed.  Aborting.\n");
289*4882a593Smuzhiyun         return FALSE;
290*4882a593Smuzhiyun     }
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun     return TRUE;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun /* See Porting Layer Definition - p. 29, 30 */
296*4882a593Smuzhiyun static void
winDestroyColormap(ColormapPtr pColormap)297*4882a593Smuzhiyun winDestroyColormap(ColormapPtr pColormap)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun     winScreenPriv(pColormap->pScreen);
300*4882a593Smuzhiyun     winCmapPriv(pColormap);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun     /* Call the engine specific colormap destruction procedure */
303*4882a593Smuzhiyun     if (!((*pScreenPriv->pwinDestroyColormap) (pColormap))) {
304*4882a593Smuzhiyun         winErrorFVerb(2,
305*4882a593Smuzhiyun                       "winDestroyColormap - Engine specific colormap destruction "
306*4882a593Smuzhiyun                       "procedure failed.  Continuing, but it is possible that memory "
307*4882a593Smuzhiyun                       "was leaked, or that colors will be messed up from now on.\n");
308*4882a593Smuzhiyun     }
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun     /* Free the colormap privates */
311*4882a593Smuzhiyun     free(pCmapPriv);
312*4882a593Smuzhiyun     winSetCmapPriv(pColormap, NULL);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun #if CYGDEBUG
315*4882a593Smuzhiyun     winDebug("winDestroyColormap - Returning\n");
316*4882a593Smuzhiyun #endif
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun /*
320*4882a593Smuzhiyun  * Internal function to load the palette used by the Shadow DIB
321*4882a593Smuzhiyun  */
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun static Bool
winGetPaletteDIB(ScreenPtr pScreen,ColormapPtr pcmap)324*4882a593Smuzhiyun winGetPaletteDIB(ScreenPtr pScreen, ColormapPtr pcmap)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun     winScreenPriv(pScreen);
327*4882a593Smuzhiyun     int i;
328*4882a593Smuzhiyun     Pixel pixel;                /* Pixel == CARD32 */
329*4882a593Smuzhiyun     CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
330*4882a593Smuzhiyun     UINT uiColorsRetrieved = 0;
331*4882a593Smuzhiyun     RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun     /* Get the color table for the screen */
334*4882a593Smuzhiyun     uiColorsRetrieved = GetDIBColorTable(pScreenPriv->hdcScreen,
335*4882a593Smuzhiyun                                          0, WIN_NUM_PALETTE_ENTRIES, rgbColors);
336*4882a593Smuzhiyun     if (uiColorsRetrieved == 0) {
337*4882a593Smuzhiyun         ErrorF("winGetPaletteDIB - Could not retrieve screen color table\n");
338*4882a593Smuzhiyun         return FALSE;
339*4882a593Smuzhiyun     }
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun #if CYGDEBUG
342*4882a593Smuzhiyun     winDebug("winGetPaletteDIB - Retrieved %d colors from DIB\n",
343*4882a593Smuzhiyun              uiColorsRetrieved);
344*4882a593Smuzhiyun #endif
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun     /* Set the DIB color table to the default screen palette */
347*4882a593Smuzhiyun     if (SetDIBColorTable(pScreenPriv->hdcShadow,
348*4882a593Smuzhiyun                          0, uiColorsRetrieved, rgbColors) == 0) {
349*4882a593Smuzhiyun         ErrorF("winGetPaletteDIB - SetDIBColorTable () failed\n");
350*4882a593Smuzhiyun         return FALSE;
351*4882a593Smuzhiyun     }
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun     /* Alloc each color in the DIB color table */
354*4882a593Smuzhiyun     for (i = 0; i < uiColorsRetrieved; ++i) {
355*4882a593Smuzhiyun         pixel = i;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun         /* Extract the color values for current palette entry */
358*4882a593Smuzhiyun         nRed = rgbColors[i].rgbRed << 8;
359*4882a593Smuzhiyun         nGreen = rgbColors[i].rgbGreen << 8;
360*4882a593Smuzhiyun         nBlue = rgbColors[i].rgbBlue << 8;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun #if CYGDEBUG
363*4882a593Smuzhiyun         winDebug("winGetPaletteDIB - Allocating a color: %u; "
364*4882a593Smuzhiyun                  "%d %d %d\n", (unsigned int)pixel, nRed, nGreen, nBlue);
365*4882a593Smuzhiyun #endif
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun         /* Allocate a entry in the X colormap */
368*4882a593Smuzhiyun         if (AllocColor(pcmap, &nRed, &nGreen, &nBlue, &pixel, 0) != Success) {
369*4882a593Smuzhiyun             ErrorF("winGetPaletteDIB - AllocColor () failed, pixel %d\n", i);
370*4882a593Smuzhiyun             return FALSE;
371*4882a593Smuzhiyun         }
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun         if (i != pixel
374*4882a593Smuzhiyun             || nRed != rgbColors[i].rgbRed
375*4882a593Smuzhiyun             || nGreen != rgbColors[i].rgbGreen
376*4882a593Smuzhiyun             || nBlue != rgbColors[i].rgbBlue) {
377*4882a593Smuzhiyun             winDebug("winGetPaletteDIB - Got: %d; "
378*4882a593Smuzhiyun                      "%d %d %d\n", (int) pixel, nRed, nGreen, nBlue);
379*4882a593Smuzhiyun         }
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun         /* FIXME: Not sure that this bit is needed at all */
382*4882a593Smuzhiyun         pcmap->red[i].co.local.red = nRed;
383*4882a593Smuzhiyun         pcmap->red[i].co.local.green = nGreen;
384*4882a593Smuzhiyun         pcmap->red[i].co.local.blue = nBlue;
385*4882a593Smuzhiyun     }
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun     /* System is using a colormap */
388*4882a593Smuzhiyun     /* Set the black and white pixel indices */
389*4882a593Smuzhiyun     pScreen->whitePixel = uiColorsRetrieved - 1;
390*4882a593Smuzhiyun     pScreen->blackPixel = 0;
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun     return TRUE;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun /*
396*4882a593Smuzhiyun  * Internal function to load the standard system palette being used by DD
397*4882a593Smuzhiyun  */
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun static Bool
winGetPaletteDD(ScreenPtr pScreen,ColormapPtr pcmap)400*4882a593Smuzhiyun winGetPaletteDD(ScreenPtr pScreen, ColormapPtr pcmap)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun     int i;
403*4882a593Smuzhiyun     Pixel pixel;                /* Pixel == CARD32 */
404*4882a593Smuzhiyun     CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
405*4882a593Smuzhiyun     UINT uiSystemPaletteEntries;
406*4882a593Smuzhiyun     LPPALETTEENTRY ppeColors = NULL;
407*4882a593Smuzhiyun     HDC hdc = NULL;
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun     /* Get a DC to obtain the default palette */
410*4882a593Smuzhiyun     hdc = GetDC(NULL);
411*4882a593Smuzhiyun     if (hdc == NULL) {
412*4882a593Smuzhiyun         ErrorF("winGetPaletteDD - Couldn't get a DC\n");
413*4882a593Smuzhiyun         return FALSE;
414*4882a593Smuzhiyun     }
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun     /* Get the number of entries in the system palette */
417*4882a593Smuzhiyun     uiSystemPaletteEntries = GetSystemPaletteEntries(hdc, 0, 0, NULL);
418*4882a593Smuzhiyun     if (uiSystemPaletteEntries == 0) {
419*4882a593Smuzhiyun         ErrorF("winGetPaletteDD - Unable to determine number of "
420*4882a593Smuzhiyun                "system palette entries\n");
421*4882a593Smuzhiyun         return FALSE;
422*4882a593Smuzhiyun     }
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun #if CYGDEBUG
425*4882a593Smuzhiyun     winDebug("winGetPaletteDD - uiSystemPaletteEntries %d\n",
426*4882a593Smuzhiyun              uiSystemPaletteEntries);
427*4882a593Smuzhiyun #endif
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun     /* Allocate palette entries structure */
430*4882a593Smuzhiyun     ppeColors = malloc(uiSystemPaletteEntries * sizeof(PALETTEENTRY));
431*4882a593Smuzhiyun     if (ppeColors == NULL) {
432*4882a593Smuzhiyun         ErrorF("winGetPaletteDD - malloc () for colormap failed\n");
433*4882a593Smuzhiyun         return FALSE;
434*4882a593Smuzhiyun     }
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun     /* Get system palette entries */
437*4882a593Smuzhiyun     GetSystemPaletteEntries(hdc, 0, uiSystemPaletteEntries, ppeColors);
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun     /* Allocate an X colormap entry for every system palette entry */
440*4882a593Smuzhiyun     for (i = 0; i < uiSystemPaletteEntries; ++i) {
441*4882a593Smuzhiyun         pixel = i;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun         /* Extract the color values for current palette entry */
444*4882a593Smuzhiyun         nRed = ppeColors[i].peRed << 8;
445*4882a593Smuzhiyun         nGreen = ppeColors[i].peGreen << 8;
446*4882a593Smuzhiyun         nBlue = ppeColors[i].peBlue << 8;
447*4882a593Smuzhiyun #if CYGDEBUG
448*4882a593Smuzhiyun         winDebug("winGetPaletteDD - Allocating a color: %u; "
449*4882a593Smuzhiyun                  "%d %d %d\n", (unsigned int)pixel, nRed, nGreen, nBlue);
450*4882a593Smuzhiyun #endif
451*4882a593Smuzhiyun         if (AllocColor(pcmap, &nRed, &nGreen, &nBlue, &pixel, 0) != Success) {
452*4882a593Smuzhiyun             ErrorF("winGetPaletteDD - AllocColor () failed, pixel %d\n", i);
453*4882a593Smuzhiyun             free(ppeColors);
454*4882a593Smuzhiyun             ppeColors = NULL;
455*4882a593Smuzhiyun             return FALSE;
456*4882a593Smuzhiyun         }
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun         pcmap->red[i].co.local.red = nRed;
459*4882a593Smuzhiyun         pcmap->red[i].co.local.green = nGreen;
460*4882a593Smuzhiyun         pcmap->red[i].co.local.blue = nBlue;
461*4882a593Smuzhiyun     }
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun     /* System is using a colormap */
464*4882a593Smuzhiyun     /* Set the black and white pixel indices */
465*4882a593Smuzhiyun     pScreen->whitePixel = uiSystemPaletteEntries - 1;
466*4882a593Smuzhiyun     pScreen->blackPixel = 0;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun     /* Free colormap */
469*4882a593Smuzhiyun     free(ppeColors);
470*4882a593Smuzhiyun     ppeColors = NULL;
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun     /* Free the DC */
473*4882a593Smuzhiyun     if (hdc != NULL) {
474*4882a593Smuzhiyun         ReleaseDC(NULL, hdc);
475*4882a593Smuzhiyun         hdc = NULL;
476*4882a593Smuzhiyun     }
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun     return TRUE;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun /*
482*4882a593Smuzhiyun  * Install the standard fb colormap, or the GDI colormap,
483*4882a593Smuzhiyun  * depending on the current screen depth.
484*4882a593Smuzhiyun  */
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun Bool
winCreateDefColormap(ScreenPtr pScreen)487*4882a593Smuzhiyun winCreateDefColormap(ScreenPtr pScreen)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun     winScreenPriv(pScreen);
490*4882a593Smuzhiyun     winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
491*4882a593Smuzhiyun     unsigned short zero = 0, ones = 0xFFFF;
492*4882a593Smuzhiyun     VisualPtr pVisual = pScreenPriv->pRootVisual;
493*4882a593Smuzhiyun     ColormapPtr pcmap = NULL;
494*4882a593Smuzhiyun     Pixel wp, bp;
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun #if CYGDEBUG
497*4882a593Smuzhiyun     winDebug("winCreateDefColormap\n");
498*4882a593Smuzhiyun #endif
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun     /* Use standard fb colormaps for non palettized color modes */
501*4882a593Smuzhiyun     if (pScreenInfo->dwBPP > 8) {
502*4882a593Smuzhiyun         winDebug("winCreateDefColormap - Deferring to "
503*4882a593Smuzhiyun                  "fbCreateDefColormap ()\n");
504*4882a593Smuzhiyun         return fbCreateDefColormap(pScreen);
505*4882a593Smuzhiyun     }
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun     /*
508*4882a593Smuzhiyun      *  AllocAll for non-Dynamic visual classes,
509*4882a593Smuzhiyun      *  AllocNone for Dynamic visual classes.
510*4882a593Smuzhiyun      */
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun     /*
513*4882a593Smuzhiyun      * Dynamic visual classes allow the colors of the color map
514*4882a593Smuzhiyun      * to be changed by clients.
515*4882a593Smuzhiyun      */
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun #if CYGDEBUG
518*4882a593Smuzhiyun     winDebug("winCreateDefColormap - defColormap: %lu\n", pScreen->defColormap);
519*4882a593Smuzhiyun #endif
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun     /* Allocate an X colormap, owned by client 0 */
522*4882a593Smuzhiyun     if (CreateColormap(pScreen->defColormap,
523*4882a593Smuzhiyun                        pScreen,
524*4882a593Smuzhiyun                        pVisual,
525*4882a593Smuzhiyun                        &pcmap,
526*4882a593Smuzhiyun                        (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
527*4882a593Smuzhiyun                        0) != Success) {
528*4882a593Smuzhiyun         ErrorF("winCreateDefColormap - CreateColormap failed\n");
529*4882a593Smuzhiyun         return FALSE;
530*4882a593Smuzhiyun     }
531*4882a593Smuzhiyun     if (pcmap == NULL) {
532*4882a593Smuzhiyun         ErrorF("winCreateDefColormap - Colormap could not be created\n");
533*4882a593Smuzhiyun         return FALSE;
534*4882a593Smuzhiyun     }
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun #if CYGDEBUG
537*4882a593Smuzhiyun     winDebug("winCreateDefColormap - Created a colormap\n");
538*4882a593Smuzhiyun #endif
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun     /* Branch on the visual class */
541*4882a593Smuzhiyun     if (!(pVisual->class & DynamicClass)) {
542*4882a593Smuzhiyun         /* Branch on engine type */
543*4882a593Smuzhiyun         if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) {
544*4882a593Smuzhiyun             /* Load the colors being used by the Shadow DIB */
545*4882a593Smuzhiyun             if (!winGetPaletteDIB(pScreen, pcmap)) {
546*4882a593Smuzhiyun                 ErrorF("winCreateDefColormap - Couldn't get DIB colors\n");
547*4882a593Smuzhiyun                 return FALSE;
548*4882a593Smuzhiyun             }
549*4882a593Smuzhiyun         }
550*4882a593Smuzhiyun         else {
551*4882a593Smuzhiyun             /* Load the colors from the default system palette */
552*4882a593Smuzhiyun             if (!winGetPaletteDD(pScreen, pcmap)) {
553*4882a593Smuzhiyun                 ErrorF("winCreateDefColormap - Couldn't get colors "
554*4882a593Smuzhiyun                        "for DD\n");
555*4882a593Smuzhiyun                 return FALSE;
556*4882a593Smuzhiyun             }
557*4882a593Smuzhiyun         }
558*4882a593Smuzhiyun     }
559*4882a593Smuzhiyun     else {
560*4882a593Smuzhiyun         wp = pScreen->whitePixel;
561*4882a593Smuzhiyun         bp = pScreen->blackPixel;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun         /* Allocate a black and white pixel */
564*4882a593Smuzhiyun         if ((AllocColor(pcmap, &ones, &ones, &ones, &wp, 0) != Success)
565*4882a593Smuzhiyun             || (AllocColor(pcmap, &zero, &zero, &zero, &bp, 0) != Success)) {
566*4882a593Smuzhiyun             ErrorF("winCreateDefColormap - Couldn't allocate bp or wp\n");
567*4882a593Smuzhiyun             return FALSE;
568*4882a593Smuzhiyun         }
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun         pScreen->whitePixel = wp;
571*4882a593Smuzhiyun         pScreen->blackPixel = bp;
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun #if 0
574*4882a593Smuzhiyun         /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */
575*4882a593Smuzhiyun         if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI) {
576*4882a593Smuzhiyun             int k;
577*4882a593Smuzhiyun             Pixel p;
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun             for (k = 1; k < 10; ++k) {
580*4882a593Smuzhiyun                 p = k;
581*4882a593Smuzhiyun                 if (AllocColor(pcmap, &ones, &ones, &ones, &p, 0) != Success)
582*4882a593Smuzhiyun                     FatalError("Foo!\n");
583*4882a593Smuzhiyun             }
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun             for (k = 245; k < 255; ++k) {
586*4882a593Smuzhiyun                 p = k;
587*4882a593Smuzhiyun                 if (AllocColor(pcmap, &zero, &zero, &zero, &p, 0) != Success)
588*4882a593Smuzhiyun                     FatalError("Baz!\n");
589*4882a593Smuzhiyun             }
590*4882a593Smuzhiyun         }
591*4882a593Smuzhiyun #endif
592*4882a593Smuzhiyun     }
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun     /* Install the created colormap */
595*4882a593Smuzhiyun     (*pScreen->InstallColormap) (pcmap);
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun #if CYGDEBUG
598*4882a593Smuzhiyun     winDebug("winCreateDefColormap - Returning\n");
599*4882a593Smuzhiyun #endif
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun     return TRUE;
602*4882a593Smuzhiyun }
603