First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xwin / wincmap.c
blob7ebe002446034c10a361945506a73879414c702c
1 /*
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
29 * Suhaib M Siddiqi
30 * Peter Busch
31 * Harold L Hunt II
34 #ifdef HAVE_XWIN_CONFIG_H
35 #include <xwin-config.h>
36 #endif
37 #include "win.h"
41 * Local prototypes
44 static int
45 winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps);
47 static void
48 winStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs);
50 static void
51 winInstallColormap (ColormapPtr pmap);
53 static void
54 winUninstallColormap (ColormapPtr pmap);
56 static void
57 winResolveColor (unsigned short *pred,
58 unsigned short *pgreen,
59 unsigned short *pblue,
60 VisualPtr pVisual);
62 static Bool
63 winCreateColormap (ColormapPtr pmap);
65 static void
66 winDestroyColormap (ColormapPtr pmap);
68 static Bool
69 winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap);
71 static Bool
72 winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap);
76 * Set screen functions for colormaps
79 void
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.
98 static int
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
106 * be one.
108 *pmaps = pScreenPriv->pcmapInstalled->mid;
109 return 1;
113 /* See Porting Layer Definition - p. 30 */
114 /* See Programming Windows - p. 663 */
115 static void
116 winInstallColormap (ColormapPtr pColormap)
118 ScreenPtr pScreen = pColormap->pScreen;
119 winScreenPriv(pScreen);
120 ColormapPtr oldpmap = pScreenPriv->pcmapInstalled;
122 #if CYGDEBUG
123 winDebug ("winInstallColormap\n");
124 #endif
126 /* Did the colormap actually change? */
127 if (pColormap != oldpmap)
129 #if CYGDEBUG
130 winDebug ("winInstallColormap - Colormap has changed, attempt "
131 "to install.\n");
132 #endif
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 */
160 static void
161 winUninstallColormap (ColormapPtr pmap)
163 winScreenPriv(pmap->pScreen);
164 ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
166 #if CYGDEBUG
167 winDebug ("winUninstallColormap\n");
168 #endif
170 /* Is the colormap currently installed? */
171 if (pmap != curpmap)
173 /* Colormap not installed, nothing to do */
174 return;
177 /* Clear the installed colormap flag */
178 pScreenPriv->pcmapInstalled = NULL;
181 * NOTE: The default colormap does not get "uninstalled" before
182 * it is destroyed.
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,
189 RT_COLORMAP);
190 (*pmap->pScreen->InstallColormap) (curpmap);
195 /* See Porting Layer Definition - p. 30 */
196 static void
197 winStoreColors (ColormapPtr pmap,
198 int ndef,
199 xColorItem *pdefs)
201 ScreenPtr pScreen = pmap->pScreen;
202 winScreenPriv(pScreen);
203 winCmapPriv(pmap);
204 int i;
205 unsigned short nRed, nGreen, nBlue;
207 #if CYGDEBUG
208 if (ndef != 1)
209 winDebug ("winStoreColors - ndef: %d\n",
210 ndef);
211 #endif
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;
231 #if CYGDEBUG
232 winDebug ("winStoreColors - nRed %d nGreen %d nBlue %d\n",
233 nRed, nGreen, nBlue);
234 #endif
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 "
242 "on.\n");
247 /* See Porting Layer Definition - p. 30 */
248 static void
249 winResolveColor (unsigned short *pred,
250 unsigned short *pgreen,
251 unsigned short *pblue,
252 VisualPtr pVisual)
254 #if CYGDEBUG
255 winDebug ("winResolveColor ()\n");
256 #endif
258 miResolveColor (pred, pgreen, pblue, pVisual);
262 /* See Porting Layer Definition - p. 29 */
263 static Bool
264 winCreateColormap (ColormapPtr pmap)
266 winPrivCmapPtr pCmapPriv = NULL;
267 ScreenPtr pScreen = pmap->pScreen;
268 winScreenPriv(pScreen);
270 #if CYGDEBUG
271 winDebug ("winCreateColormap\n");
272 #endif
274 /* Allocate colormap privates */
275 if (!winAllocateCmapPrivates (pmap))
277 ErrorF ("winCreateColorma - Couldn't allocate cmap privates\n");
278 return FALSE;
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");
305 return FALSE;
308 return TRUE;
312 /* See Porting Layer Definition - p. 29, 30 */
313 static void
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 */
328 free (pCmapPriv);
329 winSetCmapPriv (pColormap, NULL);
331 #if CYGDEBUG
332 winDebug ("winDestroyColormap - Returning\n");
333 #endif
338 * Internal function to load the palette used by the Shadow DIB
341 static Bool
342 winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap)
344 winScreenPriv(pScreen);
345 int i;
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,
355 rgbColors);
356 if (uiColorsRetrieved == 0)
358 ErrorF ("winGetPaletteDIB - Could not retrieve screen color table\n");
359 return FALSE;
362 #if CYGDEBUG
363 winDebug ("winGetPaletteDIB - Retrieved %d colors from DIB\n",
364 uiColorsRetrieved);
365 #endif
367 /* Set the DIB color table to the default screen palette */
368 if (SetDIBColorTable (pScreenPriv->hdcShadow,
370 uiColorsRetrieved,
371 rgbColors) == 0)
373 ErrorF ("winGetPaletteDIB - SetDIBColorTable () failed\n");
374 return FALSE;
377 /* Alloc each color in the DIB color table */
378 for (i = 0; i < uiColorsRetrieved; ++i)
380 pixel = 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;
387 #if CYGDEBUG
388 winDebug ("winGetPaletteDIB - Allocating a color: %d; "
389 "%d %d %d\n",
390 pixel, nRed, nGreen, nBlue);
391 #endif
393 /* Allocate a entry in the X colormap */
394 if (AllocColor (pcmap,
395 &nRed,
396 &nGreen,
397 &nBlue,
398 &pixel,
399 0) != Success)
401 ErrorF ("winGetPaletteDIB - AllocColor () failed, pixel %d\n",
403 return FALSE;
406 if (i != pixel
407 || nRed != rgbColors[i].rgbRed
408 || nGreen != rgbColors[i].rgbGreen
409 || nBlue != rgbColors[i].rgbBlue)
411 winDebug ("winGetPaletteDIB - Got: %d; "
412 "%d %d %d\n",
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;
427 return TRUE;
432 * Internal function to load the standard system palette being used by DD
435 static Bool
436 winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap)
438 int i;
439 Pixel pixel; /* Pixel == CARD32 */
440 CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
441 UINT uiSystemPaletteEntries;
442 LPPALETTEENTRY ppeColors = NULL;
443 HDC hdc = NULL;
445 /* Get a DC to obtain the default palette */
446 hdc = GetDC (NULL);
447 if (hdc == NULL)
449 ErrorF ("winGetPaletteDD - Couldn't get a DC\n");
450 return FALSE;
453 /* Get the number of entries in the system palette */
454 uiSystemPaletteEntries = GetSystemPaletteEntries (hdc,
455 0, 0, NULL);
456 if (uiSystemPaletteEntries == 0)
458 ErrorF ("winGetPaletteDD - Unable to determine number of "
459 "system palette entries\n");
460 return FALSE;
463 #if CYGDEBUG
464 winDebug ("winGetPaletteDD - uiSystemPaletteEntries %d\n",
465 uiSystemPaletteEntries);
466 #endif
468 /* Allocate palette entries structure */
469 ppeColors = malloc (uiSystemPaletteEntries * sizeof (PALETTEENTRY));
470 if (ppeColors == NULL)
472 ErrorF ("winGetPaletteDD - malloc () for colormap failed\n");
473 return FALSE;
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)
483 pixel = 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;
489 #if CYGDEBUG
490 winDebug ("winGetPaletteDD - Allocating a color: %d; "
491 "%d %d %d\n",
492 pixel, nRed, nGreen, nBlue);
493 #endif
494 if (AllocColor (pcmap,
495 &nRed,
496 &nGreen,
497 &nBlue,
498 &pixel,
499 0) != Success)
501 ErrorF ("winGetPaletteDD - AllocColor () failed, pixel %d\n",
503 free (ppeColors);
504 ppeColors = NULL;
505 return FALSE;
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;
518 /* Free colormap */
519 if (ppeColors != NULL)
521 free (ppeColors);
522 ppeColors = NULL;
525 /* Free the DC */
526 if (hdc != NULL)
528 ReleaseDC (NULL, hdc);
529 hdc = NULL;
532 return TRUE;
537 * Install the standard fb colormap, or the GDI colormap,
538 * depending on the current screen depth.
541 Bool
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;
549 Pixel wp, bp;
551 #if CYGDEBUG
552 winDebug ("winCreateDefColormap\n");
553 #endif
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.
573 #if CYGDEBUG
574 winDebug ("winCreateDefColormap - defColormap: %d\n",
575 pScreen->defColormap);
576 #endif
578 /* Allocate an X colormap, owned by client 0 */
579 if (CreateColormap (pScreen->defColormap,
580 pScreen,
581 pVisual,
582 &pcmap,
583 (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
584 0) != Success)
586 ErrorF ("winCreateDefColormap - CreateColormap failed\n");
587 return FALSE;
589 if (pcmap == NULL)
591 ErrorF ("winCreateDefColormap - Colormap could not be created\n");
592 return FALSE;
595 #if CYGDEBUG
596 winDebug ("winCreateDefColormap - Created a colormap\n");
597 #endif
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");
609 return FALSE;
612 else
614 /* Load the colors from the default system palette */
615 if (!winGetPaletteDD (pScreen, pcmap))
617 ErrorF ("winCreateDefColormap - Couldn't get colors "
618 "for DD\n");
619 return FALSE;
623 else
625 wp = pScreen->whitePixel;
626 bp = pScreen->blackPixel;
628 /* Allocate a black and white pixel */
629 if ((AllocColor (pcmap, &ones, &ones, &ones, &wp, 0) !=
630 Success)
632 (AllocColor (pcmap, &zero, &zero, &zero, &bp, 0) !=
633 Success))
635 ErrorF ("winCreateDefColormap - Couldn't allocate bp or wp\n");
636 return FALSE;
639 pScreen->whitePixel = wp;
640 pScreen->blackPixel = bp;
642 #if 0
643 /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */
644 if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI)
646 int k;
647 Pixel p;
649 for (k = 1; k < 10; ++k)
651 p = k;
652 if (AllocColor (pcmap, &ones, &ones, &ones, &p, 0) != Success)
653 FatalError ("Foo!\n");
656 for (k = 245; k < 255; ++k)
658 p = k;
659 if (AllocColor (pcmap, &zero, &zero, &zero, &p, 0) != Success)
660 FatalError ("Baz!\n");
663 #endif
666 /* Install the created colormap */
667 (*pScreen->InstallColormap)(pcmap);
669 #if CYGDEBUG
670 winDebug ("winCreateDefColormap - Returning\n");
671 #endif
673 return TRUE;