- Removed last GvG's fix to COMCTL32.
[reactos.git] / reactos / subsys / win32k / objects / color.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: color.c,v 1.30 2003/12/19 22:58:47 navaraf Exp $ */
20
21 // FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
22
23 #undef WIN32_LEAN_AND_MEAN
24 #include <windows.h>
25 #include <ddk/ntddk.h>
26 #include <ddk/winddi.h>
27 #include <win32k/brush.h>
28 #include <win32k/dc.h>
29 #include <win32k/color.h>
30 #include <win32k/pen.h>
31 #include "../eng/handle.h"
32 #include <include/inteng.h>
33 #include <include/color.h>
34 #include <include/palette.h>
35 #include <include/error.h>
36
37 #define NDEBUG
38 #include <win32k/debug1.h>
39
40 int COLOR_gapStart = 256;
41 int COLOR_gapEnd = -1;
42 int COLOR_gapFilled = 0;
43 int COLOR_max = 256;
44
45 static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED
46 //static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it
47
48 const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
49 {
50 // first 10 entries in the system palette
51 // red green blue flags
52 { 0x00, 0x00, 0x00, PC_SYS_USED },
53 { 0x80, 0x00, 0x00, PC_SYS_USED },
54 { 0x00, 0x80, 0x00, PC_SYS_USED },
55 { 0x80, 0x80, 0x00, PC_SYS_USED },
56 { 0x00, 0x00, 0x80, PC_SYS_USED },
57 { 0x80, 0x00, 0x80, PC_SYS_USED },
58 { 0x00, 0x80, 0x80, PC_SYS_USED },
59 { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
60 { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
61 { 0xa6, 0xca, 0xf0, PC_SYS_USED },
62
63 // ... c_min/2 dynamic colorcells
64 // ... gap (for sparse palettes)
65 // ... c_min/2 dynamic colorcells
66
67 { 0xff, 0xfb, 0xf0, PC_SYS_USED },
68 { 0xa0, 0xa0, 0xa4, PC_SYS_USED },
69 { 0x80, 0x80, 0x80, PC_SYS_USED },
70 { 0xff, 0x00, 0x00, PC_SYS_USED },
71 { 0x00, 0xff, 0x00, PC_SYS_USED },
72 { 0xff, 0xff, 0x00, PC_SYS_USED },
73 { 0x00, 0x00, 0xff, PC_SYS_USED },
74 { 0xff, 0x00, 0xff, PC_SYS_USED },
75 { 0x00, 0xff, 0xff, PC_SYS_USED },
76 { 0xff, 0xff, 0xff, PC_SYS_USED } // last 10
77 };
78
79 const COLORREF SysColours[] =
80 {
81 RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
82 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
83 RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
84 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
85 RGB(192, 192, 192) /* COLOR_MENU */,
86 RGB(255, 255, 255) /* COLOR_WINDOW */,
87 RGB(0, 0, 0) /* COLOR_WINDOWFRAME */,
88 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
89 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
90 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
91 RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
92 RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
93 RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
94 RGB(224, 224, 224) /* COLOR_HILIGHT */,
95 RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
96 RGB(192, 192, 192) /* COLOR_BTNFACE */,
97 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
98 RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
99 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
100 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
101 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
102 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
103 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
104 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
105 RGB(255, 255, 192) /* COLOR_INFOBK */,
106 RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
107 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
108 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
109 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
110 };
111
112 ULONG FASTCALL NtGdiGetSysColor(int nIndex)
113 {
114 #if 0
115 const PALETTEENTRY *p = COLOR_sysPalTemplate + (nIndex * sizeof(PALETTEENTRY));
116 return RGB(p->peRed, p->peGreen, p->peBlue);
117 #else
118 if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex)
119 {
120 SetLastWin32Error(ERROR_INVALID_PARAMETER);
121 return 0;
122 }
123
124 return SysColours[nIndex];
125 #endif
126 }
127
128 HPEN STDCALL NtGdiGetSysColorPen(int nIndex)
129 {
130 #if 0
131 COLORREF Col;
132 memcpy(&Col, COLOR_sysPalTemplate + nIndex, sizeof(COLORREF));
133 return(NtGdiCreatePen(PS_SOLID, 1, Col));
134 #else
135 static HPEN SysPens[sizeof(SysColours) / sizeof(SysColours[0])];
136
137 if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex)
138 {
139 SetLastWin32Error(ERROR_INVALID_PARAMETER);
140 return NULL;
141 }
142
143 /* FIXME should register this object with DeleteObject() so it
144 can't be deleted */
145 if (NULL == SysPens[nIndex])
146 {
147 SysPens[nIndex] = (HPEN)((DWORD)NtGdiCreatePen(PS_SOLID, 0, SysColours[nIndex]) | 0x00800000);
148 }
149
150 return SysPens[nIndex];
151 #endif
152 }
153
154 HBRUSH STDCALL NtGdiGetSysColorBrush(int nIndex)
155 {
156 static HBRUSH SysBrushes[sizeof(SysColours) / sizeof(SysColours[0])];
157
158 if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex)
159 {
160 SetLastWin32Error(ERROR_INVALID_PARAMETER);
161 return NULL;
162 }
163
164 /* FIXME Should be changed when a new user logs in? */
165 if (NULL == SysBrushes[nIndex])
166 {
167 SysBrushes[nIndex] = (HBRUSH) ((DWORD)NtGdiCreateSolidBrush(SysColours[nIndex]));
168 if (NULL != SysBrushes[nIndex])
169 {
170 GDIOBJ_SetOwnership(SysBrushes[nIndex], NULL);
171 }
172 }
173
174 return SysBrushes[nIndex];
175 }
176
177
178
179 const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate(void)
180 {
181 return (const PALETTEENTRY*)&COLOR_sysPalTemplate;
182 }
183
184 BOOL STDCALL NtGdiAnimatePalette(HPALETTE hpal,
185 UINT StartIndex,
186 UINT Entries,
187 CONST PPALETTEENTRY ppe)
188 {
189 /*
190 if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) )
191 {
192 PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
193 if (!palPtr) return FALSE;
194
195 if( (StartIndex + NumEntries) <= palPtr->logpalette->palNumEntries )
196 {
197 UINT u;
198 for( u = 0; u < NumEntries; u++ )
199 palPtr->logpalette->palPalEntry[u + StartIndex] = PaletteColors[u];
200 PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries, hPal != hPrimaryPalette );
201 GDI_ReleaseObj(hPal);
202 return TRUE;
203 }
204 GDI_ReleaseObj(hPal);
205 }
206 return FALSE;
207 */
208 UNIMPLEMENTED;
209 }
210
211 HPALETTE STDCALL NtGdiCreateHalftonePalette(HDC hDC)
212 {
213 int i, r, g, b;
214 struct {
215 WORD Version;
216 WORD NumberOfEntries;
217 PALETTEENTRY aEntries[256];
218 } Palette;
219
220 Palette.Version = 0x300;
221 Palette.NumberOfEntries = 256;
222 NtGdiGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries);
223
224 for (r = 0; r < 6; r++) {
225 for (g = 0; g < 6; g++) {
226 for (b = 0; b < 6; b++) {
227 i = r + g*6 + b*36 + 10;
228 Palette.aEntries[i].peRed = r * 51;
229 Palette.aEntries[i].peGreen = g * 51;
230 Palette.aEntries[i].peBlue = b * 51;
231 }
232 }
233 }
234
235 for (i = 216; i < 246; i++) {
236 int v = (i - 216) * 8;
237 Palette.aEntries[i].peRed = v;
238 Palette.aEntries[i].peGreen = v;
239 Palette.aEntries[i].peBlue = v;
240 }
241
242 return NtGdiCreatePalette((LOGPALETTE *)&Palette);
243 }
244
245 HPALETTE STDCALL NtGdiCreatePalette(CONST PLOGPALETTE palette)
246 {
247 PPALOBJ PalObj;
248
249 HPALETTE NewPalette = PALETTE_AllocPalette(
250 PAL_INDEXED,
251 palette->palNumEntries,
252 (PULONG)palette->palPalEntry,
253 0, 0, 0);
254 ULONG size;
255
256 PalObj = (PPALOBJ) PALETTE_LockPalette(NewPalette);
257
258 size = sizeof(LOGPALETTE) + (palette->palNumEntries * sizeof(PALETTEENTRY));
259 PalObj->logpalette = ExAllocatePool(NonPagedPool, size);
260 memcpy(PalObj->logpalette, palette, size);
261 PALETTE_ValidateFlags(PalObj->logpalette->palPalEntry, PalObj->logpalette->palNumEntries);
262 PalObj->logicalToSystem = NULL;
263
264 PALETTE_UnlockPalette(NewPalette);
265
266 return NewPalette;
267 }
268
269 BOOL STDCALL NtGdiGetColorAdjustment(HDC hDC,
270 LPCOLORADJUSTMENT ca)
271 {
272 UNIMPLEMENTED;
273 }
274
275 COLORREF STDCALL NtGdiGetNearestColor(HDC hDC,
276 COLORREF Color)
277 {
278 COLORREF nearest = CLR_INVALID;
279 PDC dc;
280 PPALOBJ palObj;
281
282 dc = DC_LockDc(hDC);
283 if (NULL != dc)
284 {
285 HPALETTE hpal = (dc->w.hPalette) ? dc->w.hPalette : NtGdiGetStockObject(DEFAULT_PALETTE);
286 palObj = (PPALOBJ) PALETTE_LockPalette(hpal);
287 if (!palObj)
288 {
289 DC_UnlockDc(hDC);
290 return nearest;
291 }
292
293 nearest = COLOR_LookupNearestColor(palObj->logpalette->palPalEntry,
294 palObj->logpalette->palNumEntries, Color);
295 PALETTE_UnlockPalette(hpal);
296 DC_UnlockDc( hDC );
297 }
298
299 return nearest;
300 }
301
302 UINT STDCALL NtGdiGetNearestPaletteIndex(HPALETTE hpal,
303 COLORREF Color)
304 {
305 #if 1
306 PPALGDI palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
307 UINT index = 0;
308
309 if (NULL != palGDI)
310 {
311 /* Return closest match for the given RGB color */
312 index = COLOR_PaletteLookupPixel((LPPALETTEENTRY)palGDI->IndexedColors, palGDI->NumColors, NULL, Color, FALSE);
313 PALETTE_UnlockPalette(hpal);
314 }
315
316 return index;
317 #else
318 PPALOBJ palObj = (PPALOBJ) PALETTE_LockPalette(hpal);
319 UINT index = 0;
320
321 if (NULL != palObj)
322 {
323 /* Return closest match for the given RGB color */
324 ASSERT(palObj->logpalette != NULL);
325 index = COLOR_PaletteLookupPixel(palObj->logpalette->palPalEntry, palObj->logpalette->palNumEntries, NULL, Color, FALSE);
326 PALETTE_UnlockPalette(hpal);
327 }
328
329 return index;
330 #endif
331 }
332
333 UINT STDCALL NtGdiGetPaletteEntries(HPALETTE hpal,
334 UINT StartIndex,
335 UINT Entries,
336 LPPALETTEENTRY pe)
337 {
338 PPALOBJ palPtr;
339 UINT numEntries;
340
341 palPtr = (PPALOBJ) PALETTE_LockPalette(hpal);
342 if (NULL == palPtr)
343 {
344 return 0;
345 }
346
347 numEntries = palPtr->logpalette->palNumEntries;
348 if (numEntries < StartIndex + Entries)
349 {
350 Entries = numEntries - StartIndex;
351 }
352 if (NULL != pe)
353 {
354 if (numEntries <= StartIndex)
355 {
356 PALETTE_UnlockPalette(hpal);
357 return 0;
358 }
359 memcpy(pe, &palPtr->logpalette->palPalEntry[StartIndex], Entries * sizeof(PALETTEENTRY));
360 for (numEntries = 0; numEntries < Entries; numEntries++)
361 {
362 if (pe[numEntries].peFlags & 0xF0)
363 {
364 pe[numEntries].peFlags = 0;
365 }
366 }
367 }
368
369 PALETTE_UnlockPalette(hpal);
370 return Entries;
371 }
372
373 UINT STDCALL NtGdiGetSystemPaletteEntries(HDC hDC,
374 UINT StartIndex,
375 UINT Entries,
376 LPPALETTEENTRY pe)
377 {
378 //UINT i;
379 //PDC dc;
380 /*
381 if (!(dc = AccessUserObject(hdc))) return 0;
382
383 if (!pe)
384 {
385 Entries = dc->GDIInfo->ulNumPalReg;
386 goto done;
387 }
388
389 if (StartIndex >= dc->GDIInfo->ulNumPalReg)
390 {
391 Entries = 0;
392 goto done;
393 }
394
395 if (StartIndex + Entries >= dc->GDIInfo->ulNumPalReg) Entries = dc->GDIInfo->ulNumPalReg - StartIndex;
396
397 for (i = 0; i < Entries; i++)
398 {
399 *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry(StartIndex + i);
400 }
401
402 done:
403 // GDI_ReleaseObj(hdc);
404 return count; */
405 // FIXME UNIMPLEMENTED;
406 return 0;
407 }
408
409 UINT STDCALL NtGdiGetSystemPaletteUse(HDC hDC)
410 {
411 UNIMPLEMENTED;
412 return 0;
413 }
414
415 /*!
416 The RealizePalette function modifies the palette for the device associated with the specified device context. If the device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device context is a display DC, the physical palette for that device is modified.
417
418 A logical palette is a buffer between color-intensive applications and the system, allowing these applications to use as many colors as needed without interfering with colors displayed by other windows.
419
420 1= IF DRAWING TO A DEVICE
421 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
422 the system palette.
423 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the system palette.
424
425 2= IF DRAWING TO A MEMORY DC\BITMAP
426 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
427 the dc palette.
428 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette.
429 */
430 UINT STDCALL NtGdiRealizePalette(HDC hDC)
431 {
432 PPALOBJ palPtr, sysPtr;
433 PPALGDI palGDI, sysGDI;
434 int realized = 0;
435 PDC dc;
436 HPALETTE systemPalette;
437 PSURFGDI SurfGDI;
438 BOOLEAN success;
439 USHORT sysMode, palMode;
440
441 dc = DC_LockDc(hDC);
442 if (!dc)
443 return 0;
444
445 SurfGDI = (PSURFGDI)AccessInternalObject((ULONG)dc->Surface);
446 systemPalette = NtGdiGetStockObject((INT)DEFAULT_PALETTE);
447 palGDI = PALETTE_LockPalette(dc->w.hPalette);
448 palPtr = (PPALOBJ) palGDI;
449
450 // Step 1: Create mapping of system palette\DC palette
451 realized = PALETTE_SetMapping(palPtr, 0, palPtr->logpalette->palNumEntries,
452 (dc->w.hPalette != hPrimaryPalette) ||
453 (dc->w.hPalette == NtGdiGetStockObject(DEFAULT_PALETTE)));
454
455 sysGDI = PALETTE_LockPalette(systemPalette);
456 sysPtr = (PPALOBJ) sysGDI;
457
458 // Step 2:
459 // The RealizePalette function modifies the palette for the device associated with the specified device context. If the
460 // device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
461 // context is a display DC, the physical palette for that device is modified.
462 if(dc->w.flags == DC_MEMORY)
463 {
464 // Memory managed DC
465 DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
466 } else {
467 if(SurfGDI->SetPalette)
468 {
469 success = SurfGDI->SetPalette(dc->PDev, sysPtr, 0, 0, sysPtr->logpalette->palNumEntries);
470 }
471 }
472
473 // need to pass this to IntEngCreateXlate with palettes unlocked
474 sysMode = sysGDI->Mode;
475 palMode = palGDI->Mode;
476 PALETTE_UnlockPalette(systemPalette);
477 PALETTE_UnlockPalette(dc->w.hPalette);
478
479 // Step 3: Create the XLATEOBJ for device managed DCs
480 if(dc->w.flags != DC_MEMORY)
481 {
482 // Device managed DC
483 palPtr->logicalToSystem = IntEngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette);
484 }
485
486 DC_UnlockDc(hDC);
487
488 return realized;
489 }
490
491 BOOL STDCALL NtGdiResizePalette(HPALETTE hpal,
492 UINT Entries)
493 {
494 /* PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal);
495 UINT cPrevEnt, prevVer;
496 INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
497 PXLATEOBJ XlateObj = NULL;
498
499 if(!palPtr) return FALSE;
500 cPrevEnt = palPtr->logpalette->palNumEntries;
501 prevVer = palPtr->logpalette->palVersion;
502 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
503 size += sizeof(int*) + sizeof(GDIOBJHDR);
504 XlateObj = palPtr->logicalToSystem;
505
506 if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
507
508 if(XlateObj)
509 {
510 PXLATEOBJ NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
511 if(NewXlateObj == NULL)
512 {
513 ERR("Can not resize logicalToSystem -- out of memory!");
514 GDI_ReleaseObj( hPal );
515 return FALSE;
516 }
517 palPtr->logicalToSystem = NewXlateObj;
518 }
519
520 if(cEntries > cPrevEnt)
521 {
522 if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
523 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
524 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
525 }
526 palPtr->logpalette->palNumEntries = cEntries;
527 palPtr->logpalette->palVersion = prevVer;
528 // GDI_ReleaseObj( hPal );
529 return TRUE; */
530
531 UNIMPLEMENTED;
532 }
533
534 /*!
535 * Select logical palette into device context.
536 * \param hDC handle to the device context
537 * \param hpal handle to the palette
538 * \param ForceBackground If this value is FALSE the logical palette will be copied to the device palette only when the applicatioon
539 * is in the foreground. If this value is TRUE then map the colors in the logical palette to the device
540 * palette colors in the best way.
541 * \return old palette
542 *
543 * \todo implement ForceBackground == TRUE
544 */
545 HPALETTE STDCALL NtGdiSelectPalette(HDC hDC,
546 HPALETTE hpal,
547 BOOL ForceBackground)
548 {
549 PDC dc;
550 HPALETTE oldPal;
551 PPALGDI PalGDI;
552
553 // FIXME: mark the palette as a [fore\back]ground pal
554 dc = DC_LockDc(hDC);
555 if (NULL != dc)
556 {
557 /* Check if this is a valid palette handle */
558 PalGDI = PALETTE_LockPalette(hpal);
559 if (NULL != PalGDI)
560 {
561 PALETTE_UnlockPalette(hpal);
562 oldPal = dc->w.hPalette;
563 dc->w.hPalette = hpal;
564 }
565 else
566 {
567 oldPal = NULL;
568 }
569 DC_UnlockDc(hDC);
570 }
571
572 return oldPal;
573 }
574
575 BOOL STDCALL NtGdiSetColorAdjustment(HDC hDC,
576 CONST LPCOLORADJUSTMENT ca)
577 {
578 UNIMPLEMENTED;
579 }
580
581 UINT STDCALL NtGdiSetPaletteEntries(HPALETTE hpal,
582 UINT Start,
583 UINT Entries,
584 CONST LPPALETTEENTRY pe)
585 {
586 PPALOBJ palPtr;
587 WORD numEntries;
588
589 palPtr = (PPALOBJ)PALETTE_LockPalette(hpal);
590 if (!palPtr) return 0;
591
592 numEntries = palPtr->logpalette->palNumEntries;
593 if (Start >= numEntries)
594 {
595 PALETTE_UnlockPalette(hpal);
596 return 0;
597 }
598 if (numEntries < Start + Entries)
599 {
600 Entries = numEntries - Start;
601 }
602 memcpy(&palPtr->logpalette->palPalEntry[Start], pe, Entries * sizeof(PALETTEENTRY));
603 PALETTE_ValidateFlags(palPtr->logpalette->palPalEntry, palPtr->logpalette->palNumEntries);
604 ExFreePool(palPtr->logicalToSystem);
605 palPtr->logicalToSystem = NULL;
606 PALETTE_UnlockPalette(hpal);
607
608 return Entries;
609 }
610
611 UINT STDCALL NtGdiSetSystemPaletteUse(HDC hDC,
612 UINT Usage)
613 {
614 UNIMPLEMENTED;
615 }
616
617 BOOL STDCALL NtGdiUnrealizeObject(HGDIOBJ hgdiobj)
618 {
619 UNIMPLEMENTED;
620 }
621
622 BOOL STDCALL NtGdiUpdateColors(HDC hDC)
623 {
624 //PDC dc;
625 //HWND hWnd;
626 //int size;
627 /*
628 if (!(dc = AccessUserObject(hDC))) return 0;
629 size = dc->GDIInfo->ulNumPalReg;
630 // GDI_ReleaseObj( hDC );
631
632 if (Callout.WindowFromDC)
633 {
634 hWnd = Callout.WindowFromDC( hDC );
635
636 // Docs say that we have to remap current drawable pixel by pixel
637 // but it would take forever given the speed of XGet/PutPixel.
638 if (hWnd && size) Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
639 } */
640 // FIXME UNIMPLEMENTED
641 return 0x666;
642 }
643
644 INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size,
645 PXLATEOBJ XlateObj, COLORREF col, BOOL skipReserved)
646 {
647 int i, best = 0, diff = 0x7fffffff;
648 int r, g, b;
649
650 for( i = 0; i < size && diff ; i++ )
651 {
652 if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED))
653 continue;
654
655 r = palPalEntry[i].peRed - GetRValue(col);
656 g = palPalEntry[i].peGreen - GetGValue(col);
657 b = palPalEntry[i].peBlue - GetBValue(col);
658
659 r = r*r + g*g + b*b;
660
661 if( r < diff ) { best = i; diff = r; }
662 }
663
664 if (XlateObj == NULL)
665 return best;
666 else
667 return (XlateObj->pulXlate) ? (INT)XlateObj->pulXlate[best] : best;
668 }
669
670 COLORREF STDCALL COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
671 {
672 unsigned char spec_type = color >> 24;
673 int i;
674 PALETTEENTRY *COLOR_sysPal = (PALETTEENTRY*)ReturnSystemPalette();
675
676 // we need logical palette for PALETTERGB and PALETTEINDEX colorrefs
677
678 if( spec_type == 2 ) /* PALETTERGB */
679 color = *(COLORREF*)(palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
680
681 else if( spec_type == 1 ) /* PALETTEINDEX */
682 {
683 if( (i = color & 0x0000ffff) >= size )
684 {
685 DbgPrint("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
686 color = *(COLORREF*)palPalEntry;
687 }
688 else color = *(COLORREF*)(palPalEntry + i);
689 }
690
691 color &= 0x00ffffff;
692 return (0x00ffffff & *(COLORREF*)(COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
693 }
694
695 int STDCALL COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
696 COLORREF col )
697 {
698 int i;
699 BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
700 for( i = 0; i < size; i++ )
701 {
702 if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
703 if(palPalEntry[i].peRed == r && palPalEntry[i].peGreen == g && palPalEntry[i].peBlue == b) return i;
704 }
705 return -1;
706 }
707 /* EOF */