Release 980329
[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   FIXME(palette,"(%x): empty stub!\n", hdc);
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     FIXME(palette,"(%04x,%04x): empty stub !!!\n", hdc, use );
316     SystemPaletteUse = use;
317     return old;
318 }
319
320
321 /***********************************************************************
322  *           GetSystemPaletteUse16   (GDI.374)
323  */
324 UINT16 WINAPI GetSystemPaletteUse16( HDC16 hdc )
325 {
326     return SystemPaletteUse;
327 }
328
329
330 /***********************************************************************
331  *           GetSystemPaletteUse32   (GDI32.223)
332  */
333 UINT32 WINAPI GetSystemPaletteUse32( HDC32 hdc )
334 {
335     return SystemPaletteUse;
336 }
337
338
339 /***********************************************************************
340  *           GetSystemPaletteEntries16   (GDI.375)
341  */
342 UINT16 WINAPI GetSystemPaletteEntries16( HDC16 hdc, UINT16 start, UINT16 count,
343                                          LPPALETTEENTRY entries )
344 {
345     return GetSystemPaletteEntries32( hdc, start, count, entries );
346 }
347
348
349 /***********************************************************************
350  *           GetSystemPaletteEntries32   (GDI32.222)
351  */
352 UINT32 WINAPI GetSystemPaletteEntries32( HDC32 hdc, UINT32 start, UINT32 count,
353                                          LPPALETTEENTRY entries )
354 {
355     UINT32 i;
356     DC *dc;
357
358     TRACE(palette, "hdc = %04x, "
359                     "cound = %i\n", hdc, count );
360
361     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
362     if (start >= dc->w.devCaps->sizePalette)
363       {
364         GDI_HEAP_UNLOCK( hdc );
365         return 0;
366       }
367     if (start+count >= dc->w.devCaps->sizePalette)
368         count = dc->w.devCaps->sizePalette - start;
369     for (i = 0; i < count; i++)
370     {
371         *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry( start + i );
372
373         TRACE(palette,"\tidx(%02x) -> RGB(%08lx)\n",
374                          start + i, *(COLORREF*)(entries + i) );
375     }
376     GDI_HEAP_UNLOCK( hdc );
377     return count;
378 }
379
380
381 /***********************************************************************
382  *           GetNearestPaletteIndex16   (GDI.370)
383  */
384 UINT16 WINAPI GetNearestPaletteIndex16( HPALETTE16 hpalette, COLORREF color )
385 {
386     return GetNearestPaletteIndex32( hpalette, color );
387 }
388
389
390 /***********************************************************************
391  *           GetNearestPaletteIndex32   (GDI32.203)
392  */
393 UINT32 WINAPI GetNearestPaletteIndex32( HPALETTE32 hpalette, COLORREF color )
394 {
395     PALETTEOBJ* palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
396     UINT32 index  = 0;
397
398     if( palObj )
399         index = COLOR_PaletteLookupPixel( palObj->logpalette.palPalEntry, 
400                                           palObj->logpalette.palNumEntries,
401                                           NULL, color, FALSE );
402
403     TRACE(palette,"(%04x,%06lx): returning %d\n", 
404                     hpalette, color, index );
405     GDI_HEAP_UNLOCK( hpalette );
406     return index;
407 }
408
409
410 /***********************************************************************
411  *           GetNearestColor16   (GDI.154)
412  */
413 COLORREF WINAPI GetNearestColor16( HDC16 hdc, COLORREF color )
414 {
415     return GetNearestColor32( hdc, color );
416 }
417
418
419 /***********************************************************************
420  *           GetNearestColor32   (GDI32.202)
421  */
422 COLORREF WINAPI GetNearestColor32( HDC32 hdc, COLORREF color )
423 {
424     COLORREF     nearest = 0xFADECAFE;
425     DC          *dc;
426     PALETTEOBJ  *palObj;
427
428     if ( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) )
429     {
430       palObj = (PALETTEOBJ*) 
431                 GDI_GetObjPtr( (dc->w.hPalette)? dc->w.hPalette
432                                                : STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
433
434       nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry,
435                                           palObj->logpalette.palNumEntries, color );
436       GDI_HEAP_UNLOCK( dc->w.hPalette );
437     }
438
439     TRACE(palette,"(%06lx): returning %06lx\n", 
440                     color, nearest );
441     GDI_HEAP_UNLOCK( hdc );    
442     return nearest;
443 }
444
445
446 /***********************************************************************
447  *           PALETTE_GetObject
448  */
449 int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
450 {
451     if (count > sizeof(WORD)) count = sizeof(WORD);
452     memcpy( buffer, &palette->logpalette.palNumEntries, count );
453     return count;
454 }
455
456
457 /***********************************************************************
458  *           PALETTE_UnrealizeObject
459  */
460 BOOL32 PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
461 {
462     if (palette->mapping)
463     {
464         free( palette->mapping );
465         palette->mapping = NULL;
466     }
467     if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
468     return TRUE;
469 }
470
471
472 /***********************************************************************
473  *           PALETTE_DeleteObject
474  */
475 BOOL32 PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
476 {
477     free( palette->mapping );
478     if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
479     return GDI_FreeObject( hpalette );
480 }
481
482
483 /***********************************************************************
484  *           GDISelectPalette    (GDI.361)
485  */
486 HPALETTE16 WINAPI GDISelectPalette( HDC16 hdc, HPALETTE16 hpal, WORD wBkg)
487 {
488     HPALETTE16 prev;
489     DC *dc;
490
491     TRACE(palette, "%04x %04x\n", hdc, hpal );
492     
493     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
494     if (!dc) 
495     {
496         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
497         if (!dc) return 0;
498     }
499     prev = dc->w.hPalette;
500     dc->w.hPalette = hpal;
501     GDI_HEAP_UNLOCK( hdc );
502     if (!wBkg) hPrimaryPalette = hpal; 
503     return prev;
504 }
505
506
507 /***********************************************************************
508  *           GDIRealizePalette    (GDI.362)
509  */
510 UINT16 WINAPI GDIRealizePalette( HDC16 hdc )
511 {
512     PALETTEOBJ* palPtr;
513     int realized = 0;
514     DC*         dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
515     if (!dc) 
516     {
517         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
518         if (!dc) return 0;
519     }
520
521     TRACE(palette, "%04x...\n", hdc );
522     
523     if( dc &&  dc->w.hPalette != hLastRealizedPalette )
524     {
525         if( dc->w.hPalette == STOCK_DEFAULT_PALETTE )
526             return RealizeDefaultPalette( hdc );
527
528         palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC );
529         
530         realized = COLOR_SetMapping(palPtr,0,palPtr->logpalette.palNumEntries,
531                                     (dc->w.hPalette != hPrimaryPalette) ||
532                                     (dc->w.hPalette == STOCK_DEFAULT_PALETTE));
533         GDI_HEAP_UNLOCK( dc->w.hPalette );
534         hLastRealizedPalette = dc->w.hPalette;
535     }
536     else TRACE(palette, "  skipping (hLastRealizedPalette = %04x)\n",
537                          hLastRealizedPalette);
538     GDI_HEAP_UNLOCK( hdc );
539
540     TRACE(palette, "   realized %i colors.\n", realized );
541     return (UINT16)realized;
542 }
543
544
545 /***********************************************************************
546  *           RealizeDefaultPalette    (GDI.365)
547  */
548 UINT16 WINAPI RealizeDefaultPalette( HDC16 hdc )
549 {
550     DC          *dc;
551     PALETTEOBJ*  palPtr;
552     int          i, index, realized = 0;
553
554     TRACE(palette,"%04x\n", hdc );
555
556     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
557     if (!dc) 
558     {
559         dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
560         if (!dc) return 0;
561     }
562
563     if ( dc->w.flags & DC_MEMORY ) 
564       {
565         GDI_HEAP_UNLOCK( hdc );
566         return 0;
567       }
568
569     hPrimaryPalette = STOCK_DEFAULT_PALETTE;
570     hLastRealizedPalette = STOCK_DEFAULT_PALETTE;
571
572     palPtr = (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
573
574     /* lookup is needed to account for SetSystemPaletteUse() stuff */
575
576     for( i = 0; i < 20; i++ )
577        {
578          index = COLOR_LookupSystemPixel(*(COLORREF*)(palPtr->logpalette.palPalEntry + i));
579
580          /* mapping is allocated in COLOR_InitPalette() */
581
582          if( index != palPtr->mapping[i] ) { palPtr->mapping[i]=index; realized++; }
583        }
584     return realized;
585 }
586
587 /***********************************************************************
588  *           IsDCCurrentPalette   (GDI.412)
589  */
590 BOOL16 WINAPI IsDCCurrentPalette(HDC16 hDC)
591 {
592     DC* dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
593     if (dc) 
594     {
595       GDI_HEAP_UNLOCK( hDC );
596       return dc->w.hPalette == hPrimaryPalette;
597     }
598     return FALSE;
599 }
600
601
602 /***********************************************************************
603  *           SelectPalette16    (USER.282)
604  */
605 HPALETTE16 WINAPI SelectPalette16( HDC16 hDC, HPALETTE16 hPal,
606                                    BOOL16 bForceBackground )
607 {
608     return SelectPalette32( hDC, hPal, bForceBackground );
609 }
610
611
612 /***********************************************************************
613  *           SelectPalette32    (GDI32.300)
614  */
615 HPALETTE32 WINAPI SelectPalette32( HDC32 hDC, HPALETTE32 hPal,
616                                    BOOL32 bForceBackground )
617 {
618     WORD        wBkgPalette = 1;
619     PALETTEOBJ* lpt = (PALETTEOBJ*) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
620
621     TRACE(palette,"dc %04x pal %04x, force=%i \n", 
622                             hDC, hPal, bForceBackground);
623     if( !lpt ) return 0;
624
625     TRACE(palette," entries = %d\n", 
626                             lpt->logpalette.palNumEntries);
627     GDI_HEAP_UNLOCK( hPal );
628
629     if( hPal != STOCK_DEFAULT_PALETTE )
630     {
631         HWND32 hWnd = WindowFromDC32( hDC );
632         HWND32 hActive = GetActiveWindow32();
633         
634         /* set primary palette if it's related to current active */
635
636         if((!hWnd || (hActive == hWnd || IsChild16(hActive,hWnd))) &&
637             !bForceBackground )
638             wBkgPalette = 0;
639     }
640     return GDISelectPalette( hDC, hPal, wBkgPalette);
641 }
642
643
644 /***********************************************************************
645  *           RealizePalette16    (USER.283)
646  */
647 UINT16 WINAPI RealizePalette16( HDC16 hDC )
648 {
649     return RealizePalette32( hDC );
650 }
651
652
653 /***********************************************************************
654  *           RealizePalette32    (GDI32.280)
655  */
656 UINT32 WINAPI RealizePalette32( HDC32 hDC )
657 {
658     UINT32 realized = GDIRealizePalette( hDC );
659
660     /* do not send anything if no colors were changed */
661
662     if( IsDCCurrentPalette( hDC ) && realized && 
663         !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
664     {
665         /* Send palette change notification */
666
667         HWND32 hWnd;
668         if( (hWnd = WindowFromDC32( hDC )) )
669             SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
670     }
671     return realized;
672 }
673
674
675 /**********************************************************************
676  *            UpdateColors16   (GDI.366)
677  */
678 INT16 WINAPI UpdateColors16( HDC16 hDC )
679 {
680     HWND32 hWnd = WindowFromDC32( hDC );
681
682     /* Docs say that we have to remap current drawable pixel by pixel
683      * but it would take forever given the speed of XGet/PutPixel.
684      */
685     if (hWnd && !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) ) 
686         InvalidateRect32( hWnd, NULL, FALSE );
687     return 0x666;
688 }
689
690
691 /**********************************************************************
692  *            UpdateColors32   (GDI32.359)
693  */
694 BOOL32 WINAPI UpdateColors32( HDC32 hDC )
695 {
696     UpdateColors16( hDC );
697     return TRUE;
698 }