2 *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
4 *Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 *"Software"), to deal in the Software without restriction, including
7 *without limitation the rights to use, copy, modify, merge, publish,
8 *distribute, sublicense, and/or sell copies of the Software, and to
9 *permit persons to whom the Software is furnished to do so, subject to
10 *the following conditions:
12 *The above copyright notice and this permission notice shall be
13 *included in all copies or substantial portions of the Software.
15 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR
19 *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *Except as contained in this notice, the name of the XFree86 Project
24 *shall not be used in advertising or otherwise to promote the sale, use
25 *or other dealings in this Software without prior written authorization
26 *from the XFree86 Project.
28 * Authors: Dakshinamurthy Karra
34 #ifdef HAVE_XWIN_CONFIG_H
35 #include <xwin-config.h>
44 winListInstalledColormaps(ScreenPtr pScreen
, Colormap
* pmaps
);
47 winStoreColors(ColormapPtr pmap
, int ndef
, xColorItem
* pdefs
);
50 winInstallColormap(ColormapPtr pmap
);
53 winUninstallColormap(ColormapPtr pmap
);
57 winResolveColor(unsigned short *pred
,
58 unsigned short *pgreen
,
59 unsigned short *pblue
, VisualPtr pVisual
);
62 winCreateColormap(ColormapPtr pmap
);
65 winDestroyColormap(ColormapPtr pmap
);
68 winGetPaletteDIB(ScreenPtr pScreen
, ColormapPtr pcmap
);
71 winGetPaletteDD(ScreenPtr pScreen
, ColormapPtr pcmap
);
74 * Set screen functions for colormaps
78 winSetColormapFunctions(ScreenPtr pScreen
)
80 pScreen
->CreateColormap
= winCreateColormap
;
81 pScreen
->DestroyColormap
= winDestroyColormap
;
82 pScreen
->InstallColormap
= winInstallColormap
;
83 pScreen
->UninstallColormap
= winUninstallColormap
;
84 pScreen
->ListInstalledColormaps
= winListInstalledColormaps
;
85 pScreen
->StoreColors
= winStoreColors
;
86 pScreen
->ResolveColor
= winResolveColor
;
89 /* See Porting Layer Definition - p. 30 */
91 * Walk the list of installed colormaps, filling the pmaps list
92 * with the resource ids of the installed maps, and return
93 * a count of the total number of installed maps.
96 winListInstalledColormaps(ScreenPtr pScreen
, Colormap
* pmaps
)
98 winScreenPriv(pScreen
);
101 * There will only be one installed colormap, so we only need
102 * to return one id, and the count of installed maps will always
105 *pmaps
= pScreenPriv
->pcmapInstalled
->mid
;
109 /* See Porting Layer Definition - p. 30 */
110 /* See Programming Windows - p. 663 */
112 winInstallColormap(ColormapPtr pColormap
)
114 ScreenPtr pScreen
= pColormap
->pScreen
;
116 winScreenPriv(pScreen
);
117 ColormapPtr oldpmap
= pScreenPriv
->pcmapInstalled
;
120 winDebug("winInstallColormap\n");
123 /* Did the colormap actually change? */
124 if (pColormap
!= oldpmap
) {
126 winDebug("winInstallColormap - Colormap has changed, attempt "
130 /* Was there a previous colormap? */
131 if (oldpmap
!= (ColormapPtr
) None
) {
132 /* There was a previous colormap; tell clients it is gone */
133 WalkTree(pColormap
->pScreen
, TellLostMap
, (char *) &oldpmap
->mid
);
136 /* Install new colormap */
137 pScreenPriv
->pcmapInstalled
= pColormap
;
138 WalkTree(pColormap
->pScreen
, TellGainedMap
, (char *) &pColormap
->mid
);
140 /* Call the engine specific colormap install procedure */
141 if (!((*pScreenPriv
->pwinInstallColormap
) (pColormap
))) {
143 "winInstallColormap - Screen specific colormap install "
144 "procedure failed. Continuing, but colors may be "
145 "messed up from now on.\n");
149 /* Save a pointer to the newly installed colormap */
150 pScreenPriv
->pcmapInstalled
= pColormap
;
153 /* See Porting Layer Definition - p. 30 */
155 winUninstallColormap(ColormapPtr pmap
)
157 winScreenPriv(pmap
->pScreen
);
158 ColormapPtr curpmap
= pScreenPriv
->pcmapInstalled
;
161 winDebug("winUninstallColormap\n");
164 /* Is the colormap currently installed? */
165 if (pmap
!= curpmap
) {
166 /* Colormap not installed, nothing to do */
170 /* Clear the installed colormap flag */
171 pScreenPriv
->pcmapInstalled
= NULL
;
174 * NOTE: The default colormap does not get "uninstalled" before
178 /* Install the default cmap in place of the cmap to be uninstalled */
179 if (pmap
->mid
!= pmap
->pScreen
->defColormap
) {
180 dixLookupResourceByType((pointer
) &curpmap
, pmap
->pScreen
->defColormap
,
181 RT_COLORMAP
, NullClient
, DixUnknownAccess
);
182 (*pmap
->pScreen
->InstallColormap
) (curpmap
);
186 /* See Porting Layer Definition - p. 30 */
188 winStoreColors(ColormapPtr pmap
, int ndef
, xColorItem
* pdefs
)
190 ScreenPtr pScreen
= pmap
->pScreen
;
192 winScreenPriv(pScreen
);
195 unsigned short nRed
, nGreen
, nBlue
;
199 winDebug("winStoreColors - ndef: %d\n", ndef
);
202 /* Save the new colors in the colormap privates */
203 for (i
= 0; i
< ndef
; ++i
) {
204 /* Adjust the colors from the X color spec to the Windows color spec */
205 nRed
= pdefs
[i
].red
>> 8;
206 nGreen
= pdefs
[i
].green
>> 8;
207 nBlue
= pdefs
[i
].blue
>> 8;
209 /* Copy the colors to a palette entry table */
210 pCmapPriv
->peColors
[pdefs
[0].pixel
+ i
].peRed
= nRed
;
211 pCmapPriv
->peColors
[pdefs
[0].pixel
+ i
].peGreen
= nGreen
;
212 pCmapPriv
->peColors
[pdefs
[0].pixel
+ i
].peBlue
= nBlue
;
214 /* Copy the colors to a RGBQUAD table */
215 pCmapPriv
->rgbColors
[pdefs
[0].pixel
+ i
].rgbRed
= nRed
;
216 pCmapPriv
->rgbColors
[pdefs
[0].pixel
+ i
].rgbGreen
= nGreen
;
217 pCmapPriv
->rgbColors
[pdefs
[0].pixel
+ i
].rgbBlue
= nBlue
;
220 winDebug("winStoreColors - nRed %d nGreen %d nBlue %d\n",
221 nRed
, nGreen
, nBlue
);
225 /* Call the engine specific store colors procedure */
226 if (!((pScreenPriv
->pwinStoreColors
) (pmap
, ndef
, pdefs
))) {
228 "winStoreColors - Engine cpecific color storage procedure "
229 "failed. Continuing, but colors may be messed up from now "
234 /* See Porting Layer Definition - p. 30 */
236 winResolveColor(unsigned short *pred
,
237 unsigned short *pgreen
,
238 unsigned short *pblue
, VisualPtr pVisual
)
241 winDebug("winResolveColor ()\n");
244 miResolveColor(pred
, pgreen
, pblue
, pVisual
);
247 /* See Porting Layer Definition - p. 29 */
249 winCreateColormap(ColormapPtr pmap
)
251 winPrivCmapPtr pCmapPriv
= NULL
;
252 ScreenPtr pScreen
= pmap
->pScreen
;
254 winScreenPriv(pScreen
);
257 winDebug("winCreateColormap\n");
260 /* Allocate colormap privates */
261 if (!winAllocateCmapPrivates(pmap
)) {
262 ErrorF("winCreateColorma - Couldn't allocate cmap privates\n");
266 /* Get a pointer to the newly allocated privates */
267 pCmapPriv
= winGetCmapPriv(pmap
);
270 * FIXME: This is some evil hackery to help in handling some X clients
271 * that expect the top pixel to be white. This "help" only lasts until
272 * some client overwrites the top colormap entry.
274 * We don't want to actually allocate the top entry, as that causes
275 * problems with X clients that need 7 planes (128 colors) in the default
276 * colormap, such as Magic 7.1.
278 pCmapPriv
->rgbColors
[WIN_NUM_PALETTE_ENTRIES
- 1].rgbRed
= 255;
279 pCmapPriv
->rgbColors
[WIN_NUM_PALETTE_ENTRIES
- 1].rgbGreen
= 255;
280 pCmapPriv
->rgbColors
[WIN_NUM_PALETTE_ENTRIES
- 1].rgbBlue
= 255;
281 pCmapPriv
->peColors
[WIN_NUM_PALETTE_ENTRIES
- 1].peRed
= 255;
282 pCmapPriv
->peColors
[WIN_NUM_PALETTE_ENTRIES
- 1].peGreen
= 255;
283 pCmapPriv
->peColors
[WIN_NUM_PALETTE_ENTRIES
- 1].peBlue
= 255;
285 /* Call the engine specific colormap initialization procedure */
286 if (!((*pScreenPriv
->pwinCreateColormap
) (pmap
))) {
287 ErrorF("winCreateColormap - Engine specific colormap creation "
288 "procedure failed. Aborting.\n");
295 /* See Porting Layer Definition - p. 29, 30 */
297 winDestroyColormap(ColormapPtr pColormap
)
299 winScreenPriv(pColormap
->pScreen
);
300 winCmapPriv(pColormap
);
302 /* Call the engine specific colormap destruction procedure */
303 if (!((*pScreenPriv
->pwinDestroyColormap
) (pColormap
))) {
305 "winDestroyColormap - Engine specific colormap destruction "
306 "procedure failed. Continuing, but it is possible that memory "
307 "was leaked, or that colors will be messed up from now on.\n");
310 /* Free the colormap privates */
312 winSetCmapPriv(pColormap
, NULL
);
315 winDebug("winDestroyColormap - Returning\n");
320 * Internal function to load the palette used by the Shadow DIB
324 winGetPaletteDIB(ScreenPtr pScreen
, ColormapPtr pcmap
)
326 winScreenPriv(pScreen
);
328 Pixel pixel
; /* Pixel == CARD32 */
329 CARD16 nRed
, nGreen
, nBlue
; /* CARD16 == unsigned short */
330 UINT uiColorsRetrieved
= 0;
331 RGBQUAD rgbColors
[WIN_NUM_PALETTE_ENTRIES
];
333 /* Get the color table for the screen */
334 uiColorsRetrieved
= GetDIBColorTable(pScreenPriv
->hdcScreen
,
335 0, WIN_NUM_PALETTE_ENTRIES
, rgbColors
);
336 if (uiColorsRetrieved
== 0) {
337 ErrorF("winGetPaletteDIB - Could not retrieve screen color table\n");
342 winDebug("winGetPaletteDIB - Retrieved %d colors from DIB\n",
346 /* Set the DIB color table to the default screen palette */
347 if (SetDIBColorTable(pScreenPriv
->hdcShadow
,
348 0, uiColorsRetrieved
, rgbColors
) == 0) {
349 ErrorF("winGetPaletteDIB - SetDIBColorTable () failed\n");
353 /* Alloc each color in the DIB color table */
354 for (i
= 0; i
< uiColorsRetrieved
; ++i
) {
357 /* Extract the color values for current palette entry */
358 nRed
= rgbColors
[i
].rgbRed
<< 8;
359 nGreen
= rgbColors
[i
].rgbGreen
<< 8;
360 nBlue
= rgbColors
[i
].rgbBlue
<< 8;
363 winDebug("winGetPaletteDIB - Allocating a color: %d; "
364 "%d %d %d\n", pixel
, nRed
, nGreen
, nBlue
);
367 /* Allocate a entry in the X colormap */
368 if (AllocColor(pcmap
, &nRed
, &nGreen
, &nBlue
, &pixel
, 0) != Success
) {
369 ErrorF("winGetPaletteDIB - AllocColor () failed, pixel %d\n", i
);
374 || nRed
!= rgbColors
[i
].rgbRed
375 || nGreen
!= rgbColors
[i
].rgbGreen
376 || nBlue
!= rgbColors
[i
].rgbBlue
) {
377 winDebug("winGetPaletteDIB - Got: %d; "
378 "%d %d %d\n", (int) pixel
, nRed
, nGreen
, nBlue
);
381 /* FIXME: Not sure that this bit is needed at all */
382 pcmap
->red
[i
].co
.local
.red
= nRed
;
383 pcmap
->red
[i
].co
.local
.green
= nGreen
;
384 pcmap
->red
[i
].co
.local
.blue
= nBlue
;
387 /* System is using a colormap */
388 /* Set the black and white pixel indices */
389 pScreen
->whitePixel
= uiColorsRetrieved
- 1;
390 pScreen
->blackPixel
= 0;
396 * Internal function to load the standard system palette being used by DD
400 winGetPaletteDD(ScreenPtr pScreen
, ColormapPtr pcmap
)
403 Pixel pixel
; /* Pixel == CARD32 */
404 CARD16 nRed
, nGreen
, nBlue
; /* CARD16 == unsigned short */
405 UINT uiSystemPaletteEntries
;
406 LPPALETTEENTRY ppeColors
= NULL
;
409 /* Get a DC to obtain the default palette */
412 ErrorF("winGetPaletteDD - Couldn't get a DC\n");
416 /* Get the number of entries in the system palette */
417 uiSystemPaletteEntries
= GetSystemPaletteEntries(hdc
, 0, 0, NULL
);
418 if (uiSystemPaletteEntries
== 0) {
419 ErrorF("winGetPaletteDD - Unable to determine number of "
420 "system palette entries\n");
425 winDebug("winGetPaletteDD - uiSystemPaletteEntries %d\n",
426 uiSystemPaletteEntries
);
429 /* Allocate palette entries structure */
430 ppeColors
= malloc(uiSystemPaletteEntries
* sizeof(PALETTEENTRY
));
431 if (ppeColors
== NULL
) {
432 ErrorF("winGetPaletteDD - malloc () for colormap failed\n");
436 /* Get system palette entries */
437 GetSystemPaletteEntries(hdc
, 0, uiSystemPaletteEntries
, ppeColors
);
439 /* Allocate an X colormap entry for every system palette entry */
440 for (i
= 0; i
< uiSystemPaletteEntries
; ++i
) {
443 /* Extract the color values for current palette entry */
444 nRed
= ppeColors
[i
].peRed
<< 8;
445 nGreen
= ppeColors
[i
].peGreen
<< 8;
446 nBlue
= ppeColors
[i
].peBlue
<< 8;
448 winDebug("winGetPaletteDD - Allocating a color: %d; "
449 "%d %d %d\n", pixel
, nRed
, nGreen
, nBlue
);
451 if (AllocColor(pcmap
, &nRed
, &nGreen
, &nBlue
, &pixel
, 0) != Success
) {
452 ErrorF("winGetPaletteDD - AllocColor () failed, pixel %d\n", i
);
458 pcmap
->red
[i
].co
.local
.red
= nRed
;
459 pcmap
->red
[i
].co
.local
.green
= nGreen
;
460 pcmap
->red
[i
].co
.local
.blue
= nBlue
;
463 /* System is using a colormap */
464 /* Set the black and white pixel indices */
465 pScreen
->whitePixel
= uiSystemPaletteEntries
- 1;
466 pScreen
->blackPixel
= 0;
474 ReleaseDC(NULL
, hdc
);
482 * Install the standard fb colormap, or the GDI colormap,
483 * depending on the current screen depth.
487 winCreateDefColormap(ScreenPtr pScreen
)
489 winScreenPriv(pScreen
);
490 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
491 unsigned short zero
= 0, ones
= 0xFFFF;
492 VisualPtr pVisual
= pScreenPriv
->pRootVisual
;
493 ColormapPtr pcmap
= NULL
;
497 winDebug("winCreateDefColormap\n");
500 /* Use standard fb colormaps for non palettized color modes */
501 if (pScreenInfo
->dwBPP
> 8) {
502 winDebug("winCreateDefColormap - Deferring to "
503 "fbCreateDefColormap ()\n");
504 return fbCreateDefColormap(pScreen
);
508 * AllocAll for non-Dynamic visual classes,
509 * AllocNone for Dynamic visual classes.
513 * Dynamic visual classes allow the colors of the color map
514 * to be changed by clients.
518 winDebug("winCreateDefColormap - defColormap: %d\n", pScreen
->defColormap
);
521 /* Allocate an X colormap, owned by client 0 */
522 if (CreateColormap(pScreen
->defColormap
,
526 (pVisual
->class & DynamicClass
) ? AllocNone
: AllocAll
,
528 ErrorF("winCreateDefColormap - CreateColormap failed\n");
532 ErrorF("winCreateDefColormap - Colormap could not be created\n");
537 winDebug("winCreateDefColormap - Created a colormap\n");
540 /* Branch on the visual class */
541 if (!(pVisual
->class & DynamicClass
)) {
542 /* Branch on engine type */
543 if (pScreenInfo
->dwEngine
== WIN_SERVER_SHADOW_GDI
) {
544 /* Load the colors being used by the Shadow DIB */
545 if (!winGetPaletteDIB(pScreen
, pcmap
)) {
546 ErrorF("winCreateDefColormap - Couldn't get DIB colors\n");
551 /* Load the colors from the default system palette */
552 if (!winGetPaletteDD(pScreen
, pcmap
)) {
553 ErrorF("winCreateDefColormap - Couldn't get colors "
560 wp
= pScreen
->whitePixel
;
561 bp
= pScreen
->blackPixel
;
563 /* Allocate a black and white pixel */
564 if ((AllocColor(pcmap
, &ones
, &ones
, &ones
, &wp
, 0) != Success
)
565 || (AllocColor(pcmap
, &zero
, &zero
, &zero
, &bp
, 0) != Success
)) {
566 ErrorF("winCreateDefColormap - Couldn't allocate bp or wp\n");
570 pScreen
->whitePixel
= wp
;
571 pScreen
->blackPixel
= bp
;
574 /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */
575 if (pScreenInfo
->dwEngine
!= WIN_SERVER_SHADOW_GDI
) {
579 for (k
= 1; k
< 10; ++k
) {
581 if (AllocColor(pcmap
, &ones
, &ones
, &ones
, &p
, 0) != Success
)
582 FatalError("Foo!\n");
585 for (k
= 245; k
< 255; ++k
) {
587 if (AllocColor(pcmap
, &zero
, &zero
, &zero
, &p
, 0) != Success
)
588 FatalError("Baz!\n");
594 /* Install the created colormap */
595 (*pScreen
->InstallColormap
) (pcmap
);
598 winDebug("winCreateDefColormap - Returning\n");