wbemprox: Add support for enumerating class properties.
[wine] / dlls / gdi32 / palette.c
1 /*
2  * GDI palette objects
3  *
4  * Copyright 1993,1994 Alexandre Julliard
5  * Copyright 1996 Alex Korobka
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * NOTES:
22  * PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
23  * Information in the "Undocumented Windows" is incorrect.
24  */
25
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "wingdi.h"
34 #include "winuser.h"
35
36 #include "gdi_private.h"
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(palette);
40
41 typedef BOOL (*unrealize_function)(HPALETTE);
42
43 typedef struct tagPALETTEOBJ
44 {
45     GDIOBJHDR           header;
46     unrealize_function  unrealize;
47     WORD                version;    /* palette version */
48     WORD                count;      /* count of palette entries */
49     PALETTEENTRY       *entries;
50 } PALETTEOBJ;
51
52 static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
53 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle );
54 static BOOL PALETTE_DeleteObject( HGDIOBJ handle );
55
56 static const struct gdi_obj_funcs palette_funcs =
57 {
58     NULL,                     /* pSelectObject */
59     PALETTE_GetObject,        /* pGetObjectA */
60     PALETTE_GetObject,        /* pGetObjectW */
61     PALETTE_UnrealizeObject,  /* pUnrealizeObject */
62     PALETTE_DeleteObject      /* pDeleteObject */
63 };
64
65 /* Pointers to USER implementation of SelectPalette/RealizePalette */
66 /* they will be patched by USER on startup */
67 HPALETTE (WINAPI *pfnSelectPalette)(HDC hdc, HPALETTE hpal, WORD bkgnd ) = GDISelectPalette;
68 UINT (WINAPI *pfnRealizePalette)(HDC hdc) = GDIRealizePalette;
69
70 static UINT SystemPaletteUse = SYSPAL_STATIC;  /* currently not considered */
71
72 static HPALETTE hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
73 static HPALETTE hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
74
75
76 /***********************************************************************
77  *           PALETTE_Init
78  *
79  * Create the system palette.
80  */
81 HPALETTE PALETTE_Init(void)
82 {
83     const RGBQUAD *entries = get_default_color_table( 8 );
84     char buffer[FIELD_OFFSET( LOGPALETTE, palPalEntry[20] )];
85     LOGPALETTE *palPtr = (LOGPALETTE *)buffer;
86     int i;
87
88     /* create default palette (20 system colors) */
89
90     palPtr->palVersion = 0x300;
91     palPtr->palNumEntries = 20;
92     for (i = 0; i < 20; i++)
93     {
94         palPtr->palPalEntry[i].peRed   = entries[i < 10 ? i : 236 + i].rgbRed;
95         palPtr->palPalEntry[i].peGreen = entries[i < 10 ? i : 236 + i].rgbGreen;
96         palPtr->palPalEntry[i].peBlue  = entries[i < 10 ? i : 236 + i].rgbBlue;
97         palPtr->palPalEntry[i].peFlags = 0;
98     }
99     return CreatePalette( palPtr );
100 }
101
102
103 /***********************************************************************
104  * CreatePalette [GDI32.@]
105  *
106  * Creates a logical color palette.
107  *
108  * RETURNS
109  *    Success: Handle to logical palette
110  *    Failure: NULL
111  */
112 HPALETTE WINAPI CreatePalette(
113     const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
114 {
115     PALETTEOBJ * palettePtr;
116     HPALETTE hpalette;
117     int size;
118
119     if (!palette) return 0;
120     TRACE("entries=%i\n", palette->palNumEntries);
121
122     if (!(palettePtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*palettePtr) ))) return 0;
123     palettePtr->unrealize = NULL;
124     palettePtr->version = palette->palVersion;
125     palettePtr->count   = palette->palNumEntries;
126     size = palettePtr->count * sizeof(*palettePtr->entries);
127     if (!(palettePtr->entries = HeapAlloc( GetProcessHeap(), 0, size )))
128     {
129         HeapFree( GetProcessHeap(), 0, palettePtr );
130         return 0;
131     }
132     memcpy( palettePtr->entries, palette->palPalEntry, size );
133     if (!(hpalette = alloc_gdi_handle( &palettePtr->header, OBJ_PAL, &palette_funcs )))
134     {
135         HeapFree( GetProcessHeap(), 0, palettePtr->entries );
136         HeapFree( GetProcessHeap(), 0, palettePtr );
137     }
138     TRACE("   returning %p\n", hpalette);
139     return hpalette;
140 }
141
142
143 /***********************************************************************
144  * CreateHalftonePalette [GDI32.@]
145  *
146  * Creates a halftone palette.
147  *
148  * RETURNS
149  *    Success: Handle to logical halftone palette
150  *    Failure: 0
151  *
152  * FIXME: This simply creates the halftone palette derived from running
153  *        tests on a windows NT machine. This is assuming a color depth
154  *        of greater that 256 color. On a 256 color device the halftone
155  *        palette will be different and this function will be incorrect
156  */
157 HPALETTE WINAPI CreateHalftonePalette(
158     HDC hdc) /* [in] Handle to device context */
159 {
160     const RGBQUAD *entries = get_default_color_table( 8 );
161     char buffer[FIELD_OFFSET( LOGPALETTE, palPalEntry[256] )];
162     LOGPALETTE *pal = (LOGPALETTE *)buffer;
163     int i;
164
165     pal->palVersion = 0x300;
166     pal->palNumEntries = 256;
167     for (i = 0; i < 256; i++)
168     {
169         pal->palPalEntry[i].peRed   = entries[i].rgbRed;
170         pal->palPalEntry[i].peGreen = entries[i].rgbGreen;
171         pal->palPalEntry[i].peBlue  = entries[i].rgbBlue;
172         pal->palPalEntry[i].peFlags = 0;
173     }
174     return CreatePalette( pal );
175 }
176
177
178 /***********************************************************************
179  * GetPaletteEntries [GDI32.@]
180  *
181  * Retrieves palette entries.
182  *
183  * RETURNS
184  *    Success: Number of entries from logical palette
185  *    Failure: 0
186  */
187 UINT WINAPI GetPaletteEntries(
188     HPALETTE hpalette,    /* [in]  Handle of logical palette */
189     UINT start,           /* [in]  First entry to receive */
190     UINT count,           /* [in]  Number of entries to receive */
191     LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
192 {
193     PALETTEOBJ * palPtr;
194     UINT numEntries;
195
196     TRACE("hpal = %p, count=%i\n", hpalette, count );
197
198     palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL );
199     if (!palPtr) return 0;
200
201     /* NOTE: not documented but test show this to be the case */
202     if (count == 0)
203     {
204         count = palPtr->count;
205     }
206     else
207     {
208         numEntries = palPtr->count;
209         if (start+count > numEntries) count = numEntries - start;
210         if (entries)
211         {
212             if (start >= numEntries) count = 0;
213             else memcpy( entries, &palPtr->entries[start], count * sizeof(PALETTEENTRY) );
214         }
215     }
216
217     GDI_ReleaseObj( hpalette );
218     return count;
219 }
220
221
222 /***********************************************************************
223  * SetPaletteEntries [GDI32.@]
224  *
225  * Sets color values for range in palette.
226  *
227  * RETURNS
228  *    Success: Number of entries that were set
229  *    Failure: 0
230  */
231 UINT WINAPI SetPaletteEntries(
232     HPALETTE hpalette,    /* [in] Handle of logical palette */
233     UINT start,           /* [in] Index of first entry to set */
234     UINT count,           /* [in] Number of entries to set */
235     const PALETTEENTRY *entries) /* [in] Address of array of structures */
236 {
237     PALETTEOBJ * palPtr;
238     UINT numEntries;
239
240     TRACE("hpal=%p,start=%i,count=%i\n",hpalette,start,count );
241
242     if (hpalette == GetStockObject(DEFAULT_PALETTE)) return 0;
243     palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL );
244     if (!palPtr) return 0;
245
246     numEntries = palPtr->count;
247     if (start >= numEntries)
248     {
249       GDI_ReleaseObj( hpalette );
250       return 0;
251     }
252     if (start+count > numEntries) count = numEntries - start;
253     memcpy( &palPtr->entries[start], entries, count * sizeof(PALETTEENTRY) );
254     GDI_ReleaseObj( hpalette );
255     UnrealizeObject( hpalette );
256     return count;
257 }
258
259
260 /***********************************************************************
261  * ResizePalette [GDI32.@]
262  *
263  * Resizes logical palette.
264  *
265  * RETURNS
266  *    Success: TRUE
267  *    Failure: FALSE
268  */
269 BOOL WINAPI ResizePalette(
270     HPALETTE hPal, /* [in] Handle of logical palette */
271     UINT cEntries) /* [in] Number of entries in logical palette */
272 {
273     PALETTEOBJ * palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
274     PALETTEENTRY *entries;
275
276     if( !palPtr ) return FALSE;
277     TRACE("hpal = %p, prev = %i, new = %i\n", hPal, palPtr->count, cEntries );
278
279     if (!(entries = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
280                                  palPtr->entries, cEntries * sizeof(*palPtr->entries) )))
281     {
282         GDI_ReleaseObj( hPal );
283         return FALSE;
284     }
285     palPtr->entries = entries;
286     palPtr->count = cEntries;
287
288     GDI_ReleaseObj( hPal );
289     PALETTE_UnrealizeObject( hPal );
290     return TRUE;
291 }
292
293
294 /***********************************************************************
295  * AnimatePalette [GDI32.@]
296  *
297  * Replaces entries in logical palette.
298  *
299  * RETURNS
300  *    Success: TRUE
301  *    Failure: FALSE
302  *
303  * FIXME
304  *    Should use existing mapping when animating a primary palette
305  */
306 BOOL WINAPI AnimatePalette(
307     HPALETTE hPal,              /* [in] Handle to logical palette */
308     UINT StartIndex,            /* [in] First entry in palette */
309     UINT NumEntries,            /* [in] Count of entries in palette */
310     const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */
311 {
312     TRACE("%p (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
313
314     if( hPal != GetStockObject(DEFAULT_PALETTE) )
315     {
316         PALETTEOBJ * palPtr;
317         UINT pal_entries;
318         const PALETTEENTRY *pptr = PaletteColors;
319
320         palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
321         if (!palPtr) return 0;
322
323         pal_entries = palPtr->count;
324         if (StartIndex >= pal_entries)
325         {
326           GDI_ReleaseObj( hPal );
327           return 0;
328         }
329         if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex;
330         
331         for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
332           /* According to MSDN, only animate PC_RESERVED colours */
333           if (palPtr->entries[StartIndex].peFlags & PC_RESERVED) {
334             TRACE("Animating colour (%d,%d,%d) to (%d,%d,%d)\n",
335               palPtr->entries[StartIndex].peRed,
336               palPtr->entries[StartIndex].peGreen,
337               palPtr->entries[StartIndex].peBlue,
338               pptr->peRed, pptr->peGreen, pptr->peBlue);
339             palPtr->entries[StartIndex] = *pptr;
340           } else {
341             TRACE("Not animating entry %d -- not PC_RESERVED\n", StartIndex);
342           }
343         }
344         GDI_ReleaseObj( hPal );
345         /* FIXME: check for palette selected in active window */
346     }
347     return TRUE;
348 }
349
350
351 /***********************************************************************
352  * SetSystemPaletteUse [GDI32.@]
353  *
354  * Specify whether the system palette contains 2 or 20 static colors.
355  *
356  * RETURNS
357  *    Success: Previous system palette
358  *    Failure: SYSPAL_ERROR
359  */
360 UINT WINAPI SetSystemPaletteUse(
361     HDC hdc,  /* [in] Handle of device context */
362     UINT use) /* [in] Palette-usage flag */
363 {
364     UINT old = SystemPaletteUse;
365
366     /* Device doesn't support colour palettes */
367     if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)) {
368         return SYSPAL_ERROR;
369     }
370
371     switch (use) {
372         case SYSPAL_NOSTATIC:
373         case SYSPAL_NOSTATIC256:        /* WINVER >= 0x0500 */
374         case SYSPAL_STATIC:
375             SystemPaletteUse = use;
376             return old;
377         default:
378             return SYSPAL_ERROR;
379     }
380 }
381
382
383 /***********************************************************************
384  * GetSystemPaletteUse [GDI32.@]
385  *
386  * Gets state of system palette.
387  *
388  * RETURNS
389  *    Current state of system palette
390  */
391 UINT WINAPI GetSystemPaletteUse(
392     HDC hdc) /* [in] Handle of device context */
393 {
394     return SystemPaletteUse;
395 }
396
397
398 /***********************************************************************
399  * GetSystemPaletteEntries [GDI32.@]
400  *
401  * Gets range of palette entries.
402  *
403  * RETURNS
404  *    Success: Number of entries retrieved from palette
405  *    Failure: 0
406  */
407 UINT WINAPI GetSystemPaletteEntries(
408     HDC hdc,              /* [in]  Handle of device context */
409     UINT start,           /* [in]  Index of first entry to be retrieved */
410     UINT count,           /* [in]  Number of entries to be retrieved */
411     LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
412 {
413     UINT ret = 0;
414     DC *dc;
415
416     TRACE("hdc=%p,start=%i,count=%i\n", hdc,start,count);
417
418     if ((dc = get_dc_ptr( hdc )))
419     {
420         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetSystemPaletteEntries );
421         ret = physdev->funcs->pGetSystemPaletteEntries( physdev, start, count, entries );
422         release_dc_ptr( dc );
423     }
424     return ret;
425 }
426
427
428 /***********************************************************************
429  * GetNearestPaletteIndex [GDI32.@]
430  *
431  * Gets palette index for color.
432  *
433  * NOTES
434  *    Should index be initialized to CLR_INVALID instead of 0?
435  *
436  * RETURNS
437  *    Success: Index of entry in logical palette
438  *    Failure: CLR_INVALID
439  */
440 UINT WINAPI GetNearestPaletteIndex(
441     HPALETTE hpalette, /* [in] Handle of logical color palette */
442     COLORREF color)      /* [in] Color to be matched */
443 {
444     PALETTEOBJ* palObj = GDI_GetObjPtr( hpalette, OBJ_PAL );
445     UINT index  = 0;
446
447     if( palObj )
448     {
449         int i, diff = 0x7fffffff;
450         int r,g,b;
451         PALETTEENTRY* entry = palObj->entries;
452
453         for( i = 0; i < palObj->count && diff ; i++, entry++)
454         {
455             r = entry->peRed - GetRValue(color);
456             g = entry->peGreen - GetGValue(color);
457             b = entry->peBlue - GetBValue(color);
458
459             r = r*r + g*g + b*b;
460
461             if( r < diff ) { index = i; diff = r; }
462         }
463         GDI_ReleaseObj( hpalette );
464     }
465     TRACE("(%p,%06x): returning %d\n", hpalette, color, index );
466     return index;
467 }
468
469
470 /* null driver fallback implementation for GetNearestColor */
471 COLORREF nulldrv_GetNearestColor( PHYSDEV dev, COLORREF color )
472 {
473     unsigned char spec_type;
474
475     if (!(GetDeviceCaps( dev->hdc, RASTERCAPS ) & RC_PALETTE)) return color;
476
477     spec_type = color >> 24;
478     if (spec_type == 1 || spec_type == 2)
479     {
480         /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
481         UINT index;
482         PALETTEENTRY entry;
483         HPALETTE hpal = GetCurrentObject( dev->hdc, OBJ_PAL );
484
485         if (!hpal) hpal = GetStockObject( DEFAULT_PALETTE );
486         if (spec_type == 2) /* PALETTERGB */
487             index = GetNearestPaletteIndex( hpal, color );
488         else  /* PALETTEINDEX */
489             index = LOWORD(color);
490
491         if (!GetPaletteEntries( hpal, index, 1, &entry ))
492         {
493             WARN("RGB(%x) : idx %d is out of bounds, assuming NULL\n", color, index );
494             if (!GetPaletteEntries( hpal, 0, 1, &entry )) return CLR_INVALID;
495         }
496         color = RGB( entry.peRed, entry.peGreen, entry.peBlue );
497     }
498     return color & 0x00ffffff;
499 }
500
501
502 /***********************************************************************
503  * GetNearestColor [GDI32.@]
504  *
505  * Gets a system color to match.
506  *
507  * RETURNS
508  *    Success: Color from system palette that corresponds to given color
509  *    Failure: CLR_INVALID
510  */
511 COLORREF WINAPI GetNearestColor(
512     HDC hdc,      /* [in] Handle of device context */
513     COLORREF color) /* [in] Color to be matched */
514 {
515     COLORREF nearest = CLR_INVALID;
516     DC *dc;
517
518     if ((dc = get_dc_ptr( hdc )))
519     {
520         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pGetNearestColor );
521         nearest = physdev->funcs->pGetNearestColor( physdev, color );
522         release_dc_ptr( dc );
523     }
524     return nearest;
525 }
526
527
528 /***********************************************************************
529  *           PALETTE_GetObject
530  */
531 static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
532 {
533     PALETTEOBJ *palette = GDI_GetObjPtr( handle, OBJ_PAL );
534
535     if (!palette) return 0;
536
537     if (buffer)
538     {
539         if (count > sizeof(WORD)) count = sizeof(WORD);
540         memcpy( buffer, &palette->count, count );
541     }
542     else count = sizeof(WORD);
543     GDI_ReleaseObj( handle );
544     return count;
545 }
546
547
548 /***********************************************************************
549  *           PALETTE_UnrealizeObject
550  */
551 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle )
552 {
553     PALETTEOBJ *palette = GDI_GetObjPtr( handle, OBJ_PAL );
554
555     if (palette)
556     {
557         unrealize_function unrealize = palette->unrealize;
558         palette->unrealize = NULL;
559         GDI_ReleaseObj( handle );
560         if (unrealize) unrealize( handle );
561     }
562
563     if (InterlockedCompareExchangePointer( (void **)&hLastRealizedPalette, 0, handle ) == handle)
564         TRACE("unrealizing palette %p\n", handle);
565
566     return TRUE;
567 }
568
569
570 /***********************************************************************
571  *           PALETTE_DeleteObject
572  */
573 static BOOL PALETTE_DeleteObject( HGDIOBJ handle )
574 {
575     PALETTEOBJ *obj;
576
577     PALETTE_UnrealizeObject( handle );
578     if (!(obj = free_gdi_handle( handle ))) return FALSE;
579     HeapFree( GetProcessHeap(), 0, obj->entries );
580     return HeapFree( GetProcessHeap(), 0, obj );
581 }
582
583
584 /***********************************************************************
585  *           GDISelectPalette    (Not a Windows API)
586  */
587 HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg)
588 {
589     HPALETTE ret = 0;
590     DC *dc;
591
592     TRACE("%p %p\n", hdc, hpal );
593
594     if (GetObjectType(hpal) != OBJ_PAL)
595     {
596       WARN("invalid selected palette %p\n",hpal);
597       return 0;
598     }
599     if ((dc = get_dc_ptr( hdc )))
600     {
601         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectPalette );
602         ret = dc->hPalette;
603         if (physdev->funcs->pSelectPalette( physdev, hpal, FALSE ))
604         {
605             dc->hPalette = hpal;
606             if (!wBkg) hPrimaryPalette = hpal;
607         }
608         else ret = 0;
609         release_dc_ptr( dc );
610     }
611     return ret;
612 }
613
614
615 /***********************************************************************
616  *           GDIRealizePalette    (Not a Windows API)
617  */
618 UINT WINAPI GDIRealizePalette( HDC hdc )
619 {
620     UINT realized = 0;
621     DC* dc = get_dc_ptr( hdc );
622
623     if (!dc) return 0;
624
625     TRACE("%p...\n", hdc );
626
627     if( dc->hPalette == GetStockObject( DEFAULT_PALETTE ))
628     {
629         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRealizeDefaultPalette );
630         realized = physdev->funcs->pRealizeDefaultPalette( physdev );
631     }
632     else if (InterlockedExchangePointer( (void **)&hLastRealizedPalette, dc->hPalette ) != dc->hPalette)
633     {
634         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pRealizePalette );
635         PALETTEOBJ *palPtr = GDI_GetObjPtr( dc->hPalette, OBJ_PAL );
636         if (palPtr)
637         {
638             realized = physdev->funcs->pRealizePalette( physdev, dc->hPalette,
639                                                         (dc->hPalette == hPrimaryPalette) );
640             palPtr->unrealize = physdev->funcs->pUnrealizePalette;
641             GDI_ReleaseObj( dc->hPalette );
642         }
643     }
644     else TRACE("  skipping (hLastRealizedPalette = %p)\n", hLastRealizedPalette);
645
646     release_dc_ptr( dc );
647     TRACE("   realized %i colors.\n", realized );
648     return realized;
649 }
650
651
652 /***********************************************************************
653  * SelectPalette [GDI32.@]
654  *
655  * Selects logical palette into DC.
656  *
657  * RETURNS
658  *    Success: Previous logical palette
659  *    Failure: NULL
660  */
661 HPALETTE WINAPI SelectPalette(
662     HDC hDC,               /* [in] Handle of device context */
663     HPALETTE hPal,         /* [in] Handle of logical color palette */
664     BOOL bForceBackground) /* [in] Foreground/background mode */
665 {
666     return pfnSelectPalette( hDC, hPal, bForceBackground );
667 }
668
669
670 /***********************************************************************
671  * RealizePalette [GDI32.@]
672  *
673  * Maps palette entries to system palette.
674  *
675  * RETURNS
676  *    Success: Number of entries in logical palette
677  *    Failure: GDI_ERROR
678  */
679 UINT WINAPI RealizePalette(
680     HDC hDC) /* [in] Handle of device context */
681 {
682     return pfnRealizePalette( hDC );
683 }
684
685
686 typedef HWND (WINAPI *WindowFromDC_funcptr)( HDC );
687 typedef BOOL (WINAPI *RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT );
688
689 /**********************************************************************
690  * UpdateColors [GDI32.@]
691  *
692  * Remaps current colors to logical palette.
693  *
694  * RETURNS
695  *    Success: TRUE
696  *    Failure: FALSE
697  */
698 BOOL WINAPI UpdateColors(
699     HDC hDC) /* [in] Handle of device context */
700 {
701     HMODULE mod;
702     int size = GetDeviceCaps( hDC, SIZEPALETTE );
703
704     if (!size) return 0;
705
706     mod = GetModuleHandleA("user32.dll");
707     if (mod)
708     {
709         WindowFromDC_funcptr pWindowFromDC = (WindowFromDC_funcptr)GetProcAddress(mod,"WindowFromDC");
710         if (pWindowFromDC)
711         {
712             HWND hWnd = pWindowFromDC( hDC );
713
714             /* Docs say that we have to remap current drawable pixel by pixel
715              * but it would take forever given the speed of XGet/PutPixel.
716              */
717             if (hWnd && size)
718             {
719                 RedrawWindow_funcptr pRedrawWindow = (void *)GetProcAddress( mod, "RedrawWindow" );
720                 if (pRedrawWindow) pRedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
721             }
722         }
723     }
724     return 0x666;
725 }
726
727 /*********************************************************************
728  *           SetMagicColors   (GDI32.@)
729  */
730 BOOL WINAPI SetMagicColors(HDC hdc, ULONG u1, ULONG u2)
731 {
732     FIXME("(%p 0x%08x 0x%08x): stub\n", hdc, u1, u2);
733     return TRUE;
734 }