4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
17 Colormap COLOR_WinColormap = 0;
19 /* System palette static colors */
21 #define NB_RESERVED_COLORS 20
23 /* The first and last eight colors are EGA colors */
24 static PALETTEENTRY COLOR_sysPaletteEntries[NB_RESERVED_COLORS] =
26 /* red green blue flags */
27 { 0x00, 0x00, 0x00, 0 },
28 { 0x80, 0x00, 0x00, 0 },
29 { 0x00, 0x80, 0x00, 0 },
30 { 0x80, 0x80, 0x00, 0 },
31 { 0x00, 0x00, 0x80, 0 },
32 { 0x80, 0x00, 0x80, 0 },
33 { 0x00, 0x80, 0x80, 0 },
34 { 0xc0, 0xc0, 0xc0, 0 },
35 { 0xc0, 0xdc, 0xc0, 0 },
36 { 0xa6, 0xca, 0xf0, 0 },
38 { 0xff, 0xfb, 0xf0, 0 },
39 { 0xa0, 0xa0, 0xa4, 0 },
40 { 0x80, 0x80, 0x80, 0 },
41 { 0xff, 0x00, 0x00, 0 },
42 { 0x00, 0xff, 0x00, 0 },
43 { 0xff, 0xff, 0x00, 0 },
44 { 0x00, 0x00, 0xff, 0 },
45 { 0xff, 0x00, 0xff, 0 },
46 { 0x00, 0xff, 0xff, 0 },
47 { 0xff, 0xff, 0xff, 0 }
50 static HANDLE hSysColorTranslation = 0;
51 static HANDLE hRevSysColorTranslation = 0;
53 /* Map an EGA index (0..15) to a pixel value. Used for dithering. */
54 int COLOR_mapEGAPixel[16];
56 int* COLOR_PaletteToPixel = NULL;
57 int* COLOR_PixelToPalette = NULL;
58 int COLOR_ColormapSize = 0;
60 /***********************************************************************
63 * Fill the private colormap.
65 static BOOL COLOR_BuildMap( Colormap map, int depth, int size )
68 int r, g, b, red_incr, green_incr, blue_incr;
71 /* Fill the whole map with a range of colors */
73 blue_incr = 0x10000 >> (depth / 3);
74 red_incr = 0x10000 >> ((depth + 1) / 3);
75 green_incr = 0x10000 >> ((depth + 2) / 3);
77 for (r = red_incr - 1; r < 0x10000; r += red_incr)
78 for (g = green_incr - 1; g < 0x10000; g += green_incr)
79 for (b = blue_incr - 1; b < 0x10000; b += blue_incr)
81 if (index >= size) break;
82 color.pixel = index++;
86 XStoreColor( display, map, &color );
93 /***********************************************************************
96 * Create the system palette.
98 static HPALETTE COLOR_InitPalette(void)
104 WORD *colorTranslation, *revTranslation;
106 size = DefaultVisual( display, DefaultScreen(display) )->map_entries;
107 COLOR_ColormapSize = size;
108 if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
109 sizeof(WORD)*NB_RESERVED_COLORS )))
111 if (!(hRevSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
112 sizeof(WORD)*size )))
114 colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
115 revTranslation = (WORD *) GDI_HEAP_ADDR( hRevSysColorTranslation );
117 if (COLOR_WinColormap == DefaultColormapOfScreen(screen))
119 COLOR_PaletteToPixel = (int *)malloc( sizeof(int) * size );
120 COLOR_PixelToPalette = (int *)malloc( sizeof(int) * size );
123 for (i = 0; i < NB_RESERVED_COLORS; i++)
125 color.red = COLOR_sysPaletteEntries[i].peRed * 65535 / 255;
126 color.green = COLOR_sysPaletteEntries[i].peGreen * 65535 / 255;
127 color.blue = COLOR_sysPaletteEntries[i].peBlue * 65535 / 255;
128 color.flags = DoRed | DoGreen | DoBlue;
130 if (i < NB_RESERVED_COLORS/2)
132 /* Bottom half of the colormap */
134 if (pixel >= size/2) continue;
138 /* Top half of the colormap */
139 pixel = size - NB_RESERVED_COLORS + i;
140 if (pixel < size/2) continue;
142 if (COLOR_WinColormap != DefaultColormapOfScreen(screen))
145 XStoreColor( display, COLOR_WinColormap, &color );
149 if (!XAllocColor( display, COLOR_WinColormap, &color ))
151 fprintf(stderr, "Warning: Not enough free colors. Try using the -privatemap option.\n" );
152 color.pixel = color.red = color.green = color.blue = 0;
156 COLOR_PaletteToPixel[pixel] = color.pixel;
157 COLOR_PixelToPalette[color.pixel] = pixel;
160 colorTranslation[i] = color.pixel;
161 revTranslation[color.pixel] = i;
162 /* Set EGA mapping if color in the first or last eight */
164 COLOR_mapEGAPixel[i] = color.pixel;
165 else if (i >= NB_RESERVED_COLORS-8)
166 COLOR_mapEGAPixel[i - (NB_RESERVED_COLORS-16)] = color.pixel;
169 palPtr = malloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) );
170 if (!palPtr) return FALSE;
171 palPtr->palVersion = 0x300;
172 palPtr->palNumEntries = NB_RESERVED_COLORS;
173 memcpy( palPtr->palPalEntry, COLOR_sysPaletteEntries,
174 sizeof(COLOR_sysPaletteEntries) );
175 hpalette = CreatePalette( palPtr );
181 /***********************************************************************
184 * Initialize color map and system palette.
186 HPALETTE COLOR_Init(void)
188 Visual * visual = DefaultVisual( display, DefaultScreen(display) );
190 switch(visual->class)
195 if (Options.usePrivateMap)
197 COLOR_WinColormap = XCreateColormap( display, rootWindow,
199 if (COLOR_WinColormap)
201 COLOR_BuildMap( COLOR_WinColormap, screenDepth,
202 visual->map_entries );
203 if (rootWindow != DefaultRootWindow(display))
205 XSetWindowAttributes win_attr;
206 win_attr.colormap = COLOR_WinColormap;
207 XChangeWindowAttributes( display, rootWindow,
208 CWColormap, &win_attr );
217 COLOR_WinColormap = DefaultColormapOfScreen( screen );
220 return COLOR_InitPalette();
224 /***********************************************************************
227 * Check whether 'color' can be represented with a solid color.
229 BOOL COLOR_IsSolid( COLORREF color )
232 PALETTEENTRY *pEntry = COLOR_sysPaletteEntries;
234 if (color & 0xff000000) return TRUE;
235 if (!color || (color == 0xffffff)) return TRUE;
236 for (i = NB_RESERVED_COLORS; i > 0; i--, pEntry++)
238 if ((GetRValue(color) == pEntry->peRed) &&
239 (GetGValue(color) == pEntry->peGreen) &&
240 (GetBValue(color) == pEntry->peBlue)) return TRUE;
246 /***********************************************************************
249 * Return the physical color closest to 'color'.
251 int COLOR_ToPhysical( DC *dc, COLORREF color )
256 if (screenDepth > 8) return color;
260 index = GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE, color );
262 case 1: /* PALETTEINDEX */
263 index = color & 0xffff;
265 case 2: /* PALETTERGB */
266 if (dc) index = GetNearestPaletteIndex( dc->w.hPalette, color );
272 if (index >= dc->u.x.pal.mappingSize) return 0;
273 mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping );
277 if (index >= NB_RESERVED_COLORS) return 0;
278 mapping = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
280 if (mapping) return mapping[index];
281 else return index; /* Identity mapping */
285 /***********************************************************************
288 * Set the color-mapping table in a DC.
290 void COLOR_SetMapping( DC *dc, HANDLE map, HANDLE revMap, WORD size )
292 WORD *pmap, *pnewmap;
295 if (dc->u.x.pal.hMapping && (dc->u.x.pal.hMapping != hSysColorTranslation))
296 GDI_HEAP_FREE( dc->u.x.pal.hMapping );
297 if (dc->u.x.pal.hRevMapping &&
298 (dc->u.x.pal.hRevMapping != hRevSysColorTranslation))
299 GDI_HEAP_FREE( dc->u.x.pal.hRevMapping );
300 if (map && (map != hSysColorTranslation))
302 /* Copy mapping table */
303 dc->u.x.pal.hMapping = GDI_HEAP_ALLOC(GMEM_MOVEABLE,sizeof(WORD)*size);
304 pmap = (WORD *) GDI_HEAP_ADDR( map );
305 pnewmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping );
306 memcpy( pnewmap, pmap, sizeof(WORD)*size );
307 /* Build reverse table */
308 dc->u.x.pal.hRevMapping = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
309 sizeof(WORD)*COLOR_ColormapSize );
310 pmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hRevMapping );
311 for (i = 0; i < size; i++) pmap[pnewmap[i]] = i;
315 dc->u.x.pal.hMapping = map;
316 dc->u.x.pal.hRevMapping = map ? hRevSysColorTranslation : 0;
318 dc->u.x.pal.mappingSize = size;
322 /***********************************************************************
323 * GetNearestColor (GDI.154)
325 COLORREF GetNearestColor( HDC hdc, COLORREF color )
328 DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
330 if (screenDepth > 8) return color;
331 index = (WORD)(COLOR_ToPhysical( dc, color & 0xffffff ) & 0xffff);
332 return PALETTEINDEX( index );
336 /***********************************************************************
337 * RealizeDefaultPalette (GDI.365)
339 WORD RealizeDefaultPalette( HDC hdc )
342 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
343 dc->w.hPalette = STOCK_DEFAULT_PALETTE;
344 COLOR_SetMapping( dc, hSysColorTranslation,
345 hRevSysColorTranslation, NB_RESERVED_COLORS );
346 return NB_RESERVED_COLORS;