Release 960516
[wine] / objects / palette.c
1 /*
2  * GDI palette objects
3  *
4  * Copyright 1993,1994 Alexandre Julliard
5  *
6  */
7 #include <stdlib.h>
8 #include <string.h>
9 #include <X11/Xlib.h>
10
11 #include "color.h"
12 #include "palette.h"
13 #include "stddebug.h"
14 /* #define DEBUG_PALETTE */
15 #include "debug.h"
16
17 static WORD SystemPaletteUse = SYSPAL_STATIC;   /* currently not considered */
18
19
20 /***********************************************************************
21  *           PALETTE_GetNearestIndexAndColor
22  */
23 static WORD PALETTE_GetNearestIndexAndColor(HPALETTE16 hpalette, COLORREF *color)
24 {
25     int i, minDist, dist;
26     WORD index = 0;
27     BYTE r, g, b;
28     PALETTEENTRY * entry;
29     PALETTEOBJ * palPtr;
30     
31     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
32     if (!palPtr) return 0;
33
34     if ((COLOR_WinColormap != DefaultColormapOfScreen(screen)) &&
35         (hpalette == STOCK_DEFAULT_PALETTE))
36     {
37         if ((*color & 0xffffff) == 0) return 0;  /* Entry 0 is black */
38         if ((*color & 0xffffff) == 0xffffff)     /* Max entry is white */
39             return palPtr->logpalette.palNumEntries - 1;
40     }
41     
42     r = GetRValue(*color);
43     g = GetGValue(*color);
44     b = GetBValue(*color);
45
46     entry = palPtr->logpalette.palPalEntry;
47     for (i = 0, minDist = 0xffffff; minDist !=0 &&
48          i < palPtr->logpalette.palNumEntries ; i++)
49     {
50         if (entry->peFlags != 0xff)
51         {
52             dist = (r - entry->peRed) * (r - entry->peRed) +
53                    (g - entry->peGreen) * (g - entry->peGreen) +
54                    (b - entry->peBlue) * (b - entry->peBlue);   
55             if (dist < minDist)
56             {
57                 minDist = dist;
58                 index = i;
59             }
60         }
61         entry++;
62     }
63     entry = &palPtr->logpalette.palPalEntry[index];
64     *color = RGB( entry->peRed, entry->peGreen, entry->peBlue );
65     return index;
66 }
67
68
69 /***********************************************************************
70  *           CreatePalette    (GDI.360)
71  */
72 HPALETTE16 CreatePalette( const LOGPALETTE* palette )
73 {
74     PALETTEOBJ * palettePtr;
75     HPALETTE16 hpalette;
76     int size;
77
78     size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
79     hpalette = GDI_AllocObject( sizeof(GDIOBJHDR) + size, PALETTE_MAGIC );
80     if (!hpalette) return 0;
81     palettePtr = (PALETTEOBJ *) GDI_HEAP_LIN_ADDR( hpalette );
82     memcpy( &palettePtr->logpalette, palette, size );
83     return hpalette;
84 }
85
86
87 /***********************************************************************
88  *           GetPaletteEntries    (GDI.363)
89  */
90 WORD GetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
91                         LPPALETTEENTRY entries )
92 {
93     PALETTEOBJ * palPtr;
94     int numEntries;
95         
96     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
97     if (!palPtr) return 0;
98     numEntries = palPtr->logpalette.palNumEntries;
99     if (start >= numEntries) return 0;
100     if (start+count > numEntries) count = numEntries - start;
101     memcpy( entries, &palPtr->logpalette.palPalEntry[start],
102             count * sizeof(PALETTEENTRY) );
103     return count;
104 }
105
106
107 /***********************************************************************
108  *           SetPaletteEntries    (GDI.364)
109  */
110 WORD SetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
111                         LPPALETTEENTRY entries )
112 {
113     PALETTEOBJ * palPtr;
114     int numEntries;
115         
116     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
117     if (!palPtr) return 0;
118     numEntries = palPtr->logpalette.palNumEntries;
119     if (start >= numEntries) return 0;
120     if (start+count > numEntries) count = numEntries - start;
121     memcpy( &palPtr->logpalette.palPalEntry[start], entries,
122             count * sizeof(PALETTEENTRY) );
123     return count;
124 }
125
126 /***********************************************************************
127  *           ResizePalette          (GDI.368)
128  */
129 BOOL ResizePalette(HPALETTE16 hPal, UINT cEntries)
130 {
131     fprintf(stdnimp,"ResizePalette: empty stub! \n");
132     return FALSE;
133 }
134
135 /***********************************************************************
136  *           AnimatePalette          (GDI.367)
137  */
138 BOOL AnimatePalette(HPALETTE16 hPal, UINT StartIndex, UINT NumEntries,
139                     LPPALETTEENTRY PaletteColors)
140 {
141     fprintf(stdnimp,"AnimatePalette: empty stub! \n");
142     return TRUE;
143 }
144
145 /***********************************************************************
146  *           SetSystemPaletteUse    (GDI.373)
147  *      Should this be per DC rather than system wide?
148  *  Currently, it does not matter as the use is only set and returned,
149  *  but not taken into account
150  */
151 WORD SetSystemPaletteUse( HDC hdc, WORD use)
152 {
153          WORD old=SystemPaletteUse;
154          printf("SetSystemPaletteUse(%04x,%04x) // empty stub !!!\n", hdc, use);
155          SystemPaletteUse=use;
156          return old;
157 }
158
159 /***********************************************************************
160  *           GetSystemPaletteUse    (GDI.374)
161  */
162 WORD GetSystemPaletteUse( HDC hdc )
163 {
164         printf("GetSystemPaletteUse(%04x) // empty stub !!!\n", hdc);
165         return SystemPaletteUse;
166 }
167
168
169 /***********************************************************************
170  *           GetSystemPaletteEntries    (GDI.375)
171  */
172 WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count,
173                               LPPALETTEENTRY entries )
174 {
175     WORD i;
176     DC *dc;
177     XColor color;
178
179     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
180     if (start >= dc->w.devCaps->sizePalette) return 0;
181     if (start+count >= dc->w.devCaps->sizePalette)
182         count = dc->w.devCaps->sizePalette - start;
183     for (i = 0; i < count; i++)
184     {
185         color.pixel = start + i;
186         XQueryColor( display, COLOR_WinColormap, &color );
187         entries[i].peRed   = color.red >> 8;
188         entries[i].peGreen = color.green >> 8;
189         entries[i].peBlue  = color.blue >> 8;
190         entries[i].peFlags = 0; 
191     }
192     return count;
193 }
194
195
196 /***********************************************************************
197  *           GetNearestPaletteIndex    (GDI.370)
198  */
199 WORD GetNearestPaletteIndex( HPALETTE16 hpalette, COLORREF color )
200 {
201     WORD index = PALETTE_GetNearestIndexAndColor( hpalette, &color );
202     dprintf_palette(stddeb,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n", 
203                     hpalette, color, index );
204     return index;
205 }
206
207
208 /***********************************************************************
209  *           GetNearestColor    (GDI.154)
210  */
211 COLORREF GetNearestColor( HDC hdc, COLORREF color )
212 {
213     COLORREF nearest = color;
214     DC *dc;
215
216     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
217     PALETTE_GetNearestIndexAndColor( dc->w.hPalette, &nearest );
218     dprintf_palette(stddeb,"GetNearestColor(%06lx): returning %06lx\n", 
219                     color, nearest );
220     return nearest;
221 }
222
223
224 /***********************************************************************
225  *           PALETTE_GetObject
226  */
227 int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
228 {
229     if (count > sizeof(WORD)) count = sizeof(WORD);
230     memcpy( buffer, &palette->logpalette.palNumEntries, count );
231     return count;
232 }
233
234
235 /***********************************************************************
236  *           GDISelectPalette    (GDI.361)
237  */
238 HPALETTE16 GDISelectPalette( HDC hdc, HPALETTE16 hpal )
239 {
240     HPALETTE16 prev;
241     DC *dc;
242
243     dprintf_palette(stddeb, "GDISelectPalette: %04x %04x\n", hdc, hpal );
244     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
245     prev = dc->w.hPalette;
246     dc->w.hPalette = hpal;
247     if (hpal != STOCK_DEFAULT_PALETTE) COLOR_SetMapping( dc, 0, 0, 0 );
248     else RealizeDefaultPalette( hdc );  /* Always realize default palette */
249     return prev;
250 }
251
252
253 /***********************************************************************
254  *           GDIRealizePalette    (GDI.362)
255  */
256 UINT GDIRealizePalette( HDC hdc )
257 {
258     UINT        realized = 0;
259     COLORREF    color;
260     DC*         dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ) ;
261     PALETTEOBJ* palPtr;
262
263     dprintf_palette(stdnimp, "GDIRealizePalette: %04x...", hdc );
264
265     if( dc )
266       {
267         palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC );
268
269         if( palPtr )
270           {
271             WORD        index, i;
272             HANDLE      hMap;
273             WORD*       pMap;
274
275             hMap = GDI_HEAP_ALLOC(sizeof(WORD)*palPtr->logpalette.palNumEntries);
276             pMap = (WORD*)GDI_HEAP_LIN_ADDR( hMap );
277
278             if( pMap )
279             {
280               for (i = 0; i < palPtr->logpalette.palNumEntries ; i++)
281               {
282                 color = *(COLORREF*)(palPtr->logpalette.palPalEntry + i);
283                 index = PALETTE_GetNearestIndexAndColor( STOCK_DEFAULT_PALETTE, &color);
284                 if( index != i ) realized++;
285                 pMap[i] = index;
286               }
287               COLOR_SetMapping(dc, hMap, 0, i);
288               GDI_HEAP_FREE(hMap);
289             }
290           }
291       }
292     dprintf_palette(stdnimp, " realized %i colors\n", realized );
293     return realized;
294 }
295
296
297 /***********************************************************************
298  *           SelectPalette    (USER.282)
299  */
300 HPALETTE16 SelectPalette(HDC hDC, HPALETTE16 hPal, BOOL bForceBackground)
301 {
302     return GDISelectPalette( hDC, hPal );
303 }
304
305
306 /***********************************************************************
307  *           RealizePalette    (USER.283)
308  */
309 UINT RealizePalette(HDC hDC)
310 {
311     return GDIRealizePalette( hDC );
312 }
313