Release 940722
[wine/multimedia.git] / objects / color.c
blobc6cbddc1bc303b339fcd70367d5cc3ec2ab01c22
1 /*
2 * Color functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include <stdlib.h>
10 #include <X11/Xlib.h>
12 #include "windows.h"
13 #include "options.h"
14 #include "gdi.h"
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 /***********************************************************************
57 * COLOR_BuildMap
59 * Fill the private colormap.
61 static BOOL COLOR_BuildMap( Colormap map, int depth, int size )
63 XColor color;
64 int r, g, b, red_incr, green_incr, blue_incr;
65 int index = 0;
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++;
79 color.red = r;
80 color.green = g;
81 color.blue = b;
82 XStoreColor( display, map, &color );
85 return TRUE;
89 /***********************************************************************
90 * COLOR_InitPalette
92 * Create the system palette.
94 static HPALETTE COLOR_InitPalette()
96 int i, size;
97 XColor color;
98 HPALETTE hpalette;
99 LOGPALETTE * palPtr;
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 */
118 color.pixel = i;
119 if (color.pixel >= size/2) continue;
121 else
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 printf( "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;
135 #if 0
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;
140 #endif
141 /* Set EGA mapping if color in the first or last eight */
142 if (i < 8)
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 );
155 free( palPtr );
156 return hpalette;
160 /***********************************************************************
161 * COLOR_Init
163 * Initialize color map and system palette.
165 HPALETTE COLOR_Init()
167 Visual * visual = DefaultVisual( display, DefaultScreen(display) );
169 switch(visual->class)
171 case GrayScale:
172 case PseudoColor:
173 case DirectColor:
174 if (Options.usePrivateMap)
176 COLOR_WinColormap = XCreateColormap( display, rootWindow,
177 visual, AllocAll );
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 );
189 break;
192 /* Fall through */
193 case StaticGray:
194 case StaticColor:
195 case TrueColor:
196 COLOR_WinColormap = DefaultColormapOfScreen( screen );
197 break;
199 return COLOR_InitPalette();
203 /***********************************************************************
204 * COLOR_IsSolid
206 * Check whether 'color' can be represented with a solid color.
208 BOOL COLOR_IsSolid( COLORREF color )
210 int i;
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;
221 return FALSE;
225 /***********************************************************************
226 * COLOR_ToPhysical
228 * Return the physical color closest to 'color'.
230 WORD COLOR_ToPhysical( DC *dc, COLORREF color )
232 WORD index = 0;
233 WORD *mapping;
235 if (!dc->u.x.pal.hMapping) return 0;
236 switch(color >> 24)
238 case 0: /* RGB */
239 index = GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE, color );
240 break;
241 case 1: /* PALETTEINDEX */
242 index = color & 0xffff;
243 break;
244 case 2: /* PALETTERGB */
245 index = GetNearestPaletteIndex( dc->w.hPalette, color );
246 break;
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 /***********************************************************************
255 * COLOR_SetMapping
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 )
283 WORD index;
284 DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
285 if (!dc) return 0;
286 index = COLOR_ToPhysical( dc, color & 0xffffff );
287 return PALETTEINDEX( index );
291 /***********************************************************************
292 * RealizeDefaultPalette (GDI.365)
294 WORD RealizeDefaultPalette( HDC hdc )
296 DC *dc;
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;