4 * Copyright 1993 Alexandre Julliard
7 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;
52 /* Map an EGA index (0..15) to a pixel value. Used for dithering. */
53 int COLOR_mapEGAPixel
[16];
56 /***********************************************************************
59 * Fill the private colormap.
61 static BOOL
COLOR_BuildMap( Colormap map
, int depth
, int size
)
64 int r
, g
, b
, red_incr
, green_incr
, blue_incr
;
67 /* Fill the whole map with a range of colors */
69 blue_incr
= 0x10000 >> (depth
/ 3);
70 red_incr
= 0x10000 >> ((depth
+ 1) / 3);
71 green_incr
= 0x10000 >> ((depth
+ 2) / 3);
73 for (r
= red_incr
- 1; r
< 0x10000; r
+= red_incr
)
74 for (g
= green_incr
- 1; g
< 0x10000; g
+= green_incr
)
75 for (b
= blue_incr
- 1; b
< 0x10000; b
+= blue_incr
)
77 if (index
>= size
) break;
78 color
.pixel
= index
++;
82 XStoreColor( display
, map
, &color
);
89 /***********************************************************************
92 * Create the system palette.
94 static HPALETTE
COLOR_InitPalette()
100 WORD
*colorTranslation
;
102 if (!(hSysColorTranslation
= GDI_HEAP_ALLOC( GMEM_MOVEABLE
,
103 sizeof(WORD
)*NB_RESERVED_COLORS
))) return FALSE
;
104 colorTranslation
= (WORD
*) GDI_HEAP_ADDR( hSysColorTranslation
);
105 size
= DefaultVisual( display
, DefaultScreen(display
) )->map_entries
;
106 for (i
= 0; i
< NB_RESERVED_COLORS
; i
++)
108 color
.red
= COLOR_sysPaletteEntries
[i
].peRed
* 65535 / 255;
109 color
.green
= COLOR_sysPaletteEntries
[i
].peGreen
* 65535 / 255;
110 color
.blue
= COLOR_sysPaletteEntries
[i
].peBlue
* 65535 / 255;
111 color
.flags
= DoRed
| DoGreen
| DoBlue
;
113 if (COLOR_WinColormap
!= DefaultColormapOfScreen(screen
))
115 if (i
< NB_RESERVED_COLORS
/2)
117 /* Bottom half of the colormap */
119 if (color
.pixel
>= size
/2) continue;
123 /* Top half of the colormap */
124 color
.pixel
= size
- NB_RESERVED_COLORS
+ i
;
125 if (color
.pixel
< size
/2) continue;
127 XStoreColor( display
, COLOR_WinColormap
, &color
);
129 else if (!XAllocColor( display
, COLOR_WinColormap
, &color
))
131 fprintf(stderr
, "Warning: Not enough free colors. Try using the -privatemap option.\n" );
132 color
.pixel
= color
.red
= color
.green
= color
.blue
= 0;
134 colorTranslation
[i
] = color
.pixel
;
136 /* Put the allocated colors back in the list */
137 COLOR_sysPaletteEntries
[i
].peRed
= color
.red
>> 8;
138 COLOR_sysPaletteEntries
[i
].peGreen
= color
.green
>> 8;
139 COLOR_sysPaletteEntries
[i
].peBlue
= color
.blue
>> 8;
141 /* Set EGA mapping if color in the first or last eight */
143 COLOR_mapEGAPixel
[i
] = color
.pixel
;
144 else if (i
>= NB_RESERVED_COLORS
-8)
145 COLOR_mapEGAPixel
[i
- (NB_RESERVED_COLORS
-16)] = color
.pixel
;
148 palPtr
= malloc( sizeof(LOGPALETTE
) + (NB_RESERVED_COLORS
-1)*sizeof(PALETTEENTRY
) );
149 if (!palPtr
) return FALSE
;
150 palPtr
->palVersion
= 0x300;
151 palPtr
->palNumEntries
= NB_RESERVED_COLORS
;
152 memcpy( palPtr
->palPalEntry
, COLOR_sysPaletteEntries
,
153 sizeof(COLOR_sysPaletteEntries
) );
154 hpalette
= CreatePalette( palPtr
);
160 /***********************************************************************
163 * Initialize color map and system palette.
165 HPALETTE
COLOR_Init()
167 Visual
* visual
= DefaultVisual( display
, DefaultScreen(display
) );
169 switch(visual
->class)
174 if (Options
.usePrivateMap
)
176 COLOR_WinColormap
= XCreateColormap( display
, rootWindow
,
178 if (COLOR_WinColormap
)
180 COLOR_BuildMap( COLOR_WinColormap
, screenDepth
,
181 visual
->map_entries
);
182 if (rootWindow
!= DefaultRootWindow(display
))
184 XSetWindowAttributes win_attr
;
185 win_attr
.colormap
= COLOR_WinColormap
;
186 XChangeWindowAttributes( display
, rootWindow
,
187 CWColormap
, &win_attr
);
196 COLOR_WinColormap
= DefaultColormapOfScreen( screen
);
199 return COLOR_InitPalette();
203 /***********************************************************************
206 * Check whether 'color' can be represented with a solid color.
208 BOOL
COLOR_IsSolid( COLORREF color
)
211 PALETTEENTRY
*pEntry
= COLOR_sysPaletteEntries
;
213 if (color
& 0xff000000) return TRUE
;
214 if (!color
|| (color
== 0xffffff)) return TRUE
;
215 for (i
= NB_RESERVED_COLORS
; i
> 0; i
--, pEntry
++)
217 if ((GetRValue(color
) == pEntry
->peRed
) &&
218 (GetGValue(color
) == pEntry
->peGreen
) &&
219 (GetBValue(color
) == pEntry
->peBlue
)) return TRUE
;
225 /***********************************************************************
228 * Return the physical color closest to 'color'.
230 WORD
COLOR_ToPhysical( DC
*dc
, COLORREF color
)
235 if (!dc
->u
.x
.pal
.hMapping
) return 0;
239 index
= GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE
, color
);
241 case 1: /* PALETTEINDEX */
242 index
= color
& 0xffff;
244 case 2: /* PALETTERGB */
245 index
= GetNearestPaletteIndex( dc
->w
.hPalette
, color
);
248 if (index
>= dc
->u
.x
.pal
.mappingSize
) return 0;
249 mapping
= (WORD
*) GDI_HEAP_ADDR( dc
->u
.x
.pal
.hMapping
);
250 return mapping
[index
];
254 /***********************************************************************
257 * Set the color-mapping table in a DC.
259 void COLOR_SetMapping( DC
*dc
, HANDLE map
, WORD size
)
261 WORD
*pmap
, *pnewmap
;
263 if (dc
->u
.x
.pal
.hMapping
&& (dc
->u
.x
.pal
.hMapping
!= hSysColorTranslation
))
264 GDI_HEAP_FREE( dc
->u
.x
.pal
.hMapping
);
265 if (map
&& (map
!= hSysColorTranslation
))
267 /* Copy mapping table */
268 dc
->u
.x
.pal
.hMapping
= GDI_HEAP_ALLOC(GMEM_MOVEABLE
,sizeof(WORD
)*size
);
269 pmap
= (WORD
*) GDI_HEAP_ADDR( map
);
270 pnewmap
= (WORD
*) GDI_HEAP_ADDR( dc
->u
.x
.pal
.hMapping
);
271 memcpy( pnewmap
, pmap
, sizeof(WORD
)*size
);
273 else dc
->u
.x
.pal
.hMapping
= map
;
274 dc
->u
.x
.pal
.mappingSize
= size
;
278 /***********************************************************************
279 * GetNearestColor (GDI.154)
281 COLORREF
GetNearestColor( HDC hdc
, COLORREF color
)
284 DC
*dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
286 index
= COLOR_ToPhysical( dc
, color
& 0xffffff );
287 return PALETTEINDEX( index
);
291 /***********************************************************************
292 * RealizeDefaultPalette (GDI.365)
294 WORD
RealizeDefaultPalette( HDC hdc
)
297 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
298 dc
->w
.hPalette
= STOCK_DEFAULT_PALETTE
;
299 COLOR_SetMapping( dc
, hSysColorTranslation
, NB_RESERVED_COLORS
);
300 return NB_RESERVED_COLORS
;