Release 960717
[wine/multimedia.git] / objects / palette.c
blobc287be84b77c74122d9ef0e6105702b472c5a832
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 HWND DCE_hDC2hWnd( HDC ); /* get associated window by
19 * walking DCE list */
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,
31 COLORREF *color)
33 int i, minDist, dist;
34 WORD index = 0;
35 BYTE r, g, b;
36 PALETTEENTRY * entry;
37 PALETTEOBJ * palPtr;
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);
62 if (dist < minDist)
64 minDist = dist;
65 index = i;
68 entry++;
71 entry = &palPtr->logpalette.palPalEntry[index];
72 *color = RGB( entry->peRed, entry->peGreen, entry->peBlue );
73 return index;
77 /***********************************************************************
78 * PALETTE_ValidateFlags
80 void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
82 int i = 0;
83 for( ; i<size ; i++ )
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;
94 HPALETTE16 hpalette;
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);
111 return hpalette;
115 /***********************************************************************
116 * GetPaletteEntries (GDI.363)
118 WORD GetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
119 LPPALETTEENTRY entries )
121 PALETTEOBJ * palPtr;
122 int numEntries;
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;
136 return count;
140 /***********************************************************************
141 * SetPaletteEntries (GDI.364)
143 WORD SetPaletteEntries( HPALETTE16 hpalette, WORD start, WORD count,
144 LPPALETTEENTRY entries )
146 PALETTEOBJ * palPtr;
147 int numEntries;
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);
161 return count;
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");
174 return FALSE;
177 /***********************************************************************
178 * AnimatePalette (GDI.367)
180 BOOL AnimatePalette(HPALETTE16 hPal, UINT StartIndex, UINT NumEntries,
181 LPPALETTEENTRY PaletteColors)
183 fprintf(stdnimp,"AnimatePalette: empty stub! \n");
184 return TRUE;
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;
195 return old;
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 )
214 WORD i;
215 DC *dc;
216 XColor color;
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]
226 : 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;
233 return count;
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 );
245 return index;
249 /***********************************************************************
250 * GetNearestColor (GDI.154)
252 COLORREF GetNearestColor( HDC hdc, COLORREF color )
254 COLORREF nearest = color;
255 DC *dc;
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",
260 color, nearest );
261 return nearest;
265 /***********************************************************************
266 * PALETTE_GetObject
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 );
272 return 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;
287 return TRUE;
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)
306 HPALETTE16 prev;
307 DC *dc;
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;
314 return prev;
318 /***********************************************************************
319 * GDIRealizePalette (GDI.362)
322 UINT GDIRealizePalette( HDC hdc )
324 DC* dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ) ;
325 PALETTEOBJ* palPtr;
326 int realized = 0;
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 )
350 DC *dc;
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);
382 if( !lpt ) return 0;
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)) &&
395 !bForceBackground )
396 wBkgPalette = 0;
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 */
415 HWND hWnd;
416 if( (hWnd = DCE_hDC2hWnd( hDC )) )
417 SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
419 return realized;
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 );
435 return 0x666;