More bitmap fixes.
[wine] / objects / palette.c
1 /*
2  * GDI palette objects
3  *
4  * Copyright 1993,1994 Alexandre Julliard
5  * Copyright 1996 Alex Korobka
6  *
7  * PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
8  * Information in the "Undocumented Windows" is incorrect.
9  */
10
11 #include <stdlib.h>
12 #include <string.h>
13 #include "ts_xlib.h"
14
15 #include "gdi.h"
16 #include "color.h"
17 #include "palette.h"
18 #include "xmalloc.h"
19 #include "debug.h"
20
21 FARPROC32 pfnSelectPalette = NULL;
22 FARPROC32 pfnRealizePalette = NULL;
23
24 static UINT32 SystemPaletteUse = SYSPAL_STATIC;  /* currently not considered */
25
26 static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
27 static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
28
29
30 /***********************************************************************
31  *           PALETTE_Init
32  *
33  * Create the system palette.
34  */
35 HPALETTE16 PALETTE_Init(void)
36 {
37     int                 i;
38     HPALETTE16          hpalette;
39     LOGPALETTE *        palPtr;
40     PALETTEOBJ*         palObj;
41     const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate();
42
43     /* create default palette (20 system colors) */
44
45     palPtr = HeapAlloc( GetProcessHeap(), 0,
46              sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
47     if (!palPtr) return FALSE;
48
49     palPtr->palVersion = 0x300;
50     palPtr->palNumEntries = NB_RESERVED_COLORS;
51     for( i = 0; i < NB_RESERVED_COLORS; i ++ )
52     {
53         palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
54         palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
55         palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
56         palPtr->palPalEntry[i].peFlags = 0;
57     }
58     hpalette = CreatePalette16( palPtr );
59
60     palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
61
62     palObj->mapping = xmalloc( sizeof(int) * 20 );
63
64     GDI_HEAP_UNLOCK( hpalette );
65
66     HeapFree( GetProcessHeap(), 0, palPtr );
67     return hpalette;
68 }
69
70 /***********************************************************************
71  *           PALETTE_ValidateFlags
72  */
73 void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
74 {
75     int i = 0;
76     for( ; i<size ; i++ )
77         lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
78 }
79
80
81 /***********************************************************************
82  *           CreatePalette16    (GDI.360)
83  */
84 HPALETTE16 WINAPI CreatePalette16( const LOGPALETTE* palette )
85 {
86     return CreatePalette32( palette );
87 }
88
89
90 /***********************************************************************
91  * CreatePalette32 [GDI32.53]  Creates a logical color palette
92  *
93  * RETURNS
94  *    Success: Handle to logical palette
95  *    Failure: NULL
96  */
97 HPALETTE32 WINAPI CreatePalette32(
98     const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
99 {
100     PALETTEOBJ * palettePtr;
101     HPALETTE32 hpalette;
102     int size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
103
104     TRACE(palette,"entries=%i\n", palette->palNumEntries);
105
106     hpalette = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR) , PALETTE_MAGIC );
107     if (!hpalette) return 0;
108
109     palettePtr = (PALETTEOBJ *) GDI_HEAP_LOCK( hpalette );
110     memcpy( &palettePtr->logpalette, palette, size );
111     PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry, 
112                           palettePtr->logpalette.palNumEntries);
113     palettePtr->mapping = NULL;
114     GDI_HEAP_UNLOCK( hpalette );
115
116     TRACE(palette,"   returning %04x\n", hpalette);
117     return hpalette;
118 }
119
120
121 /***********************************************************************
122  * CreateHalftonePalette [GDI32.47]  Creates a halftone palette
123  *
124  * RETURNS
125  *    Success: Handle to logical halftone palette
126  *    Failure: 0
127  */
128 HPALETTE32 WINAPI CreateHalftonePalette(
129     HDC32 hdc) /* [in] Handle to device context */
130 {
131     FIXME(palette,"(0x%x): stub\n", hdc);
132     return (HPALETTE32)NULL;
133 }
134
135
136 /***********************************************************************
137  *           GetPaletteEntries16    (GDI.363)
138  */
139 UINT16 WINAPI GetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
140                                    UINT16 count, LPPALETTEENTRY entries )
141 {
142     return GetPaletteEntries32( hpalette, start, count, entries );
143 }
144
145
146 /***********************************************************************
147  * GetPaletteEntries32 [GDI32.209]  Retrieves palette entries
148  *
149  * RETURNS
150  *    Success: Number of entries from logical palette
151  *    Failure: 0
152  */
153 UINT32 WINAPI GetPaletteEntries32(
154     HPALETTE32 hpalette,    /* [in]  Handle of logical palette */
155     UINT32 start,           /* [in]  First entry to receive */
156     UINT32 count,           /* [in]  Number of entries to receive */
157     LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
158 {
159     PALETTEOBJ * palPtr;
160     INT32 numEntries;
161
162     TRACE(palette,"hpal = %04x, count=%i\n", hpalette, count );
163         
164     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
165     if (!palPtr) return 0;
166
167     numEntries = palPtr->logpalette.palNumEntries;
168     if (start+count > numEntries) count = numEntries - start;
169     if (entries)
170     { 
171       if (start >= numEntries) 
172       {
173         GDI_HEAP_UNLOCK( hpalette );
174         return 0;
175       }
176       memcpy( entries, &palPtr->logpalette.palPalEntry[start],
177               count * sizeof(PALETTEENTRY) );
178       for( numEntries = 0; numEntries < count ; numEntries++ )
179            if (entries[numEntries].peFlags & 0xF0)
180                entries[numEntries].peFlags = 0;
181       GDI_HEAP_UNLOCK( hpalette );
182     }
183
184     return count;
185 }
186
187
188 /***********************************************************************
189  *           SetPaletteEntries16    (GDI.364)
190  */
191 UINT16 WINAPI SetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
192                                    UINT16 count, LPPALETTEENTRY entries )
193 {
194     return SetPaletteEntries32( hpalette, start, count, entries );
195 }
196
197
198 /***********************************************************************
199  * SetPaletteEntries32 [GDI32.326]  Sets color values for range in palette
200  *
201  * RETURNS
202  *    Success: Number of entries that were set
203  *    Failure: 0
204  */
205 UINT32 WINAPI SetPaletteEntries32(
206     HPALETTE32 hpalette,    /* [in] Handle of logical palette */
207     UINT32 start,           /* [in] Index of first entry to set */
208     UINT32 count,           /* [in] Number of entries to set */
209     LPPALETTEENTRY entries) /* [in] Address of array of structures */
210 {
211     PALETTEOBJ * palPtr;
212     INT32 numEntries;
213
214     TRACE(palette,"hpal=%04x,start=%i,count=%i\n",hpalette,start,count );
215
216     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
217     if (!palPtr) return 0;
218
219     numEntries = palPtr->logpalette.palNumEntries;
220     if (start >= numEntries) 
221     {
222       GDI_HEAP_UNLOCK( hpalette );
223       return 0;
224     }
225     if (start+count > numEntries) count = numEntries - start;
226     memcpy( &palPtr->logpalette.palPalEntry[start], entries,
227             count * sizeof(PALETTEENTRY) );
228     PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, 
229                           palPtr->logpalette.palNumEntries);
230     free(palPtr->mapping);
231     palPtr->mapping = NULL;
232     GDI_HEAP_UNLOCK( hpalette );
233     return count;
234 }
235
236
237 /***********************************************************************
238  *           ResizePalette16   (GDI.368)
239  */
240 BOOL16 WINAPI ResizePalette16( HPALETTE16 hPal, UINT16 cEntries )
241 {
242     return ResizePalette32( hPal, cEntries );
243 }
244
245
246 /***********************************************************************
247  * ResizePalette32 [GDI32.289]  Resizes logical palette
248  *
249  * RETURNS
250  *    Success: TRUE
251  *    Failure: FALSE
252  */
253 BOOL32 WINAPI ResizePalette32(
254     HPALETTE32 hPal, /* [in] Handle of logical palette */
255     UINT32 cEntries) /* [in] Number of entries in logical palette */
256 {
257     PALETTEOBJ * palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
258     UINT32       cPrevEnt, prevVer;
259     int          prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
260     int*         mapping = NULL;
261
262     TRACE(palette,"hpal = %04x, prev = %i, new = %i\n",
263                     hPal, palPtr ? palPtr->logpalette.palNumEntries : -1,
264                     cEntries );
265     if( !palPtr ) return FALSE;
266     cPrevEnt = palPtr->logpalette.palNumEntries;
267     prevVer = palPtr->logpalette.palVersion;
268     prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) +
269                                         sizeof(int*) + sizeof(GDIOBJHDR);
270     size += sizeof(int*) + sizeof(GDIOBJHDR);
271     mapping = palPtr->mapping;
272     
273     GDI_HEAP_UNLOCK( hPal );
274     
275     hPal = GDI_HEAP_REALLOC( hPal, size );
276     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
277     if( !palPtr ) return FALSE;
278
279     if( mapping )
280         palPtr->mapping = (int*) xrealloc( mapping, cEntries * sizeof(int) );
281     if( cEntries > cPrevEnt ) 
282     {
283         if( mapping )
284             memset(palPtr->mapping + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
285         memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
286         PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), 
287                                                      cEntries - cPrevEnt );
288     }
289     palPtr->logpalette.palNumEntries = cEntries;
290     palPtr->logpalette.palVersion = prevVer;
291     GDI_HEAP_UNLOCK( hPal );
292     return TRUE;
293 }
294
295
296 /***********************************************************************
297  *           AnimatePalette16   (GDI.367)
298  */
299 void WINAPI AnimatePalette16( HPALETTE16 hPal, UINT16 StartIndex,
300                               UINT16 NumEntries, const PALETTEENTRY* PaletteColors)
301 {
302     AnimatePalette32( hPal, StartIndex, NumEntries, PaletteColors );
303 }
304
305
306 /***********************************************************************
307  * AnimatePalette32 [GDI32.6]  Replaces entries in logical palette
308  *
309  * RETURNS
310  *    Success: TRUE
311  *    Failure: FALSE
312  *
313  * FIXME
314  *    Should use existing mapping when animating a primary palette
315  */
316 BOOL32 WINAPI AnimatePalette32(
317     HPALETTE32 hPal,              /* [in] Handle to logical palette */
318     UINT32 StartIndex,            /* [in] First entry in palette */
319     UINT32 NumEntries,            /* [in] Count of entries in palette */
320     const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */
321 {
322     TRACE(palette, "%04x (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
323
324     if( hPal != STOCK_DEFAULT_PALETTE ) 
325     {
326         PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
327
328         if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
329         {
330             UINT32 u;
331             for( u = 0; u < NumEntries; u++ )
332                 palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
333             COLOR_SetMapping(palPtr, StartIndex, NumEntries,
334                              hPal != hPrimaryPalette );
335             GDI_HEAP_UNLOCK( hPal );
336             return TRUE;
337         }
338     }
339     return FALSE;
340 }
341
342
343 /***********************************************************************
344  *           SetSystemPaletteUse16   (GDI.373)
345  */
346 UINT16 WINAPI SetSystemPaletteUse16( HDC16 hdc, UINT16 use )
347 {
348     return SetSystemPaletteUse32( hdc, use );
349 }
350
351
352 /***********************************************************************
353  * SetSystemPaletteUse32 [GDI32.335]
354  *
355  * RETURNS
356  *    Success: Previous system palette
357  *    Failure: SYSPAL_ERROR
358  */
359 UINT32 WINAPI SetSystemPaletteUse32(
360     HDC32 hdc,  /* [in] Handle of device context */
361     UINT32 use) /* [in] Palette-usage flag */
362 {
363     UINT32 old = SystemPaletteUse;
364     FIXME(palette,"(%04x,%04x): stub\n", hdc, use );
365     SystemPaletteUse = use;
366     return old;
367 }
368
369
370 /***********************************************************************
371  *           GetSystemPaletteUse16   (GDI.374)
372  */
373 UINT16 WINAPI GetSystemPaletteUse16( HDC16 hdc )
374 {
375     return SystemPaletteUse;
376 }
377
378
379 /***********************************************************************
380  * GetSystemPaletteUse32 [GDI32.223]  Gets state of system palette
381  *
382  * RETURNS
383  *    Current state of system palette
384  */
385 UINT32 WINAPI GetSystemPaletteUse32(
386     HDC32 hdc) /* [in] Handle of device context */
387 {
388     return SystemPaletteUse;
389 }
390
391
392 /***********************************************************************
393  *           GetSystemPaletteEntries16   (GDI.375)
394  */
395 UINT16 WINAPI GetSystemPaletteEntries16( HDC16 hdc, UINT16 start, UINT16 count,
396                                          LPPALETTEENTRY entries )
397 {
398     return GetSystemPaletteEntries32( hdc, start, count, entries );
399 }
400
401
402 /***********************************************************************
403  * GetSystemPaletteEntries32 [GDI32.222]  Gets range of palette entries
404  *
405  * RETURNS
406  *    Success: Number of entries retrieved from palette
407  *    Failure: 0
408  */
409 UINT32 WINAPI GetSystemPaletteEntries32(
410     HDC32 hdc,              /* [in]  Handle of device context */
411     UINT32 start,           /* [in]  Index of first entry to be retrieved */
412     UINT32 count,           /* [in]  Number of entries to be retrieved */
413     LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
414 {
415     UINT32 i;
416     DC *dc;
417
418     TRACE(palette, "hdc=%04x,start=%i,count=%i\n", hdc,start,count);
419
420     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
421     if (start >= dc->w.devCaps->sizePalette)
422       {
423         GDI_HEAP_UNLOCK( hdc );
424         return 0;
425       }
426     if (start+count >= dc->w.devCaps->sizePalette)
427         count = dc->w.devCaps->sizePalette - start;
428     for (i = 0; i < count; i++)
429     {
430         *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry( start + i );
431
432         TRACE(palette,"\tidx(%02x) -> RGB(%08lx)\n",
433                          start + i, *(COLORREF*)(entries + i) );
434     }
435     GDI_HEAP_UNLOCK( hdc );
436     return count;
437 }
438
439
440 /***********************************************************************
441  *           GetNearestPaletteIndex16   (GDI.370)
442  */
443 UINT16 WINAPI GetNearestPaletteIndex16( HPALETTE16 hpalette, COLORREF color )
444 {
445     return GetNearestPaletteIndex32( hpalette, color );
446 }
447
448
449 /***********************************************************************
450  * GetNearestPaletteIndex32 [GDI32.203]  Gets palette index for color
451  *
452  * NOTES
453  *    Should index be initialized to CLR_INVALID instead of 0?
454  *
455  * RETURNS
456  *    Success: Index of entry in logical palette
457  *    Failure: CLR_INVALID
458  */
459 UINT32 WINAPI GetNearestPaletteIndex32(
460     HPALETTE32 hpalette, /* [in] Handle of logical color palette */
461     COLORREF color)      /* [in] Color to be matched */
462 {
463     PALETTEOBJ* palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
464     UINT32 index  = 0;
465
466     if( palObj )
467         index = COLOR_PaletteLookupPixel( palObj->logpalette.palPalEntry, 
468                                           palObj->logpalette.palNumEntries,
469                                           NULL, color, FALSE );
470
471     TRACE(palette,"(%04x,%06lx): returning %d\n", hpalette, color, index );
472     GDI_HEAP_UNLOCK( hpalette );
473     return index;
474 }
475
476
477 /***********************************************************************
478  *           GetNearestColor16   (GDI.154)
479  */
480 COLORREF WINAPI GetNearestColor16( HDC16 hdc, COLORREF color )
481 {
482     return GetNearestColor32( hdc, color );
483 }
484
485
486 /***********************************************************************
487  * GetNearestColor32 [GDI32.202]  Gets a system color to match
488  *
489  * NOTES
490  *    Should this return CLR_INVALID instead of FadeCafe?
491  *
492  * RETURNS
493  *    Success: Color from system palette that corresponds to given color
494  *    Failure: CLR_INVALID
495  */
496 COLORREF WINAPI GetNearestColor32(
497     HDC32 hdc,      /* [in] Handle of device context */
498     COLORREF color) /* [in] Color to be matched */
499 {
500     COLORREF     nearest = 0xFADECAFE;
501     DC          *dc;
502     PALETTEOBJ  *palObj;
503
504     if ( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) )
505     {
506       palObj = (PALETTEOBJ*) 
507                 GDI_GetObjPtr( (dc->w.hPalette)? dc->w.hPalette
508                                                : STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
509
510       nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry,
511                                           palObj->logpalette.palNumEntries, color );
512       GDI_HEAP_UNLOCK( dc->w.hPalette );
513     }
514
515     TRACE(palette,"(%06lx): returning %06lx\n", color, nearest );
516     GDI_HEAP_UNLOCK( hdc );    
517     return nearest;
518 }
519
520
521 /***********************************************************************
522  *           PALETTE_GetObject
523  */
524 int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
525 {
526     if (count > sizeof(WORD)) count = sizeof(WORD);
527     memcpy( buffer, &palette->logpalette.palNumEntries, count );
528     return count;
529 }
530
531
532 /***********************************************************************
533  *           PALETTE_UnrealizeObject
534  */
535 BOOL32 PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
536 {
537     if (palette->mapping)
538     {
539         free( palette->mapping );
540         palette->mapping = NULL;
541     }
542     if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
543     return TRUE;
544 }
545
546
547 /***********************************************************************
548  *           PALETTE_DeleteObject
549  */
550 BOOL32 PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
551 {
552     free( palette->mapping );
553     if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
554     return GDI_FreeObject( hpalette );
555 }
556
557
558 /***********************************************************************
559  *           GDISelectPalette    (GDI.361)
560  */
561 HPALETTE16 WINAPI GDISelectPalette( HDC16 hdc, HPALETTE16 hpal, WORD wBkg)
562 {
563     HPALETTE16 prev;
564     DC *dc;
565
566     TRACE(palette, "%04x %04x\n", hdc, hpal );
567     
568     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
569     if (!dc) 
570     {
571         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
572         if (!dc) return 0;
573     }
574     prev = dc->w.hPalette;
575     dc->w.hPalette = hpal;
576     GDI_HEAP_UNLOCK( hdc );
577     if (!wBkg) hPrimaryPalette = hpal; 
578     return prev;
579 }
580
581
582 /***********************************************************************
583  *           GDIRealizePalette    (GDI.362)
584  */
585 UINT16 WINAPI GDIRealizePalette( HDC16 hdc )
586 {
587     PALETTEOBJ* palPtr;
588     int realized = 0;
589     DC*         dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
590     if (!dc) 
591     {
592         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
593         if (!dc) return 0;
594     }
595
596     TRACE(palette, "%04x...\n", hdc );
597     
598     if( dc &&  dc->w.hPalette != hLastRealizedPalette )
599     {
600         if( dc->w.hPalette == STOCK_DEFAULT_PALETTE )
601             return RealizeDefaultPalette( hdc );
602
603         palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC );
604
605         if (!palPtr) {
606                 FIXME(palette,"invalid selected palette %04x\n",dc->w.hPalette);
607                 return 0;
608         }
609         
610         realized = COLOR_SetMapping(palPtr,0,palPtr->logpalette.palNumEntries,
611                                     (dc->w.hPalette != hPrimaryPalette) ||
612                                     (dc->w.hPalette == STOCK_DEFAULT_PALETTE));
613         GDI_HEAP_UNLOCK( dc->w.hPalette );
614         hLastRealizedPalette = dc->w.hPalette;
615     }
616     else TRACE(palette, "  skipping (hLastRealizedPalette = %04x)\n",
617                          hLastRealizedPalette);
618     GDI_HEAP_UNLOCK( hdc );
619
620     TRACE(palette, "   realized %i colors.\n", realized );
621     return (UINT16)realized;
622 }
623
624
625 /***********************************************************************
626  *           RealizeDefaultPalette    (GDI.365)
627  */
628 UINT16 WINAPI RealizeDefaultPalette( HDC16 hdc )
629 {
630     DC          *dc;
631     PALETTEOBJ*  palPtr;
632     int          i, index, realized = 0;
633
634     TRACE(palette,"%04x\n", hdc );
635
636     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
637     if (!dc) 
638     {
639         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
640         if (!dc) return 0;
641     }
642
643     if ( dc->w.flags & DC_MEMORY ) 
644       {
645         GDI_HEAP_UNLOCK( hdc );
646         return 0;
647       }
648
649     hPrimaryPalette = STOCK_DEFAULT_PALETTE;
650     hLastRealizedPalette = STOCK_DEFAULT_PALETTE;
651
652     palPtr = (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
653
654     /* lookup is needed to account for SetSystemPaletteUse() stuff */
655
656     for( i = 0; i < 20; i++ )
657        {
658          index = COLOR_LookupSystemPixel(*(COLORREF*)(palPtr->logpalette.palPalEntry + i));
659
660          /* mapping is allocated in COLOR_InitPalette() */
661
662          if( index != palPtr->mapping[i] ) { palPtr->mapping[i]=index; realized++; }
663        }
664     return realized;
665 }
666
667 /***********************************************************************
668  *           IsDCCurrentPalette   (GDI.412)
669  */
670 BOOL16 WINAPI IsDCCurrentPalette(HDC16 hDC)
671 {
672     DC* dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
673     if (dc) 
674     {
675       GDI_HEAP_UNLOCK( hDC );
676       return dc->w.hPalette == hPrimaryPalette;
677     }
678     return FALSE;
679 }
680
681
682 /***********************************************************************
683  *           SelectPalette16    (USER.282)
684  */
685 HPALETTE16 WINAPI SelectPalette16( HDC16 hDC, HPALETTE16 hPal,
686                                    BOOL16 bForceBackground )
687 {
688     return SelectPalette32( hDC, hPal, bForceBackground );
689 }
690
691
692 /***********************************************************************
693  * SelectPalette32 [GDI32.300]  Selects logical palette into DC
694  *
695  * RETURNS
696  *    Success: Previous logical palette
697  *    Failure: NULL
698  */
699 HPALETTE32 WINAPI SelectPalette32(
700     HDC32 hDC,               /* [in] Handle of device context */
701     HPALETTE32 hPal,         /* [in] Handle of logical color palette */
702     BOOL32 bForceBackground) /* [in] Foreground/background mode */
703 {
704     WORD        wBkgPalette = 1;
705     PALETTEOBJ* lpt = (PALETTEOBJ*) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
706
707     TRACE(palette,"dc=%04x,pal=%04x,force=%i\n", hDC, hPal, bForceBackground);
708     if( !lpt ) return 0;
709
710     TRACE(palette," entries = %d\n", lpt->logpalette.palNumEntries);
711     GDI_HEAP_UNLOCK( hPal );
712
713     if( hPal != STOCK_DEFAULT_PALETTE )
714     {
715         HWND32 hWnd = WindowFromDC32( hDC );
716         HWND32 hActive = GetActiveWindow32();
717         
718         /* set primary palette if it's related to current active */
719
720         if((!hWnd || (hActive == hWnd || IsChild16(hActive,hWnd))) &&
721             !bForceBackground )
722             wBkgPalette = 0;
723     }
724     return GDISelectPalette( hDC, hPal, wBkgPalette);
725 }
726
727
728 /***********************************************************************
729  *           RealizePalette16    (USER.283)
730  */
731 UINT16 WINAPI RealizePalette16( HDC16 hDC )
732 {
733     return RealizePalette32( hDC );
734 }
735
736
737 /***********************************************************************
738  * RealizePalette32 [GDI32.280]  Maps palette entries to system palette
739  *
740  * RETURNS
741  *    Success: Number of entries in logical palette
742  *    Failure: GDI_ERROR
743  */
744 UINT32 WINAPI RealizePalette32(
745     HDC32 hDC) /* [in] Handle of device context */
746 {
747     UINT32 realized = GDIRealizePalette( hDC );
748
749     /* do not send anything if no colors were changed */
750
751     if( IsDCCurrentPalette( hDC ) && realized && 
752         !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
753     {
754         /* Send palette change notification */
755
756         HWND32 hWnd;
757         if( (hWnd = WindowFromDC32( hDC )) )
758             SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
759     }
760     return realized;
761 }
762
763
764 /**********************************************************************
765  *            UpdateColors16   (GDI.366)
766  */
767 INT16 WINAPI UpdateColors16( HDC16 hDC )
768 {
769     HWND32 hWnd = WindowFromDC32( hDC );
770
771     /* Docs say that we have to remap current drawable pixel by pixel
772      * but it would take forever given the speed of XGet/PutPixel.
773      */
774     if (hWnd && !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) ) 
775         InvalidateRect32( hWnd, NULL, FALSE );
776     return 0x666;
777 }
778
779
780 /**********************************************************************
781  * UpdateColors32 [GDI32.359]  Remaps current colors to logical palette
782  *
783  * RETURNS
784  *    Success: TRUE
785  *    Failure: FALSE
786  */
787 BOOL32 WINAPI UpdateColors32(
788     HDC32 hDC) /* [in] Handle of device context */
789 {
790     UpdateColors16( hDC );
791     return TRUE;
792 }
793