Release 960928
[wine/multimedia.git] / objects / palette.c
blob1682d9155434417ed0acc1d25cd15461c598f96f
1 /*
2 * GDI palette objects
4 * Copyright 1993,1994 Alexandre Julliard
5 * Copyright 1996 Alex Korobka
7 */
8 #include <stdlib.h>
9 #include <string.h>
10 #include <X11/Xlib.h>
12 #include "color.h"
13 #include "palette.h"
14 #include "stddebug.h"
15 /* #define DEBUG_PALETTE */
16 #include "debug.h"
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)
33 int i = 0;
34 for( ; i<size ; i++ )
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;
45 HPALETTE16 hpalette;
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);
62 return hpalette;
66 /***********************************************************************
67 * GetPaletteEntries (GDI.363)
69 WORD GetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
70 LPPALETTEENTRY entries )
72 PALETTEOBJ * palPtr;
73 int numEntries;
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;
87 return count;
91 /***********************************************************************
92 * SetPaletteEntries (GDI.364)
94 WORD SetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
95 LPPALETTEENTRY entries )
97 PALETTEOBJ * palPtr;
98 int numEntries;
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;
115 return count;
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");
128 return FALSE;
131 /***********************************************************************
132 * AnimatePalette (GDI.367)
134 BOOL AnimatePalette(HPALETTE16 hPal, UINT StartIndex, UINT NumEntries,
135 LPPALETTEENTRY PaletteColors)
137 fprintf(stdnimp,"AnimatePalette: empty stub! \n");
138 return TRUE;
141 /***********************************************************************
142 * SetSystemPaletteUse (GDI.373)
144 WORD SetSystemPaletteUse( HDC hdc, WORD use)
146 WORD old=SystemPaletteUse;
147 fprintf(stdnimp,"SetSystemPaletteUse(%04x,%04x) // empty stub !!!\n", hdc, use);
148 SystemPaletteUse=use;
149 return old;
152 /***********************************************************************
153 * GetSystemPaletteUse (GDI.374)
155 WORD GetSystemPaletteUse( HDC hdc )
157 fprintf(stdnimp,"GetSystemPaletteUse(%04x) // empty stub !!!\n", hdc);
158 return SystemPaletteUse;
162 /***********************************************************************
163 * GetSystemPaletteEntries (GDI.375)
165 WORD GetSystemPaletteEntries( HDC hdc, WORD start, WORD count,
166 LPPALETTEENTRY entries )
168 WORD i;
169 DC *dc;
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) );
184 return count;
188 /***********************************************************************
189 * GetNearestPaletteIndex (GDI.370)
191 WORD GetNearestPaletteIndex( HPALETTE16 hpalette, COLORREF color )
193 PALETTEOBJ* palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
194 WORD index = 0;
196 if( palObj )
197 index = COLOR_PaletteLookupPixel( palObj->logpalette.palPalEntry,
198 palObj->logpalette.palNumEntries, NULL,
199 color, FALSE );
201 dprintf_palette(stddeb,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n",
202 hpalette, color, index );
203 return index;
207 /***********************************************************************
208 * GetNearestColor (GDI.154)
210 COLORREF GetNearestColor( HDC hdc, COLORREF color )
212 COLORREF nearest = 0xFADECAFE;
213 DC *dc;
214 PALETTEOBJ *palObj;
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",
227 color, nearest );
228 return nearest;
232 /***********************************************************************
233 * PALETTE_GetObject
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 );
239 return 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;
254 return TRUE;
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( HDC hdc, HPALETTE16 hpal, WORD wBkg)
273 HPALETTE16 prev;
274 DC *dc;
276 dprintf_palette(stddeb, "GDISelectPalette: %04x %04x\n", hdc, hpal );
278 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
279 if (!dc)
281 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
282 if (!dc) return 0;
284 prev = dc->w.hPalette;
285 dc->w.hPalette = hpal;
286 if (!wBkg) hPrimaryPalette = hpal;
287 return prev;
291 /***********************************************************************
292 * GDIRealizePalette (GDI.362)
295 UINT GDIRealizePalette( HDC hdc )
297 PALETTEOBJ* palPtr;
298 int realized = 0;
299 DC* dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
300 if (!dc)
302 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
303 if (!dc) return 0;
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( HDC hdc )
331 DC *dc;
332 PALETTEOBJ* palPtr;
333 int i, index, realized = 0;
335 dprintf_palette(stddeb,"RealizeDefaultPalette: %04x\n", hdc );
337 dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
338 if (!dc)
340 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
341 if (!dc) return 0;
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++; }
361 return realized;
364 /***********************************************************************
365 * IsDCCurrentPalette (GDI.412)
367 BOOL IsDCCurrentPalette(HDC 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( HDC 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);
383 if( !lpt ) return 0;
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))) &&
396 !bForceBackground )
397 wBkgPalette = 0;
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 */
417 HWND32 hWnd;
418 if( (hWnd = WindowFromDC32( hDC )) )
419 SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
421 return realized;
425 /**********************************************************************
426 * UpdateColors (GDI.366)
429 int UpdateColors( HDC 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 );
438 return 0x666;