4 * Copyright 1993,1994 Alexandre Julliard
5 * Copyright 1996 Alex Korobka
15 /* #define DEBUG_PALETTE */
18 extern int COLOR_LookupSystemPixel(COLORREF
); /* lookup pixel among static entries
19 * of the system palette */
20 extern COLORREF
COLOR_GetSystemPaletteEntry(BYTE
);
22 static WORD SystemPaletteUse
= SYSPAL_STATIC
; /* currently not considered */
24 static HPALETTE16 hPrimaryPalette
= 0; /* used for WM_PALETTECHANGED */
25 static HPALETTE16 hLastRealizedPalette
= 0; /* UnrealizeObject() needs it */
28 /***********************************************************************
29 * PALETTE_ValidateFlags
31 void PALETTE_ValidateFlags(PALETTEENTRY
* lpPalE
, int size
)
35 lpPalE
[i
].peFlags
= PC_SYS_USED
| (lpPalE
[i
].peFlags
& 0x07);
39 /***********************************************************************
40 * CreatePalette (GDI.360)
42 HPALETTE16
CreatePalette( const LOGPALETTE
* palette
)
44 PALETTEOBJ
* palettePtr
;
46 int size
= sizeof(LOGPALETTE
) + (palette
->palNumEntries
- 1) * sizeof(PALETTEENTRY
);
48 dprintf_palette(stddeb
,"CreatePalette: ");
50 dprintf_palette(stddeb
,"%i entries, ", palette
->palNumEntries
);
52 hpalette
= GDI_AllocObject( size
+ sizeof(int*) +sizeof(GDIOBJHDR
) , PALETTE_MAGIC
);
53 if (!hpalette
) return 0;
55 palettePtr
= (PALETTEOBJ
*) GDI_HEAP_LIN_ADDR( hpalette
);
56 memcpy( &palettePtr
->logpalette
, palette
, size
);
57 PALETTE_ValidateFlags(palettePtr
->logpalette
.palPalEntry
,
58 palettePtr
->logpalette
.palNumEntries
);
59 palettePtr
->mapping
= NULL
;
61 dprintf_palette(stddeb
,"returning %04x\n", hpalette
);
66 /***********************************************************************
67 * GetPaletteEntries (GDI.363)
69 WORD
GetPaletteEntries( HPALETTE16 hpalette
, WORD start
, WORD count
,
70 LPPALETTEENTRY entries
)
75 dprintf_palette(stddeb
,"GetPaletteEntries: hpal = %04x, %i entries\n", hpalette
, count
);
77 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
78 if (!palPtr
) return 0;
80 numEntries
= palPtr
->logpalette
.palNumEntries
;
81 if (start
>= numEntries
) return 0;
82 if (start
+count
> numEntries
) count
= numEntries
- start
;
83 memcpy( entries
, &palPtr
->logpalette
.palPalEntry
[start
],
84 count
* sizeof(PALETTEENTRY
) );
85 for( numEntries
= 0; numEntries
< count
; numEntries
++ )
86 if( entries
[numEntries
].peFlags
& 0xF0 ) entries
[numEntries
].peFlags
= 0;
91 /***********************************************************************
92 * SetPaletteEntries (GDI.364)
94 WORD
SetPaletteEntries( HPALETTE16 hpalette
, WORD start
, WORD count
,
95 LPPALETTEENTRY entries
)
100 dprintf_palette(stddeb
,"SetPaletteEntries: hpal = %04x, %i entries\n", hpalette
, count
);
102 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
103 if (!palPtr
) return 0;
105 numEntries
= palPtr
->logpalette
.palNumEntries
;
106 if (start
>= numEntries
) return 0;
107 if (start
+count
> numEntries
) count
= numEntries
- start
;
108 memcpy( &palPtr
->logpalette
.palPalEntry
[start
], entries
,
109 count
* sizeof(PALETTEENTRY
) );
110 PALETTE_ValidateFlags(palPtr
->logpalette
.palPalEntry
,
111 palPtr
->logpalette
.palNumEntries
);
112 free(palPtr
->mapping
);
113 palPtr
->mapping
= NULL
;
118 /***********************************************************************
119 * ResizePalette (GDI.368)
121 BOOL
ResizePalette(HPALETTE16 hPal
, UINT cEntries
)
124 /* should simply realloc memory and zero out
125 * added entries, if any */
127 fprintf(stdnimp
,"ResizePalette: empty stub! \n");
131 /***********************************************************************
132 * AnimatePalette (GDI.367)
134 BOOL
AnimatePalette(HPALETTE16 hPal
, UINT StartIndex
, UINT NumEntries
,
135 LPPALETTEENTRY PaletteColors
)
137 fprintf(stdnimp
,"AnimatePalette: empty stub! \n");
141 /***********************************************************************
142 * SetSystemPaletteUse (GDI.373)
144 WORD
SetSystemPaletteUse( HDC16 hdc
, WORD use
)
146 WORD old
=SystemPaletteUse
;
147 fprintf(stdnimp
,"SetSystemPaletteUse(%04x,%04x) // empty stub !!!\n", hdc
, use
);
148 SystemPaletteUse
=use
;
152 /***********************************************************************
153 * GetSystemPaletteUse (GDI.374)
155 WORD
GetSystemPaletteUse( HDC16 hdc
)
157 fprintf(stdnimp
,"GetSystemPaletteUse(%04x) // empty stub !!!\n", hdc
);
158 return SystemPaletteUse
;
162 /***********************************************************************
163 * GetSystemPaletteEntries (GDI.375)
165 WORD
GetSystemPaletteEntries( HDC16 hdc
, WORD start
, WORD count
,
166 LPPALETTEENTRY entries
)
171 dprintf_palette(stddeb
,"GetSystemPaletteEntries: hdc = %04x, cound = %i", hdc
, count
);
173 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
174 if (start
>= dc
->w
.devCaps
->sizePalette
) return 0;
175 if (start
+count
>= dc
->w
.devCaps
->sizePalette
)
176 count
= dc
->w
.devCaps
->sizePalette
- start
;
177 for (i
= 0; i
< count
; i
++)
179 *(COLORREF
*)(entries
+ i
) = COLOR_GetSystemPaletteEntry((BYTE
)(start
+ i
));
181 dprintf_palette(stddeb
,"\tidx(%02x) -> RGB(%08lx)\n", (unsigned char)(start
+ i
),
182 *(COLORREF
*)(entries
+ i
) );
188 /***********************************************************************
189 * GetNearestPaletteIndex (GDI.370)
191 WORD
GetNearestPaletteIndex( HPALETTE16 hpalette
, COLORREF color
)
193 PALETTEOBJ
* palObj
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
197 index
= COLOR_PaletteLookupPixel( palObj
->logpalette
.palPalEntry
,
198 palObj
->logpalette
.palNumEntries
, NULL
,
201 dprintf_palette(stddeb
,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n",
202 hpalette
, color
, index
);
207 /***********************************************************************
208 * GetNearestColor (GDI.154)
210 COLORREF
GetNearestColor( HDC16 hdc
, COLORREF color
)
212 COLORREF nearest
= 0xFADECAFE;
216 if ( (dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
)) )
218 palObj
= (PALETTEOBJ
*)
219 GDI_GetObjPtr( (dc
->w
.hPalette
)? dc
->w
.hPalette
220 : STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
);
222 nearest
= COLOR_LookupNearestColor( palObj
->logpalette
.palPalEntry
,
223 palObj
->logpalette
.palNumEntries
, color
);
226 dprintf_palette(stddeb
,"GetNearestColor(%06lx): returning %06lx\n",
232 /***********************************************************************
235 int PALETTE_GetObject( PALETTEOBJ
* palette
, int count
, LPSTR buffer
)
237 if (count
> sizeof(WORD
)) count
= sizeof(WORD
);
238 memcpy( buffer
, &palette
->logpalette
.palNumEntries
, count
);
243 /***********************************************************************
244 * PALETTE_UnrealizeObject
246 BOOL32
PALETTE_UnrealizeObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
248 if (palette
->mapping
)
250 free( palette
->mapping
);
251 palette
->mapping
= NULL
;
253 if (hLastRealizedPalette
== hpalette
) hLastRealizedPalette
= 0;
258 /***********************************************************************
259 * PALETTE_DeleteObject
261 BOOL32
PALETTE_DeleteObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
263 free( palette
->mapping
);
264 return GDI_FreeObject( hpalette
);
268 /***********************************************************************
269 * GDISelectPalette (GDI.361)
271 HPALETTE16
GDISelectPalette( HDC16 hdc
, HPALETTE16 hpal
, WORD wBkg
)
276 dprintf_palette(stddeb
, "GDISelectPalette: %04x %04x\n", hdc
, hpal
);
278 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
281 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
284 prev
= dc
->w
.hPalette
;
285 dc
->w
.hPalette
= hpal
;
286 if (!wBkg
) hPrimaryPalette
= hpal
;
291 /***********************************************************************
292 * GDIRealizePalette (GDI.362)
295 UINT
GDIRealizePalette( HDC16 hdc
)
299 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
302 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
306 dprintf_palette(stddeb
, "GDIRealizePalette: %04x...", hdc
);
308 if( dc
&& dc
->w
.hPalette
!= hLastRealizedPalette
)
310 if( dc
->w
.hPalette
== STOCK_DEFAULT_PALETTE
)
311 return RealizeDefaultPalette( hdc
);
313 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
);
315 realized
= COLOR_SetMapping(palPtr
, dc
->w
.hPalette
!= hPrimaryPalette
316 || dc
->w
.hPalette
== STOCK_DEFAULT_PALETTE
);
317 hLastRealizedPalette
= dc
->w
.hPalette
;
319 else dprintf_palette(stddeb
, " skipping ");
321 dprintf_palette(stdnimp
, " realized %i colors\n", realized
);
322 return (UINT
)realized
;
326 /***********************************************************************
327 * RealizeDefaultPalette (GDI.365)
329 WORD
RealizeDefaultPalette( HDC16 hdc
)
333 int i
, index
, realized
= 0;
335 dprintf_palette(stddeb
,"RealizeDefaultPalette: %04x\n", hdc
);
337 dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
340 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
344 if ( dc
->w
.flags
& DC_MEMORY
) return 0;
346 hPrimaryPalette
= STOCK_DEFAULT_PALETTE
;
347 hLastRealizedPalette
= STOCK_DEFAULT_PALETTE
;
349 palPtr
= (PALETTEOBJ
*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
);
351 /* lookup is needed to account for SetSystemPaletteUse() stuff */
353 for( i
= 0; i
< 20; i
++ )
355 index
= COLOR_LookupSystemPixel(*(COLORREF
*)(palPtr
->logpalette
.palPalEntry
+ i
));
357 /* mapping is allocated in COLOR_InitPalette() */
359 if( index
!= palPtr
->mapping
[i
] ) { palPtr
->mapping
[i
]=index
; realized
++; }
364 /***********************************************************************
365 * IsDCCurrentPalette (GDI.412)
367 BOOL
IsDCCurrentPalette(HDC16 hDC
)
369 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
370 return (dc
)?(dc
->w
.hPalette
== hPrimaryPalette
):FALSE
;
373 /***********************************************************************
374 * SelectPalette (USER.282)
376 HPALETTE16
SelectPalette( HDC16 hDC
, HPALETTE16 hPal
, BOOL bForceBackground
)
378 WORD wBkgPalette
= 1;
379 PALETTEOBJ
* lpt
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
381 dprintf_palette(stddeb
,"SelectPalette: dc %04x pal %04x, force=%i ",
382 hDC
, hPal
, bForceBackground
);
385 dprintf_palette(stddeb
," entries = %d\n",
386 lpt
->logpalette
.palNumEntries
);
388 if( hPal
!= STOCK_DEFAULT_PALETTE
)
390 HWND32 hWnd
= WindowFromDC32( hDC
);
391 HWND32 hActive
= GetActiveWindow();
393 /* set primary palette if it's related to current active */
395 if((!hWnd
|| (hActive
== hWnd
|| IsChild(hActive
,hWnd
))) &&
399 return GDISelectPalette( hDC
, hPal
, wBkgPalette
);
403 /***********************************************************************
404 * RealizePalette (USER.283) (GDI32.280)
406 UINT16
RealizePalette( HDC32 hDC
)
408 UINT16 realized
= GDIRealizePalette( hDC
);
410 /* do not send anything if no colors were changed */
412 if( IsDCCurrentPalette( hDC
) && realized
&&
413 !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
415 /* Send palette change notification */
418 if( (hWnd
= WindowFromDC32( hDC
)) )
419 SendMessage16( HWND_BROADCAST
, WM_PALETTECHANGED
, hWnd
, 0L);
425 /**********************************************************************
426 * UpdateColors (GDI.366)
429 int UpdateColors( HDC16 hDC
)
431 HWND32 hWnd
= WindowFromDC32( hDC
);
433 /* Docs say that we have to remap current drawable pixel by pixel
434 * but it would take forever given the speed of XGet/PutPixel.
436 if (hWnd
&& !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL
) )
437 InvalidateRect16( hWnd
, NULL
, FALSE
);