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