Added function table to GDI objects for better encapsulation.
[wine.git] / objects / palette.c
blobe577f5766d512afdba2ce6e20faa963695d5c3e3
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * NOTES:
22 * PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993.
23 * Information in the "Undocumented Windows" is incorrect.
26 #include <stdlib.h>
27 #include <string.h>
29 #include "winbase.h"
30 #include "windef.h"
31 #include "wingdi.h"
32 #include "wine/winuser16.h"
33 #include "gdi.h"
34 #include "color.h"
35 #include "palette.h"
36 #include "wine/debug.h"
37 #include "winerror.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(palette);
41 static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
42 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle, void *obj );
43 static BOOL PALETTE_DeleteObject( HGDIOBJ handle, void *obj );
45 static const struct gdi_obj_funcs palette_funcs =
47 NULL, /* pSelectObject */
48 PALETTE_GetObject, /* pGetObject16 */
49 PALETTE_GetObject, /* pGetObjectA */
50 PALETTE_GetObject, /* pGetObjectW */
51 PALETTE_UnrealizeObject, /* pUnrealizeObject */
52 PALETTE_DeleteObject /* pDeleteObject */
55 PALETTE_DRIVER *PALETTE_Driver = NULL;
57 /* Pointers to USER implementation of SelectPalette/RealizePalette */
58 /* they will be patched by USER on startup */
59 FARPROC pfnSelectPalette = NULL;
60 FARPROC pfnRealizePalette = NULL;
62 static UINT SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
64 static HPALETTE hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
65 static HPALETTE hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
68 /***********************************************************************
69 * PALETTE_Init
71 * Create the system palette.
73 HPALETTE16 PALETTE_Init(void)
75 int i;
76 HPALETTE16 hpalette;
77 LOGPALETTE * palPtr;
78 PALETTEOBJ* palObj;
79 const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate();
81 /* create default palette (20 system colors) */
83 palPtr = HeapAlloc( GetProcessHeap(), 0,
84 sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
85 if (!palPtr) return FALSE;
87 palPtr->palVersion = 0x300;
88 palPtr->palNumEntries = NB_RESERVED_COLORS;
89 for( i = 0; i < NB_RESERVED_COLORS; i ++ )
91 palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed;
92 palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen;
93 palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue;
94 palPtr->palPalEntry[i].peFlags = 0;
96 hpalette = CreatePalette16( palPtr );
97 HeapFree( GetProcessHeap(), 0, palPtr );
99 palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
100 if (palObj)
102 if (!(palObj->mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(int) * 20 )))
103 ERR("Can not create palette mapping -- out of memory!\n");
104 GDI_ReleaseObj( hpalette );
106 return hpalette;
109 /***********************************************************************
110 * PALETTE_ValidateFlags
112 void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
114 int i = 0;
115 for( ; i<size ; i++ )
116 lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07);
120 /***********************************************************************
121 * CreatePalette (GDI.360)
123 HPALETTE16 WINAPI CreatePalette16( const LOGPALETTE* palette )
125 return CreatePalette( palette );
129 /***********************************************************************
130 * CreatePalette [GDI32.@] Creates a logical color palette
132 * RETURNS
133 * Success: Handle to logical palette
134 * Failure: NULL
136 HPALETTE WINAPI CreatePalette(
137 const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
139 PALETTEOBJ * palettePtr;
140 HPALETTE hpalette;
141 int size;
143 if (!palette) return 0;
144 TRACE("entries=%i\n", palette->palNumEntries);
146 size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
148 if (!(palettePtr = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR),
149 PALETTE_MAGIC, &hpalette, &palette_funcs ))) return 0;
150 memcpy( &palettePtr->logpalette, palette, size );
151 PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry,
152 palettePtr->logpalette.palNumEntries);
153 palettePtr->mapping = NULL;
154 GDI_ReleaseObj( hpalette );
156 TRACE(" returning %04x\n", hpalette);
157 return hpalette;
161 /***********************************************************************
162 * CreateHalftonePalette [GDI.529] Creates a halftone palette
164 * RETURNS
165 * Success: Handle to logical halftone palette
166 * Failure: 0
168 HPALETTE16 WINAPI CreateHalftonePalette16(
169 HDC16 hdc) /* [in] Handle to device context */
171 return CreateHalftonePalette(hdc);
175 /***********************************************************************
176 * CreateHalftonePalette [GDI32.@] Creates a halftone palette
178 * RETURNS
179 * Success: Handle to logical halftone palette
180 * Failure: 0
182 * FIXME: This simply creates the halftone palette dirived from runing
183 * tests on an windows NT machine. this is assuming a color depth
184 * of greater that 256 color. On a 256 color device the halftone
185 * palette will be differnt and this funtion will be incorrect
187 HPALETTE WINAPI CreateHalftonePalette(
188 HDC hdc) /* [in] Handle to device context */
190 int i;
191 struct {
192 WORD Version;
193 WORD NumberOfEntries;
194 PALETTEENTRY aEntries[256];
195 } Palette;
197 Palette.Version = 0x300;
198 Palette.NumberOfEntries = 256;
199 GetSystemPaletteEntries(hdc, 0, 256, Palette.aEntries);
201 Palette.NumberOfEntries = 20;
203 for (i = 0; i < Palette.NumberOfEntries; i++)
205 Palette.aEntries[i].peRed=0xff;
206 Palette.aEntries[i].peGreen=0xff;
207 Palette.aEntries[i].peBlue=0xff;
208 Palette.aEntries[i].peFlags=0x00;
211 Palette.aEntries[0].peRed=0x00;
212 Palette.aEntries[0].peBlue=0x00;
213 Palette.aEntries[0].peGreen=0x00;
215 /* the first 6 */
216 for (i=1; i <= 6; i++)
218 Palette.aEntries[i].peRed=(i%2)?0x80:0;
219 Palette.aEntries[i].peGreen=(i==2)?0x80:(i==3)?0x80:(i==6)?0x80:0;
220 Palette.aEntries[i].peBlue=(i>3)?0x80:0;
223 for (i=7; i <= 12; i++)
225 switch(i)
227 case 7:
228 Palette.aEntries[i].peRed=0xc0;
229 Palette.aEntries[i].peBlue=0xc0;
230 Palette.aEntries[i].peGreen=0xc0;
231 break;
232 case 8:
233 Palette.aEntries[i].peRed=0xc0;
234 Palette.aEntries[i].peGreen=0xdc;
235 Palette.aEntries[i].peBlue=0xc0;
236 break;
237 case 9:
238 Palette.aEntries[i].peRed=0xa6;
239 Palette.aEntries[i].peGreen=0xca;
240 Palette.aEntries[i].peBlue=0xf0;
241 break;
242 case 10:
243 Palette.aEntries[i].peRed=0xff;
244 Palette.aEntries[i].peGreen=0xfb;
245 Palette.aEntries[i].peBlue=0xf0;
246 break;
247 case 11:
248 Palette.aEntries[i].peRed=0xa0;
249 Palette.aEntries[i].peGreen=0xa0;
250 Palette.aEntries[i].peBlue=0xa4;
251 break;
252 case 12:
253 Palette.aEntries[i].peRed=0x80;
254 Palette.aEntries[i].peGreen=0x80;
255 Palette.aEntries[i].peBlue=0x80;
259 for (i=13; i <= 18; i++)
261 Palette.aEntries[i].peRed=(i%2)?0xff:0;
262 Palette.aEntries[i].peGreen=(i==14)?0xff:(i==15)?0xff:(i==18)?0xff:0;
263 Palette.aEntries[i].peBlue=(i>15)?0xff:0x00;
266 return CreatePalette((LOGPALETTE *)&Palette);
270 /***********************************************************************
271 * GetPaletteEntries (GDI.363)
273 UINT16 WINAPI GetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
274 UINT16 count, LPPALETTEENTRY entries )
276 return GetPaletteEntries( hpalette, start, count, entries );
280 /***********************************************************************
281 * GetPaletteEntries [GDI32.@] Retrieves palette entries
283 * RETURNS
284 * Success: Number of entries from logical palette
285 * Failure: 0
287 UINT WINAPI GetPaletteEntries(
288 HPALETTE hpalette, /* [in] Handle of logical palette */
289 UINT start, /* [in] First entry to receive */
290 UINT count, /* [in] Number of entries to receive */
291 LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
293 PALETTEOBJ * palPtr;
294 UINT numEntries;
296 TRACE("hpal = %04x, count=%i\n", hpalette, count );
298 palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
299 if (!palPtr) return 0;
301 /* NOTE: not documented but test show this to be the case */
302 if (count == 0)
304 int rc = palPtr->logpalette.palNumEntries;
305 GDI_ReleaseObj( hpalette );
306 return rc;
309 numEntries = palPtr->logpalette.palNumEntries;
310 if (start+count > numEntries) count = numEntries - start;
311 if (entries)
313 if (start >= numEntries)
315 GDI_ReleaseObj( hpalette );
316 return 0;
318 memcpy( entries, &palPtr->logpalette.palPalEntry[start],
319 count * sizeof(PALETTEENTRY) );
320 for( numEntries = 0; numEntries < count ; numEntries++ )
321 if (entries[numEntries].peFlags & 0xF0)
322 entries[numEntries].peFlags = 0;
325 GDI_ReleaseObj( hpalette );
326 return count;
330 /***********************************************************************
331 * SetPaletteEntries (GDI.364)
333 UINT16 WINAPI SetPaletteEntries16( HPALETTE16 hpalette, UINT16 start,
334 UINT16 count, LPPALETTEENTRY entries )
336 return SetPaletteEntries( hpalette, start, count, entries );
340 /***********************************************************************
341 * SetPaletteEntries [GDI32.@] Sets color values for range in palette
343 * RETURNS
344 * Success: Number of entries that were set
345 * Failure: 0
347 UINT WINAPI SetPaletteEntries(
348 HPALETTE hpalette, /* [in] Handle of logical palette */
349 UINT start, /* [in] Index of first entry to set */
350 UINT count, /* [in] Number of entries to set */
351 LPPALETTEENTRY entries) /* [in] Address of array of structures */
353 PALETTEOBJ * palPtr;
354 UINT numEntries;
356 TRACE("hpal=%04x,start=%i,count=%i\n",hpalette,start,count );
358 palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
359 if (!palPtr) return 0;
361 numEntries = palPtr->logpalette.palNumEntries;
362 if (start >= numEntries)
364 GDI_ReleaseObj( hpalette );
365 return 0;
367 if (start+count > numEntries) count = numEntries - start;
368 memcpy( &palPtr->logpalette.palPalEntry[start], entries,
369 count * sizeof(PALETTEENTRY) );
370 PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry,
371 palPtr->logpalette.palNumEntries);
372 HeapFree( GetProcessHeap(), 0, palPtr->mapping );
373 palPtr->mapping = NULL;
374 GDI_ReleaseObj( hpalette );
375 return count;
379 /***********************************************************************
380 * ResizePalette (GDI.368)
382 BOOL16 WINAPI ResizePalette16( HPALETTE16 hPal, UINT16 cEntries )
384 return ResizePalette( hPal, cEntries );
388 /***********************************************************************
389 * ResizePalette [GDI32.@] Resizes logical palette
391 * RETURNS
392 * Success: TRUE
393 * Failure: FALSE
395 BOOL WINAPI ResizePalette(
396 HPALETTE hPal, /* [in] Handle of logical palette */
397 UINT cEntries) /* [in] Number of entries in logical palette */
399 PALETTEOBJ * palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC );
400 UINT cPrevEnt, prevVer;
401 int prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
402 int* mapping = NULL;
404 TRACE("hpal = %04x, prev = %i, new = %i\n",
405 hPal, palPtr ? palPtr->logpalette.palNumEntries : -1,
406 cEntries );
407 if( !palPtr ) return FALSE;
408 cPrevEnt = palPtr->logpalette.palNumEntries;
409 prevVer = palPtr->logpalette.palVersion;
410 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) +
411 sizeof(int*) + sizeof(GDIOBJHDR);
412 size += sizeof(int*) + sizeof(GDIOBJHDR);
413 mapping = palPtr->mapping;
415 if (!(palPtr = GDI_ReallocObject( size, hPal, palPtr ))) return FALSE;
417 if( mapping )
419 int *newMap = (int*) HeapReAlloc(GetProcessHeap(), 0,
420 mapping, cEntries * sizeof(int) );
421 if(newMap == NULL)
423 ERR("Can not resize mapping -- out of memory!\n");
424 GDI_ReleaseObj( hPal );
425 return FALSE;
427 palPtr->mapping = newMap;
430 if( cEntries > cPrevEnt )
432 if( mapping )
433 memset(palPtr->mapping + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
434 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
435 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize),
436 cEntries - cPrevEnt );
438 palPtr->logpalette.palNumEntries = cEntries;
439 palPtr->logpalette.palVersion = prevVer;
440 GDI_ReleaseObj( hPal );
441 return TRUE;
445 /***********************************************************************
446 * AnimatePalette (GDI.367)
448 void WINAPI AnimatePalette16( HPALETTE16 hPal, UINT16 StartIndex,
449 UINT16 NumEntries, const PALETTEENTRY* PaletteColors)
451 AnimatePalette( hPal, StartIndex, NumEntries, PaletteColors );
455 /***********************************************************************
456 * AnimatePalette [GDI32.@] Replaces entries in logical palette
458 * RETURNS
459 * Success: TRUE
460 * Failure: FALSE
462 * FIXME
463 * Should use existing mapping when animating a primary palette
465 BOOL WINAPI AnimatePalette(
466 HPALETTE hPal, /* [in] Handle to logical palette */
467 UINT StartIndex, /* [in] First entry in palette */
468 UINT NumEntries, /* [in] Count of entries in palette */
469 const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */
471 TRACE("%04x (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
473 if( hPal != GetStockObject(DEFAULT_PALETTE) )
475 PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
476 if (!palPtr) return FALSE;
478 if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
480 UINT u;
481 for( u = 0; u < NumEntries; u++ )
482 palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
483 if (PALETTE_Driver) PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries,
484 hPal != hPrimaryPalette );
485 GDI_ReleaseObj( hPal );
486 return TRUE;
488 GDI_ReleaseObj( hPal );
490 return FALSE;
494 /***********************************************************************
495 * SetSystemPaletteUse (GDI.373)
497 UINT16 WINAPI SetSystemPaletteUse16( HDC16 hdc, UINT16 use )
499 return SetSystemPaletteUse( hdc, use );
503 /***********************************************************************
504 * SetSystemPaletteUse [GDI32.@]
506 * RETURNS
507 * Success: Previous system palette
508 * Failure: SYSPAL_ERROR
510 UINT WINAPI SetSystemPaletteUse(
511 HDC hdc, /* [in] Handle of device context */
512 UINT use) /* [in] Palette-usage flag */
514 UINT old = SystemPaletteUse;
515 FIXME("(%04x,%04x): stub\n", hdc, use );
516 SystemPaletteUse = use;
517 return old;
521 /***********************************************************************
522 * GetSystemPaletteUse (GDI.374)
524 UINT16 WINAPI GetSystemPaletteUse16( HDC16 hdc )
526 return SystemPaletteUse;
530 /***********************************************************************
531 * GetSystemPaletteUse [GDI32.@] Gets state of system palette
533 * RETURNS
534 * Current state of system palette
536 UINT WINAPI GetSystemPaletteUse(
537 HDC hdc) /* [in] Handle of device context */
539 return SystemPaletteUse;
543 /***********************************************************************
544 * GetSystemPaletteEntries (GDI.375)
546 UINT16 WINAPI GetSystemPaletteEntries16( HDC16 hdc, UINT16 start, UINT16 count,
547 LPPALETTEENTRY entries )
549 return GetSystemPaletteEntries( hdc, start, count, entries );
553 /***********************************************************************
554 * GetSystemPaletteEntries [GDI32.@] Gets range of palette entries
556 * RETURNS
557 * Success: Number of entries retrieved from palette
558 * Failure: 0
560 UINT WINAPI GetSystemPaletteEntries(
561 HDC hdc, /* [in] Handle of device context */
562 UINT start, /* [in] Index of first entry to be retrieved */
563 UINT count, /* [in] Number of entries to be retrieved */
564 LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
566 UINT i;
567 INT sizePalette = GetDeviceCaps( hdc, SIZEPALETTE );
569 TRACE("hdc=%04x,start=%i,count=%i\n", hdc,start,count);
571 if (!entries) return sizePalette;
572 if (start >= sizePalette) return 0;
573 if (start+count >= sizePalette) count = sizePalette - start;
575 for (i = 0; i < count; i++)
577 *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry( start + i );
579 TRACE("\tidx(%02x) -> RGB(%08lx)\n",
580 start + i, *(COLORREF*)(entries + i) );
582 return count;
586 /***********************************************************************
587 * GetNearestPaletteIndex (GDI.370)
589 UINT16 WINAPI GetNearestPaletteIndex16( HPALETTE16 hpalette, COLORREF color )
591 return GetNearestPaletteIndex( hpalette, color );
595 /***********************************************************************
596 * GetNearestPaletteIndex [GDI32.@] Gets palette index for color
598 * NOTES
599 * Should index be initialized to CLR_INVALID instead of 0?
601 * RETURNS
602 * Success: Index of entry in logical palette
603 * Failure: CLR_INVALID
605 UINT WINAPI GetNearestPaletteIndex(
606 HPALETTE hpalette, /* [in] Handle of logical color palette */
607 COLORREF color) /* [in] Color to be matched */
609 PALETTEOBJ* palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
610 UINT index = 0;
612 if( palObj )
614 index = COLOR_PaletteLookupPixel(palObj->logpalette.palPalEntry,
615 palObj->logpalette.palNumEntries,
616 NULL, color, FALSE );
618 GDI_ReleaseObj( hpalette );
620 TRACE("(%04x,%06lx): returning %d\n", hpalette, color, index );
621 return index;
625 /***********************************************************************
626 * GetNearestColor (GDI.154)
628 COLORREF WINAPI GetNearestColor16( HDC16 hdc, COLORREF color )
630 return GetNearestColor( hdc, color );
634 /***********************************************************************
635 * GetNearestColor [GDI32.@] Gets a system color to match
637 * RETURNS
638 * Success: Color from system palette that corresponds to given color
639 * Failure: CLR_INVALID
641 COLORREF WINAPI GetNearestColor(
642 HDC hdc, /* [in] Handle of device context */
643 COLORREF color) /* [in] Color to be matched */
645 COLORREF nearest = CLR_INVALID;
646 DC *dc;
647 PALETTEOBJ *palObj;
649 if(!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)) {
650 return color;
652 if ( (dc = DC_GetDCPtr( hdc )) )
654 HPALETTE hpal = (dc->hPalette)? dc->hPalette : GetStockObject( DEFAULT_PALETTE );
655 palObj = GDI_GetObjPtr( hpal, PALETTE_MAGIC );
656 if (!palObj) {
657 GDI_ReleaseObj( hdc );
658 return nearest;
661 nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry,
662 palObj->logpalette.palNumEntries, color );
663 GDI_ReleaseObj( hpal );
664 GDI_ReleaseObj( hdc );
667 TRACE("(%06lx): returning %06lx\n", color, nearest );
668 return nearest;
672 /***********************************************************************
673 * PALETTE_GetObject
675 static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
677 PALETTEOBJ *palette = obj;
679 if (count > sizeof(WORD)) count = sizeof(WORD);
680 memcpy( buffer, &palette->logpalette.palNumEntries, count );
681 return count;
685 /***********************************************************************
686 * PALETTE_UnrealizeObject
688 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle, void *obj )
690 PALETTEOBJ *palette = obj;
692 if (palette->mapping)
694 HeapFree( GetProcessHeap(), 0, palette->mapping );
695 palette->mapping = NULL;
697 if (hLastRealizedPalette == handle) hLastRealizedPalette = 0;
698 return TRUE;
702 /***********************************************************************
703 * PALETTE_DeleteObject
705 static BOOL PALETTE_DeleteObject( HGDIOBJ handle, void *obj )
707 PALETTEOBJ *palette = obj;
709 HeapFree( GetProcessHeap(), 0, palette->mapping );
710 if (hLastRealizedPalette == handle) hLastRealizedPalette = 0;
711 return GDI_FreeObject( handle, obj );
715 /***********************************************************************
716 * GDISelectPalette (GDI.361)
718 HPALETTE16 WINAPI GDISelectPalette16( HDC16 hdc, HPALETTE16 hpal, WORD wBkg)
720 HPALETTE16 prev;
721 DC *dc;
723 TRACE("%04x %04x\n", hdc, hpal );
725 if (GetObjectType(hpal) != OBJ_PAL)
727 WARN("invalid selected palette %04x\n",hpal);
728 return 0;
730 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
731 prev = dc->hPalette;
732 dc->hPalette = hpal;
733 GDI_ReleaseObj( hdc );
734 if (!wBkg) hPrimaryPalette = hpal;
735 return prev;
739 /***********************************************************************
740 * GDIRealizePalette (GDI.362)
742 UINT16 WINAPI GDIRealizePalette16( HDC16 hdc )
744 PALETTEOBJ* palPtr;
745 int realized = 0;
746 DC* dc = DC_GetDCPtr( hdc );
748 if (!dc) return 0;
750 TRACE("%04x...\n", hdc );
752 if(dc->hPalette != hLastRealizedPalette )
754 if( dc->hPalette == GetStockObject( DEFAULT_PALETTE )) {
755 realized = RealizeDefaultPalette16( hdc );
756 GDI_ReleaseObj( hdc );
757 return (UINT16)realized;
761 palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC );
763 if (!palPtr) {
764 GDI_ReleaseObj( hdc );
765 FIXME("invalid selected palette %04x\n",dc->hPalette);
766 return 0;
768 if (PALETTE_Driver)
769 realized = PALETTE_Driver->pSetMapping(palPtr,0,palPtr->logpalette.palNumEntries,
770 (dc->hPalette != hPrimaryPalette) ||
771 (dc->hPalette == GetStockObject( DEFAULT_PALETTE )));
772 hLastRealizedPalette = dc->hPalette;
773 GDI_ReleaseObj( dc->hPalette );
775 else TRACE(" skipping (hLastRealizedPalette = %04x)\n",
776 hLastRealizedPalette);
777 GDI_ReleaseObj( hdc );
779 TRACE(" realized %i colors.\n", realized );
780 return (UINT16)realized;
784 /***********************************************************************
785 * RealizeDefaultPalette (GDI.365)
787 UINT16 WINAPI RealizeDefaultPalette16( HDC16 hdc )
789 UINT16 ret = 0;
790 DC *dc;
791 PALETTEOBJ* palPtr;
793 TRACE("%04x\n", hdc );
795 if (!(dc = DC_GetDCPtr( hdc ))) return 0;
797 if (!(dc->flags & DC_MEMORY))
799 palPtr = (PALETTEOBJ*)GDI_GetObjPtr( GetStockObject(DEFAULT_PALETTE), PALETTE_MAGIC );
800 if (palPtr)
802 /* lookup is needed to account for SetSystemPaletteUse() stuff */
803 if (PALETTE_Driver) ret = PALETTE_Driver->pUpdateMapping(palPtr);
804 GDI_ReleaseObj( GetStockObject(DEFAULT_PALETTE) );
807 GDI_ReleaseObj( hdc );
808 return ret;
811 /***********************************************************************
812 * IsDCCurrentPalette (GDI.412)
814 BOOL16 WINAPI IsDCCurrentPalette16(HDC16 hDC)
816 DC *dc = DC_GetDCPtr( hDC );
817 if (dc)
819 BOOL bRet = dc->hPalette == hPrimaryPalette;
820 GDI_ReleaseObj( hDC );
821 return bRet;
823 return FALSE;
827 /***********************************************************************
828 * SelectPalette [GDI32.@] Selects logical palette into DC
830 * RETURNS
831 * Success: Previous logical palette
832 * Failure: NULL
834 HPALETTE WINAPI SelectPalette(
835 HDC hDC, /* [in] Handle of device context */
836 HPALETTE hPal, /* [in] Handle of logical color palette */
837 BOOL bForceBackground) /* [in] Foreground/background mode */
839 return pfnSelectPalette( hDC, hPal, bForceBackground );
843 /***********************************************************************
844 * RealizePalette [GDI32.@] Maps palette entries to system palette
846 * RETURNS
847 * Success: Number of entries in logical palette
848 * Failure: GDI_ERROR
850 UINT WINAPI RealizePalette(
851 HDC hDC) /* [in] Handle of device context */
853 return pfnRealizePalette( hDC );
857 typedef HWND (WINAPI *WindowFromDC_funcptr)( HDC );
858 typedef BOOL (WINAPI *RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT );
860 /**********************************************************************
861 * UpdateColors [GDI32.@] Remaps current colors to logical palette
863 * RETURNS
864 * Success: TRUE
865 * Failure: FALSE
867 BOOL WINAPI UpdateColors(
868 HDC hDC) /* [in] Handle of device context */
870 HMODULE mod;
871 int size = GetDeviceCaps( hDC, SIZEPALETTE );
873 if (!size) return 0;
875 mod = GetModuleHandleA("user32.dll");
876 if (mod)
878 WindowFromDC_funcptr pWindowFromDC = (WindowFromDC_funcptr)GetProcAddress(mod,"WindowFromDC");
879 if (pWindowFromDC)
881 HWND hWnd = pWindowFromDC( hDC );
883 /* Docs say that we have to remap current drawable pixel by pixel
884 * but it would take forever given the speed of XGet/PutPixel.
886 if (hWnd && size)
888 RedrawWindow_funcptr pRedrawWindow = GetProcAddress( mod, "RedrawWindow" );
889 if (pRedrawWindow) pRedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
893 return 0x666;
897 /**********************************************************************
898 * UpdateColors (GDI.366)
900 INT16 WINAPI UpdateColors16( HDC16 hDC )
902 UpdateColors( hDC );
903 return TRUE;
907 /*********************************************************************
908 * SetMagicColors (GDI.606)
910 VOID WINAPI SetMagicColors16(HDC16 hDC, COLORREF color, UINT16 index)
912 FIXME("(hDC %04x, color %04x, index %04x): stub\n", hDC, (int)color, index);
916 /**********************************************************************
917 * GetICMProfileA [GDI32.@]
919 * Returns the filename of the specified device context's color
920 * management profile, even if color management is not enabled
921 * for that DC.
923 * RETURNS
924 * TRUE if name copied succesfully OR lpszFilename is NULL
925 * FALSE if the buffer length pointed to by lpcbName is too small
927 * NOTE
928 * The buffer length pointed to by lpcbName is ALWAYS updated to
929 * the length required regardless of other actions this function
930 * may take.
932 * FIXME
933 * How does Windows assign these? Some registry key?
936 #define WINEICM "winefake.icm" /* easy-to-identify fake filename */
938 /*********************************************************************/
940 BOOL WINAPI GetICMProfileA(HDC hDC, LPDWORD lpcbName, LPSTR lpszFilename)
942 DWORD callerLen;
944 FIXME("(%04x, %p, %p): partial stub\n", hDC, lpcbName, lpszFilename);
946 callerLen = *lpcbName;
948 /* all 3 behaviors require the required buffer size to be set */
949 *lpcbName = strlen(WINEICM);
951 /* behavior 1: if lpszFilename is NULL, return size of string and no error */
952 if ((DWORD)lpszFilename == (DWORD)0x00000000)
953 return TRUE;
955 /* behavior 2: if buffer size too small, return size of string and error */
956 if (callerLen < strlen(WINEICM))
958 SetLastError(ERROR_INSUFFICIENT_BUFFER);
959 return FALSE;
962 /* behavior 3: if buffer size OK and pointer not NULL, copy and return size */
963 strcpy(lpszFilename, WINEICM);
964 return TRUE;