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