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 struct tagPALETTEOBJ
42 {
43 GDIOBJHDR header;
44 const DC_FUNCTIONS *funcs; /* DC function table */
45 WORD version; /* palette version */
46 WORD count; /* count of palette entries */
47 PALETTEENTRY *entries;
48 } PALETTEOBJ;
49
50 static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
51 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle );
52 static BOOL PALETTE_DeleteObject( HGDIOBJ handle );
53
54 static const struct gdi_obj_funcs palette_funcs =
55 {
56 NULL, /* pSelectObject */
57 PALETTE_GetObject, /* pGetObjectA */
58 PALETTE_GetObject, /* pGetObjectW */
59 PALETTE_UnrealizeObject, /* pUnrealizeObject */
60 PALETTE_DeleteObject /* pDeleteObject */
61 };
62
63 /* Pointers to USER implementation of SelectPalette/RealizePalette */
64 /* they will be patched by USER on startup */
65 HPALETTE (WINAPI *pfnSelectPalette)(HDC hdc, HPALETTE hpal, WORD bkgnd ) = GDISelectPalette;
66 UINT (WINAPI *pfnRealizePalette)(HDC hdc) = GDIRealizePalette;
67
68 static UINT SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */
69
70 static HPALETTE hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
71 static HPALETTE hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
72
73 #define NB_RESERVED_COLORS 20 /* number of fixed colors in system palette */
74
75 static const PALETTEENTRY sys_pal_template[NB_RESERVED_COLORS] =
76 {
77 /* first 10 entries in the system palette */
78 /* red green blue flags */
79 { 0x00, 0x00, 0x00, 0 },
80 { 0x80, 0x00, 0x00, 0 },
81 { 0x00, 0x80, 0x00, 0 },
82 { 0x80, 0x80, 0x00, 0 },
83 { 0x00, 0x00, 0x80, 0 },
84 { 0x80, 0x00, 0x80, 0 },
85 { 0x00, 0x80, 0x80, 0 },
86 { 0xc0, 0xc0, 0xc0, 0 },
87 { 0xc0, 0xdc, 0xc0, 0 },
88 { 0xa6, 0xca, 0xf0, 0 },
89
90 /* ... c_min/2 dynamic colorcells */
91
92 /* ... gap (for sparse palettes) */
93
94 /* ... c_min/2 dynamic colorcells */
95
96 { 0xff, 0xfb, 0xf0, 0 },
97 { 0xa0, 0xa0, 0xa4, 0 },
98 { 0x80, 0x80, 0x80, 0 },
99 { 0xff, 0x00, 0x00, 0 },
100 { 0x00, 0xff, 0x00, 0 },
101 { 0xff, 0xff, 0x00, 0 },
102 { 0x00, 0x00, 0xff, 0 },
103 { 0xff, 0x00, 0xff, 0 },
104 { 0x00, 0xff, 0xff, 0 },
105 { 0xff, 0xff, 0xff, 0 } /* last 10 */
106 };
107
108 /***********************************************************************
109 * PALETTE_Init
110 *
111 * Create the system palette.
112 */
113 HPALETTE PALETTE_Init(void)
114 {
115 HPALETTE hpalette;
116 LOGPALETTE * palPtr;
117
118 /* create default palette (20 system colors) */
119
120 palPtr = HeapAlloc( GetProcessHeap(), 0,
121 sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY));
122 if (!palPtr) return FALSE;
123
124 palPtr->palVersion = 0x300;
125 palPtr->palNumEntries = NB_RESERVED_COLORS;
126 memcpy( palPtr->palPalEntry, sys_pal_template, sizeof(sys_pal_template) );
127 hpalette = CreatePalette( palPtr );
128 HeapFree( GetProcessHeap(), 0, palPtr );
129 return hpalette;
130 }
131
132
133 /***********************************************************************
134 * CreatePalette [GDI32.@]
135 *
136 * Creates a logical color palette.
137 *
138 * RETURNS
139 * Success: Handle to logical palette
140 * Failure: NULL
141 */
142 HPALETTE WINAPI CreatePalette(
143 const LOGPALETTE* palette) /* [in] Pointer to logical color palette */
144 {
145 PALETTEOBJ * palettePtr;
146 HPALETTE hpalette;
147 int size;
148
149 if (!palette) return 0;
150 TRACE("entries=%i\n", palette->palNumEntries);
151
152 size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
153
154 if (!(palettePtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*palettePtr) ))) return 0;
155 palettePtr->funcs = NULL;
156 palettePtr->version = palette->palVersion;
157 palettePtr->count = palette->palNumEntries;
158 size = palettePtr->count * sizeof(*palettePtr->entries);
159 if (!(palettePtr->entries = HeapAlloc( GetProcessHeap(), 0, size )))
160 {
161 HeapFree( GetProcessHeap(), 0, palettePtr );
162 return 0;
163 }
164 memcpy( palettePtr->entries, palette->palPalEntry, size );
165 if (!(hpalette = alloc_gdi_handle( &palettePtr->header, OBJ_PAL, &palette_funcs )))
166 {
167 HeapFree( GetProcessHeap(), 0, palettePtr->entries );
168 HeapFree( GetProcessHeap(), 0, palettePtr );
169 }
170 TRACE(" returning %p\n", hpalette);
171 return hpalette;
172 }
173
174
175 /***********************************************************************
176 * CreateHalftonePalette [GDI32.@]
177 *
178 * Creates a halftone palette.
179 *
180 * RETURNS
181 * Success: Handle to logical halftone palette
182 * Failure: 0
183 *
184 * FIXME: This simply creates the halftone palette derived from running
185 * tests on a windows NT machine. This is assuming a color depth
186 * of greater that 256 color. On a 256 color device the halftone
187 * palette will be different and this function will be incorrect
188 */
189 HPALETTE WINAPI CreateHalftonePalette(
190 HDC hdc) /* [in] Handle to device context */
191 {
192 int i;
193 struct {
194 WORD Version;
195 WORD NumberOfEntries;
196 PALETTEENTRY aEntries[256];
197 } Palette;
198
199 Palette.Version = 0x300;
200 Palette.NumberOfEntries = 256;
201 GetSystemPaletteEntries(hdc, 0, 256, Palette.aEntries);
202
203 Palette.NumberOfEntries = 20;
204
205 for (i = 0; i < Palette.NumberOfEntries; i++)
206 {
207 Palette.aEntries[i].peRed=0xff;
208 Palette.aEntries[i].peGreen=0xff;
209 Palette.aEntries[i].peBlue=0xff;
210 Palette.aEntries[i].peFlags=0x00;
211 }
212
213 Palette.aEntries[0].peRed=0x00;
214 Palette.aEntries[0].peBlue=0x00;
215 Palette.aEntries[0].peGreen=0x00;
216
217 /* the first 6 */
218 for (i=1; i <= 6; i++)
219 {
220 Palette.aEntries[i].peRed=(i%2)?0x80:0;
221 Palette.aEntries[i].peGreen=(i==2)?0x80:(i==3)?0x80:(i==6)?0x80:0;
222 Palette.aEntries[i].peBlue=(i>3)?0x80:0;
223 }
224
225 for (i=7; i <= 12; i++)
226 {
227 switch(i)
228 {
229 case 7:
230 Palette.aEntries[i].peRed=0xc0;
231 Palette.aEntries[i].peBlue=0xc0;
232 Palette.aEntries[i].peGreen=0xc0;
233 break;
234 case 8:
235 Palette.aEntries[i].peRed=0xc0;
236 Palette.aEntries[i].peGreen=0xdc;
237 Palette.aEntries[i].peBlue=0xc0;
238 break;
239 case 9:
240 Palette.aEntries[i].peRed=0xa6;
241 Palette.aEntries[i].peGreen=0xca;
242 Palette.aEntries[i].peBlue=0xf0;
243 break;
244 case 10:
245 Palette.aEntries[i].peRed=0xff;
246 Palette.aEntries[i].peGreen=0xfb;
247 Palette.aEntries[i].peBlue=0xf0;
248 break;
249 case 11:
250 Palette.aEntries[i].peRed=0xa0;
251 Palette.aEntries[i].peGreen=0xa0;
252 Palette.aEntries[i].peBlue=0xa4;
253 break;
254 case 12:
255 Palette.aEntries[i].peRed=0x80;
256 Palette.aEntries[i].peGreen=0x80;
257 Palette.aEntries[i].peBlue=0x80;
258 }
259 }
260
261 for (i=13; i <= 18; i++)
262 {
263 Palette.aEntries[i].peRed=(i%2)?0xff:0;
264 Palette.aEntries[i].peGreen=(i==14)?0xff:(i==15)?0xff:(i==18)?0xff:0;
265 Palette.aEntries[i].peBlue=(i>15)?0xff:0x00;
266 }
267
268 return CreatePalette((LOGPALETTE *)&Palette);
269 }
270
271
272 /***********************************************************************
273 * GetPaletteEntries [GDI32.@]
274 *
275 * Retrieves palette entries.
276 *
277 * RETURNS
278 * Success: Number of entries from logical palette
279 * Failure: 0
280 */
281 UINT WINAPI GetPaletteEntries(
282 HPALETTE hpalette, /* [in] Handle of logical palette */
283 UINT start, /* [in] First entry to receive */
284 UINT count, /* [in] Number of entries to receive */
285 LPPALETTEENTRY entries) /* [out] Address of array receiving entries */
286 {
287 PALETTEOBJ * palPtr;
288 UINT numEntries;
289
290 TRACE("hpal = %p, count=%i\n", hpalette, count );
291
292 palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL );
293 if (!palPtr) return 0;
294
295 /* NOTE: not documented but test show this to be the case */
296 if (count == 0)
297 {
298 count = palPtr->count;
299 }
300 else
301 {
302 numEntries = palPtr->count;
303 if (start+count > numEntries) count = numEntries - start;
304 if (entries)
305 {
306 if (start >= numEntries) count = 0;
307 else memcpy( entries, &palPtr->entries[start], count * sizeof(PALETTEENTRY) );
308 }
309 }
310
311 GDI_ReleaseObj( hpalette );
312 return count;
313 }
314
315
316 /***********************************************************************
317 * SetPaletteEntries [GDI32.@]
318 *
319 * Sets color values for range in palette.
320 *
321 * RETURNS
322 * Success: Number of entries that were set
323 * Failure: 0
324 */
325 UINT WINAPI SetPaletteEntries(
326 HPALETTE hpalette, /* [in] Handle of logical palette */
327 UINT start, /* [in] Index of first entry to set */
328 UINT count, /* [in] Number of entries to set */
329 const PALETTEENTRY *entries) /* [in] Address of array of structures */
330 {
331 PALETTEOBJ * palPtr;
332 UINT numEntries;
333
334 TRACE("hpal=%p,start=%i,count=%i\n",hpalette,start,count );
335
336 if (hpalette == GetStockObject(DEFAULT_PALETTE)) return 0;
337 palPtr = GDI_GetObjPtr( hpalette, OBJ_PAL );
338 if (!palPtr) return 0;
339
340 numEntries = palPtr->count;
341 if (start >= numEntries)
342 {
343 GDI_ReleaseObj( hpalette );
344 return 0;
345 }
346 if (start+count > numEntries) count = numEntries - start;
347 memcpy( &palPtr->entries[start], entries, count * sizeof(PALETTEENTRY) );
348 GDI_ReleaseObj( hpalette );
349 UnrealizeObject( hpalette );
350 return count;
351 }
352
353
354 /***********************************************************************
355 * ResizePalette [GDI32.@]
356 *
357 * Resizes logical palette.
358 *
359 * RETURNS
360 * Success: TRUE
361 * Failure: FALSE
362 */
363 BOOL WINAPI ResizePalette(
364 HPALETTE hPal, /* [in] Handle of logical palette */
365 UINT cEntries) /* [in] Number of entries in logical palette */
366 {
367 PALETTEOBJ * palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
368 PALETTEENTRY *entries;
369
370 if( !palPtr ) return FALSE;
371 TRACE("hpal = %p, prev = %i, new = %i\n", hPal, palPtr->count, cEntries );
372
373 if (!(entries = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
374 palPtr->entries, cEntries * sizeof(*palPtr->entries) )))
375 {
376 GDI_ReleaseObj( hPal );
377 return FALSE;
378 }
379 palPtr->entries = entries;
380 palPtr->count = cEntries;
381
382 GDI_ReleaseObj( hPal );
383 PALETTE_UnrealizeObject( hPal );
384 return TRUE;
385 }
386
387
388 /***********************************************************************
389 * AnimatePalette [GDI32.@]
390 *
391 * Replaces entries in logical palette.
392 *
393 * RETURNS
394 * Success: TRUE
395 * Failure: FALSE
396 *
397 * FIXME
398 * Should use existing mapping when animating a primary palette
399 */
400 BOOL WINAPI AnimatePalette(
401 HPALETTE hPal, /* [in] Handle to logical palette */
402 UINT StartIndex, /* [in] First entry in palette */
403 UINT NumEntries, /* [in] Count of entries in palette */
404 const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */
405 {
406 TRACE("%p (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries);
407
408 if( hPal != GetStockObject(DEFAULT_PALETTE) )
409 {
410 PALETTEOBJ * palPtr;
411 UINT pal_entries;
412 const PALETTEENTRY *pptr = PaletteColors;
413 const DC_FUNCTIONS *funcs;
414
415 palPtr = GDI_GetObjPtr( hPal, OBJ_PAL );
416 if (!palPtr) return 0;
417
418 pal_entries = palPtr->count;
419 if (StartIndex >= pal_entries)
420 {
421 GDI_ReleaseObj( hPal );
422 return 0;
423 }
424 if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex;
425
426 for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
427 /* According to MSDN, only animate PC_RESERVED colours */
428 if (palPtr->entries[StartIndex].peFlags & PC_RESERVED) {
429 TRACE("Animating colour (%d,%d,%d) to (%d,%d,%d)\n",
430 palPtr->entries[StartIndex].peRed,
431 palPtr->entries[StartIndex].peGreen,
432 palPtr->entries[StartIndex].peBlue,
433 pptr->peRed, pptr->peGreen, pptr->peBlue);
434 palPtr->entries[StartIndex] = *pptr;
435 } else {
436 TRACE("Not animating entry %d -- not PC_RESERVED\n", StartIndex);
437 }
438 }
439 funcs = palPtr->funcs;
440 GDI_ReleaseObj( hPal );
441 if (funcs && funcs->pRealizePalette) funcs->pRealizePalette( NULL, hPal, hPal == hPrimaryPalette );
442 }
443 return TRUE;
444 }
445
446
447 /***********************************************************************
448 * SetSystemPaletteUse [GDI32.@]
449 *
450 * Specify whether the system palette contains 2 or 20 static colors.
451 *
452 * RETURNS
453 * Success: Previous system palette
454 * Failure: SYSPAL_ERROR
455 */
456 UINT WINAPI SetSystemPaletteUse(
457 HDC hdc, /* [in] Handle of device context */
458 UINT use) /* [in] Palette-usage flag */
459 {
460 UINT old = SystemPaletteUse;
461
462 /* Device doesn't support colour palettes */
463 if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)) {
464 return SYSPAL_ERROR;
465 }
466
467 switch (use) {
468 case SYSPAL_NOSTATIC:
469 case SYSPAL_NOSTATIC256: /* WINVER >= 0x0500 */
470 case SYSPAL_STATIC:
471 SystemPaletteUse = use;
472 return old;
473 default:
474 return SYSPAL_ERROR;
475 }
476 }
477
478
479 /***********************************************************************
480 * GetSystemPaletteUse [GDI32.@]
481 *
482 * Gets state of system palette.
483 *
484 * RETURNS
485 * Current state of system palette
486 */
487 UINT WINAPI GetSystemPaletteUse(
488 HDC hdc) /* [in] Handle of device context */
489 {
490 return SystemPaletteUse;
491 }
492
493
494 /***********************************************************************
495 * GetSystemPaletteEntries [GDI32.@]
496 *
497 * Gets range of palette entries.
498 *
499 * RETURNS
500 * Success: Number of entries retrieved from palette
501 * Failure: 0
502 */
503 UINT WINAPI GetSystemPaletteEntries(
504 HDC hdc, /* [in] Handle of device context */
505 UINT start, /* [in] Index of first entry to be retrieved */
506 UINT count, /* [in] Number of entries to be retrieved */
507 LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
508 {
509 UINT ret = 0;
510 DC *dc;
511
512 TRACE("hdc=%p,start=%i,count=%i\n", hdc,start,count);
513
514 if ((dc = get_dc_ptr( hdc )))
515 {
516 if (dc->funcs->pGetSystemPaletteEntries)
517 ret = dc->funcs->pGetSystemPaletteEntries( dc->physDev, start, count, entries );
518 release_dc_ptr( dc );
519 }
520 return ret;
521 }
522
523
524 /***********************************************************************
525 * GetNearestPaletteIndex [GDI32.@]
526 *
527 * Gets palette index for color.
528 *
529 * NOTES
530 * Should index be initialized to CLR_INVALID instead of 0?
531 *
532 * RETURNS
533 * Success: Index of entry in logical palette
534 * Failure: CLR_INVALID
535 */
536 UINT WINAPI GetNearestPaletteIndex(
537 HPALETTE hpalette, /* [in] Handle of logical color palette */
538 COLORREF color) /* [in] Color to be matched */
539 {
540 PALETTEOBJ* palObj = GDI_GetObjPtr( hpalette, OBJ_PAL );
541 UINT index = 0;
542
543 if( palObj )
544 {
545 int i, diff = 0x7fffffff;
546 int r,g,b;
547 PALETTEENTRY* entry = palObj->entries;
548
549 for( i = 0; i < palObj->count && diff ; i++, entry++)
550 {
551 r = entry->peRed - GetRValue(color);
552 g = entry->peGreen - GetGValue(color);
553 b = entry->peBlue - GetBValue(color);
554
555 r = r*r + g*g + b*b;
556
557 if( r < diff ) { index = i; diff = r; }
558 }
559 GDI_ReleaseObj( hpalette );
560 }
561 TRACE("(%p,%06x): returning %d\n", hpalette, color, index );
562 return index;
563 }
564
565
566 /***********************************************************************
567 * GetNearestColor [GDI32.@]
568 *
569 * Gets a system color to match.
570 *
571 * RETURNS
572 * Success: Color from system palette that corresponds to given color
573 * Failure: CLR_INVALID
574 */
575 COLORREF WINAPI GetNearestColor(
576 HDC hdc, /* [in] Handle of device context */
577 COLORREF color) /* [in] Color to be matched */
578 {
579 unsigned char spec_type;
580 COLORREF nearest;
581 DC *dc;
582
583 if (!(dc = get_dc_ptr( hdc ))) return CLR_INVALID;
584
585 if (dc->funcs->pGetNearestColor)
586 {
587 nearest = dc->funcs->pGetNearestColor( dc->physDev, color );
588 release_dc_ptr( dc );
589 return nearest;
590 }
591
592 if (!(GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE))
593 {
594 release_dc_ptr( dc );
595 return color;
596 }
597
598 spec_type = color >> 24;
599 if (spec_type == 1 || spec_type == 2)
600 {
601 /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
602
603 UINT index;
604 PALETTEENTRY entry;
605 HPALETTE hpal = dc->hPalette ? dc->hPalette : GetStockObject( DEFAULT_PALETTE );
606
607 if (spec_type == 2) /* PALETTERGB */
608 index = GetNearestPaletteIndex( hpal, color );
609 else /* PALETTEINDEX */
610 index = LOWORD(color);
611
612 if (!GetPaletteEntries( hpal, index, 1, &entry ))
613 {
614 WARN("RGB(%x) : idx %d is out of bounds, assuming NULL\n", color, index );
615 if (!GetPaletteEntries( hpal, 0, 1, &entry ))
616 {
617 release_dc_ptr( dc );
618 return CLR_INVALID;
619 }
620 }
621 color = RGB( entry.peRed, entry.peGreen, entry.peBlue );
622 }
623 nearest = color & 0x00ffffff;
624 release_dc_ptr( dc );
625
626 TRACE("(%06x): returning %06x\n", color, nearest );
627 return nearest;
628 }
629
630
631 /***********************************************************************
632 * PALETTE_GetObject
633 */
634 static INT PALETTE_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
635 {
636 PALETTEOBJ *palette = GDI_GetObjPtr( handle, OBJ_PAL );
637
638 if (!palette) return 0;
639
640 if (buffer)
641 {
642 if (count > sizeof(WORD)) count = sizeof(WORD);
643 memcpy( buffer, &palette->count, count );
644 }
645 else count = sizeof(WORD);
646 GDI_ReleaseObj( handle );
647 return count;
648 }
649
650
651 /***********************************************************************
652 * PALETTE_UnrealizeObject
653 */
654 static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle )
655 {
656 PALETTEOBJ *palette = GDI_GetObjPtr( handle, OBJ_PAL );
657
658 if (palette)
659 {
660 const DC_FUNCTIONS *funcs = palette->funcs;
661 palette->funcs = NULL;
662 GDI_ReleaseObj( handle );
663 if (funcs && funcs->pUnrealizePalette) funcs->pUnrealizePalette( handle );
664 }
665
666 if (InterlockedCompareExchangePointer( (void **)&hLastRealizedPalette, 0, handle ) == handle)
667 TRACE("unrealizing palette %p\n", handle);
668
669 return TRUE;
670 }
671
672
673 /***********************************************************************
674 * PALETTE_DeleteObject
675 */
676 static BOOL PALETTE_DeleteObject( HGDIOBJ handle )
677 {
678 PALETTEOBJ *obj;
679
680 PALETTE_UnrealizeObject( handle );
681 if (!(obj = free_gdi_handle( handle ))) return FALSE;
682 HeapFree( GetProcessHeap(), 0, obj->entries );
683 return HeapFree( GetProcessHeap(), 0, obj );
684 }
685
686
687 /***********************************************************************
688 * GDISelectPalette (Not a Windows API)
689 */
690 HPALETTE WINAPI GDISelectPalette( HDC hdc, HPALETTE hpal, WORD wBkg)
691 {
692 HPALETTE ret;
693 DC *dc;
694
695 TRACE("%p %p\n", hdc, hpal );
696
697 if (GetObjectType(hpal) != OBJ_PAL)
698 {
699 WARN("invalid selected palette %p\n",hpal);
700 return 0;
701 }
702 if (!(dc = get_dc_ptr( hdc ))) return 0;
703 ret = dc->hPalette;
704 if (dc->funcs->pSelectPalette) hpal = dc->funcs->pSelectPalette( dc->physDev, hpal, FALSE );
705 if (hpal)
706 {
707 dc->hPalette = hpal;
708 if (!wBkg) hPrimaryPalette = hpal;
709 }
710 else ret = 0;
711 release_dc_ptr( dc );
712 return ret;
713 }
714
715
716 /***********************************************************************
717 * GDIRealizePalette (Not a Windows API)
718 */
719 UINT WINAPI GDIRealizePalette( HDC hdc )
720 {
721 UINT realized = 0;
722 DC* dc = get_dc_ptr( hdc );
723
724 if (!dc) return 0;
725
726 TRACE("%p...\n", hdc );
727
728 if( dc->hPalette == GetStockObject( DEFAULT_PALETTE ))
729 {
730 if (dc->funcs->pRealizeDefaultPalette)
731 realized = dc->funcs->pRealizeDefaultPalette( dc->physDev );
732 }
733 else if (InterlockedExchangePointer( (void **)&hLastRealizedPalette, dc->hPalette ) != dc->hPalette)
734 {
735 if (dc->funcs->pRealizePalette)
736 {
737 PALETTEOBJ *palPtr = GDI_GetObjPtr( dc->hPalette, OBJ_PAL );
738 if (palPtr)
739 {
740 realized = dc->funcs->pRealizePalette( dc->physDev, dc->hPalette,
741 (dc->hPalette == hPrimaryPalette) );
742 palPtr->funcs = dc->funcs;
743 GDI_ReleaseObj( dc->hPalette );
744 }
745 }
746 }
747 else TRACE(" skipping (hLastRealizedPalette = %p)\n", hLastRealizedPalette);
748
749 release_dc_ptr( dc );
750 TRACE(" realized %i colors.\n", realized );
751 return realized;
752 }
753
754
755 /***********************************************************************
756 * SelectPalette [GDI32.@]
757 *
758 * Selects logical palette into DC.
759 *
760 * RETURNS
761 * Success: Previous logical palette
762 * Failure: NULL
763 */
764 HPALETTE WINAPI SelectPalette(
765 HDC hDC, /* [in] Handle of device context */
766 HPALETTE hPal, /* [in] Handle of logical color palette */
767 BOOL bForceBackground) /* [in] Foreground/background mode */
768 {
769 return pfnSelectPalette( hDC, hPal, bForceBackground );
770 }
771
772
773 /***********************************************************************
774 * RealizePalette [GDI32.@]
775 *
776 * Maps palette entries to system palette.
777 *
778 * RETURNS
779 * Success: Number of entries in logical palette
780 * Failure: GDI_ERROR
781 */
782 UINT WINAPI RealizePalette(
783 HDC hDC) /* [in] Handle of device context */
784 {
785 return pfnRealizePalette( hDC );
786 }
787
788
789 typedef HWND (WINAPI *WindowFromDC_funcptr)( HDC );
790 typedef BOOL (WINAPI *RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT );
791
792 /**********************************************************************
793 * UpdateColors [GDI32.@]
794 *
795 * Remaps current colors to logical palette.
796 *
797 * RETURNS
798 * Success: TRUE
799 * Failure: FALSE
800 */
801 BOOL WINAPI UpdateColors(
802 HDC hDC) /* [in] Handle of device context */
803 {
804 HMODULE mod;
805 int size = GetDeviceCaps( hDC, SIZEPALETTE );
806
807 if (!size) return 0;
808
809 mod = GetModuleHandleA("user32.dll");
810 if (mod)
811 {
812 WindowFromDC_funcptr pWindowFromDC = (WindowFromDC_funcptr)GetProcAddress(mod,"WindowFromDC");
813 if (pWindowFromDC)
814 {
815 HWND hWnd = pWindowFromDC( hDC );
816
817 /* Docs say that we have to remap current drawable pixel by pixel
818 * but it would take forever given the speed of XGet/PutPixel.
819 */
820 if (hWnd && size)
821 {
822 RedrawWindow_funcptr pRedrawWindow = (void *)GetProcAddress( mod, "RedrawWindow" );
823 if (pRedrawWindow) pRedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
824 }
825 }
826 }
827 return 0x666;
828 }
829
830 /*********************************************************************
831 * SetMagicColors (GDI32.@)
832 */
833 BOOL WINAPI SetMagicColors(HDC hdc, ULONG u1, ULONG u2)
834 {
835 FIXME("(%p 0x%08x 0x%08x): stub\n", hdc, u1, u2);
836 return TRUE;
837 }
838
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.