4 * Copyright 1993,1994 Alexandre Julliard
5 * Copyright 1996 Alex Korobka
17 /* #define DEBUG_PALETTE */
20 extern int COLOR_LookupSystemPixel(COLORREF
); /* lookup pixel among static entries
21 * of the system palette */
22 extern COLORREF
COLOR_GetSystemPaletteEntry(BYTE
);
24 static WORD 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 * CreatePalette (GDI.360)
44 HPALETTE16
CreatePalette( const LOGPALETTE
* palette
)
46 PALETTEOBJ
* palettePtr
;
48 int size
= sizeof(LOGPALETTE
) + (palette
->palNumEntries
- 1) * sizeof(PALETTEENTRY
);
50 dprintf_palette(stddeb
,"CreatePalette: ");
52 dprintf_palette(stddeb
,"%i entries, ", palette
->palNumEntries
);
54 hpalette
= GDI_AllocObject( size
+ sizeof(int*) +sizeof(GDIOBJHDR
) , PALETTE_MAGIC
);
55 if (!hpalette
) return 0;
57 palettePtr
= (PALETTEOBJ
*) GDI_HEAP_LIN_ADDR( hpalette
);
58 memcpy( &palettePtr
->logpalette
, palette
, size
);
59 PALETTE_ValidateFlags(palettePtr
->logpalette
.palPalEntry
,
60 palettePtr
->logpalette
.palNumEntries
);
61 palettePtr
->mapping
= NULL
;
63 dprintf_palette(stddeb
,"returning %04x\n", hpalette
);
68 /***********************************************************************
69 * GetPaletteEntries (GDI.363)
71 WORD
GetPaletteEntries( HPALETTE16 hpalette
, WORD start
, WORD count
,
72 LPPALETTEENTRY entries
)
77 dprintf_palette(stddeb
,"GetPaletteEntries: hpal = %04x, %i entries\n", hpalette
, count
);
79 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
80 if (!palPtr
) return 0;
82 numEntries
= palPtr
->logpalette
.palNumEntries
;
83 if (start
>= numEntries
) return 0;
84 if (start
+count
> numEntries
) count
= numEntries
- start
;
85 memcpy( entries
, &palPtr
->logpalette
.palPalEntry
[start
],
86 count
* sizeof(PALETTEENTRY
) );
87 for( numEntries
= 0; numEntries
< count
; numEntries
++ )
88 if( entries
[numEntries
].peFlags
& 0xF0 ) entries
[numEntries
].peFlags
= 0;
93 /***********************************************************************
94 * SetPaletteEntries (GDI.364)
96 WORD
SetPaletteEntries( HPALETTE16 hpalette
, WORD start
, WORD count
,
97 LPPALETTEENTRY entries
)
102 dprintf_palette(stddeb
,"SetPaletteEntries: hpal = %04x, %i entries\n", hpalette
, count
);
104 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
105 if (!palPtr
) return 0;
107 numEntries
= palPtr
->logpalette
.palNumEntries
;
108 if (start
>= numEntries
) return 0;
109 if (start
+count
> numEntries
) count
= numEntries
- start
;
110 memcpy( &palPtr
->logpalette
.palPalEntry
[start
], entries
,
111 count
* sizeof(PALETTEENTRY
) );
112 PALETTE_ValidateFlags(palPtr
->logpalette
.palPalEntry
,
113 palPtr
->logpalette
.palNumEntries
);
114 free(palPtr
->mapping
);
115 palPtr
->mapping
= NULL
;
120 /***********************************************************************
121 * ResizePalette (GDI.368)
123 BOOL
ResizePalette(HPALETTE16 hPal
, UINT cEntries
)
125 PALETTEOBJ
* palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
126 UINT cPrevEnt
, prevVer
;
127 int prevsize
, size
= sizeof(LOGPALETTE
) + (cEntries
- 1) * sizeof(PALETTEENTRY
);
130 dprintf_palette(stddeb
,"ResizePalette: hpal = %04x, prev = %i, new = %i\n",
131 hPal
, (palPtr
)? -1: palPtr
->logpalette
.palNumEntries
, cEntries
);
132 if( !palPtr
) return FALSE
;
133 cPrevEnt
= palPtr
->logpalette
.palNumEntries
;
134 prevVer
= palPtr
->logpalette
.palVersion
;
135 prevsize
= sizeof(LOGPALETTE
) + (cPrevEnt
- 1) * sizeof(PALETTEENTRY
) +
136 sizeof(int*) + sizeof(GDIOBJHDR
);
137 size
+= sizeof(int*) + sizeof(GDIOBJHDR
);
138 mapping
= palPtr
->mapping
;
140 GDI_HEAP_REALLOC( hPal
, size
);
141 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
142 if( !palPtr
) return FALSE
;
145 palPtr
->mapping
= (int*) xrealloc( mapping
, cEntries
* sizeof(int) );
146 if( cEntries
> cPrevEnt
)
149 memset(palPtr
->mapping
+ cPrevEnt
, 0, (cEntries
- cPrevEnt
)*sizeof(int));
150 memset( (BYTE
*)palPtr
+ prevsize
, 0, size
- prevsize
);
151 PALETTE_ValidateFlags((PALETTEENTRY
*)((BYTE
*)palPtr
+ prevsize
),
152 cEntries
- cPrevEnt
);
154 palPtr
->logpalette
.palNumEntries
= cEntries
;
155 palPtr
->logpalette
.palVersion
= prevVer
;
159 /***********************************************************************
160 * AnimatePalette (GDI.367)
162 BOOL
AnimatePalette(HPALETTE16 hPal
, UINT StartIndex
, UINT NumEntries
,
163 LPPALETTEENTRY PaletteColors
)
165 fprintf(stdnimp
,"AnimatePalette: empty stub! \n");
169 /***********************************************************************
170 * SetSystemPaletteUse (GDI.373)
172 WORD
SetSystemPaletteUse( HDC16 hdc
, WORD use
)
174 WORD old
=SystemPaletteUse
;
175 fprintf(stdnimp
,"SetSystemPaletteUse(%04x,%04x) // empty stub !!!\n", hdc
, use
);
176 SystemPaletteUse
=use
;
180 /***********************************************************************
181 * GetSystemPaletteUse (GDI.374)
183 WORD
GetSystemPaletteUse( HDC16 hdc
)
185 fprintf(stdnimp
,"GetSystemPaletteUse(%04x) // empty stub !!!\n", hdc
);
186 return SystemPaletteUse
;
190 /***********************************************************************
191 * GetSystemPaletteEntries (GDI.375)
193 WORD
GetSystemPaletteEntries( HDC16 hdc
, WORD start
, WORD count
,
194 LPPALETTEENTRY entries
)
199 dprintf_palette(stddeb
,"GetSystemPaletteEntries: hdc = %04x, cound = %i", hdc
, count
);
201 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
202 if (start
>= dc
->w
.devCaps
->sizePalette
) return 0;
203 if (start
+count
>= dc
->w
.devCaps
->sizePalette
)
204 count
= dc
->w
.devCaps
->sizePalette
- start
;
205 for (i
= 0; i
< count
; i
++)
207 *(COLORREF
*)(entries
+ i
) = COLOR_GetSystemPaletteEntry((BYTE
)(start
+ i
));
209 dprintf_palette(stddeb
,"\tidx(%02x) -> RGB(%08lx)\n", (unsigned char)(start
+ i
),
210 *(COLORREF
*)(entries
+ i
) );
216 /***********************************************************************
217 * GetNearestPaletteIndex (GDI.370)
219 WORD
GetNearestPaletteIndex( HPALETTE16 hpalette
, COLORREF color
)
221 PALETTEOBJ
* palObj
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
225 index
= COLOR_PaletteLookupPixel( palObj
->logpalette
.palPalEntry
,
226 palObj
->logpalette
.palNumEntries
, NULL
,
229 dprintf_palette(stddeb
,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n",
230 hpalette
, color
, index
);
235 /***********************************************************************
236 * GetNearestColor (GDI.154)
238 COLORREF
GetNearestColor( HDC16 hdc
, COLORREF color
)
240 COLORREF nearest
= 0xFADECAFE;
244 if ( (dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
)) )
246 palObj
= (PALETTEOBJ
*)
247 GDI_GetObjPtr( (dc
->w
.hPalette
)? dc
->w
.hPalette
248 : STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
);
250 nearest
= COLOR_LookupNearestColor( palObj
->logpalette
.palPalEntry
,
251 palObj
->logpalette
.palNumEntries
, color
);
254 dprintf_palette(stddeb
,"GetNearestColor(%06lx): returning %06lx\n",
260 /***********************************************************************
263 int PALETTE_GetObject( PALETTEOBJ
* palette
, int count
, LPSTR buffer
)
265 if (count
> sizeof(WORD
)) count
= sizeof(WORD
);
266 memcpy( buffer
, &palette
->logpalette
.palNumEntries
, count
);
271 /***********************************************************************
272 * PALETTE_UnrealizeObject
274 BOOL32
PALETTE_UnrealizeObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
276 if (palette
->mapping
)
278 free( palette
->mapping
);
279 palette
->mapping
= NULL
;
281 if (hLastRealizedPalette
== hpalette
) hLastRealizedPalette
= 0;
286 /***********************************************************************
287 * PALETTE_DeleteObject
289 BOOL32
PALETTE_DeleteObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
291 free( palette
->mapping
);
292 return GDI_FreeObject( hpalette
);
296 /***********************************************************************
297 * GDISelectPalette (GDI.361)
299 HPALETTE16
GDISelectPalette( HDC16 hdc
, HPALETTE16 hpal
, WORD wBkg
)
304 dprintf_palette(stddeb
, "GDISelectPalette: %04x %04x\n", hdc
, hpal
);
306 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
309 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
312 prev
= dc
->w
.hPalette
;
313 dc
->w
.hPalette
= hpal
;
314 if (!wBkg
) hPrimaryPalette
= hpal
;
319 /***********************************************************************
320 * GDIRealizePalette (GDI.362)
323 UINT
GDIRealizePalette( HDC16 hdc
)
327 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
330 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
334 dprintf_palette(stddeb
, "GDIRealizePalette: %04x...", hdc
);
336 if( dc
&& dc
->w
.hPalette
!= hLastRealizedPalette
)
338 if( dc
->w
.hPalette
== STOCK_DEFAULT_PALETTE
)
339 return RealizeDefaultPalette( hdc
);
341 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
);
343 realized
= COLOR_SetMapping(palPtr
, dc
->w
.hPalette
!= hPrimaryPalette
344 || dc
->w
.hPalette
== STOCK_DEFAULT_PALETTE
);
345 hLastRealizedPalette
= dc
->w
.hPalette
;
347 else dprintf_palette(stddeb
, " skipping ");
349 dprintf_palette(stdnimp
, " realized %i colors\n", realized
);
350 return (UINT
)realized
;
354 /***********************************************************************
355 * RealizeDefaultPalette (GDI.365)
357 WORD
RealizeDefaultPalette( HDC16 hdc
)
361 int i
, index
, realized
= 0;
363 dprintf_palette(stddeb
,"RealizeDefaultPalette: %04x\n", hdc
);
365 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
368 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
372 if ( dc
->w
.flags
& DC_MEMORY
) return 0;
374 hPrimaryPalette
= STOCK_DEFAULT_PALETTE
;
375 hLastRealizedPalette
= STOCK_DEFAULT_PALETTE
;
377 palPtr
= (PALETTEOBJ
*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
);
379 /* lookup is needed to account for SetSystemPaletteUse() stuff */
381 for( i
= 0; i
< 20; i
++ )
383 index
= COLOR_LookupSystemPixel(*(COLORREF
*)(palPtr
->logpalette
.palPalEntry
+ i
));
385 /* mapping is allocated in COLOR_InitPalette() */
387 if( index
!= palPtr
->mapping
[i
] ) { palPtr
->mapping
[i
]=index
; realized
++; }
392 /***********************************************************************
393 * IsDCCurrentPalette (GDI.412)
395 BOOL
IsDCCurrentPalette(HDC16 hDC
)
397 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
398 return (dc
)?(dc
->w
.hPalette
== hPrimaryPalette
):FALSE
;
401 /***********************************************************************
402 * SelectPalette (USER.282)
404 HPALETTE16
SelectPalette( HDC16 hDC
, HPALETTE16 hPal
, BOOL bForceBackground
)
406 WORD wBkgPalette
= 1;
407 PALETTEOBJ
* lpt
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
409 dprintf_palette(stddeb
,"SelectPalette: dc %04x pal %04x, force=%i ",
410 hDC
, hPal
, bForceBackground
);
413 dprintf_palette(stddeb
," entries = %d\n",
414 lpt
->logpalette
.palNumEntries
);
416 if( hPal
!= STOCK_DEFAULT_PALETTE
)
418 HWND32 hWnd
= WindowFromDC32( hDC
);
419 HWND32 hActive
= GetActiveWindow();
421 /* set primary palette if it's related to current active */
423 if((!hWnd
|| (hActive
== hWnd
|| IsChild(hActive
,hWnd
))) &&
427 return GDISelectPalette( hDC
, hPal
, wBkgPalette
);
431 /***********************************************************************
432 * RealizePalette (USER.283) (GDI32.280)
434 UINT16
RealizePalette( HDC32 hDC
)
436 UINT16 realized
= GDIRealizePalette( hDC
);
438 /* do not send anything if no colors were changed */
440 if( IsDCCurrentPalette( hDC
) && realized
&&
441 !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
443 /* Send palette change notification */
446 if( (hWnd
= WindowFromDC32( hDC
)) )
447 SendMessage16( HWND_BROADCAST
, WM_PALETTECHANGED
, hWnd
, 0L);
453 /**********************************************************************
454 * UpdateColors (GDI.366)
457 int UpdateColors( HDC16 hDC
)
459 HWND32 hWnd
= WindowFromDC32( hDC
);
461 /* Docs say that we have to remap current drawable pixel by pixel
462 * but it would take forever given the speed of XGet/PutPixel.
464 if (hWnd
&& !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
465 InvalidateRect16( hWnd
, NULL
, FALSE
);