winecfg: Add ability to change colors and non-client sizes.
[wine.git] / dlls / gdi32 / palette.c
blobecf98fc05859ac24a2fb7b570f0d0c4bc96a668d
1 /*
2 * GDI palette objects
4 * Copyright 1993,1994 Alexandre Julliard
5 * Copyright 1996 Alex Korobka
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.
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.
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
21 * NOTES:
22 * PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
23 * Information in the "Undocumented Windows" is incorrect.
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "wownt32.h"
34 #include "wine/winuser16.h"
35 #include "gdi_private.h"
36 #include "wine/debug.h"
37 #include "winerror.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(palette);
41 typedef struct tagPALETTEOBJ
43 GDIOBJHDR header;
44 const DC_FUNCTIONS *funcs; /* DC function table */
45 LOGPALETTE logpalette; /* _MUST_ be the last field */
46 } PALETTEOBJ;
48 static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
49 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle, void *obj );
50 static BOOL PALETTE_DeleteObject( HGDIOBJ handle, void *obj );
52 static const struct gdi_obj_funcs palette_funcs =
54 NULL, /* pSelectObject */
55 PALETTE_GetObject, /* pGetObject16 */
56 PALETTE_GetObject, /* pGetObjectA */
57 PALETTE_GetObject, /* pGetObjectW */
58 PALETTE_UnrealizeObject, /* pUnrealizeObject */
59 PALETTE_DeleteObject /* pDeleteObject */
62 /* Pointers to USER implementation of SelectPalette/RealizePalette */
63 /* they will be patched by USER on startup */
64 HPALETTE (WINAPI *pfnSelectPalette)(HDC hdc, HPALETTE hpal, WORD bkgnd ) = GDISelectPalette;
65 UINT (WINAPI *pfnRealizePalette)(HDC hdc) = GDIRealizePalette;
67 static UINT SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
69 static HPALETTE hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
70 static HPALETTE hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
72 #define NB_RESERVED_COLORS 20 /* number of fixed colors in system palette */
74 static const PALETTEENTRY sys_pal_template[NB_RESERVED_COLORS] =
76 /* first 10 entries in the system palette */
77 /* red green blue flags */
78 { 0x00, 0x00, 0x00, 0 },
79 { 0x80, 0x00, 0x00, 0 },
80 { 0x00, 0x80, 0x00, 0 },
81 { 0x80, 0x80, 0x00, 0 },
82 { 0x00, 0x00, 0x80, 0 },
83 { 0x80, 0x00, 0x80, 0 },
84 { 0x00, 0x80, 0x80, 0 },
85 { 0xc0, 0xc0, 0xc0, 0 },
86 { 0xc0, 0xdc, 0xc0, 0 },
87 { 0xa6, 0xca, 0xf0, 0 },
89 /* ... c_min/2 dynamic colorcells */
91 /* ... gap (for sparse palettes) */
93 /* ... c_min/2 dynamic colorcells */
95 { 0xff, 0xfb, 0xf0, 0 },
96 { 0xa0, 0xa0, 0xa4, 0 },
97 { 0x80, 0x80, 0x80, 0 },
98 { 0xff, 0x00, 0x00, 0 },
99 { 0x00, 0xff, 0x00, 0 },
100 { 0xff, 0xff, 0x00, 0 },
101 { 0x00, 0x00, 0xff, 0 },
102 { 0xff, 0x00, 0xff, 0 },
103 { 0x00, 0xff, 0xff, 0 },
104 { 0xff, 0xff, 0xff, 0 } /* last 10 */
107 /***********************************************************************
108 * PALETTE_Init
110 * Create the system palette.
112 HPALETTE PALETTE_Init(void)
114 HPALETTE hpalette;
115 LOGPALETTE * palPtr;
117 /* create default palette (20 system colors) */
119 palPtr = HeapAlloc( GetProcessHeap(), 0,
120 sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
121 if (!palPtr) return FALSE;
123 palPtr->palVersion = 0x300;
124 palPtr->palNumEntries = NB_RESERVED_COLORS;
125 memcpy( palPtr->palPalEntry, sys_pal_template, sizeof(sys_pal_template) );
126 hpalette = CreatePalette( palPtr );
127 HeapFree( GetProcessHeap(), 0, palPtr );
128 return hpalette;
132 /***********************************************************************
133 * CreatePalette [GDI32.@]
135 * Creates a logical color palette.
137 * RETURNS
138 * Success: Handle to logical palette
139 * Failure: NULL
141 HPALETTE WINAPI CreatePalette(
142 const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
144 PALETTEOBJ * palettePtr;
145 HPALETTE hpalette;
146 int size;
148 if (!palette) return 0;
149 TRACE("entries=%i\n", palette->palNumEntries);
151 size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
153 if (!(palettePtr = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR),
154 PALETTE_MAGIC, (HGDIOBJ *)&hpalette,
155 &palette_funcs ))) return 0;
156 memcpy( &palettePtr->logpalette, palette, size );
157 palettePtr->funcs = NULL;
158 GDI_ReleaseObj( hpalette );
160 TRACE(" returning %p\n", hpalette);
161 return hpalette;
165 /***********************************************************************
166 * CreateHalftonePalette [GDI32.@]
168 * Creates a halftone palette.
170 * RETURNS
171 * Success: Handle to logical halftone palette
172 * Failure: 0
174 * FIXME: This simply creates the halftone palette derived from running
175 * tests on a windows NT machine. This is assuming a color depth
176 * of greater that 256 color. On a 256 color device the halftone
177 * palette will be different and this function will be incorrect
179 HPALETTE WINAPI CreateHalftonePalette(
180 HDC hdc) /* [in] Handle to device context */
182 int i;
183 struct {
184 WORD Version;
185 WORD NumberOfEntries;
186 PALETTEENTRY aEntries[256];
187 } Palette;
189 Palette.Version = 0x300;
190 Palette.NumberOfEntries = 256;
191 GetSystemPaletteEntries(hdc, 0, 256, Palette.aEntries);
193 Palette.NumberOfEntries = 20;
195 for (i = 0; i < Palette.NumberOfEntries; i++)
197 Palette.aEntries[i].peRed=0xff;
198 Palette.aEntries[i].peGreen=0xff;
199 Palette.aEntries[i].peBlue=0xff;
200 Palette.aEntries[i].peFlags=0x00;
203 Palette.aEntries[0].peRed=0x00;
204 Palette.aEntries[0].peBlue=0x00;
205 Palette.aEntries[0].peGreen=0x00;
207 /* the first 6 */
208 for (i=1; i <= 6; i++)
210 Palette.aEntries[i].peRed=(i%2)?0x80:0;
211 Palette.aEntries[i].peGreen=(i==2)?0x80:(i==3)?0x80:(i==6)?0x80:0;
212 Palette.aEntries[i].peBlue=(i>3)?0x80:0;
215 for (i=7; i <= 12; i++)
217 switch(i)
219 case 7:
220 Palette.aEntries[i].peRed=0xc0;
221 Palette.aEntries[i].peBlue=0xc0;
222 Palette.aEntries[i].peGreen=0xc0;
223 break;
224 case 8:
225 Palette.aEntries[i].peRed=0xc0;
226 Palette.aEntries[i].peGreen=0xdc;
227 Palette.aEntries[i].peBlue=0xc0;
228 break;
229 case 9:
230 Palette.aEntries[i].peRed=0xa6;
231 Palette.aEntries[i].peGreen=0xca;
232 Palette.aEntries[i].peBlue=0xf0;
233 break;
234 case 10:
235 Palette.aEntries[i].peRed=0xff;
236 Palette.aEntries[i].peGreen=0xfb;
237 Palette.aEntries[i].peBlue=0xf0;
238 break;
239 case 11:
240 Palette.aEntries[i].peRed=0xa0;
241 Palette.aEntries[i].peGreen=0xa0;
242 Palette.aEntries[i].peBlue=0xa4;
243 break;
244 case 12:
245 Palette.aEntries[i].peRed=0x80;
246 Palette.aEntries[i].peGreen=0x80;
247 Palette.aEntries[i].peBlue=0x80;
251 for (i=13; i <= 18; i++)
253 Palette.aEntries[i].peRed=(i%2)?0xff:0;
254 Palette.aEntries[i].peGreen=(i==14)?0xff:(i==15)?0xff:(i==18)?0xff:0;
255 Palette.aEntries[i].peBlue=(i>15)?0xff:0x00;
258 return CreatePalette((LOGPALETTE *)&Palette);
262 /***********************************************************************
263 * GetPaletteEntries [GDI32.@]
265 * Retrieves palette entries.
267 * RETURNS
268 * Success: Number of entries from logical palette
269 * Failure: 0
271 UINT WINAPI GetPaletteEntries(
272 HPALETTE hpalette, /* [in] Handle of logical palette */
273 UINT start, /* [in] First entry to receive */
274 UINT count, /* [in] Number of entries to receive */
275 LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
277 PALETTEOBJ * palPtr;
278 UINT numEntries;
280 TRACE("hpal = %p, count=%i\n", hpalette, count );
282 palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
283 if (!palPtr) return 0;
285 /* NOTE: not documented but test show this to be the case */
286 if (count == 0)
288 int rc = palPtr->logpalette.palNumEntries;
289 GDI_ReleaseObj( hpalette );
290 return rc;
293 numEntries = palPtr->logpalette.palNumEntries;
294 if (start+count > numEntries) count = numEntries - start;
295 if (entries)
297 if (start >= numEntries)
299 GDI_ReleaseObj( hpalette );
300 return 0;
302 memcpy( entries, &palPtr->logpalette.palPalEntry[start],
303 count * sizeof(PALETTEENTRY) );
304 for( numEntries = 0; numEntries < count ; numEntries++ )
305 if (entries[numEntries].peFlags & 0xF0)
306 entries[numEntries].peFlags = 0;
309 GDI_ReleaseObj( hpalette );
310 return count;
314 /***********************************************************************
315 * SetPaletteEntries [GDI32.@]
317 * Sets color values for range in palette.
319 * RETURNS
320 * Success: Number of entries that were set
321 * Failure: 0
323 UINT WINAPI SetPaletteEntries(
324 HPALETTE hpalette, /* [in] Handle of logical palette */
325 UINT start, /* [in] Index of first entry to set */
326 UINT count, /* [in] Number of entries to set */
327 const PALETTEENTRY *entries) /* [in] Address of array of structures */
329 PALETTEOBJ * palPtr;
330 UINT numEntries;
332 TRACE("hpal=%p,start=%i,count=%i\n",hpalette,start,count );
334 if (hpalette == GetStockObject(DEFAULT_PALETTE)) return 0;
335 palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
336 if (!palPtr) return 0;
338 numEntries = palPtr->logpalette.palNumEntries;
339 if (start >= numEntries)
341 GDI_ReleaseObj( hpalette );
342 return 0;
344 if (start+count > numEntries) count = numEntries - start;
345 memcpy( &palPtr->logpalette.palPalEntry[start], entries,
346 count * sizeof(PALETTEENTRY) );
347 UnrealizeObject( hpalette );
348 GDI_ReleaseObj( hpalette );
349 return count;
353 /***********************************************************************
354 * ResizePalette [GDI32.@]
356 * Resizes logical palette.
358 * RETURNS
359 * Success: TRUE
360 * Failure: FALSE
362 BOOL WINAPI ResizePalette(
363 HPALETTE hPal, /* [in] Handle of logical palette */
364 UINT cEntries) /* [in] Number of entries in logical palette */
366 PALETTEOBJ * palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
367 UINT cPrevEnt, prevVer;
368 int prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
370 TRACE("hpal = %p, prev = %i, new = %i\n",
371 hPal, palPtr ? palPtr->logpalette.palNumEntries : -1, cEntries );
372 if( !palPtr ) return FALSE;
373 cPrevEnt = palPtr->logpalette.palNumEntries;
374 prevVer = palPtr->logpalette.palVersion;
375 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) +
376 sizeof(int*) + sizeof(GDIOBJHDR);
377 size += sizeof(int*) + sizeof(GDIOBJHDR);
379 if (!(palPtr = GDI_ReallocObject( size, hPal, palPtr ))) return FALSE;
381 PALETTE_UnrealizeObject( hPal, palPtr );
383 if( cEntries > cPrevEnt ) memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
384 palPtr->logpalette.palNumEntries = cEntries;
385 palPtr->logpalette.palVersion = prevVer;
386 GDI_ReleaseObj( hPal );
387 return TRUE;
391 /***********************************************************************
392 * AnimatePalette [GDI32.@]
394 * Replaces entries in logical palette.
396 * RETURNS
397 * Success: TRUE
398 * Failure: FALSE
400 * FIXME
401 * Should use existing mapping when animating a primary palette
403 BOOL WINAPI AnimatePalette(
404 HPALETTE hPal, /* [in] Handle to logical palette */
405 UINT StartIndex, /* [in] First entry in palette */
406 UINT NumEntries, /* [in] Count of entries in palette */
407 const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */
409 TRACE("%p (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
411 if( hPal != GetStockObject(DEFAULT_PALETTE) )
413 PALETTEOBJ * palPtr;
414 UINT pal_entries;
415 const PALETTEENTRY *pptr = PaletteColors;
417 palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
418 if (!palPtr) return 0;
420 pal_entries = palPtr->logpalette.palNumEntries;
421 if (StartIndex >= pal_entries)
423 GDI_ReleaseObj( hPal );
424 return 0;
426 if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex;
428 for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
429 /* According to MSDN, only animate PC_RESERVED colours */
430 if (palPtr->logpalette.palPalEntry[StartIndex].peFlags & PC_RESERVED) {
431 TRACE("Animating colour (%d,%d,%d) to (%d,%d,%d)\n",
432 palPtr->logpalette.palPalEntry[StartIndex].peRed,
433 palPtr->logpalette.palPalEntry[StartIndex].peGreen,
434 palPtr->logpalette.palPalEntry[StartIndex].peBlue,
435 pptr->peRed, pptr->peGreen, pptr->peBlue);
436 memcpy( &palPtr->logpalette.palPalEntry[StartIndex], pptr,
437 sizeof(PALETTEENTRY) );
438 } else {
439 TRACE("Not animating entry %d -- not PC_RESERVED\n", StartIndex);
442 if (palPtr->funcs && palPtr->funcs->pRealizePalette)
443 palPtr->funcs->pRealizePalette( NULL, hPal, hPal == hPrimaryPalette );
445 GDI_ReleaseObj( hPal );
447 return TRUE;
451 /***********************************************************************
452 * SetSystemPaletteUse [GDI32.@]
454 * Specify whether the system palette contains 2 or 20 static colors.
456 * RETURNS
457 * Success: Previous system palette
458 * Failure: SYSPAL_ERROR
460 UINT WINAPI SetSystemPaletteUse(
461 HDC hdc, /* [in] Handle of device context */
462 UINT use) /* [in] Palette-usage flag */
464 UINT old = SystemPaletteUse;
466 /* Device doesn't support colour palettes */
467 if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)) {
468 return SYSPAL_ERROR;
471 switch (use) {
472 case SYSPAL_NOSTATIC:
473 case SYSPAL_NOSTATIC256: /* WINVER >= 0x0500 */
474 case SYSPAL_STATIC:
475 SystemPaletteUse = use;
476 return old;
477 default:
478 return SYSPAL_ERROR;
483 /***********************************************************************
484 * GetSystemPaletteUse [GDI32.@]
486 * Gets state of system palette.
488 * RETURNS
489 * Current state of system palette
491 UINT WINAPI GetSystemPaletteUse(
492 HDC hdc) /* [in] Handle of device context */
494 return SystemPaletteUse;
498 /***********************************************************************
499 * GetSystemPaletteEntries [GDI32.@]
501 * Gets range of palette entries.
503 * RETURNS
504 * Success: Number of entries retrieved from palette
505 * Failure: 0
507 UINT WINAPI GetSystemPaletteEntries(
508 HDC hdc, /* [in] Handle of device context */
509 UINT start, /* [in] Index of first entry to be retrieved */
510 UINT count, /* [in] Number of entries to be retrieved */
511 LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
513 UINT ret = 0;
514 DC *dc;
516 TRACE("hdc=%p,start=%i,count=%i\n", hdc,start,count);
518 if ((dc = DC_GetDCPtr( hdc )))
520 if (dc->funcs->pGetSystemPaletteEntries)
521 ret = dc->funcs->pGetSystemPaletteEntries( dc->physDev, start, count, entries );
522 GDI_ReleaseObj( hdc );
524 return ret;
528 /***********************************************************************
529 * GetNearestPaletteIndex [GDI32.@]
531 * Gets palette index for color.
533 * NOTES
534 * Should index be initialized to CLR_INVALID instead of 0?
536 * RETURNS
537 * Success: Index of entry in logical palette
538 * Failure: CLR_INVALID
540 UINT WINAPI GetNearestPaletteIndex(
541 HPALETTE hpalette, /* [in] Handle of logical color palette */
542 COLORREF color) /* [in] Color to be matched */
544 PALETTEOBJ* palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
545 UINT index = 0;
547 if( palObj )
549 int i, diff = 0x7fffffff;
550 int r,g,b;
551 PALETTEENTRY* entry = palObj->logpalette.palPalEntry;
553 for( i = 0; i < palObj->logpalette.palNumEntries && diff ; i++, entry++)
555 r = entry->peRed - GetRValue(color);
556 g = entry->peGreen - GetGValue(color);
557 b = entry->peBlue - GetBValue(color);
559 r = r*r + g*g + b*b;
561 if( r < diff ) { index = i; diff = r; }
563 GDI_ReleaseObj( hpalette );
565 TRACE("(%p,%06x): returning %d\n", hpalette, color, index );
566 return index;
570 /***********************************************************************
571 * GetNearestColor [GDI32.@]
573 * Gets a system color to match.
575 * RETURNS
576 * Success: Color from system palette that corresponds to given color
577 * Failure: CLR_INVALID
579 COLORREF WINAPI GetNearestColor(
580 HDC hdc, /* [in] Handle of device context */
581 COLORREF color) /* [in] Color to be matched */
583 unsigned char spec_type;
584 COLORREF nearest;
585 DC *dc;
587 if (!(dc = DC_GetDCPtr( hdc ))) return CLR_INVALID;
589 if (dc->funcs->pGetNearestColor)
591 nearest = dc->funcs->pGetNearestColor( dc->physDev, color );
592 GDI_ReleaseObj( hdc );
593 return nearest;
596 if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE))
598 GDI_ReleaseObj( hdc );
599 return color;
602 spec_type = color >> 24;
603 if (spec_type == 1 || spec_type == 2)
605 /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
607 UINT index;
608 PALETTEENTRY entry;
609 HPALETTE hpal = dc->hPalette ? dc->hPalette : GetStockObject( DEFAULT_PALETTE );
611 if (spec_type == 2) /* PALETTERGB */
612 index = GetNearestPaletteIndex( hpal, color );
613 else /* PALETTEINDEX */
614 index = LOWORD(color);
616 if (!GetPaletteEntries( hpal, index, 1, &entry ))
618 WARN("RGB(%x) : idx %d is out of bounds, assuming NULL\n", color, index );
619 if (!GetPaletteEntries( hpal, 0, 1, &entry ))
621 GDI_ReleaseObj( hdc );
622 return CLR_INVALID;
625 color = RGB( entry.peRed, entry.peGreen, entry.peBlue );
627 nearest = color & 0x00ffffff;
628 GDI_ReleaseObj( hdc );
630 TRACE("(%06x): returning %06x\n", color, nearest );
631 return nearest;
635 /***********************************************************************
636 * PALETTE_GetObject
638 static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
640 PALETTEOBJ *palette = obj;
642 if( !buffer )
643 return sizeof(WORD);
645 if (count > sizeof(WORD)) count = sizeof(WORD);
646 memcpy( buffer, &palette->logpalette.palNumEntries, count );
647 return count;
651 /***********************************************************************
652 * PALETTE_UnrealizeObject
654 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle, void *obj )
656 PALETTEOBJ *palette = obj;
658 if (palette->funcs)
660 if (palette->funcs->pUnrealizePalette)
661 palette->funcs->pUnrealizePalette( handle );
662 palette->funcs = NULL;
665 if (hLastRealizedPalette == handle)
667 TRACE("unrealizing palette %p\n", handle);
668 hLastRealizedPalette = 0;
670 return TRUE;
674 /***********************************************************************
675 * PALETTE_DeleteObject
677 static BOOL PALETTE_DeleteObject( HGDIOBJ handle, void *obj )
679 PALETTE_UnrealizeObject( handle, obj );
680 return GDI_FreeObject( handle, obj );
684 /***********************************************************************
685 * GDISelectPalette (Not a Windows API)
687 HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg)
689 HPALETTE ret;
690 DC *dc;
692 TRACE("%p %p\n", hdc, hpal );
694 if (GetObjectType(hpal) != OBJ_PAL)
696 WARN("invalid selected palette %p\n",hpal);
697 return 0;
699 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
700 ret = dc->hPalette;
701 if (dc->funcs->pSelectPalette) hpal = dc->funcs->pSelectPalette( dc->physDev, hpal, FALSE );
702 if (hpal)
704 dc->hPalette = hpal;
705 if (!wBkg) hPrimaryPalette = hpal;
707 else ret = 0;
708 GDI_ReleaseObj( hdc );
709 return ret;
713 /***********************************************************************
714 * GDIRealizePalette (Not a Windows API)
716 UINT WINAPI GDIRealizePalette( HDC hdc )
718 UINT realized = 0;
719 DC* dc = DC_GetDCPtr( hdc );
721 if (!dc) return 0;
723 TRACE("%p...\n", hdc );
725 if( dc->hPalette == GetStockObject( DEFAULT_PALETTE ))
727 if (dc->funcs->pRealizeDefaultPalette)
728 realized = dc->funcs->pRealizeDefaultPalette( dc->physDev );
730 else if(dc->hPalette != hLastRealizedPalette )
732 if (dc->funcs->pRealizePalette)
734 PALETTEOBJ *palPtr = GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC );
735 if (palPtr)
737 realized = dc->funcs->pRealizePalette( dc->physDev, dc->hPalette,
738 (dc->hPalette == hPrimaryPalette) );
739 palPtr->funcs = dc->funcs;
740 GDI_ReleaseObj( dc->hPalette );
743 hLastRealizedPalette = dc->hPalette;
745 else TRACE(" skipping (hLastRealizedPalette = %p)\n", hLastRealizedPalette);
747 GDI_ReleaseObj( hdc );
748 TRACE(" realized %i colors.\n", realized );
749 return realized;
753 /***********************************************************************
754 * RealizeDefaultPalette (GDI.365)
756 UINT16 WINAPI RealizeDefaultPalette16( HDC16 hdc )
758 UINT16 ret = 0;
759 DC *dc;
761 TRACE("%04x\n", hdc );
763 if (!(dc = DC_GetDCPtr( HDC_32(hdc) ))) return 0;
765 if (dc->funcs->pRealizeDefaultPalette) ret = dc->funcs->pRealizeDefaultPalette( dc->physDev );
766 GDI_ReleaseObj( HDC_32(hdc) );
767 return ret;
770 /***********************************************************************
771 * IsDCCurrentPalette (GDI.412)
773 BOOL16 WINAPI IsDCCurrentPalette16(HDC16 hDC)
775 DC *dc = DC_GetDCPtr( HDC_32(hDC) );
776 if (dc)
778 BOOL bRet = dc->hPalette == hPrimaryPalette;
779 GDI_ReleaseObj( HDC_32(hDC) );
780 return bRet;
782 return FALSE;
786 /***********************************************************************
787 * SelectPalette [GDI32.@]
789 * Selects logical palette into DC.
791 * RETURNS
792 * Success: Previous logical palette
793 * Failure: NULL
795 HPALETTE WINAPI SelectPalette(
796 HDC hDC, /* [in] Handle of device context */
797 HPALETTE hPal, /* [in] Handle of logical color palette */
798 BOOL bForceBackground) /* [in] Foreground/background mode */
800 return pfnSelectPalette( hDC, hPal, bForceBackground );
804 /***********************************************************************
805 * RealizePalette [GDI32.@]
807 * Maps palette entries to system palette.
809 * RETURNS
810 * Success: Number of entries in logical palette
811 * Failure: GDI_ERROR
813 UINT WINAPI RealizePalette(
814 HDC hDC) /* [in] Handle of device context */
816 return pfnRealizePalette( hDC );
820 typedef HWND (WINAPI *WindowFromDC_funcptr)( HDC );
821 typedef BOOL (WINAPI *RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT );
823 /**********************************************************************
824 * UpdateColors [GDI32.@]
826 * Remaps current colors to logical palette.
828 * RETURNS
829 * Success: TRUE
830 * Failure: FALSE
832 BOOL WINAPI UpdateColors(
833 HDC hDC) /* [in] Handle of device context */
835 HMODULE mod;
836 int size = GetDeviceCaps( hDC, SIZEPALETTE );
838 if (!size) return 0;
840 mod = GetModuleHandleA("user32.dll");
841 if (mod)
843 WindowFromDC_funcptr pWindowFromDC = (WindowFromDC_funcptr)GetProcAddress(mod,"WindowFromDC");
844 if (pWindowFromDC)
846 HWND hWnd = pWindowFromDC( hDC );
848 /* Docs say that we have to remap current drawable pixel by pixel
849 * but it would take forever given the speed of XGet/PutPixel.
851 if (hWnd && size)
853 RedrawWindow_funcptr pRedrawWindow = GetProcAddress( mod, "RedrawWindow" );
854 if (pRedrawWindow) pRedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
858 return 0x666;
862 /*********************************************************************
863 * SetMagicColors (GDI.606)
865 VOID WINAPI SetMagicColors16(HDC16 hDC, COLORREF color, UINT16 index)
867 FIXME("(hDC %04x, color %04x, index %04x): stub\n", hDC, (int)color, index);
871 /*********************************************************************
872 * SetMagicColors (GDI.@)
874 BOOL WINAPI SetMagicColors(HDC hdc, ULONG u1, ULONG u2)
876 FIXME("(%p 0x%08x 0x%08x): stub\n", hdc, u1, u2);
877 return TRUE;
880 /**********************************************************************
881 * GetICMProfileA [GDI32.@]
883 * Returns the filename of the specified device context's color
884 * management profile, even if color management is not enabled
885 * for that DC.
887 * RETURNS
888 * TRUE if name copied successfully OR lpszFilename is NULL
889 * FALSE if the buffer length pointed to by lpcbName is too small
891 * NOTE
892 * The buffer length pointed to by lpcbName is ALWAYS updated to
893 * the length required regardless of other actions this function
894 * may take.
896 * FIXME
897 * How does Windows assign these? Some registry key?
901 /*********************************************************************/
903 BOOL WINAPI GetICMProfileA(HDC hDC, LPDWORD lpcbName, LPSTR lpszFilename)
905 DWORD callerLen;
906 static const char icm[] = "winefake.icm";
908 FIXME("(%p, %p, %p): partial stub\n", hDC, lpcbName, lpszFilename);
910 callerLen = *lpcbName;
912 /* all 3 behaviors require the required buffer size to be set */
913 *lpcbName = sizeof(icm);
915 /* behavior 1: if lpszFilename is NULL, return size of string and no error */
916 if (!lpszFilename) return TRUE;
918 /* behavior 2: if buffer size too small, return size of string and error */
919 if (callerLen < sizeof(icm))
921 SetLastError(ERROR_INSUFFICIENT_BUFFER);
922 return FALSE;
925 /* behavior 3: if buffer size OK and pointer not NULL, copy and return size */
926 memcpy(lpszFilename, icm, sizeof(icm));
927 return TRUE;
930 /**********************************************************************
931 * GetICMProfileW [GDI32.@]
933 BOOL WINAPI GetICMProfileW(HDC hDC, LPDWORD lpcbName, LPWSTR lpszFilename)
935 DWORD callerLen;
936 static const WCHAR icm[] = { 'w','i','n','e','f','a','k','e','.','i','c','m', 0 };
938 FIXME("(%p, %p, %p): partial stub\n", hDC, lpcbName, lpszFilename);
940 callerLen = *lpcbName;
942 /* all 3 behaviors require the required buffer size to be set */
943 *lpcbName = sizeof(icm) / sizeof(WCHAR);
945 /* behavior 1: if lpszFilename is NULL, return size of string and no error */
946 if (!lpszFilename) return TRUE;
948 /* behavior 2: if buffer size too small, return size of string and error */
949 if (callerLen < sizeof(icm)/sizeof(WCHAR))
951 SetLastError(ERROR_INSUFFICIENT_BUFFER);
952 return FALSE;
955 /* behavior 3: if buffer size OK and pointer not NULL, copy and return size */
956 memcpy(lpszFilename, icm, sizeof(icm));
957 return TRUE;
960 /**********************************************************************
961 * GetLogColorSpaceA [GDI32.@]
964 BOOL WINAPI GetLogColorSpaceA(HCOLORSPACE hColorSpace, LPLOGCOLORSPACEA lpBuffer, DWORD nSize)
966 FIXME("%p %p 0x%08x: stub!\n", hColorSpace, lpBuffer, nSize);
967 return FALSE;
970 /**********************************************************************
971 * GetLogColorSpaceW [GDI32.@]
974 BOOL WINAPI GetLogColorSpaceW(HCOLORSPACE hColorSpace, LPLOGCOLORSPACEW lpBuffer, DWORD nSize)
976 FIXME("%p %p 0x%08x: stub!\n", hColorSpace, lpBuffer, nSize);
977 return FALSE;
980 /**********************************************************************
981 * SetICMProfileA [GDI32.@]
984 BOOL WINAPI SetICMProfileA(HDC hDC, LPSTR lpszFilename)
986 FIXME("hDC %p filename '%s': stub!\n", hDC, debugstr_a(lpszFilename));
987 return TRUE; /* success */
990 /**********************************************************************
991 * SetICMProfileA [GDI32.@]
994 BOOL WINAPI SetICMProfileW(HDC hDC, LPWSTR lpszFilename)
996 FIXME("hDC %p filename '%s': stub!\n", hDC, debugstr_w(lpszFilename));
997 return TRUE; /* success */
1000 /**********************************************************************
1001 * UpdateICMRegKeyA [GDI32.@]
1004 BOOL WINAPI UpdateICMRegKeyA(DWORD dwReserved, LPSTR lpszCMID, LPSTR lpszFileName, UINT nCommand)
1006 FIXME("(0x%08x, %s, %s, 0x%08x): stub!\n", dwReserved, debugstr_a(lpszCMID),
1007 debugstr_a(lpszFileName), nCommand);
1008 return TRUE; /* success */
1011 /**********************************************************************
1012 * UpdateICMRegKeyW [GDI32.@]
1015 BOOL WINAPI UpdateICMRegKeyW(DWORD dwReserved, LPWSTR lpszCMID, LPWSTR lpszFileName, UINT nCommand)
1017 FIXME("(0x%08x, %s, %s, 0x%08x): stub!\n", dwReserved, debugstr_w(lpszCMID),
1018 debugstr_w(lpszFileName), nCommand);
1019 return TRUE; /* success */