Commit | Line | Data |
---|---|---|
401710d7 AJ |
1 | /* |
2 | * GDI palette objects | |
3 | * | |
8d24ae6d | 4 | * Copyright 1993,1994 Alexandre Julliard |
18f92e76 | 5 | * Copyright 1996 Alex Korobka |
234bc24d | 6 | * |
23946ad2 AJ |
7 | * PALETTEOBJ is documented in the Dr. Dobbs Journal May 1993. |
8 | * Information in the "Undocumented Windows" is incorrect. | |
59730ae1 | 9 | */ |
f0cbfa0c | 10 | |
401710d7 | 11 | #include <stdlib.h> |
8d24ae6d | 12 | #include <string.h> |
b87fe2e9 | 13 | |
92ae219e | 14 | #include "winbase.h" |
d3e22d9d JW |
15 | #include "windef.h" |
16 | #include "wingdi.h" | |
92ae219e | 17 | #include "wine/winuser16.h" |
75d86e1f | 18 | #include "gdi.h" |
234bc24d | 19 | #include "color.h" |
7cbe6572 | 20 | #include "palette.h" |
15657090 | 21 | #include "debugtools.h" |
31b47218 | 22 | #include "winerror.h" |
401710d7 | 23 | |
39932167 | 24 | DEFAULT_DEBUG_CHANNEL(palette); |
b4b9fae6 | 25 | |
b87fe2e9 PS |
26 | PALETTE_DRIVER *PALETTE_Driver = NULL; |
27 | ||
39932167 AJ |
28 | /* Pointers to USER implementation of SelectPalette/RealizePalette */ |
29 | /* they will be patched by USER on startup */ | |
a3960292 AJ |
30 | FARPROC pfnSelectPalette = NULL; |
31 | FARPROC pfnRealizePalette = NULL; | |
d30dfd24 | 32 | |
a3960292 | 33 | static UINT SystemPaletteUse = SYSPAL_STATIC; /* currently not considered */ |
a2f2e019 | 34 | |
18f92e76 AJ |
35 | static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */ |
36 | static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */ | |
37 | ||
902da699 | 38 | |
23946ad2 AJ |
39 | /*********************************************************************** |
40 | * PALETTE_Init | |
41 | * | |
42 | * Create the system palette. | |
43 | */ | |
44 | HPALETTE16 PALETTE_Init(void) | |
45 | { | |
23946ad2 AJ |
46 | int i; |
47 | HPALETTE16 hpalette; | |
48 | LOGPALETTE * palPtr; | |
49 | PALETTEOBJ* palObj; | |
50 | const PALETTEENTRY* __sysPalTemplate = COLOR_GetSystemPaletteTemplate(); | |
51 | ||
52 | /* create default palette (20 system colors) */ | |
53 | ||
491502b9 AJ |
54 | palPtr = HeapAlloc( GetProcessHeap(), 0, |
55 | sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY)); | |
23946ad2 AJ |
56 | if (!palPtr) return FALSE; |
57 | ||
58 | palPtr->palVersion = 0x300; | |
59 | palPtr->palNumEntries = NB_RESERVED_COLORS; | |
60 | for( i = 0; i < NB_RESERVED_COLORS; i ++ ) | |
61 | { | |
62 | palPtr->palPalEntry[i].peRed = __sysPalTemplate[i].peRed; | |
63 | palPtr->palPalEntry[i].peGreen = __sysPalTemplate[i].peGreen; | |
64 | palPtr->palPalEntry[i].peBlue = __sysPalTemplate[i].peBlue; | |
65 | palPtr->palPalEntry[i].peFlags = 0; | |
66 | } | |
67 | hpalette = CreatePalette16( palPtr ); | |
9ad96367 | 68 | HeapFree( GetProcessHeap(), 0, palPtr ); |
23946ad2 AJ |
69 | |
70 | palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC ); | |
58b2f0a0 JS |
71 | if (palObj) |
72 | { | |
9ad96367 | 73 | if (!(palObj->mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(int) * 20 ))) |
e76218dd | 74 | ERR("Can not create palette mapping -- out of memory!\n"); |
2a2321bb | 75 | GDI_ReleaseObj( hpalette ); |
58b2f0a0 | 76 | } |
23946ad2 AJ |
77 | return hpalette; |
78 | } | |
79 | ||
18f92e76 AJ |
80 | /*********************************************************************** |
81 | * PALETTE_ValidateFlags | |
82 | */ | |
83 | void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size) | |
84 | { | |
85 | int i = 0; | |
86 | for( ; i<size ; i++ ) | |
87 | lpPalE[i].peFlags = PC_SYS_USED | (lpPalE[i].peFlags & 0x07); | |
88 | } | |
89 | ||
90 | ||
401710d7 | 91 | /*********************************************************************** |
17fd4e38 | 92 | * CreatePalette (GDI.360) |
f0cbfa0c | 93 | */ |
670cdc45 | 94 | HPALETTE16 WINAPI CreatePalette16( const LOGPALETTE* palette ) |
f0cbfa0c | 95 | { |
a3960292 | 96 | return CreatePalette( palette ); |
f0cbfa0c AJ |
97 | } |
98 | ||
99 | ||
100 | /*********************************************************************** | |
d0a41774 | 101 | * CreatePalette [GDI32.@] Creates a logical color palette |
c7c217b3 AJ |
102 | * |
103 | * RETURNS | |
104 | * Success: Handle to logical palette | |
105 | * Failure: NULL | |
401710d7 | 106 | */ |
a3960292 | 107 | HPALETTE WINAPI CreatePalette( |
c7c217b3 | 108 | const LOGPALETTE* palette) /* [in] Pointer to logical color palette */ |
401710d7 AJ |
109 | { |
110 | PALETTEOBJ * palettePtr; | |
a3960292 | 111 | HPALETTE hpalette; |
c509615f JS |
112 | int size; |
113 | ||
114 | if (!palette) return 0; | |
15657090 | 115 | TRACE("entries=%i\n", palette->palNumEntries); |
18f92e76 | 116 | |
c509615f JS |
117 | size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY); |
118 | ||
2a2321bb AJ |
119 | if (!(palettePtr = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR), |
120 | PALETTE_MAGIC, &hpalette ))) return 0; | |
401710d7 | 121 | memcpy( &palettePtr->logpalette, palette, size ); |
18f92e76 AJ |
122 | PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry, |
123 | palettePtr->logpalette.palNumEntries); | |
124 | palettePtr->mapping = NULL; | |
2a2321bb | 125 | GDI_ReleaseObj( hpalette ); |
18f92e76 | 126 | |
15657090 | 127 | TRACE(" returning %04x\n", hpalette); |
401710d7 AJ |
128 | return hpalette; |
129 | } | |
130 | ||
c7c217b3 | 131 | |
44ed71f5 | 132 | /*********************************************************************** |
17fd4e38 | 133 | * CreateHalftonePalette [GDI.529] Creates a halftone palette |
c7c217b3 AJ |
134 | * |
135 | * RETURNS | |
136 | * Success: Handle to logical halftone palette | |
137 | * Failure: 0 | |
44ed71f5 | 138 | */ |
0bdff36d BP |
139 | HPALETTE16 WINAPI CreateHalftonePalette16( |
140 | HDC16 hdc) /* [in] Handle to device context */ | |
141 | { | |
a3960292 | 142 | return CreateHalftonePalette(hdc); |
b87fe2e9 | 143 | } |
0bdff36d | 144 | |
58b2f0a0 | 145 | |
0bdff36d | 146 | /*********************************************************************** |
d0a41774 | 147 | * CreateHalftonePalette [GDI32.@] Creates a halftone palette |
0bdff36d BP |
148 | * |
149 | * RETURNS | |
150 | * Success: Handle to logical halftone palette | |
151 | * Failure: 0 | |
152 | * | |
153 | * FIXME: not truly tested | |
154 | */ | |
a3960292 AJ |
155 | HPALETTE WINAPI CreateHalftonePalette( |
156 | HDC hdc) /* [in] Handle to device context */ | |
0bdff36d BP |
157 | { |
158 | int i, r, g, b; | |
159 | struct { | |
160 | WORD Version; | |
161 | WORD NumberOfEntries; | |
162 | PALETTEENTRY aEntries[256]; | |
f87b96e7 | 163 | } Palette; |
0bdff36d | 164 | |
f87b96e7 PS |
165 | Palette.Version = 0x300; |
166 | Palette.NumberOfEntries = 256; | |
a3960292 | 167 | GetSystemPaletteEntries(hdc, 0, 256, Palette.aEntries); |
0bdff36d BP |
168 | |
169 | for (r = 0; r < 6; r++) { | |
170 | for (g = 0; g < 6; g++) { | |
171 | for (b = 0; b < 6; b++) { | |
172 | i = r + g*6 + b*36 + 10; | |
173 | Palette.aEntries[i].peRed = r * 51; | |
174 | Palette.aEntries[i].peGreen = g * 51; | |
175 | Palette.aEntries[i].peBlue = b * 51; | |
58b2f0a0 JS |
176 | } |
177 | } | |
178 | } | |
58b2f0a0 | 179 | |
0bdff36d BP |
180 | for (i = 216; i < 246; i++) { |
181 | int v = (i - 216) * 8; | |
182 | Palette.aEntries[i].peRed = v; | |
183 | Palette.aEntries[i].peGreen = v; | |
184 | Palette.aEntries[i].peBlue = v; | |
58b2f0a0 JS |
185 | } |
186 | ||
a3960292 | 187 | return CreatePalette((LOGPALETTE *)&Palette); |
44ed71f5 | 188 | } |
401710d7 | 189 | |
c7c217b3 | 190 | |
401710d7 | 191 | /*********************************************************************** |
17fd4e38 | 192 | * GetPaletteEntries (GDI.363) |
f0cbfa0c | 193 | */ |
670cdc45 AJ |
194 | UINT16 WINAPI GetPaletteEntries16( HPALETTE16 hpalette, UINT16 start, |
195 | UINT16 count, LPPALETTEENTRY entries ) | |
f0cbfa0c | 196 | { |
a3960292 | 197 | return GetPaletteEntries( hpalette, start, count, entries ); |
f0cbfa0c AJ |
198 | } |
199 | ||
200 | ||
201 | /*********************************************************************** | |
d0a41774 | 202 | * GetPaletteEntries [GDI32.@] Retrieves palette entries |
c7c217b3 AJ |
203 | * |
204 | * RETURNS | |
205 | * Success: Number of entries from logical palette | |
206 | * Failure: 0 | |
401710d7 | 207 | */ |
a3960292 AJ |
208 | UINT WINAPI GetPaletteEntries( |
209 | HPALETTE hpalette, /* [in] Handle of logical palette */ | |
210 | UINT start, /* [in] First entry to receive */ | |
211 | UINT count, /* [in] Number of entries to receive */ | |
c7c217b3 | 212 | LPPALETTEENTRY entries) /* [out] Address of array receiving entries */ |
401710d7 AJ |
213 | { |
214 | PALETTEOBJ * palPtr; | |
4d75640d | 215 | UINT numEntries; |
18f92e76 | 216 | |
15657090 | 217 | TRACE("hpal = %04x, count=%i\n", hpalette, count ); |
401710d7 AJ |
218 | |
219 | palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC ); | |
220 | if (!palPtr) return 0; | |
18f92e76 | 221 | |
401710d7 | 222 | numEntries = palPtr->logpalette.palNumEntries; |
829fe323 AJ |
223 | if (start+count > numEntries) count = numEntries - start; |
224 | if (entries) | |
225 | { | |
226 | if (start >= numEntries) | |
227 | { | |
2a2321bb | 228 | GDI_ReleaseObj( hpalette ); |
829fe323 AJ |
229 | return 0; |
230 | } | |
231 | memcpy( entries, &palPtr->logpalette.palPalEntry[start], | |
232 | count * sizeof(PALETTEENTRY) ); | |
233 | for( numEntries = 0; numEntries < count ; numEntries++ ) | |
234 | if (entries[numEntries].peFlags & 0xF0) | |
235 | entries[numEntries].peFlags = 0; | |
670cdc45 | 236 | } |
829fe323 | 237 | |
2a2321bb | 238 | GDI_ReleaseObj( hpalette ); |
401710d7 AJ |
239 | return count; |
240 | } | |
241 | ||
242 | ||
243 | /*********************************************************************** | |
17fd4e38 | 244 | * SetPaletteEntries (GDI.364) |
f0cbfa0c | 245 | */ |
670cdc45 AJ |
246 | UINT16 WINAPI SetPaletteEntries16( HPALETTE16 hpalette, UINT16 start, |
247 | UINT16 count, LPPALETTEENTRY entries ) | |
f0cbfa0c | 248 | { |
a3960292 | 249 | return SetPaletteEntries( hpalette, start, count, entries ); |
f0cbfa0c AJ |
250 | } |
251 | ||
252 | ||
253 | /*********************************************************************** | |
d0a41774 | 254 | * SetPaletteEntries [GDI32.@] Sets color values for range in palette |
c7c217b3 AJ |
255 | * |
256 | * RETURNS | |
257 | * Success: Number of entries that were set | |
258 | * Failure: 0 | |
401710d7 | 259 | */ |
a3960292 AJ |
260 | UINT WINAPI SetPaletteEntries( |
261 | HPALETTE hpalette, /* [in] Handle of logical palette */ | |
262 | UINT start, /* [in] Index of first entry to set */ | |
263 | UINT count, /* [in] Number of entries to set */ | |
c7c217b3 | 264 | LPPALETTEENTRY entries) /* [in] Address of array of structures */ |
401710d7 AJ |
265 | { |
266 | PALETTEOBJ * palPtr; | |
4d75640d | 267 | UINT numEntries; |
18f92e76 | 268 | |
15657090 | 269 | TRACE("hpal=%04x,start=%i,count=%i\n",hpalette,start,count ); |
18f92e76 | 270 | |
401710d7 AJ |
271 | palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC ); |
272 | if (!palPtr) return 0; | |
18f92e76 | 273 | |
401710d7 | 274 | numEntries = palPtr->logpalette.palNumEntries; |
670cdc45 AJ |
275 | if (start >= numEntries) |
276 | { | |
2a2321bb | 277 | GDI_ReleaseObj( hpalette ); |
670cdc45 AJ |
278 | return 0; |
279 | } | |
401710d7 AJ |
280 | if (start+count > numEntries) count = numEntries - start; |
281 | memcpy( &palPtr->logpalette.palPalEntry[start], entries, | |
282 | count * sizeof(PALETTEENTRY) ); | |
18f92e76 AJ |
283 | PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, |
284 | palPtr->logpalette.palNumEntries); | |
a7116b05 | 285 | HeapFree( GetProcessHeap(), 0, palPtr->mapping ); |
ac9c9b07 | 286 | palPtr->mapping = NULL; |
2a2321bb | 287 | GDI_ReleaseObj( hpalette ); |
401710d7 AJ |
288 | return count; |
289 | } | |
290 | ||
f0cbfa0c AJ |
291 | |
292 | /*********************************************************************** | |
17fd4e38 | 293 | * ResizePalette (GDI.368) |
f0cbfa0c | 294 | */ |
670cdc45 | 295 | BOOL16 WINAPI ResizePalette16( HPALETTE16 hPal, UINT16 cEntries ) |
f0cbfa0c | 296 | { |
a3960292 | 297 | return ResizePalette( hPal, cEntries ); |
f0cbfa0c AJ |
298 | } |
299 | ||
300 | ||
af0bae58 | 301 | /*********************************************************************** |
d0a41774 | 302 | * ResizePalette [GDI32.@] Resizes logical palette |
c7c217b3 AJ |
303 | * |
304 | * RETURNS | |
305 | * Success: TRUE | |
306 | * Failure: FALSE | |
af0bae58 | 307 | */ |
a3960292 AJ |
308 | BOOL WINAPI ResizePalette( |
309 | HPALETTE hPal, /* [in] Handle of logical palette */ | |
310 | UINT cEntries) /* [in] Number of entries in logical palette */ | |
af0bae58 | 311 | { |
75d86e1f | 312 | PALETTEOBJ * palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hPal, PALETTE_MAGIC ); |
a3960292 | 313 | UINT cPrevEnt, prevVer; |
75d86e1f AJ |
314 | int prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY); |
315 | int* mapping = NULL; | |
316 | ||
15657090 | 317 | TRACE("hpal = %04x, prev = %i, new = %i\n", |
889f7424 AJ |
318 | hPal, palPtr ? palPtr->logpalette.palNumEntries : -1, |
319 | cEntries ); | |
75d86e1f AJ |
320 | if( !palPtr ) return FALSE; |
321 | cPrevEnt = palPtr->logpalette.palNumEntries; | |
322 | prevVer = palPtr->logpalette.palVersion; | |
323 | prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + | |
324 | sizeof(int*) + sizeof(GDIOBJHDR); | |
325 | size += sizeof(int*) + sizeof(GDIOBJHDR); | |
326 | mapping = palPtr->mapping; | |
670cdc45 | 327 | |
2a2321bb | 328 | if (!(palPtr = GDI_ReallocObject( size, hPal, palPtr ))) return FALSE; |
75d86e1f | 329 | |
9ad96367 DP |
330 | if( mapping ) |
331 | { | |
332 | int *newMap = (int*) HeapReAlloc(GetProcessHeap(), 0, | |
333 | mapping, cEntries * sizeof(int) ); | |
334 | if(newMap == NULL) | |
335 | { | |
e76218dd | 336 | ERR("Can not resize mapping -- out of memory!\n"); |
2a2321bb | 337 | GDI_ReleaseObj( hPal ); |
9ad96367 DP |
338 | return FALSE; |
339 | } | |
340 | palPtr->mapping = newMap; | |
341 | } | |
342 | ||
75d86e1f AJ |
343 | if( cEntries > cPrevEnt ) |
344 | { | |
345 | if( mapping ) | |
346 | memset(palPtr->mapping + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int)); | |
347 | memset( (BYTE*)palPtr + prevsize, 0, size - prevsize ); | |
348 | PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), | |
349 | cEntries - cPrevEnt ); | |
350 | } | |
351 | palPtr->logpalette.palNumEntries = cEntries; | |
352 | palPtr->logpalette.palVersion = prevVer; | |
2a2321bb | 353 | GDI_ReleaseObj( hPal ); |
75d86e1f | 354 | return TRUE; |
ade697e8 AJ |
355 | } |
356 | ||
f0cbfa0c AJ |
357 | |
358 | /*********************************************************************** | |
17fd4e38 | 359 | * AnimatePalette (GDI.367) |
f0cbfa0c | 360 | */ |
670cdc45 | 361 | void WINAPI AnimatePalette16( HPALETTE16 hPal, UINT16 StartIndex, |
241c730d | 362 | UINT16 NumEntries, const PALETTEENTRY* PaletteColors) |
f0cbfa0c | 363 | { |
a3960292 | 364 | AnimatePalette( hPal, StartIndex, NumEntries, PaletteColors ); |
f0cbfa0c AJ |
365 | } |
366 | ||
367 | ||
ade697e8 | 368 | /*********************************************************************** |
d0a41774 | 369 | * AnimatePalette [GDI32.@] Replaces entries in logical palette |
c7c217b3 AJ |
370 | * |
371 | * RETURNS | |
372 | * Success: TRUE | |
373 | * Failure: FALSE | |
670cdc45 | 374 | * |
c7c217b3 AJ |
375 | * FIXME |
376 | * Should use existing mapping when animating a primary palette | |
ade697e8 | 377 | */ |
a3960292 AJ |
378 | BOOL WINAPI AnimatePalette( |
379 | HPALETTE hPal, /* [in] Handle to logical palette */ | |
380 | UINT StartIndex, /* [in] First entry in palette */ | |
381 | UINT NumEntries, /* [in] Count of entries in palette */ | |
241c730d | 382 | const PALETTEENTRY* PaletteColors) /* [in] Pointer to first replacement */ |
ade697e8 | 383 | { |
15657090 | 384 | TRACE("%04x (%i - %i)\n", hPal, StartIndex,StartIndex+NumEntries); |
670cdc45 | 385 | |
4c18636d | 386 | if( hPal != GetStockObject(DEFAULT_PALETTE) ) |
670cdc45 AJ |
387 | { |
388 | PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC); | |
58b2f0a0 | 389 | if (!palPtr) return FALSE; |
670cdc45 | 390 | |
02e90087 | 391 | if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries ) |
670cdc45 | 392 | { |
a3960292 | 393 | UINT u; |
670cdc45 AJ |
394 | for( u = 0; u < NumEntries; u++ ) |
395 | palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u]; | |
b87fe2e9 PS |
396 | PALETTE_Driver-> |
397 | pSetMapping(palPtr, StartIndex, NumEntries, | |
398 | hPal != hPrimaryPalette ); | |
2a2321bb | 399 | GDI_ReleaseObj( hPal ); |
670cdc45 AJ |
400 | return TRUE; |
401 | } | |
2a2321bb | 402 | GDI_ReleaseObj( hPal ); |
670cdc45 AJ |
403 | } |
404 | return FALSE; | |
af0bae58 | 405 | } |
401710d7 | 406 | |
f0cbfa0c AJ |
407 | |
408 | /*********************************************************************** | |
17fd4e38 | 409 | * SetSystemPaletteUse (GDI.373) |
f0cbfa0c | 410 | */ |
670cdc45 | 411 | UINT16 WINAPI SetSystemPaletteUse16( HDC16 hdc, UINT16 use ) |
f0cbfa0c | 412 | { |
a3960292 | 413 | return SetSystemPaletteUse( hdc, use ); |
f0cbfa0c AJ |
414 | } |
415 | ||
416 | ||
417 | /*********************************************************************** | |
d0a41774 | 418 | * SetSystemPaletteUse [GDI32.@] |
c7c217b3 AJ |
419 | * |
420 | * RETURNS | |
421 | * Success: Previous system palette | |
422 | * Failure: SYSPAL_ERROR | |
f0cbfa0c | 423 | */ |
a3960292 AJ |
424 | UINT WINAPI SetSystemPaletteUse( |
425 | HDC hdc, /* [in] Handle of device context */ | |
426 | UINT use) /* [in] Palette-usage flag */ | |
f0cbfa0c | 427 | { |
a3960292 | 428 | UINT old = SystemPaletteUse; |
15657090 | 429 | FIXME("(%04x,%04x): stub\n", hdc, use ); |
f0cbfa0c AJ |
430 | SystemPaletteUse = use; |
431 | return old; | |
432 | } | |
433 | ||
434 | ||
435 | /*********************************************************************** | |
17fd4e38 | 436 | * GetSystemPaletteUse (GDI.374) |
f0cbfa0c | 437 | */ |
670cdc45 | 438 | UINT16 WINAPI GetSystemPaletteUse16( HDC16 hdc ) |
f0cbfa0c AJ |
439 | { |
440 | return SystemPaletteUse; | |
441 | } | |
442 | ||
443 | ||
a2f2e019 | 444 | /*********************************************************************** |
d0a41774 | 445 | * GetSystemPaletteUse [GDI32.@] Gets state of system palette |
c7c217b3 AJ |
446 | * |
447 | * RETURNS | |
448 | * Current state of system palette | |
a2f2e019 | 449 | */ |
a3960292 AJ |
450 | UINT WINAPI GetSystemPaletteUse( |
451 | HDC hdc) /* [in] Handle of device context */ | |
a2f2e019 | 452 | { |
f0cbfa0c | 453 | return SystemPaletteUse; |
a2f2e019 AJ |
454 | } |
455 | ||
f0cbfa0c | 456 | |
2787be87 | 457 | /*********************************************************************** |
17fd4e38 | 458 | * GetSystemPaletteEntries (GDI.375) |
2787be87 | 459 | */ |
670cdc45 AJ |
460 | UINT16 WINAPI GetSystemPaletteEntries16( HDC16 hdc, UINT16 start, UINT16 count, |
461 | LPPALETTEENTRY entries ) | |
2787be87 | 462 | { |
a3960292 | 463 | return GetSystemPaletteEntries( hdc, start, count, entries ); |
2787be87 AJ |
464 | } |
465 | ||
466 | ||
8d24ae6d | 467 | /*********************************************************************** |
d0a41774 | 468 | * GetSystemPaletteEntries [GDI32.@] Gets range of palette entries |
c7c217b3 AJ |
469 | * |
470 | * RETURNS | |
471 | * Success: Number of entries retrieved from palette | |
472 | * Failure: 0 | |
8d24ae6d | 473 | */ |
a3960292 AJ |
474 | UINT WINAPI GetSystemPaletteEntries( |
475 | HDC hdc, /* [in] Handle of device context */ | |
476 | UINT start, /* [in] Index of first entry to be retrieved */ | |
477 | UINT count, /* [in] Number of entries to be retrieved */ | |
c7c217b3 | 478 | LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */ |
8d24ae6d | 479 | { |
a3960292 | 480 | UINT i; |
99bb9f97 | 481 | INT sizePalette = GetDeviceCaps( hdc, SIZEPALETTE ); |
ac9c9b07 | 482 | |
15657090 | 483 | TRACE("hdc=%04x,start=%i,count=%i\n", hdc,start,count); |
8d24ae6d | 484 | |
99bb9f97 AJ |
485 | if (!entries) return sizePalette; |
486 | if (start >= sizePalette) return 0; | |
487 | if (start+count >= sizePalette) count = sizePalette - start; | |
2a2321bb | 488 | |
8d24ae6d AJ |
489 | for (i = 0; i < count; i++) |
490 | { | |
f0cbfa0c | 491 | *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry( start + i ); |
ac9c9b07 | 492 | |
15657090 | 493 | TRACE("\tidx(%02x) -> RGB(%08lx)\n", |
f0cbfa0c | 494 | start + i, *(COLORREF*)(entries + i) ); |
8d24ae6d AJ |
495 | } |
496 | return count; | |
497 | } | |
498 | ||
499 | ||
401710d7 | 500 | /*********************************************************************** |
17fd4e38 | 501 | * GetNearestPaletteIndex (GDI.370) |
f0cbfa0c | 502 | */ |
670cdc45 | 503 | UINT16 WINAPI GetNearestPaletteIndex16( HPALETTE16 hpalette, COLORREF color ) |
f0cbfa0c | 504 | { |
a3960292 | 505 | return GetNearestPaletteIndex( hpalette, color ); |
f0cbfa0c AJ |
506 | } |
507 | ||
508 | ||
509 | /*********************************************************************** | |
d0a41774 | 510 | * GetNearestPaletteIndex [GDI32.@] Gets palette index for color |
c7c217b3 AJ |
511 | * |
512 | * NOTES | |
513 | * Should index be initialized to CLR_INVALID instead of 0? | |
514 | * | |
515 | * RETURNS | |
516 | * Success: Index of entry in logical palette | |
517 | * Failure: CLR_INVALID | |
401710d7 | 518 | */ |
a3960292 AJ |
519 | UINT WINAPI GetNearestPaletteIndex( |
520 | HPALETTE hpalette, /* [in] Handle of logical color palette */ | |
c7c217b3 | 521 | COLORREF color) /* [in] Color to be matched */ |
401710d7 | 522 | { |
f0cbfa0c | 523 | PALETTEOBJ* palObj = (PALETTEOBJ*)GDI_GetObjPtr( hpalette, PALETTE_MAGIC ); |
a3960292 | 524 | UINT index = 0; |
ac9c9b07 AJ |
525 | |
526 | if( palObj ) | |
2a2321bb | 527 | { |
b87fe2e9 PS |
528 | index = COLOR_PaletteLookupPixel(palObj->logpalette.palPalEntry, |
529 | palObj->logpalette.palNumEntries, | |
530 | NULL, color, FALSE ); | |
ac9c9b07 | 531 | |
2a2321bb AJ |
532 | GDI_ReleaseObj( hpalette ); |
533 | } | |
15657090 | 534 | TRACE("(%04x,%06lx): returning %d\n", hpalette, color, index ); |
401710d7 AJ |
535 | return index; |
536 | } | |
537 | ||
538 | ||
902da699 | 539 | /*********************************************************************** |
17fd4e38 | 540 | * GetNearestColor (GDI.154) |
902da699 | 541 | */ |
670cdc45 | 542 | COLORREF WINAPI GetNearestColor16( HDC16 hdc, COLORREF color ) |
f0cbfa0c | 543 | { |
a3960292 | 544 | return GetNearestColor( hdc, color ); |
f0cbfa0c AJ |
545 | } |
546 | ||
547 | ||
548 | /*********************************************************************** | |
d0a41774 | 549 | * GetNearestColor [GDI32.@] Gets a system color to match |
c7c217b3 | 550 | * |
c7c217b3 AJ |
551 | * RETURNS |
552 | * Success: Color from system palette that corresponds to given color | |
553 | * Failure: CLR_INVALID | |
f0cbfa0c | 554 | */ |
a3960292 AJ |
555 | COLORREF WINAPI GetNearestColor( |
556 | HDC hdc, /* [in] Handle of device context */ | |
c7c217b3 | 557 | COLORREF color) /* [in] Color to be matched */ |
902da699 | 558 | { |
2a2321bb | 559 | COLORREF nearest = CLR_INVALID; |
ac9c9b07 AJ |
560 | DC *dc; |
561 | PALETTEOBJ *palObj; | |
562 | ||
2239abb9 | 563 | if ( (dc = DC_GetDCPtr( hdc )) ) |
ac9c9b07 | 564 | { |
2239abb9 | 565 | HPALETTE hpal = (dc->hPalette)? dc->hPalette : GetStockObject( DEFAULT_PALETTE ); |
2a2321bb AJ |
566 | palObj = GDI_GetObjPtr( hpal, PALETTE_MAGIC ); |
567 | if (!palObj) { | |
568 | GDI_ReleaseObj( hdc ); | |
569 | return nearest; | |
570 | } | |
571 | ||
572 | nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry, | |
573 | palObj->logpalette.palNumEntries, color ); | |
574 | GDI_ReleaseObj( hpal ); | |
575 | GDI_ReleaseObj( hdc ); | |
ac9c9b07 | 576 | } |
902da699 | 577 | |
15657090 | 578 | TRACE("(%06lx): returning %06lx\n", color, nearest ); |
902da699 AJ |
579 | return nearest; |
580 | } | |
581 | ||
582 | ||
401710d7 AJ |
583 | /*********************************************************************** |
584 | * PALETTE_GetObject | |
585 | */ | |
586 | int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer ) | |
587 | { | |
588 | if (count > sizeof(WORD)) count = sizeof(WORD); | |
589 | memcpy( buffer, &palette->logpalette.palNumEntries, count ); | |
590 | return count; | |
591 | } | |
5f721f81 AJ |
592 | |
593 | ||
18f92e76 AJ |
594 | /*********************************************************************** |
595 | * PALETTE_UnrealizeObject | |
596 | */ | |
a3960292 | 597 | BOOL PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette ) |
18f92e76 AJ |
598 | { |
599 | if (palette->mapping) | |
600 | { | |
a7116b05 | 601 | HeapFree( GetProcessHeap(), 0, palette->mapping ); |
18f92e76 AJ |
602 | palette->mapping = NULL; |
603 | } | |
604 | if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0; | |
605 | return TRUE; | |
606 | } | |
607 | ||
608 | ||
609 | /*********************************************************************** | |
610 | * PALETTE_DeleteObject | |
611 | */ | |
a3960292 | 612 | BOOL PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette ) |
18f92e76 | 613 | { |
a7116b05 | 614 | HeapFree( GetProcessHeap(), 0, palette->mapping ); |
670cdc45 | 615 | if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0; |
2a2321bb | 616 | return GDI_FreeObject( hpalette, palette ); |
18f92e76 AJ |
617 | } |
618 | ||
619 | ||
8d24ae6d AJ |
620 | /*********************************************************************** |
621 | * GDISelectPalette (GDI.361) | |
622 | */ | |
a3960292 | 623 | HPALETTE16 WINAPI GDISelectPalette16( HDC16 hdc, HPALETTE16 hpal, WORD wBkg) |
8d24ae6d | 624 | { |
e2bfa4c7 | 625 | HPALETTE16 prev; |
8d24ae6d AJ |
626 | DC *dc; |
627 | ||
15657090 | 628 | TRACE("%04x %04x\n", hdc, hpal ); |
39932167 | 629 | |
ea8795b9 | 630 | if (GetObjectType(hpal) != OBJ_PAL) |
39932167 AJ |
631 | { |
632 | WARN("invalid selected palette %04x\n",hpal); | |
633 | return 0; | |
634 | } | |
2a2321bb | 635 | if (!(dc = DC_GetDCPtr( hdc ))) return 0; |
2239abb9 AJ |
636 | prev = dc->hPalette; |
637 | dc->hPalette = hpal; | |
2a2321bb | 638 | GDI_ReleaseObj( hdc ); |
18f92e76 | 639 | if (!wBkg) hPrimaryPalette = hpal; |
8d24ae6d AJ |
640 | return prev; |
641 | } | |
642 | ||
643 | ||
644 | /*********************************************************************** | |
645 | * GDIRealizePalette (GDI.362) | |
646 | */ | |
a3960292 | 647 | UINT16 WINAPI GDIRealizePalette16( HDC16 hdc ) |
8d24ae6d | 648 | { |
e2bfa4c7 | 649 | PALETTEOBJ* palPtr; |
f0cbfa0c | 650 | int realized = 0; |
2a2321bb AJ |
651 | DC* dc = DC_GetDCPtr( hdc ); |
652 | ||
653 | if (!dc) return 0; | |
e2bfa4c7 | 654 | |
15657090 | 655 | TRACE("%04x...\n", hdc ); |
18f92e76 | 656 | |
2239abb9 | 657 | if(dc->hPalette != hLastRealizedPalette ) |
18f92e76 | 658 | { |
2239abb9 | 659 | if( dc->hPalette == GetStockObject( DEFAULT_PALETTE )) { |
2a2321bb AJ |
660 | realized = RealizeDefaultPalette16( hdc ); |
661 | GDI_ReleaseObj( hdc ); | |
662 | return (UINT16)realized; | |
663 | } | |
664 | ||
ac9c9b07 | 665 | |
2239abb9 | 666 | palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC ); |
642d3136 AJ |
667 | |
668 | if (!palPtr) { | |
2a2321bb | 669 | GDI_ReleaseObj( hdc ); |
2239abb9 | 670 | FIXME("invalid selected palette %04x\n",dc->hPalette); |
2a2321bb | 671 | return 0; |
642d3136 | 672 | } |
18f92e76 | 673 | |
b87fe2e9 PS |
674 | realized = PALETTE_Driver-> |
675 | pSetMapping(palPtr,0,palPtr->logpalette.palNumEntries, | |
2239abb9 AJ |
676 | (dc->hPalette != hPrimaryPalette) || |
677 | (dc->hPalette == GetStockObject( DEFAULT_PALETTE ))); | |
678 | hLastRealizedPalette = dc->hPalette; | |
679 | GDI_ReleaseObj( dc->hPalette ); | |
18f92e76 | 680 | } |
15657090 | 681 | else TRACE(" skipping (hLastRealizedPalette = %04x)\n", |
670cdc45 | 682 | hLastRealizedPalette); |
2a2321bb | 683 | GDI_ReleaseObj( hdc ); |
54c2711f | 684 | |
15657090 | 685 | TRACE(" realized %i colors.\n", realized ); |
f0cbfa0c | 686 | return (UINT16)realized; |
8d24ae6d AJ |
687 | } |
688 | ||
689 | ||
5f721f81 | 690 | /*********************************************************************** |
18f92e76 | 691 | * RealizeDefaultPalette (GDI.365) |
5f721f81 | 692 | */ |
a3960292 | 693 | UINT16 WINAPI RealizeDefaultPalette16( HDC16 hdc ) |
5f721f81 | 694 | { |
2a2321bb | 695 | UINT16 ret = 0; |
ac9c9b07 AJ |
696 | DC *dc; |
697 | PALETTEOBJ* palPtr; | |
18f92e76 | 698 | |
15657090 | 699 | TRACE("%04x\n", hdc ); |
18f92e76 | 700 | |
2a2321bb AJ |
701 | if (!(dc = DC_GetDCPtr( hdc ))) return 0; |
702 | ||
2239abb9 | 703 | if (!(dc->flags & DC_MEMORY)) |
ac9c9b07 | 704 | { |
4c18636d | 705 | palPtr = (PALETTEOBJ*)GDI_GetObjPtr( GetStockObject(DEFAULT_PALETTE), PALETTE_MAGIC ); |
2a2321bb AJ |
706 | if (palPtr) |
707 | { | |
708 | /* lookup is needed to account for SetSystemPaletteUse() stuff */ | |
709 | ret = PALETTE_Driver->pUpdateMapping(palPtr); | |
4c18636d | 710 | GDI_ReleaseObj( GetStockObject(DEFAULT_PALETTE) ); |
2a2321bb | 711 | } |
ac9c9b07 | 712 | } |
2a2321bb AJ |
713 | GDI_ReleaseObj( hdc ); |
714 | return ret; | |
ac9c9b07 | 715 | } |
8d24ae6d | 716 | |
ca22b33d | 717 | /*********************************************************************** |
18f92e76 | 718 | * IsDCCurrentPalette (GDI.412) |
ca22b33d | 719 | */ |
a3960292 | 720 | BOOL16 WINAPI IsDCCurrentPalette16(HDC16 hDC) |
ca22b33d | 721 | { |
2239abb9 | 722 | DC *dc = DC_GetDCPtr( hDC ); |
670cdc45 AJ |
723 | if (dc) |
724 | { | |
2239abb9 | 725 | BOOL bRet = dc->hPalette == hPrimaryPalette; |
2a2321bb AJ |
726 | GDI_ReleaseObj( hDC ); |
727 | return bRet; | |
670cdc45 AJ |
728 | } |
729 | return FALSE; | |
ca22b33d AJ |
730 | } |
731 | ||
f0cbfa0c | 732 | |
5f721f81 | 733 | /*********************************************************************** |
d0a41774 | 734 | * SelectPalette [GDI32.@] Selects logical palette into DC |
c7c217b3 AJ |
735 | * |
736 | * RETURNS | |
737 | * Success: Previous logical palette | |
738 | * Failure: NULL | |
5f721f81 | 739 | */ |
a3960292 AJ |
740 | HPALETTE WINAPI SelectPalette( |
741 | HDC hDC, /* [in] Handle of device context */ | |
742 | HPALETTE hPal, /* [in] Handle of logical color palette */ | |
743 | BOOL bForceBackground) /* [in] Foreground/background mode */ | |
5f721f81 | 744 | { |
39932167 | 745 | return pfnSelectPalette( hDC, hPal, bForceBackground ); |
5f721f81 AJ |
746 | } |
747 | ||
ca22b33d | 748 | |
f0cbfa0c | 749 | /*********************************************************************** |
d0a41774 | 750 | * RealizePalette [GDI32.@] Maps palette entries to system palette |
c7c217b3 AJ |
751 | * |
752 | * RETURNS | |
753 | * Success: Number of entries in logical palette | |
754 | * Failure: GDI_ERROR | |
ca22b33d | 755 | */ |
a3960292 AJ |
756 | UINT WINAPI RealizePalette( |
757 | HDC hDC) /* [in] Handle of device context */ | |
ca22b33d | 758 | { |
39932167 | 759 | return pfnRealizePalette( hDC ); |
ca22b33d AJ |
760 | } |
761 | ||
18f92e76 | 762 | |
ea2a9a89 AJ |
763 | typedef HWND WINAPI (*WindowFromDC_funcptr)( HDC ); |
764 | typedef BOOL WINAPI (*RedrawWindow_funcptr)( HWND, const RECT *, HRGN, UINT ); | |
765 | ||
18f92e76 | 766 | /********************************************************************** |
56a19923 DT |
767 | * UpdateColors [GDI32.@] Remaps current colors to logical palette |
768 | * | |
769 | * RETURNS | |
770 | * Success: TRUE | |
771 | * Failure: FALSE | |
18f92e76 | 772 | */ |
56a19923 DT |
773 | BOOL WINAPI UpdateColors( |
774 | HDC hDC) /* [in] Handle of device context */ | |
18f92e76 | 775 | { |
ea2a9a89 | 776 | HMODULE mod; |
99bb9f97 | 777 | int size = GetDeviceCaps( hDC, SIZEPALETTE ); |
b87fe2e9 | 778 | |
99bb9f97 | 779 | if (!size) return 0; |
b87fe2e9 | 780 | |
ea2a9a89 AJ |
781 | mod = GetModuleHandleA("user32.dll"); |
782 | if (mod) | |
783 | { | |
784 | WindowFromDC_funcptr pWindowFromDC = (WindowFromDC_funcptr)GetProcAddress(mod,"WindowFromDC"); | |
785 | if (pWindowFromDC) | |
786 | { | |
787 | HWND hWnd = pWindowFromDC( hDC ); | |
788 | ||
789 | /* Docs say that we have to remap current drawable pixel by pixel | |
790 | * but it would take forever given the speed of XGet/PutPixel. | |
791 | */ | |
792 | if (hWnd && size) | |
793 | { | |
794 | RedrawWindow_funcptr pRedrawWindow = GetProcAddress( mod, "RedrawWindow" ); | |
795 | if (pRedrawWindow) pRedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE ); | |
796 | } | |
797 | } | |
4e951ea2 | 798 | } |
18f92e76 AJ |
799 | return 0x666; |
800 | } | |
ac9c9b07 | 801 | |
21979019 AJ |
802 | |
803 | /********************************************************************** | |
01d5e5b0 | 804 | * UpdateColors (GDI.366) |
21979019 | 805 | */ |
56a19923 | 806 | INT16 WINAPI UpdateColors16( HDC16 hDC ) |
21979019 | 807 | { |
56a19923 | 808 | UpdateColors( hDC ); |
21979019 AJ |
809 | return TRUE; |
810 | } | |
c7c217b3 | 811 | |
8150b52c IS |
812 | |
813 | /********************************************************************* | |
17fd4e38 | 814 | * SetMagicColors (GDI.606) |
8150b52c IS |
815 | */ |
816 | VOID WINAPI SetMagicColors16(HDC16 hDC, COLORREF color, UINT16 index) | |
817 | { | |
15657090 | 818 | FIXME("(hDC %04x, color %04x, index %04x): stub\n", hDC, (int)color, index); |
8150b52c IS |
819 | |
820 | } | |
31b47218 IS |
821 | |
822 | /********************************************************************** | |
d0a41774 | 823 | * GetICMProfileA [GDI32.@] |
31b47218 IS |
824 | * |
825 | * Returns the filename of the specified device context's color | |
826 | * management profile, even if color management is not enabled | |
827 | * for that DC. | |
828 | * | |
829 | * RETURNS | |
830 | * TRUE if name copied succesfully OR lpszFilename is NULL | |
831 | * FALSE if the buffer length pointed to by lpcbName is too small | |
832 | * | |
833 | * NOTE | |
834 | * The buffer length pointed to by lpcbName is ALWAYS updated to | |
835 | * the length required regardless of other actions this function | |
836 | * may take. | |
837 | * | |
838 | * FIXME | |
839 | * How does Windows assign these? Some registry key? | |
840 | */ | |
841 | ||
842 | #define WINEICM "winefake.icm" /* easy-to-identify fake filename */ | |
843 | ||
2b3aa616 PS |
844 | /*********************************************************************/ |
845 | ||
31b47218 IS |
846 | BOOL WINAPI GetICMProfileA(HDC hDC, LPDWORD lpcbName, LPSTR lpszFilename) |
847 | { | |
848 | DWORD callerLen; | |
849 | ||
850 | FIXME("(%04x, %p, %p): partial stub\n", hDC, lpcbName, lpszFilename); | |
851 | ||
852 | callerLen = *lpcbName; | |
853 | ||
854 | /* all 3 behaviors require the required buffer size to be set */ | |
855 | *lpcbName = strlen(WINEICM); | |
856 | ||
857 | /* behavior 1: if lpszFilename is NULL, return size of string and no error */ | |
858 | if ((DWORD)lpszFilename == (DWORD)0x00000000) | |
859 | return TRUE; | |
860 | ||
861 | /* behavior 2: if buffer size too small, return size of string and error */ | |
862 | if (callerLen < strlen(WINEICM)) | |
863 | { | |
864 | SetLastError(ERROR_INSUFFICIENT_BUFFER); | |
865 | return FALSE; | |
866 | } | |
867 | ||
868 | /* behavior 3: if buffer size OK and pointer not NULL, copy and return size */ | |
c7e7df8b | 869 | strcpy(lpszFilename, WINEICM); |
31b47218 IS |
870 | return TRUE; |
871 | } |