- Removed commented-out code from FillRect to prevent anyone from uncommenting it...
[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.26 2003/10/22 14:02:54 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 #if 0
157 COLORREF Col;
158 memcpy(&Col, COLOR_sysPalTemplate + nIndex, sizeof(COLORREF));
159 return(NtGdiCreateSolidBrush(Col));
160 #else
161 static HBRUSH SysBrushes[sizeof(SysColours) / sizeof(SysColours[0])];
162
163 if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex)
164 {
165 SetLastWin32Error(ERROR_INVALID_PARAMETER);
166 return NULL;
167 }
168
169 /* FIXME should register this object with DeleteObject() so it
170 can't be deleted */
171 if (NULL == SysBrushes[nIndex])
172 {
173 SysBrushes[nIndex] = (HBRUSH) ((DWORD)NtGdiCreateSolidBrush(SysColours[nIndex]) | 0x00800000);
174 }
175
176 return SysBrushes[nIndex];
177 #endif
178 }
179
180
181
182 const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate(void)
183 {
184 return (const PALETTEENTRY*)&COLOR_sysPalTemplate;
185 }
186
187 BOOL STDCALL NtGdiAnimatePalette(HPALETTE hpal,
188 UINT StartIndex,
189 UINT Entries,
190 CONST PPALETTEENTRY ppe)
191 {
192 /*
193 if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) )
194 {
195 PALETTEOBJ* palPtr = (PALETTEOBJ *)GDI_GetObjPtr(hPal, PALETTE_MAGIC);
196 if (!palPtr) return FALSE;
197
198 if( (StartIndex + NumEntries) <= palPtr->logpalette.palNumEntries )
199 {
200 UINT u;
201 for( u = 0; u < NumEntries; u++ )
202 palPtr->logpalette.palPalEntry[u + StartIndex] = PaletteColors[u];
203 PALETTE_Driver->pSetMapping(palPtr, StartIndex, NumEntries, hPal != hPrimaryPalette );
204 GDI_ReleaseObj(hPal);
205 return TRUE;
206 }
207 GDI_ReleaseObj(hPal);
208 }
209 return FALSE;
210 */
211 UNIMPLEMENTED;
212 }
213
214 HPALETTE STDCALL NtGdiCreateHalftonePalette(HDC hDC)
215 {
216 int i, r, g, b;
217 struct {
218 WORD Version;
219 WORD NumberOfEntries;
220 PALETTEENTRY aEntries[256];
221 } Palette;
222
223 Palette.Version = 0x300;
224 Palette.NumberOfEntries = 256;
225 NtGdiGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries);
226
227 for (r = 0; r < 6; r++) {
228 for (g = 0; g < 6; g++) {
229 for (b = 0; b < 6; b++) {
230 i = r + g*6 + b*36 + 10;
231 Palette.aEntries[i].peRed = r * 51;
232 Palette.aEntries[i].peGreen = g * 51;
233 Palette.aEntries[i].peBlue = b * 51;
234 }
235 }
236 }
237
238 for (i = 216; i < 246; i++) {
239 int v = (i - 216) * 8;
240 Palette.aEntries[i].peRed = v;
241 Palette.aEntries[i].peGreen = v;
242 Palette.aEntries[i].peBlue = v;
243 }
244
245 return NtGdiCreatePalette((LOGPALETTE *)&Palette);
246 }
247
248 HPALETTE STDCALL NtGdiCreatePalette(CONST PLOGPALETTE palette)
249 {
250 PPALOBJ PalObj;
251
252 HPALETTE NewPalette = PALETTE_AllocPalette(
253 PAL_INDEXED,
254 palette->palNumEntries,
255 (PULONG)palette->palPalEntry,
256 0, 0, 0);
257 ULONG size;
258
259 PalObj = (PPALOBJ) PALETTE_LockPalette(NewPalette);
260
261 size = sizeof(LOGPALETTE) + (palette->palNumEntries * sizeof(PALETTEENTRY));
262 PalObj->logpalette = ExAllocatePool(NonPagedPool, size);
263 memcpy(PalObj->logpalette, palette, size);
264 PALETTE_ValidateFlags(PalObj->logpalette->palPalEntry, PalObj->logpalette->palNumEntries);
265 PalObj->logicalToSystem = NULL;
266
267 PALETTE_UnlockPalette(NewPalette);
268
269 return NewPalette;
270 }
271
272 BOOL STDCALL NtGdiGetColorAdjustment(HDC hDC,
273 LPCOLORADJUSTMENT ca)
274 {
275 UNIMPLEMENTED;
276 }
277
278 COLORREF STDCALL NtGdiGetNearestColor(HDC hDC,
279 COLORREF Color)
280 {
281 COLORREF nearest = CLR_INVALID;
282 PDC dc;
283 PPALOBJ palObj;
284
285 dc = DC_LockDc(hDC);
286 if (NULL != dc)
287 {
288 HPALETTE hpal = (dc->w.hPalette) ? dc->w.hPalette : NtGdiGetStockObject(DEFAULT_PALETTE);
289 palObj = (PPALOBJ) PALETTE_LockPalette(hpal);
290 if (!palObj)
291 {
292 DC_UnlockDc(hDC);
293 return nearest;
294 }
295
296 nearest = COLOR_LookupNearestColor(palObj->logpalette->palPalEntry,
297 palObj->logpalette->palNumEntries, Color);
298 PALETTE_UnlockPalette(hpal);
299 DC_UnlockDc( hDC );
300 }
301
302 return nearest;
303 }
304
305 UINT STDCALL NtGdiGetNearestPaletteIndex(HPALETTE hpal,
306 COLORREF Color)
307 {
308 PPALOBJ palObj = (PPALOBJ) PALETTE_LockPalette(hpal);
309 UINT index = 0;
310
311 if (NULL != palObj)
312 {
313 /* Return closest match for the given RGB color */
314 index = COLOR_PaletteLookupPixel(palObj->logpalette->palPalEntry, palObj->logpalette->palNumEntries, NULL, Color, FALSE);
315 PALETTE_UnlockPalette(hpal);
316 }
317
318 return index;
319 }
320
321 UINT STDCALL NtGdiGetPaletteEntries(HPALETTE hpal,
322 UINT StartIndex,
323 UINT Entries,
324 LPPALETTEENTRY pe)
325 {
326 PPALOBJ palPtr;
327 UINT numEntries;
328
329 palPtr = (PPALOBJ) PALETTE_LockPalette(hpal);
330 if (NULL == palPtr)
331 {
332 return 0;
333 }
334
335 numEntries = palPtr->logpalette->palNumEntries;
336 if (numEntries < StartIndex + Entries)
337 {
338 Entries = numEntries - StartIndex;
339 }
340 if (NULL != pe)
341 {
342 if (numEntries <= StartIndex)
343 {
344 PALETTE_UnlockPalette(hpal);
345 return 0;
346 }
347 memcpy(pe, &palPtr->logpalette->palPalEntry[StartIndex], Entries * sizeof(PALETTEENTRY));
348 for (numEntries = 0; numEntries < Entries; numEntries++)
349 {
350 if (pe[numEntries].peFlags & 0xF0)
351 {
352 pe[numEntries].peFlags = 0;
353 }
354 }
355 }
356
357 PALETTE_UnlockPalette(hpal);
358 return Entries;
359 }
360
361 UINT STDCALL NtGdiGetSystemPaletteEntries(HDC hDC,
362 UINT StartIndex,
363 UINT Entries,
364 LPPALETTEENTRY pe)
365 {
366 //UINT i;
367 //PDC dc;
368 /*
369 if (!(dc = AccessUserObject(hdc))) return 0;
370
371 if (!pe)
372 {
373 Entries = dc->GDIInfo->ulNumPalReg;
374 goto done;
375 }
376
377 if (StartIndex >= dc->GDIInfo->ulNumPalReg)
378 {
379 Entries = 0;
380 goto done;
381 }
382
383 if (StartIndex + Entries >= dc->GDIInfo->ulNumPalReg) Entries = dc->GDIInfo->ulNumPalReg - StartIndex;
384
385 for (i = 0; i < Entries; i++)
386 {
387 *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry(StartIndex + i);
388 }
389
390 done:
391 // GDI_ReleaseObj(hdc);
392 return count; */
393 // FIXME UNIMPLEMENTED;
394 return 0;
395 }
396
397 UINT STDCALL NtGdiGetSystemPaletteUse(HDC hDC)
398 {
399 UNIMPLEMENTED;
400 return 0;
401 }
402
403 /*!
404 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.
405
406 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.
407
408 1= IF DRAWING TO A DEVICE
409 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
410 the system palette.
411 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the system palette.
412
413 2= IF DRAWING TO A MEMORY DC\BITMAP
414 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
415 the dc palette.
416 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette.
417 */
418 UINT STDCALL NtGdiRealizePalette(HDC hDC)
419 {
420 PPALOBJ palPtr, sysPtr;
421 PPALGDI palGDI, sysGDI;
422 int realized = 0;
423 PDC dc;
424 HPALETTE systemPalette;
425 PSURFGDI SurfGDI;
426 BOOLEAN success;
427 USHORT sysMode, palMode;
428
429 dc = DC_LockDc(hDC);
430 if (!dc)
431 return 0;
432
433 SurfGDI = (PSURFGDI)AccessInternalObject((ULONG)dc->Surface);
434 systemPalette = NtGdiGetStockObject((INT)DEFAULT_PALETTE);
435 palGDI = PALETTE_LockPalette(dc->w.hPalette);
436 palPtr = (PPALOBJ) palGDI;
437 sysGDI = PALETTE_LockPalette(systemPalette);
438 sysPtr = (PPALOBJ) sysGDI;
439
440 // Step 1: Create mapping of system palette\DC palette
441 realized = PALETTE_SetMapping(palPtr, 0, palPtr->logpalette->palNumEntries,
442 (dc->w.hPalette != hPrimaryPalette) ||
443 (dc->w.hPalette == NtGdiGetStockObject(DEFAULT_PALETTE)));
444
445 // Step 2:
446 // The RealizePalette function modifies the palette for the device associated with the specified device context. If the
447 // device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
448 // context is a display DC, the physical palette for that device is modified.
449 if(dc->w.flags == DC_MEMORY)
450 {
451 // Memory managed DC
452 DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
453 } else {
454 if(SurfGDI->SetPalette)
455 {
456 success = SurfGDI->SetPalette(dc->PDev, sysPtr, 0, 0, sysPtr->logpalette->palNumEntries);
457 }
458 }
459
460 // need to pass this to IntEngCreateXlate with palettes unlocked
461 sysMode = sysGDI->Mode;
462 palMode = palGDI->Mode;
463 PALETTE_UnlockPalette(systemPalette);
464 PALETTE_UnlockPalette(dc->w.hPalette);
465
466 // Step 3: Create the XLATEOBJ for device managed DCs
467 if(dc->w.flags != DC_MEMORY)
468 {
469 // Device managed DC
470 palPtr->logicalToSystem = IntEngCreateXlate(sysGDI->Mode, palGDI->Mode, systemPalette, dc->w.hPalette);
471 }
472
473 DC_UnlockDc(hDC);
474
475 return realized;
476 }
477
478 BOOL STDCALL NtGdiResizePalette(HPALETTE hpal,
479 UINT Entries)
480 {
481 /* PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal);
482 UINT cPrevEnt, prevVer;
483 INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
484 PXLATEOBJ XlateObj = NULL;
485
486 if(!palPtr) return FALSE;
487 cPrevEnt = palPtr->logpalette->palNumEntries;
488 prevVer = palPtr->logpalette->palVersion;
489 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
490 size += sizeof(int*) + sizeof(GDIOBJHDR);
491 XlateObj = palPtr->logicalToSystem;
492
493 if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
494
495 if(XlateObj)
496 {
497 PXLATEOBJ NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
498 if(NewXlateObj == NULL)
499 {
500 ERR("Can not resize logicalToSystem -- out of memory!");
501 GDI_ReleaseObj( hPal );
502 return FALSE;
503 }
504 palPtr->logicalToSystem = NewXlateObj;
505 }
506
507 if(cEntries > cPrevEnt)
508 {
509 if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
510 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
511 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
512 }
513 palPtr->logpalette->palNumEntries = cEntries;
514 palPtr->logpalette->palVersion = prevVer;
515 // GDI_ReleaseObj( hPal );
516 return TRUE; */
517
518 UNIMPLEMENTED;
519 }
520
521 /*!
522 * Select logical palette into device context.
523 * \param hDC handle to the device context
524 * \param hpal handle to the palette
525 * \param ForceBackground If this value is FALSE the logical palette will be copied to the device palette only when the applicatioon
526 * is in the foreground. If this value is TRUE then map the colors in the logical palette to the device
527 * palette colors in the best way.
528 * \return old palette
529 *
530 * \todo implement ForceBackground == TRUE
531 */
532 HPALETTE STDCALL NtGdiSelectPalette(HDC hDC,
533 HPALETTE hpal,
534 BOOL ForceBackground)
535 {
536 PDC dc;
537 HPALETTE oldPal;
538 PPALGDI PalGDI;
539
540 // FIXME: mark the palette as a [fore\back]ground pal
541 dc = DC_LockDc(hDC);
542 if (NULL != dc)
543 {
544 /* Check if this is a valid palette handle */
545 PalGDI = PALETTE_LockPalette(hpal);
546 if (NULL != PalGDI)
547 {
548 PALETTE_UnlockPalette(hpal);
549 oldPal = dc->w.hPalette;
550 dc->w.hPalette = hpal;
551 }
552 else
553 {
554 oldPal = NULL;
555 }
556 DC_UnlockDc(hDC);
557 }
558
559 return oldPal;
560 }
561
562 BOOL STDCALL NtGdiSetColorAdjustment(HDC hDC,
563 CONST LPCOLORADJUSTMENT ca)
564 {
565 UNIMPLEMENTED;
566 }
567
568 UINT STDCALL NtGdiSetPaletteEntries(HPALETTE hpal,
569 UINT Start,
570 UINT Entries,
571 CONST LPPALETTEENTRY pe)
572 {
573 PPALOBJ palPtr;
574 WORD numEntries;
575
576 palPtr = (PPALOBJ)PALETTE_LockPalette(hpal);
577 if (!palPtr) return 0;
578
579 numEntries = palPtr->logpalette->palNumEntries;
580 if (Start >= numEntries)
581 {
582 PALETTE_UnlockPalette(hpal);
583 return 0;
584 }
585 if (numEntries < Start + Entries)
586 {
587 Entries = numEntries - Start;
588 }
589 memcpy(&palPtr->logpalette->palPalEntry[Start], pe, Entries * sizeof(PALETTEENTRY));
590 PALETTE_ValidateFlags(palPtr->logpalette->palPalEntry, palPtr->logpalette->palNumEntries);
591 ExFreePool(palPtr->logicalToSystem);
592 palPtr->logicalToSystem = NULL;
593 PALETTE_UnlockPalette(hpal);
594
595 return Entries;
596 }
597
598 UINT STDCALL NtGdiSetSystemPaletteUse(HDC hDC,
599 UINT Usage)
600 {
601 UNIMPLEMENTED;
602 }
603
604 BOOL STDCALL NtGdiUnrealizeObject(HGDIOBJ hgdiobj)
605 {
606 UNIMPLEMENTED;
607 }
608
609 BOOL STDCALL NtGdiUpdateColors(HDC hDC)
610 {
611 //PDC dc;
612 //HWND hWnd;
613 //int size;
614 /*
615 if (!(dc = AccessUserObject(hDC))) return 0;
616 size = dc->GDIInfo->ulNumPalReg;
617 // GDI_ReleaseObj( hDC );
618
619 if (Callout.WindowFromDC)
620 {
621 hWnd = Callout.WindowFromDC( hDC );
622
623 // Docs say that we have to remap current drawable pixel by pixel
624 // but it would take forever given the speed of XGet/PutPixel.
625 if (hWnd && size) Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
626 } */
627 // FIXME UNIMPLEMENTED
628 return 0x666;
629 }
630
631 INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size,
632 PXLATEOBJ XlateObj, COLORREF col, BOOL skipReserved)
633 {
634 int i, best = 0, diff = 0x7fffffff;
635 int r, g, b;
636
637 for( i = 0; i < size && diff ; i++ )
638 {
639 if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED))
640 continue;
641
642 r = palPalEntry[i].peRed - GetRValue(col);
643 g = palPalEntry[i].peGreen - GetGValue(col);
644 b = palPalEntry[i].peBlue - GetBValue(col);
645
646 r = r*r + g*g + b*b;
647
648 if( r < diff ) { best = i; diff = r; }
649 }
650
651 if (XlateObj == NULL)
652 return best;
653 else
654 return (XlateObj->pulXlate) ? (INT)XlateObj->pulXlate[best] : best;
655 }
656
657 COLORREF STDCALL COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
658 {
659 unsigned char spec_type = color >> 24;
660 int i;
661 PALETTEENTRY *COLOR_sysPal = (PALETTEENTRY*)ReturnSystemPalette();
662
663 // we need logical palette for PALETTERGB and PALETTEINDEX colorrefs
664
665 if( spec_type == 2 ) /* PALETTERGB */
666 color = *(COLORREF*)(palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
667
668 else if( spec_type == 1 ) /* PALETTEINDEX */
669 {
670 if( (i = color & 0x0000ffff) >= size )
671 {
672 DbgPrint("RGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
673 color = *(COLORREF*)palPalEntry;
674 }
675 else color = *(COLORREF*)(palPalEntry + i);
676 }
677
678 color &= 0x00ffffff;
679 return (0x00ffffff & *(COLORREF*)(COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
680 }
681
682 int STDCALL COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
683 COLORREF col )
684 {
685 int i;
686 BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
687 for( i = 0; i < size; i++ )
688 {
689 if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
690 if(palPalEntry[i].peRed == r && palPalEntry[i].peGreen == g && palPalEntry[i].peBlue == b) return i;
691 }
692 return -1;
693 }
694 /* EOF */