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
;