4 * Copyright 1993 Alexandre Julliard
19 Colormap COLOR_WinColormap
= 0;
20 static int COLOR_FixedMap
= 0;
22 static int COLOR_Redshift
= 0;
23 static int COLOR_Redmax
= 0;
24 static int COLOR_Greenshift
= 0;
25 static int COLOR_Greenmax
= 0;
26 static int COLOR_Blueshift
= 0;
27 static int COLOR_Bluemax
= 0;
28 static int COLOR_Graymax
= 0;
30 /* System palette static colors */
32 #define NB_RESERVED_COLORS 20
34 /* The first and last eight colors are EGA colors */
35 static const PALETTEENTRY COLOR_sysPaletteEntries
[NB_RESERVED_COLORS
] =
37 /* red green blue flags */
38 { 0x00, 0x00, 0x00, 0 },
39 { 0x80, 0x00, 0x00, 0 },
40 { 0x00, 0x80, 0x00, 0 },
41 { 0x80, 0x80, 0x00, 0 },
42 { 0x00, 0x00, 0x80, 0 },
43 { 0x80, 0x00, 0x80, 0 },
44 { 0x00, 0x80, 0x80, 0 },
45 { 0xc0, 0xc0, 0xc0, 0 },
46 { 0xc0, 0xdc, 0xc0, 0 },
47 { 0xa6, 0xca, 0xf0, 0 },
49 { 0xff, 0xfb, 0xf0, 0 },
50 { 0xa0, 0xa0, 0xa4, 0 },
51 { 0x80, 0x80, 0x80, 0 },
52 { 0xff, 0x00, 0x00, 0 },
53 { 0x00, 0xff, 0x00, 0 },
54 { 0xff, 0xff, 0x00, 0 },
55 { 0x00, 0x00, 0xff, 0 },
56 { 0xff, 0x00, 0xff, 0 },
57 { 0x00, 0xff, 0xff, 0 },
58 { 0xff, 0xff, 0xff, 0 }
61 static HANDLE hSysColorTranslation
= 0;
62 static HANDLE hRevSysColorTranslation
= 0;
64 /* Map an EGA index (0..15) to a pixel value. Used for dithering. */
65 int COLOR_mapEGAPixel
[16];
67 int* COLOR_PaletteToPixel
= NULL
;
68 int* COLOR_PixelToPalette
= NULL
;
69 int COLOR_ColormapSize
= 0;
71 /***********************************************************************
74 * Fill the private colormap.
76 static BOOL
COLOR_BuildMap( Colormap map
, int depth
, int size
)
79 int r
, g
, b
, red_incr
, green_incr
, blue_incr
;
82 /* Fill the whole map with a range of colors */
84 blue_incr
= 0x10000 >> (depth
/ 3);
85 red_incr
= 0x10000 >> ((depth
+ 1) / 3);
86 green_incr
= 0x10000 >> ((depth
+ 2) / 3);
88 for (r
= red_incr
- 1; r
< 0x10000; r
+= red_incr
)
89 for (g
= green_incr
- 1; g
< 0x10000; g
+= green_incr
)
90 for (b
= blue_incr
- 1; b
< 0x10000; b
+= blue_incr
)
92 if (index
>= size
) break;
93 color
.pixel
= index
++;
97 XStoreColor( display
, map
, &color
);
104 /***********************************************************************
107 * Create the system palette.
109 static HPALETTE16
COLOR_InitPalette(void)
115 WORD
*colorTranslation
, *revTranslation
;
117 size
= DefaultVisual( display
, DefaultScreen(display
) )->map_entries
;
118 COLOR_ColormapSize
= size
;
119 if (screenDepth
<= 8)
121 if (!(hSysColorTranslation
= GDI_HEAP_ALLOC(sizeof(WORD
)*NB_RESERVED_COLORS
)))
123 if (!(hRevSysColorTranslation
= GDI_HEAP_ALLOC( sizeof(WORD
)*size
)))
125 colorTranslation
= (WORD
*) GDI_HEAP_LIN_ADDR( hSysColorTranslation
);
126 revTranslation
= (WORD
*) GDI_HEAP_LIN_ADDR( hRevSysColorTranslation
);
128 else colorTranslation
= revTranslation
= NULL
;
130 if ((COLOR_WinColormap
== DefaultColormapOfScreen(screen
)) && (screenDepth
<= 8))
132 COLOR_PaletteToPixel
= (int *)xmalloc( sizeof(int) * size
);
133 COLOR_PixelToPalette
= (int *)xmalloc( sizeof(int) * size
);
134 for (i
= 0; i
< size
; i
++) /* Set the default mapping */
135 COLOR_PaletteToPixel
[i
] = COLOR_PixelToPalette
[i
] = i
;
138 for (i
= 0; i
< NB_RESERVED_COLORS
; i
++)
140 color
.red
= COLOR_sysPaletteEntries
[i
].peRed
* 65535 / 255;
141 color
.green
= COLOR_sysPaletteEntries
[i
].peGreen
* 65535 / 255;
142 color
.blue
= COLOR_sysPaletteEntries
[i
].peBlue
* 65535 / 255;
143 color
.flags
= DoRed
| DoGreen
| DoBlue
;
145 if (i
< NB_RESERVED_COLORS
/2)
147 /* Bottom half of the colormap */
149 if (pixel
>= size
/2) continue;
153 /* Top half of the colormap */
154 pixel
= size
- NB_RESERVED_COLORS
+ i
;
155 if (pixel
< size
/2) continue;
157 if (COLOR_WinColormap
!= DefaultColormapOfScreen(screen
))
160 XStoreColor( display
, COLOR_WinColormap
, &color
);
164 if (!XAllocColor( display
, COLOR_WinColormap
, &color
))
166 fprintf(stderr
, "Warning: Not enough free colors. Try using the -privatemap option.\n" );
167 color
.pixel
= color
.red
= color
.green
= color
.blue
= 0;
169 else if (COLOR_PaletteToPixel
)
171 COLOR_PaletteToPixel
[pixel
] = color
.pixel
;
172 COLOR_PixelToPalette
[color
.pixel
] = pixel
;
175 if (colorTranslation
) colorTranslation
[i
] = color
.pixel
;
176 if (revTranslation
) revTranslation
[color
.pixel
] = i
;
177 /* Set EGA mapping if color in the first or last eight */
179 COLOR_mapEGAPixel
[i
] = color
.pixel
;
180 else if (i
>= NB_RESERVED_COLORS
-8)
181 COLOR_mapEGAPixel
[i
- (NB_RESERVED_COLORS
-16)] = color
.pixel
;
184 palPtr
= malloc( sizeof(LOGPALETTE
) + (NB_RESERVED_COLORS
-1)*sizeof(PALETTEENTRY
) );
185 if (!palPtr
) return FALSE
;
186 palPtr
->palVersion
= 0x300;
187 palPtr
->palNumEntries
= NB_RESERVED_COLORS
;
188 memcpy( palPtr
->palPalEntry
, COLOR_sysPaletteEntries
,
189 sizeof(COLOR_sysPaletteEntries
) );
190 hpalette
= CreatePalette( palPtr
);
196 COLOR_Computeshifts(unsigned long maskbits
, int *shift
, int *max
)
206 for(i
=0;!(maskbits
&1);i
++)
213 /***********************************************************************
216 * Initialize color map and system palette.
218 HPALETTE16
COLOR_Init(void)
220 Visual
* visual
= DefaultVisual( display
, DefaultScreen(display
) );
222 switch(visual
->class)
228 if (Options
.usePrivateMap
)
230 COLOR_WinColormap
= XCreateColormap( display
, rootWindow
,
232 if (COLOR_WinColormap
)
234 COLOR_BuildMap( COLOR_WinColormap
, screenDepth
,
235 visual
->map_entries
);
236 if (rootWindow
!= DefaultRootWindow(display
))
238 XSetWindowAttributes win_attr
;
239 win_attr
.colormap
= COLOR_WinColormap
;
240 XChangeWindowAttributes( display
, rootWindow
,
241 CWColormap
, &win_attr
);
246 COLOR_WinColormap
= DefaultColormapOfScreen( screen
);
249 COLOR_WinColormap
= DefaultColormapOfScreen( screen
);
251 COLOR_Graymax
= (1<<screenDepth
)-1;
255 COLOR_WinColormap
= DefaultColormapOfScreen( screen
);
257 COLOR_Computeshifts(visual
->red_mask
, &COLOR_Redshift
, &COLOR_Redmax
);
258 COLOR_Computeshifts(visual
->green_mask
, &COLOR_Greenshift
, &COLOR_Greenmax
);
259 COLOR_Computeshifts(visual
->blue_mask
, &COLOR_Blueshift
, &COLOR_Bluemax
);
262 return COLOR_InitPalette();
266 /***********************************************************************
269 * Check whether 'color' can be represented with a solid color.
271 BOOL
COLOR_IsSolid( COLORREF color
)
274 const PALETTEENTRY
*pEntry
= COLOR_sysPaletteEntries
;
276 if (color
& 0xff000000) return TRUE
;
277 if (!color
|| (color
== 0xffffff)) return TRUE
;
278 for (i
= NB_RESERVED_COLORS
; i
> 0; i
--, pEntry
++)
280 if ((GetRValue(color
) == pEntry
->peRed
) &&
281 (GetGValue(color
) == pEntry
->peGreen
) &&
282 (GetBValue(color
) == pEntry
->peBlue
)) return TRUE
;
288 /***********************************************************************
291 * Return the physical color closest to 'color'.
293 * ESW: This still needs a lot of work; in particular, what happens when
294 * we have really large (> 8 bit) DirectColor boards?
295 * But it should work better in 16 and 24 bit modes now.
296 * (At least it pays attention to the X server's description
297 * in TrueColor mode, instead of blindly passing through the
298 * color spec and swapping red to blue or losing blue and part of the
299 * green entirely, depending on what mode one is in!)
302 int COLOR_ToPhysical( DC
*dc
, COLORREF color
)
306 unsigned char spec_type
;
308 spec_type
= color
>> 24;
309 if (spec_type
== 0xff)
311 spec_type
= 0; /* 'write' seems to need that for 'Page 1' text */
315 fprintf(stderr
, "COLOR_ToPhysical : color >> 24 not in {-1,0,1,2} : %08lx\n",
317 if (dc
&& (dc
->w
.bitsPerPixel
== 1) && (spec_type
== 0))
320 if (((color
>> 16) & 0xff) +
321 ((color
>> 8) & 0xff) + (color
& 0xff) > 255*3/2)
322 return 1; /* white */
323 else return 0; /* black */
328 /* there is no colormap possible; we are going to have to compute
329 the pixel value from the visual information stored earlier */
331 unsigned long red
, green
, blue
;
338 case 2: /* PALETTERGB -- needs some work, but why bother; we've got a REALLY LARGE number of colors...? */
340 red
= GetRValue(color
);
341 green
= GetGValue(color
);
342 blue
= GetBValue(color
);
345 case 1: /* PALETTEIDX -- hmm, get the real color from the stock palette */
346 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
);
347 idx
= color
& 0xffff;
348 if (idx
>= palPtr
->logpalette
.palNumEntries
)
350 fprintf(stderr
, "COLOR_ToPhysical(%lx) : idx %d is out of bounds, assuming black\n", color
, idx
);
352 red
= green
= blue
= 0;
356 red
= palPtr
->logpalette
.palPalEntry
[idx
].peRed
;
357 green
= palPtr
->logpalette
.palPalEntry
[idx
].peGreen
;
358 blue
= palPtr
->logpalette
.palPalEntry
[idx
].peBlue
;
364 /* grayscale only; return scaled value */
365 return ( (red
* 30 + green
* 69 + blue
* 11) * COLOR_Graymax
) / 25500;
369 /* scale each individually and construct the TrueColor pixel value */
370 if (COLOR_Redmax
!= 255) red
= (red
* COLOR_Redmax
) / 255;
371 if (COLOR_Greenmax
!= 255) green
= (green
* COLOR_Greenmax
) / 255;
372 if (COLOR_Bluemax
!= 255) blue
= (blue
* COLOR_Bluemax
) / 255;
374 return (red
<< COLOR_Redshift
) | (green
<< COLOR_Greenshift
) | (blue
<< COLOR_Blueshift
);
377 else switch(spec_type
)
381 index
= GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE
, color
);
383 case 1: /* PALETTEINDEX */
384 index
= color
& 0xffff;
386 case 2: /* PALETTERGB */
387 if (dc
) index
= GetNearestPaletteIndex( dc
->w
.hPalette
, color
);
391 if (dc
&&dc
->u
.x
.pal
.mappingSize
)
393 if (index
>= dc
->u
.x
.pal
.mappingSize
)
395 fprintf(stderr
, "COLOR_ToPhysical(%lx) : idx %d is >= dc->u.x.pal.mappingSize, assuming pixel 0\n", color
, index
);
398 mapping
= (WORD
*) GDI_HEAP_LIN_ADDR( dc
->u
.x
.pal
.hMapping
);
402 if (index
>= NB_RESERVED_COLORS
)
404 fprintf(stderr
, "COLOR_ToPhysical(%lx) : idx %d is >= NB_RESERVED_COLORS, assuming pixel 0\n", color
, index
);
407 mapping
= (WORD
*) GDI_HEAP_LIN_ADDR( hSysColorTranslation
);
409 if (mapping
) return mapping
[index
];
410 else return index
; /* Identity mapping */
414 /***********************************************************************
417 * Set the color-mapping table in a DC.
419 void COLOR_SetMapping( DC
*dc
, HANDLE map
, HANDLE revMap
, WORD size
)
421 WORD
*pmap
, *pnewmap
;
424 if (dc
->u
.x
.pal
.hMapping
&& (dc
->u
.x
.pal
.hMapping
!= hSysColorTranslation
))
425 GDI_HEAP_FREE( dc
->u
.x
.pal
.hMapping
);
426 if (dc
->u
.x
.pal
.hRevMapping
&&
427 (dc
->u
.x
.pal
.hRevMapping
!= hRevSysColorTranslation
))
428 GDI_HEAP_FREE( dc
->u
.x
.pal
.hRevMapping
);
429 if (map
&& (map
!= hSysColorTranslation
))
431 /* Copy mapping table */
432 dc
->u
.x
.pal
.hMapping
= GDI_HEAP_ALLOC( sizeof(WORD
) * size
);
433 pmap
= (WORD
*) GDI_HEAP_LIN_ADDR( map
);
434 pnewmap
= (WORD
*) GDI_HEAP_LIN_ADDR( dc
->u
.x
.pal
.hMapping
);
435 memcpy( pnewmap
, pmap
, sizeof(WORD
)*size
);
436 /* Build reverse table */
437 dc
->u
.x
.pal
.hRevMapping
= GDI_HEAP_ALLOC(sizeof(WORD
)*COLOR_ColormapSize
);
438 pmap
= (WORD
*) GDI_HEAP_LIN_ADDR( dc
->u
.x
.pal
.hRevMapping
);
439 for (i
= 0; i
< size
; i
++) pmap
[pnewmap
[i
]] = i
;
443 dc
->u
.x
.pal
.hMapping
= map
;
444 dc
->u
.x
.pal
.hRevMapping
= map
? hRevSysColorTranslation
: 0;
446 dc
->u
.x
.pal
.mappingSize
= size
;
450 /***********************************************************************
451 * RealizeDefaultPalette (GDI.365)
453 WORD
RealizeDefaultPalette( HDC hdc
)
456 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
457 dc
->w
.hPalette
= STOCK_DEFAULT_PALETTE
;
458 COLOR_SetMapping( dc
, hSysColorTranslation
,
459 hRevSysColorTranslation
, NB_RESERVED_COLORS
);
460 return NB_RESERVED_COLORS
;