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