4 * Copyright 1993,1994 Alexandre Julliard
5 * Copyright 1996 Alex Korobka
18 /* #define DEBUG_PALETTE */
21 /* lookup pixel among static entries of the system palette */
22 extern int COLOR_LookupSystemPixel(COLORREF
);
24 static UINT32 SystemPaletteUse
= SYSPAL_STATIC
; /* currently not considered */
26 static HPALETTE16 hPrimaryPalette
= 0; /* used for WM_PALETTECHANGED */
27 static HPALETTE16 hLastRealizedPalette
= 0; /* UnrealizeObject() needs it */
30 /***********************************************************************
31 * PALETTE_ValidateFlags
33 void PALETTE_ValidateFlags(PALETTEENTRY
* lpPalE
, int size
)
37 lpPalE
[i
].peFlags
= PC_SYS_USED
| (lpPalE
[i
].peFlags
& 0x07);
41 /***********************************************************************
42 * CreatePalette16 (GDI.360)
44 HPALETTE16
CreatePalette16( const LOGPALETTE
* palette
)
46 return CreatePalette32( palette
);
50 /***********************************************************************
51 * CreatePalette32 (GDI32.53)
53 HPALETTE32
CreatePalette32( const LOGPALETTE
* palette
)
55 PALETTEOBJ
* palettePtr
;
57 int size
= sizeof(LOGPALETTE
) + (palette
->palNumEntries
- 1) * sizeof(PALETTEENTRY
);
59 dprintf_palette(stddeb
,"CreatePalette: %i entries, ",
60 palette
->palNumEntries
);
62 hpalette
= GDI_AllocObject( size
+ sizeof(int*) +sizeof(GDIOBJHDR
) , PALETTE_MAGIC
);
63 if (!hpalette
) return 0;
65 palettePtr
= (PALETTEOBJ
*) GDI_HEAP_LIN_ADDR( hpalette
);
66 memcpy( &palettePtr
->logpalette
, palette
, size
);
67 PALETTE_ValidateFlags(palettePtr
->logpalette
.palPalEntry
,
68 palettePtr
->logpalette
.palNumEntries
);
69 palettePtr
->mapping
= NULL
;
71 dprintf_palette(stddeb
,"returning %04x\n", hpalette
);
76 /***********************************************************************
77 * GetPaletteEntries16 (GDI.363)
79 UINT16
GetPaletteEntries16( HPALETTE16 hpalette
, UINT16 start
, UINT16 count
,
80 LPPALETTEENTRY entries
)
82 return GetPaletteEntries32( hpalette
, start
, count
, entries
);
86 /***********************************************************************
87 * GetPaletteEntries32 (GDI32.209)
89 UINT32
GetPaletteEntries32( HPALETTE32 hpalette
, UINT32 start
, UINT32 count
,
90 LPPALETTEENTRY entries
)
95 dprintf_palette( stddeb
,"GetPaletteEntries: hpal = %04x, %i entries\n",
98 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
99 if (!palPtr
) return 0;
101 numEntries
= palPtr
->logpalette
.palNumEntries
;
102 if (start
>= numEntries
) return 0;
103 if (start
+count
> numEntries
) count
= numEntries
- start
;
104 memcpy( entries
, &palPtr
->logpalette
.palPalEntry
[start
],
105 count
* sizeof(PALETTEENTRY
) );
106 for( numEntries
= 0; numEntries
< count
; numEntries
++ )
107 if (entries
[numEntries
].peFlags
& 0xF0)
108 entries
[numEntries
].peFlags
= 0;
113 /***********************************************************************
114 * SetPaletteEntries16 (GDI.364)
116 UINT16
SetPaletteEntries16( HPALETTE16 hpalette
, UINT16 start
, UINT16 count
,
117 LPPALETTEENTRY entries
)
119 return SetPaletteEntries32( hpalette
, start
, count
, entries
);
123 /***********************************************************************
124 * SetPaletteEntries32 (GDI32.326)
126 UINT32
SetPaletteEntries32( HPALETTE32 hpalette
, UINT32 start
, UINT32 count
,
127 LPPALETTEENTRY entries
)
132 dprintf_palette( stddeb
,"SetPaletteEntries: hpal = %04x, %i entries\n",
135 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
136 if (!palPtr
) return 0;
138 numEntries
= palPtr
->logpalette
.palNumEntries
;
139 if (start
>= numEntries
) return 0;
140 if (start
+count
> numEntries
) count
= numEntries
- start
;
141 memcpy( &palPtr
->logpalette
.palPalEntry
[start
], entries
,
142 count
* sizeof(PALETTEENTRY
) );
143 PALETTE_ValidateFlags(palPtr
->logpalette
.palPalEntry
,
144 palPtr
->logpalette
.palNumEntries
);
145 free(palPtr
->mapping
);
146 palPtr
->mapping
= NULL
;
152 /***********************************************************************
153 * ResizePalette16 (GDI.368)
155 BOOL16
ResizePalette16( HPALETTE16 hPal
, UINT16 cEntries
)
157 return ResizePalette32( hPal
, cEntries
);
161 /***********************************************************************
162 * ResizePalette32 (GDI32.289)
164 BOOL32
ResizePalette32( HPALETTE32 hPal
, UINT32 cEntries
)
166 PALETTEOBJ
* palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
167 UINT32 cPrevEnt
, prevVer
;
168 int prevsize
, size
= sizeof(LOGPALETTE
) + (cEntries
- 1) * sizeof(PALETTEENTRY
);
171 dprintf_palette(stddeb
,"ResizePalette: hpal = %04x, prev = %i, new = %i\n",
172 hPal
, (palPtr
)? -1: palPtr
->logpalette
.palNumEntries
, cEntries
);
173 if( !palPtr
) return FALSE
;
174 cPrevEnt
= palPtr
->logpalette
.palNumEntries
;
175 prevVer
= palPtr
->logpalette
.palVersion
;
176 prevsize
= sizeof(LOGPALETTE
) + (cPrevEnt
- 1) * sizeof(PALETTEENTRY
) +
177 sizeof(int*) + sizeof(GDIOBJHDR
);
178 size
+= sizeof(int*) + sizeof(GDIOBJHDR
);
179 mapping
= palPtr
->mapping
;
181 GDI_HEAP_REALLOC( hPal
, size
);
182 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
183 if( !palPtr
) return FALSE
;
186 palPtr
->mapping
= (int*) xrealloc( mapping
, cEntries
* sizeof(int) );
187 if( cEntries
> cPrevEnt
)
190 memset(palPtr
->mapping
+ cPrevEnt
, 0, (cEntries
- cPrevEnt
)*sizeof(int));
191 memset( (BYTE
*)palPtr
+ prevsize
, 0, size
- prevsize
);
192 PALETTE_ValidateFlags((PALETTEENTRY
*)((BYTE
*)palPtr
+ prevsize
),
193 cEntries
- cPrevEnt
);
195 palPtr
->logpalette
.palNumEntries
= cEntries
;
196 palPtr
->logpalette
.palVersion
= prevVer
;
201 /***********************************************************************
202 * AnimatePalette16 (GDI.367)
204 BOOL16
AnimatePalette16( HPALETTE16 hPal
, UINT16 StartIndex
, UINT16 NumEntries
,
205 LPPALETTEENTRY PaletteColors
)
207 return AnimatePalette32( hPal
, StartIndex
, NumEntries
, PaletteColors
);
211 /***********************************************************************
212 * AnimatePalette32 (GDI32.6)
214 BOOL32
AnimatePalette32( HPALETTE32 hPal
, UINT32 StartIndex
, UINT32 NumEntries
,
215 LPPALETTEENTRY PaletteColors
)
217 fprintf(stdnimp
,"AnimatePalette: empty stub! \n");
222 /***********************************************************************
223 * SetSystemPaletteUse16 (GDI.373)
225 UINT16
SetSystemPaletteUse16( HDC16 hdc
, UINT16 use
)
227 return SetSystemPaletteUse32( hdc
, use
);
231 /***********************************************************************
232 * SetSystemPaletteUse32 (GDI32.335)
234 UINT32
SetSystemPaletteUse32( HDC32 hdc
, UINT32 use
)
236 UINT32 old
= SystemPaletteUse
;
237 fprintf( stdnimp
,"SetSystemPaletteUse(%04x,%04x) // empty stub !!!\n",
239 SystemPaletteUse
= use
;
244 /***********************************************************************
245 * GetSystemPaletteUse16 (GDI.374)
247 UINT16
GetSystemPaletteUse16( HDC16 hdc
)
249 return SystemPaletteUse
;
253 /***********************************************************************
254 * GetSystemPaletteUse32 (GDI32.223)
256 UINT32
GetSystemPaletteUse32( HDC32 hdc
)
258 return SystemPaletteUse
;
262 /***********************************************************************
263 * GetSystemPaletteEntries16 (GDI.375)
265 UINT16
GetSystemPaletteEntries16( HDC16 hdc
, UINT16 start
, UINT16 count
,
266 LPPALETTEENTRY entries
)
268 return GetSystemPaletteEntries32( hdc
, start
, count
, entries
);
272 /***********************************************************************
273 * GetSystemPaletteEntries32 (GDI32.222)
275 UINT32
GetSystemPaletteEntries32( HDC32 hdc
, UINT32 start
, UINT32 count
,
276 LPPALETTEENTRY entries
)
281 dprintf_palette(stddeb
,"GetSystemPaletteEntries: hdc = %04x, cound = %i", hdc
, count
);
283 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
284 if (start
>= dc
->w
.devCaps
->sizePalette
) return 0;
285 if (start
+count
>= dc
->w
.devCaps
->sizePalette
)
286 count
= dc
->w
.devCaps
->sizePalette
- start
;
287 for (i
= 0; i
< count
; i
++)
289 *(COLORREF
*)(entries
+ i
) = COLOR_GetSystemPaletteEntry( start
+ i
);
291 dprintf_palette( stddeb
,"\tidx(%02x) -> RGB(%08lx)\n",
292 start
+ i
, *(COLORREF
*)(entries
+ i
) );
298 /***********************************************************************
299 * GetNearestPaletteIndex16 (GDI.370)
301 UINT16
GetNearestPaletteIndex16( HPALETTE16 hpalette
, COLORREF color
)
303 return GetNearestPaletteIndex32( hpalette
, color
);
307 /***********************************************************************
308 * GetNearestPaletteIndex32 (GDI32.203)
310 UINT32
GetNearestPaletteIndex32( HPALETTE32 hpalette
, COLORREF color
)
312 PALETTEOBJ
* palObj
= (PALETTEOBJ
*)GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
316 index
= COLOR_PaletteLookupPixel( palObj
->logpalette
.palPalEntry
,
317 palObj
->logpalette
.palNumEntries
,
318 NULL
, color
, FALSE
);
320 dprintf_palette(stddeb
,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n",
321 hpalette
, color
, index
);
326 /***********************************************************************
327 * GetNearestColor16 (GDI.154)
329 COLORREF
GetNearestColor16( HDC16 hdc
, COLORREF color
)
331 return GetNearestColor32( hdc
, color
);
335 /***********************************************************************
336 * GetNearestColor32 (GDI32.202)
338 COLORREF
GetNearestColor32( HDC32 hdc
, COLORREF color
)
340 COLORREF nearest
= 0xFADECAFE;
344 if ( (dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
)) )
346 palObj
= (PALETTEOBJ
*)
347 GDI_GetObjPtr( (dc
->w
.hPalette
)? dc
->w
.hPalette
348 : STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
);
350 nearest
= COLOR_LookupNearestColor( palObj
->logpalette
.palPalEntry
,
351 palObj
->logpalette
.palNumEntries
, color
);
354 dprintf_palette(stddeb
,"GetNearestColor(%06lx): returning %06lx\n",
360 /***********************************************************************
363 int PALETTE_GetObject( PALETTEOBJ
* palette
, int count
, LPSTR buffer
)
365 if (count
> sizeof(WORD
)) count
= sizeof(WORD
);
366 memcpy( buffer
, &palette
->logpalette
.palNumEntries
, count
);
371 /***********************************************************************
372 * PALETTE_UnrealizeObject
374 BOOL32
PALETTE_UnrealizeObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
376 if (palette
->mapping
)
378 free( palette
->mapping
);
379 palette
->mapping
= NULL
;
381 if (hLastRealizedPalette
== hpalette
) hLastRealizedPalette
= 0;
386 /***********************************************************************
387 * PALETTE_DeleteObject
389 BOOL32
PALETTE_DeleteObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
391 free( palette
->mapping
);
392 return GDI_FreeObject( hpalette
);
396 /***********************************************************************
397 * GDISelectPalette (GDI.361)
399 HPALETTE16
GDISelectPalette( HDC16 hdc
, HPALETTE16 hpal
, WORD wBkg
)
404 dprintf_palette(stddeb
, "GDISelectPalette: %04x %04x\n", hdc
, hpal
);
406 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
409 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
412 prev
= dc
->w
.hPalette
;
413 dc
->w
.hPalette
= hpal
;
414 if (!wBkg
) hPrimaryPalette
= hpal
;
419 /***********************************************************************
420 * GDIRealizePalette (GDI.362)
422 UINT16
GDIRealizePalette( HDC16 hdc
)
426 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
429 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
433 dprintf_palette(stddeb
, "GDIRealizePalette: %04x...", hdc
);
435 if( dc
&& dc
->w
.hPalette
!= hLastRealizedPalette
)
437 if( dc
->w
.hPalette
== STOCK_DEFAULT_PALETTE
)
438 return RealizeDefaultPalette( hdc
);
440 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
);
442 realized
= COLOR_SetMapping(palPtr
, dc
->w
.hPalette
!= hPrimaryPalette
443 || dc
->w
.hPalette
== STOCK_DEFAULT_PALETTE
);
444 hLastRealizedPalette
= dc
->w
.hPalette
;
446 else dprintf_palette(stddeb
, " skipping ");
448 dprintf_palette(stdnimp
, " realized %i colors\n", realized
);
449 return (UINT16
)realized
;
453 /***********************************************************************
454 * RealizeDefaultPalette (GDI.365)
456 UINT16
RealizeDefaultPalette( HDC16 hdc
)
460 int i
, index
, realized
= 0;
462 dprintf_palette(stddeb
,"RealizeDefaultPalette: %04x\n", hdc
);
464 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
467 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
471 if ( dc
->w
.flags
& DC_MEMORY
) return 0;
473 hPrimaryPalette
= STOCK_DEFAULT_PALETTE
;
474 hLastRealizedPalette
= STOCK_DEFAULT_PALETTE
;
476 palPtr
= (PALETTEOBJ
*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
);
478 /* lookup is needed to account for SetSystemPaletteUse() stuff */
480 for( i
= 0; i
< 20; i
++ )
482 index
= COLOR_LookupSystemPixel(*(COLORREF
*)(palPtr
->logpalette
.palPalEntry
+ i
));
484 /* mapping is allocated in COLOR_InitPalette() */
486 if( index
!= palPtr
->mapping
[i
] ) { palPtr
->mapping
[i
]=index
; realized
++; }
491 /***********************************************************************
492 * IsDCCurrentPalette (GDI.412)
494 BOOL16
IsDCCurrentPalette(HDC16 hDC
)
496 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
497 return (dc
)?(dc
->w
.hPalette
== hPrimaryPalette
):FALSE
;
501 /***********************************************************************
502 * SelectPalette16 (USER.282)
504 HPALETTE16
SelectPalette16( HDC16 hDC
, HPALETTE16 hPal
,
505 BOOL16 bForceBackground
)
507 return SelectPalette32( hDC
, hPal
, bForceBackground
);
511 /***********************************************************************
512 * SelectPalette32 (GDI32.300)
514 HPALETTE32
SelectPalette32( HDC32 hDC
, HPALETTE32 hPal
,
515 BOOL32 bForceBackground
)
517 WORD wBkgPalette
= 1;
518 PALETTEOBJ
* lpt
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
520 dprintf_palette(stddeb
,"SelectPalette: dc %04x pal %04x, force=%i ",
521 hDC
, hPal
, bForceBackground
);
524 dprintf_palette(stddeb
," entries = %d\n",
525 lpt
->logpalette
.palNumEntries
);
527 if( hPal
!= STOCK_DEFAULT_PALETTE
)
529 HWND32 hWnd
= WindowFromDC32( hDC
);
530 HWND32 hActive
= GetActiveWindow32();
532 /* set primary palette if it's related to current active */
534 if((!hWnd
|| (hActive
== hWnd
|| IsChild16(hActive
,hWnd
))) &&
538 return GDISelectPalette( hDC
, hPal
, wBkgPalette
);
542 /***********************************************************************
543 * RealizePalette16 (USER.283)
545 UINT16
RealizePalette16( HDC16 hDC
)
547 return RealizePalette32( hDC
);
551 /***********************************************************************
552 * RealizePalette32 (GDI32.280)
554 UINT32
RealizePalette32( HDC32 hDC
)
556 UINT32 realized
= GDIRealizePalette( hDC
);
558 /* do not send anything if no colors were changed */
560 if( IsDCCurrentPalette( hDC
) && realized
&&
561 !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
563 /* Send palette change notification */
566 if( (hWnd
= WindowFromDC32( hDC
)) )
567 SendMessage16( HWND_BROADCAST
, WM_PALETTECHANGED
, hWnd
, 0L);
573 /**********************************************************************
574 * UpdateColors16 (GDI.366)
576 INT16
UpdateColors16( HDC16 hDC
)
578 HWND32 hWnd
= WindowFromDC32( hDC
);
580 /* Docs say that we have to remap current drawable pixel by pixel
581 * but it would take forever given the speed of XGet/PutPixel.
583 if (hWnd
&& !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
584 InvalidateRect32( hWnd
, NULL
, FALSE
);
589 /**********************************************************************
590 * UpdateColors32 (GDI32.359)
592 BOOL32
UpdateColors32( HDC32 hDC
)
594 UpdateColors16( hDC
);