4 * Copyright 1993,1994 Alexandre Julliard
5 * Copyright 1996 Alex Korobka
15 /* #define DEBUG_PALETTE */
18 extern HWND
DCE_hDC2hWnd( HDC
); /* get associated window by
21 static WORD SystemPaletteUse
= SYSPAL_STATIC
; /* currently not considered */
23 static HPALETTE16 hPrimaryPalette
= 0; /* used for WM_PALETTECHANGED */
24 static HPALETTE16 hLastRealizedPalette
= 0; /* UnrealizeObject() needs it */
27 /***********************************************************************
28 * PALETTE_GetNearestIndexAndColor
30 static WORD
PALETTE_GetNearestIndexAndColor( HPALETTE16 hpalette
,
39 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
40 if (!palPtr
) return 0;
42 if ( hpalette
== STOCK_DEFAULT_PALETTE
)
44 if ((*color
& 0xffffff) == 0) return 0; /* Entry 0 is black */
45 if ((*color
& 0xffffff) == 0xffffff) /* Max entry is white */
46 return palPtr
->logpalette
.palNumEntries
- 1;
49 r
= GetRValue(*color
);
50 g
= GetGValue(*color
);
51 b
= GetBValue(*color
);
53 entry
= palPtr
->logpalette
.palPalEntry
;
54 for (i
= 0, minDist
= 0xffffff; minDist
!=0 &&
55 i
< palPtr
->logpalette
.palNumEntries
; i
++)
57 if (entry
->peFlags
!= 0xff)
59 dist
= (r
- entry
->peRed
) * (r
- entry
->peRed
) +
60 (g
- entry
->peGreen
) * (g
- entry
->peGreen
) +
61 (b
- entry
->peBlue
) * (b
- entry
->peBlue
);
71 entry
= &palPtr
->logpalette
.palPalEntry
[index
];
72 *color
= RGB( entry
->peRed
, entry
->peGreen
, entry
->peBlue
);
77 /***********************************************************************
78 * PALETTE_ValidateFlags
80 void PALETTE_ValidateFlags(PALETTEENTRY
* lpPalE
, int size
)
84 lpPalE
[i
].peFlags
= PC_SYS_USED
| (lpPalE
[i
].peFlags
& 0x07);
88 /***********************************************************************
89 * CreatePalette (GDI.360)
91 HPALETTE16
CreatePalette( const LOGPALETTE
* palette
)
93 PALETTEOBJ
* palettePtr
;
95 int size
= sizeof(LOGPALETTE
) + (palette
->palNumEntries
- 1) * sizeof(PALETTEENTRY
);
97 dprintf_palette(stddeb
,"CreatePalette: ");
99 dprintf_palette(stddeb
,"%i entries, ", palette
->palNumEntries
);
101 hpalette
= GDI_AllocObject( size
+ sizeof(int*) +sizeof(GDIOBJHDR
) , PALETTE_MAGIC
);
102 if (!hpalette
) return 0;
104 palettePtr
= (PALETTEOBJ
*) GDI_HEAP_LIN_ADDR( hpalette
);
105 memcpy( &palettePtr
->logpalette
, palette
, size
);
106 PALETTE_ValidateFlags(palettePtr
->logpalette
.palPalEntry
,
107 palettePtr
->logpalette
.palNumEntries
);
108 palettePtr
->mapping
= NULL
;
110 dprintf_palette(stddeb
,"returning %04x\n", hpalette
);
115 /***********************************************************************
116 * GetPaletteEntries (GDI.363)
118 WORD
GetPaletteEntries( HPALETTE16 hpalette
, WORD start
, WORD count
,
119 LPPALETTEENTRY entries
)
124 dprintf_palette(stddeb
,"GetPaletteEntries: hpal = %04x, %i entries\n", hpalette
, count
);
126 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
127 if (!palPtr
) return 0;
129 numEntries
= palPtr
->logpalette
.palNumEntries
;
130 if (start
>= numEntries
) return 0;
131 if (start
+count
> numEntries
) count
= numEntries
- start
;
132 memcpy( entries
, &palPtr
->logpalette
.palPalEntry
[start
],
133 count
* sizeof(PALETTEENTRY
) );
134 for( numEntries
= 0; numEntries
< count
; numEntries
++ )
135 if( entries
[numEntries
].peFlags
& 0xF0 ) entries
[numEntries
].peFlags
= 0;
140 /***********************************************************************
141 * SetPaletteEntries (GDI.364)
143 WORD
SetPaletteEntries( HPALETTE16 hpalette
, WORD start
, WORD count
,
144 LPPALETTEENTRY entries
)
149 dprintf_palette(stddeb
,"SetPaletteEntries: hpal = %04x, %i entries\n", hpalette
, count
);
151 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( hpalette
, PALETTE_MAGIC
);
152 if (!palPtr
) return 0;
154 numEntries
= palPtr
->logpalette
.palNumEntries
;
155 if (start
>= numEntries
) return 0;
156 if (start
+count
> numEntries
) count
= numEntries
- start
;
157 memcpy( &palPtr
->logpalette
.palPalEntry
[start
], entries
,
158 count
* sizeof(PALETTEENTRY
) );
159 PALETTE_ValidateFlags(palPtr
->logpalette
.palPalEntry
,
160 palPtr
->logpalette
.palNumEntries
);
164 /***********************************************************************
165 * ResizePalette (GDI.368)
167 BOOL
ResizePalette(HPALETTE16 hPal
, UINT cEntries
)
170 /* should simply realloc memory and zero out
171 * added entries, if any */
173 fprintf(stdnimp
,"ResizePalette: empty stub! \n");
177 /***********************************************************************
178 * AnimatePalette (GDI.367)
180 BOOL
AnimatePalette(HPALETTE16 hPal
, UINT StartIndex
, UINT NumEntries
,
181 LPPALETTEENTRY PaletteColors
)
183 fprintf(stdnimp
,"AnimatePalette: empty stub! \n");
187 /***********************************************************************
188 * SetSystemPaletteUse (GDI.373)
190 WORD
SetSystemPaletteUse( HDC hdc
, WORD use
)
192 WORD old
=SystemPaletteUse
;
193 fprintf(stdnimp
,"SetSystemPaletteUse(%04x,%04x) // empty stub !!!\n", hdc
, use
);
194 SystemPaletteUse
=use
;
198 /***********************************************************************
199 * GetSystemPaletteUse (GDI.374)
201 WORD
GetSystemPaletteUse( HDC hdc
)
203 fprintf(stdnimp
,"GetSystemPaletteUse(%04x) // empty stub !!!\n", hdc
);
204 return SystemPaletteUse
;
208 /***********************************************************************
209 * GetSystemPaletteEntries (GDI.375)
211 WORD
GetSystemPaletteEntries( HDC hdc
, WORD start
, WORD count
,
212 LPPALETTEENTRY entries
)
218 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
219 if (start
>= dc
->w
.devCaps
->sizePalette
) return 0;
220 if (start
+count
>= dc
->w
.devCaps
->sizePalette
)
221 count
= dc
->w
.devCaps
->sizePalette
- start
;
222 for (i
= 0; i
< count
; i
++)
224 color
.pixel
= (COLOR_PaletteToPixel
)
225 ? COLOR_PaletteToPixel
[start
+ i
]
227 XQueryColor( display
, COLOR_GetColormap(), &color
);
228 entries
[i
].peRed
= color
.red
>> 8;
229 entries
[i
].peGreen
= color
.green
>> 8;
230 entries
[i
].peBlue
= color
.blue
>> 8;
231 entries
[i
].peFlags
= 0;
237 /***********************************************************************
238 * GetNearestPaletteIndex (GDI.370)
240 WORD
GetNearestPaletteIndex( HPALETTE16 hpalette
, COLORREF color
)
242 WORD index
= PALETTE_GetNearestIndexAndColor( hpalette
, &color
);
243 dprintf_palette(stddeb
,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n",
244 hpalette
, color
, index
);
249 /***********************************************************************
250 * GetNearestColor (GDI.154)
252 COLORREF
GetNearestColor( HDC hdc
, COLORREF color
)
254 COLORREF nearest
= color
;
257 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
258 PALETTE_GetNearestIndexAndColor( dc
->w
.hPalette
, &nearest
);
259 dprintf_palette(stddeb
,"GetNearestColor(%06lx): returning %06lx\n",
265 /***********************************************************************
268 int PALETTE_GetObject( PALETTEOBJ
* palette
, int count
, LPSTR buffer
)
270 if (count
> sizeof(WORD
)) count
= sizeof(WORD
);
271 memcpy( buffer
, &palette
->logpalette
.palNumEntries
, count
);
276 /***********************************************************************
277 * PALETTE_UnrealizeObject
279 BOOL
PALETTE_UnrealizeObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
281 if (palette
->mapping
)
283 free( palette
->mapping
);
284 palette
->mapping
= NULL
;
286 if (hLastRealizedPalette
== hpalette
) hLastRealizedPalette
= 0;
291 /***********************************************************************
292 * PALETTE_DeleteObject
294 BOOL
PALETTE_DeleteObject( HPALETTE16 hpalette
, PALETTEOBJ
*palette
)
296 free( palette
->mapping
);
297 return GDI_FreeObject( hpalette
);
301 /***********************************************************************
302 * GDISelectPalette (GDI.361)
304 HPALETTE16
GDISelectPalette( HDC hdc
, HPALETTE16 hpal
, WORD wBkg
)
309 dprintf_palette(stddeb
, "GDISelectPalette: %04x %04x\n", hdc
, hpal
);
310 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
311 prev
= dc
->w
.hPalette
;
312 dc
->w
.hPalette
= hpal
;
313 if (!wBkg
) hPrimaryPalette
= hpal
;
318 /***********************************************************************
319 * GDIRealizePalette (GDI.362)
322 UINT
GDIRealizePalette( HDC hdc
)
324 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
) ;
328 dprintf_palette(stddeb
, "GDIRealizePalette: %04x...", hdc
);
330 if( dc
&& dc
->w
.hPalette
!= hLastRealizedPalette
)
332 palPtr
= (PALETTEOBJ
*) GDI_GetObjPtr( dc
->w
.hPalette
, PALETTE_MAGIC
);
334 realized
= COLOR_SetMapping(palPtr
, dc
->w
.hPalette
!= hPrimaryPalette
335 || dc
->w
.hPalette
== STOCK_DEFAULT_PALETTE
);
336 hLastRealizedPalette
= dc
->w
.hPalette
;
338 else dprintf_palette(stddeb
, " skipping ");
340 dprintf_palette(stdnimp
, " realized %i colors\n", realized
);
341 return (UINT
)realized
;
345 /***********************************************************************
346 * RealizeDefaultPalette (GDI.365)
348 WORD
RealizeDefaultPalette( HDC hdc
)
352 dprintf_palette(stddeb
,"RealizeDefaultPalette: %04x\n", hdc
);
354 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
355 if ( dc
->w
.flags
& DC_MEMORY
) return 0;
357 hPrimaryPalette
= STOCK_DEFAULT_PALETTE
;
358 hLastRealizedPalette
= STOCK_DEFAULT_PALETTE
;
359 return COLOR_SetMapping( (PALETTEOBJ
*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE
, PALETTE_MAGIC
), TRUE
);
363 /***********************************************************************
364 * IsDCCurrentPalette (GDI.412)
366 BOOL
IsDCCurrentPalette(HDC hDC
)
368 DC
* dc
= (DC
*)GDI_GetObjPtr( hDC
, DC_MAGIC
);
369 return (dc
->w
.hPalette
== hPrimaryPalette
);
372 /***********************************************************************
373 * SelectPalette (USER.282)
375 HPALETTE16
SelectPalette( HDC hDC
, HPALETTE16 hPal
, BOOL bForceBackground
)
377 WORD wBkgPalette
= 1;
378 PALETTEOBJ
* lpt
= (PALETTEOBJ
*) GDI_GetObjPtr( hPal
, PALETTE_MAGIC
);
380 dprintf_palette(stddeb
,"SelectPalette: dc %04x pal %04x, force=%i ",
381 hDC
, hPal
, bForceBackground
);
384 dprintf_palette(stddeb
," entries = %d\n",
385 lpt
->logpalette
.palNumEntries
);
387 if( hPal
!= STOCK_DEFAULT_PALETTE
)
389 HWND hWnd
= DCE_hDC2hWnd( hDC
);
390 HWND hActive
= GetActiveWindow();
392 /* set primary palette if it's related to current active */
394 if( hWnd
&& (hActive
== hWnd
|| IsChild(hActive
,hWnd
)) &&
398 return GDISelectPalette( hDC
, hPal
, wBkgPalette
);
402 /***********************************************************************
403 * RealizePalette (USER.283) (GDI32.280)
405 UINT16
RealizePalette( HDC32 hDC
)
407 UINT16 realized
= GDIRealizePalette( hDC
);
409 /* do not send anything if no colors were changed */
411 if( IsDCCurrentPalette( hDC
) && realized
)
413 /* Send palette change notification */
416 if( (hWnd
= DCE_hDC2hWnd( hDC
)) )
417 SendMessage16( HWND_BROADCAST
, WM_PALETTECHANGED
, hWnd
, 0L);
423 /**********************************************************************
424 * UpdateColors (GDI.366)
427 int UpdateColors( HDC hDC
)
429 HWND hWnd
= DCE_hDC2hWnd( hDC
);
431 /* Docs say that we have to remap current drawable pixel by pixel
432 * but it would take forever given the speed of XGet/PutPixel.
434 if (hWnd
) InvalidateRect16( hWnd
, NULL
, FALSE
);