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>
45 winListInstalledColormaps (ScreenPtr pScreen
, Colormap
*pmaps
);
48 winStoreColors (ColormapPtr pmap
, int ndef
, xColorItem
*pdefs
);
51 winInstallColormap (ColormapPtr pmap
);
54 winUninstallColormap (ColormapPtr pmap
);
57 winResolveColor (unsigned short *pred
,
58 unsigned short *pgreen
,
59 unsigned short *pblue
,
63 winCreateColormap (ColormapPtr pmap
);
66 winDestroyColormap (ColormapPtr pmap
);
69 winGetPaletteDIB (ScreenPtr pScreen
, ColormapPtr pcmap
);
72 winGetPaletteDD (ScreenPtr pScreen
, ColormapPtr pcmap
);
76 * Set screen functions for colormaps
80 winSetColormapFunctions (ScreenPtr pScreen
)
82 pScreen
->CreateColormap
= winCreateColormap
;
83 pScreen
->DestroyColormap
= winDestroyColormap
;
84 pScreen
->InstallColormap
= winInstallColormap
;
85 pScreen
->UninstallColormap
= winUninstallColormap
;
86 pScreen
->ListInstalledColormaps
= winListInstalledColormaps
;
87 pScreen
->StoreColors
= winStoreColors
;
88 pScreen
->ResolveColor
= winResolveColor
;
92 /* See Porting Layer Definition - p. 30 */
94 * Walk the list of installed colormaps, filling the pmaps list
95 * with the resource ids of the installed maps, and return
96 * a count of the total number of installed maps.
99 winListInstalledColormaps (ScreenPtr pScreen
, Colormap
*pmaps
)
101 winScreenPriv(pScreen
);
104 * There will only be one installed colormap, so we only need
105 * to return one id, and the count of installed maps will always
108 *pmaps
= pScreenPriv
->pcmapInstalled
->mid
;
113 /* See Porting Layer Definition - p. 30 */
114 /* See Programming Windows - p. 663 */
116 winInstallColormap (ColormapPtr pColormap
)
118 ScreenPtr pScreen
= pColormap
->pScreen
;
119 winScreenPriv(pScreen
);
120 ColormapPtr oldpmap
= pScreenPriv
->pcmapInstalled
;
123 winDebug ("winInstallColormap\n");
126 /* Did the colormap actually change? */
127 if (pColormap
!= oldpmap
)
130 winDebug ("winInstallColormap - Colormap has changed, attempt "
134 /* Was there a previous colormap? */
135 if (oldpmap
!= (ColormapPtr
) None
)
137 /* There was a previous colormap; tell clients it is gone */
138 WalkTree (pColormap
->pScreen
, TellLostMap
, (char *)&oldpmap
->mid
);
141 /* Install new colormap */
142 pScreenPriv
->pcmapInstalled
= pColormap
;
143 WalkTree (pColormap
->pScreen
, TellGainedMap
, (char *)&pColormap
->mid
);
145 /* Call the engine specific colormap install procedure */
146 if (!((*pScreenPriv
->pwinInstallColormap
) (pColormap
)))
148 winErrorFVerb (2, "winInstallColormap - Screen specific colormap install "
149 "procedure failed. Continuing, but colors may be "
150 "messed up from now on.\n");
154 /* Save a pointer to the newly installed colormap */
155 pScreenPriv
->pcmapInstalled
= pColormap
;
159 /* See Porting Layer Definition - p. 30 */
161 winUninstallColormap (ColormapPtr pmap
)
163 winScreenPriv(pmap
->pScreen
);
164 ColormapPtr curpmap
= pScreenPriv
->pcmapInstalled
;
167 winDebug ("winUninstallColormap\n");
170 /* Is the colormap currently installed? */
173 /* Colormap not installed, nothing to do */
177 /* Clear the installed colormap flag */
178 pScreenPriv
->pcmapInstalled
= NULL
;
181 * NOTE: The default colormap does not get "uninstalled" before
185 /* Install the default cmap in place of the cmap to be uninstalled */
186 if (pmap
->mid
!= pmap
->pScreen
->defColormap
)
188 curpmap
= (ColormapPtr
) LookupIDByType(pmap
->pScreen
->defColormap
,
190 (*pmap
->pScreen
->InstallColormap
) (curpmap
);
195 /* See Porting Layer Definition - p. 30 */
197 winStoreColors (ColormapPtr pmap
,
201 ScreenPtr pScreen
= pmap
->pScreen
;
202 winScreenPriv(pScreen
);
205 unsigned short nRed
, nGreen
, nBlue
;
209 winDebug ("winStoreColors - ndef: %d\n",
213 /* Save the new colors in the colormap privates */
214 for (i
= 0; i
< ndef
; ++i
)
216 /* Adjust the colors from the X color spec to the Windows color spec */
217 nRed
= pdefs
[i
].red
>> 8;
218 nGreen
= pdefs
[i
].green
>> 8;
219 nBlue
= pdefs
[i
].blue
>> 8;
221 /* Copy the colors to a palette entry table */
222 pCmapPriv
->peColors
[pdefs
[0].pixel
+ i
].peRed
= nRed
;
223 pCmapPriv
->peColors
[pdefs
[0].pixel
+ i
].peGreen
= nGreen
;
224 pCmapPriv
->peColors
[pdefs
[0].pixel
+ i
].peBlue
= nBlue
;
226 /* Copy the colors to a RGBQUAD table */
227 pCmapPriv
->rgbColors
[pdefs
[0].pixel
+ i
].rgbRed
= nRed
;
228 pCmapPriv
->rgbColors
[pdefs
[0].pixel
+ i
].rgbGreen
= nGreen
;
229 pCmapPriv
->rgbColors
[pdefs
[0].pixel
+ i
].rgbBlue
= nBlue
;
232 winDebug ("winStoreColors - nRed %d nGreen %d nBlue %d\n",
233 nRed
, nGreen
, nBlue
);
237 /* Call the engine specific store colors procedure */
238 if (!((pScreenPriv
->pwinStoreColors
) (pmap
, ndef
, pdefs
)))
240 winErrorFVerb (2, "winStoreColors - Engine cpecific color storage procedure "
241 "failed. Continuing, but colors may be messed up from now "
247 /* See Porting Layer Definition - p. 30 */
249 winResolveColor (unsigned short *pred
,
250 unsigned short *pgreen
,
251 unsigned short *pblue
,
255 winDebug ("winResolveColor ()\n");
258 miResolveColor (pred
, pgreen
, pblue
, pVisual
);
262 /* See Porting Layer Definition - p. 29 */
264 winCreateColormap (ColormapPtr pmap
)
266 winPrivCmapPtr pCmapPriv
= NULL
;
267 ScreenPtr pScreen
= pmap
->pScreen
;
268 winScreenPriv(pScreen
);
271 winDebug ("winCreateColormap\n");
274 /* Allocate colormap privates */
275 if (!winAllocateCmapPrivates (pmap
))
277 ErrorF ("winCreateColorma - Couldn't allocate cmap privates\n");
281 /* Get a pointer to the newly allocated privates */
282 pCmapPriv
= winGetCmapPriv (pmap
);
285 * FIXME: This is some evil hackery to help in handling some X clients
286 * that expect the top pixel to be white. This "help" only lasts until
287 * some client overwrites the top colormap entry.
289 * We don't want to actually allocate the top entry, as that causes
290 * problems with X clients that need 7 planes (128 colors) in the default
291 * colormap, such as Magic 7.1.
293 pCmapPriv
->rgbColors
[WIN_NUM_PALETTE_ENTRIES
- 1].rgbRed
= 255;
294 pCmapPriv
->rgbColors
[WIN_NUM_PALETTE_ENTRIES
- 1].rgbGreen
= 255;
295 pCmapPriv
->rgbColors
[WIN_NUM_PALETTE_ENTRIES
- 1].rgbBlue
= 255;
296 pCmapPriv
->peColors
[WIN_NUM_PALETTE_ENTRIES
- 1].peRed
= 255;
297 pCmapPriv
->peColors
[WIN_NUM_PALETTE_ENTRIES
- 1].peGreen
= 255;
298 pCmapPriv
->peColors
[WIN_NUM_PALETTE_ENTRIES
- 1].peBlue
= 255;
300 /* Call the engine specific colormap initialization procedure */
301 if (!((*pScreenPriv
->pwinCreateColormap
) (pmap
)))
303 ErrorF ("winCreateColormap - Engine specific colormap creation "
304 "procedure failed. Aborting.\n");
312 /* See Porting Layer Definition - p. 29, 30 */
314 winDestroyColormap (ColormapPtr pColormap
)
316 winScreenPriv(pColormap
->pScreen
);
317 winCmapPriv(pColormap
);
319 /* Call the engine specific colormap destruction procedure */
320 if (!((*pScreenPriv
->pwinDestroyColormap
) (pColormap
)))
322 winErrorFVerb (2, "winDestroyColormap - Engine specific colormap destruction "
323 "procedure failed. Continuing, but it is possible that memory "
324 "was leaked, or that colors will be messed up from now on.\n");
327 /* Free the colormap privates */
329 winSetCmapPriv (pColormap
, NULL
);
332 winDebug ("winDestroyColormap - Returning\n");
338 * Internal function to load the palette used by the Shadow DIB
342 winGetPaletteDIB (ScreenPtr pScreen
, ColormapPtr pcmap
)
344 winScreenPriv(pScreen
);
346 Pixel pixel
; /* Pixel == CARD32 */
347 CARD16 nRed
, nGreen
, nBlue
; /* CARD16 == unsigned short */
348 UINT uiColorsRetrieved
= 0;
349 RGBQUAD rgbColors
[WIN_NUM_PALETTE_ENTRIES
];
351 /* Get the color table for the screen */
352 uiColorsRetrieved
= GetDIBColorTable (pScreenPriv
->hdcScreen
,
354 WIN_NUM_PALETTE_ENTRIES
,
356 if (uiColorsRetrieved
== 0)
358 ErrorF ("winGetPaletteDIB - Could not retrieve screen color table\n");
363 winDebug ("winGetPaletteDIB - Retrieved %d colors from DIB\n",
367 /* Set the DIB color table to the default screen palette */
368 if (SetDIBColorTable (pScreenPriv
->hdcShadow
,
373 ErrorF ("winGetPaletteDIB - SetDIBColorTable () failed\n");
377 /* Alloc each color in the DIB color table */
378 for (i
= 0; i
< uiColorsRetrieved
; ++i
)
382 /* Extract the color values for current palette entry */
383 nRed
= rgbColors
[i
].rgbRed
<< 8;
384 nGreen
= rgbColors
[i
].rgbGreen
<< 8;
385 nBlue
= rgbColors
[i
].rgbBlue
<< 8;
388 winDebug ("winGetPaletteDIB - Allocating a color: %d; "
390 pixel
, nRed
, nGreen
, nBlue
);
393 /* Allocate a entry in the X colormap */
394 if (AllocColor (pcmap
,
401 ErrorF ("winGetPaletteDIB - AllocColor () failed, pixel %d\n",
407 || nRed
!= rgbColors
[i
].rgbRed
408 || nGreen
!= rgbColors
[i
].rgbGreen
409 || nBlue
!= rgbColors
[i
].rgbBlue
)
411 winDebug ("winGetPaletteDIB - Got: %d; "
413 (int) pixel
, nRed
, nGreen
, nBlue
);
416 /* FIXME: Not sure that this bit is needed at all */
417 pcmap
->red
[i
].co
.local
.red
= nRed
;
418 pcmap
->red
[i
].co
.local
.green
= nGreen
;
419 pcmap
->red
[i
].co
.local
.blue
= nBlue
;
422 /* System is using a colormap */
423 /* Set the black and white pixel indices */
424 pScreen
->whitePixel
= uiColorsRetrieved
- 1;
425 pScreen
->blackPixel
= 0;
432 * Internal function to load the standard system palette being used by DD
436 winGetPaletteDD (ScreenPtr pScreen
, ColormapPtr pcmap
)
439 Pixel pixel
; /* Pixel == CARD32 */
440 CARD16 nRed
, nGreen
, nBlue
; /* CARD16 == unsigned short */
441 UINT uiSystemPaletteEntries
;
442 LPPALETTEENTRY ppeColors
= NULL
;
445 /* Get a DC to obtain the default palette */
449 ErrorF ("winGetPaletteDD - Couldn't get a DC\n");
453 /* Get the number of entries in the system palette */
454 uiSystemPaletteEntries
= GetSystemPaletteEntries (hdc
,
456 if (uiSystemPaletteEntries
== 0)
458 ErrorF ("winGetPaletteDD - Unable to determine number of "
459 "system palette entries\n");
464 winDebug ("winGetPaletteDD - uiSystemPaletteEntries %d\n",
465 uiSystemPaletteEntries
);
468 /* Allocate palette entries structure */
469 ppeColors
= malloc (uiSystemPaletteEntries
* sizeof (PALETTEENTRY
));
470 if (ppeColors
== NULL
)
472 ErrorF ("winGetPaletteDD - malloc () for colormap failed\n");
476 /* Get system palette entries */
477 GetSystemPaletteEntries (hdc
,
478 0, uiSystemPaletteEntries
, ppeColors
);
480 /* Allocate an X colormap entry for every system palette entry */
481 for (i
= 0; i
< uiSystemPaletteEntries
; ++i
)
485 /* Extract the color values for current palette entry */
486 nRed
= ppeColors
[i
].peRed
<< 8;
487 nGreen
= ppeColors
[i
].peGreen
<< 8;
488 nBlue
= ppeColors
[i
].peBlue
<< 8;
490 winDebug ("winGetPaletteDD - Allocating a color: %d; "
492 pixel
, nRed
, nGreen
, nBlue
);
494 if (AllocColor (pcmap
,
501 ErrorF ("winGetPaletteDD - AllocColor () failed, pixel %d\n",
508 pcmap
->red
[i
].co
.local
.red
= nRed
;
509 pcmap
->red
[i
].co
.local
.green
= nGreen
;
510 pcmap
->red
[i
].co
.local
.blue
= nBlue
;
513 /* System is using a colormap */
514 /* Set the black and white pixel indices */
515 pScreen
->whitePixel
= uiSystemPaletteEntries
- 1;
516 pScreen
->blackPixel
= 0;
519 if (ppeColors
!= NULL
)
528 ReleaseDC (NULL
, hdc
);
537 * Install the standard fb colormap, or the GDI colormap,
538 * depending on the current screen depth.
542 winCreateDefColormap (ScreenPtr pScreen
)
544 winScreenPriv(pScreen
);
545 winScreenInfo
*pScreenInfo
= pScreenPriv
->pScreenInfo
;
546 unsigned short zero
= 0, ones
= 0xFFFF;
547 VisualPtr pVisual
= pScreenPriv
->pRootVisual
;
548 ColormapPtr pcmap
= NULL
;
552 winDebug ("winCreateDefColormap\n");
555 /* Use standard fb colormaps for non palettized color modes */
556 if (pScreenInfo
->dwBPP
> 8)
558 winDebug ("winCreateDefColormap - Deferring to " \
559 "fbCreateDefColormap ()\n");
560 return fbCreateDefColormap (pScreen
);
564 * AllocAll for non-Dynamic visual classes,
565 * AllocNone for Dynamic visual classes.
569 * Dynamic visual classes allow the colors of the color map
570 * to be changed by clients.
574 winDebug ("winCreateDefColormap - defColormap: %d\n",
575 pScreen
->defColormap
);
578 /* Allocate an X colormap, owned by client 0 */
579 if (CreateColormap (pScreen
->defColormap
,
583 (pVisual
->class & DynamicClass
) ? AllocNone
: AllocAll
,
586 ErrorF ("winCreateDefColormap - CreateColormap failed\n");
591 ErrorF ("winCreateDefColormap - Colormap could not be created\n");
596 winDebug ("winCreateDefColormap - Created a colormap\n");
599 /* Branch on the visual class */
600 if (!(pVisual
->class & DynamicClass
))
602 /* Branch on engine type */
603 if (pScreenInfo
->dwEngine
== WIN_SERVER_SHADOW_GDI
)
605 /* Load the colors being used by the Shadow DIB */
606 if (!winGetPaletteDIB (pScreen
, pcmap
))
608 ErrorF ("winCreateDefColormap - Couldn't get DIB colors\n");
614 /* Load the colors from the default system palette */
615 if (!winGetPaletteDD (pScreen
, pcmap
))
617 ErrorF ("winCreateDefColormap - Couldn't get colors "
625 wp
= pScreen
->whitePixel
;
626 bp
= pScreen
->blackPixel
;
628 /* Allocate a black and white pixel */
629 if ((AllocColor (pcmap
, &ones
, &ones
, &ones
, &wp
, 0) !=
632 (AllocColor (pcmap
, &zero
, &zero
, &zero
, &bp
, 0) !=
635 ErrorF ("winCreateDefColormap - Couldn't allocate bp or wp\n");
639 pScreen
->whitePixel
= wp
;
640 pScreen
->blackPixel
= bp
;
643 /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */
644 if (pScreenInfo
->dwEngine
!= WIN_SERVER_SHADOW_GDI
)
649 for (k
= 1; k
< 10; ++k
)
652 if (AllocColor (pcmap
, &ones
, &ones
, &ones
, &p
, 0) != Success
)
653 FatalError ("Foo!\n");
656 for (k
= 245; k
< 255; ++k
)
659 if (AllocColor (pcmap
, &zero
, &zero
, &zero
, &p
, 0) != Success
)
660 FatalError ("Baz!\n");
666 /* Install the created colormap */
667 (*pScreen
->InstallColormap
)(pcmap
);
670 winDebug ("winCreateDefColormap - Returning\n");