fix winquake color glitc bug
[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$ */
20 #include <w32k.h>
21
22 // FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
23
24 int COLOR_gapStart = 256;
25 int COLOR_gapEnd = -1;
26 int COLOR_gapFilled = 0;
27 int COLOR_max = 256;
28
29 #ifndef NO_MAPPING
30 static HPALETTE hPrimaryPalette = 0; // used for WM_PALETTECHANGED
31 #endif
32 //static HPALETTE hLastRealizedPalette = 0; // UnrealizeObject() needs it
33
34
35 static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the palate and restore it */
36
37 const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS] =
38 {
39 // first 10 entries in the system palette
40 // red green blue flags
41 { 0x00, 0x00, 0x00, PC_SYS_USED },
42 { 0x80, 0x00, 0x00, PC_SYS_USED },
43 { 0x00, 0x80, 0x00, PC_SYS_USED },
44 { 0x80, 0x80, 0x00, PC_SYS_USED },
45 { 0x00, 0x00, 0x80, PC_SYS_USED },
46 { 0x80, 0x00, 0x80, PC_SYS_USED },
47 { 0x00, 0x80, 0x80, PC_SYS_USED },
48 { 0xc0, 0xc0, 0xc0, PC_SYS_USED },
49 { 0xc0, 0xdc, 0xc0, PC_SYS_USED },
50 { 0xd4, 0xd0, 0xc7, PC_SYS_USED },
51
52 // ... c_min/2 dynamic colorcells
53 // ... gap (for sparse palettes)
54 // ... c_min/2 dynamic colorcells
55
56 { 0xff, 0xfb, 0xf0, PC_SYS_USED },
57 { 0x3a, 0x6e, 0xa5, PC_SYS_USED },
58 { 0x80, 0x80, 0x80, PC_SYS_USED },
59 { 0xff, 0x00, 0x00, PC_SYS_USED },
60 { 0x00, 0xff, 0x00, PC_SYS_USED },
61 { 0xff, 0xff, 0x00, PC_SYS_USED },
62 { 0x00, 0x00, 0xff, PC_SYS_USED },
63 { 0xff, 0x00, 0xff, PC_SYS_USED },
64 { 0x00, 0xff, 0xff, PC_SYS_USED },
65 { 0xff, 0xff, 0xff, PC_SYS_USED } // last 10
66 };
67
68 const PALETTEENTRY* FASTCALL COLOR_GetSystemPaletteTemplate(void)
69 {
70 return (const PALETTEENTRY*)&COLOR_sysPalTemplate;
71 }
72
73 BOOL STDCALL NtGdiAnimatePalette(HPALETTE hPal, UINT StartIndex,
74 UINT NumEntries, CONST PPALETTEENTRY PaletteColors)
75 {
76 if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) )
77 {
78 PPALGDI palPtr;
79 UINT pal_entries;
80 HDC hDC;
81 PDC dc;
82 HWND hHwd;
83 const PALETTEENTRY *pptr = PaletteColors;
84
85 palPtr = (PPALGDI)PALETTE_LockPalette(hPal);
86 if (!palPtr) return FALSE;
87
88 pal_entries = palPtr->NumColors;
89 if (StartIndex >= pal_entries)
90 {
91 PALETTE_UnlockPalette(hPal);
92 return FALSE;
93 }
94 if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex;
95
96 for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) {
97 /* According to MSDN, only animate PC_RESERVED colours */
98 if (palPtr->IndexedColors[StartIndex].peFlags & PC_RESERVED) {
99 memcpy( &palPtr->IndexedColors[StartIndex], pptr,
100 sizeof(PALETTEENTRY) );
101 PALETTE_ValidateFlags(&palPtr->IndexedColors[StartIndex], 1);
102 }
103 }
104
105 PALETTE_UnlockPalette(hPal);
106
107 /* Immediately apply the new palette if current window uses it */
108 hHwd = NtUserGetDesktopWindow();
109 hDC = (HDC)NtUserGetWindowDC(hHwd);
110 dc = DC_LockDc(hDC);
111 if (NULL != dc)
112 {
113 if (dc->w.hPalette == hPal)
114 {
115 DC_UnlockDc(hDC);
116 NtGdiRealizePalette(hDC);
117 }
118 else
119 DC_UnlockDc(hDC);
120 }
121 NtUserReleaseDC(hHwd,hDC);
122 }
123 return TRUE;
124 }
125
126 HPALETTE STDCALL NtGdiCreateHalftonePalette(HDC hDC)
127 {
128 int i, r, g, b;
129 struct {
130 WORD Version;
131 WORD NumberOfEntries;
132 PALETTEENTRY aEntries[256];
133 } Palette;
134
135 Palette.Version = 0x300;
136 Palette.NumberOfEntries = 256;
137 if (NtGdiGetSystemPaletteEntries(hDC, 0, 256, Palette.aEntries) == 0)
138 {
139 return 0;
140 }
141
142 for (r = 0; r < 6; r++)
143 for (g = 0; g < 6; g++)
144 for (b = 0; b < 6; b++)
145 {
146 i = r + g*6 + b*36 + 10;
147 Palette.aEntries[i].peRed = r * 51;
148 Palette.aEntries[i].peGreen = g * 51;
149 Palette.aEntries[i].peBlue = b * 51;
150 }
151
152 for (i = 216; i < 246; i++)
153 {
154 int v = (i - 216) << 3;
155 Palette.aEntries[i].peRed = v;
156 Palette.aEntries[i].peGreen = v;
157 Palette.aEntries[i].peBlue = v;
158 }
159
160 return NtGdiCreatePalette((LOGPALETTE *)&Palette);
161 }
162
163 HPALETTE STDCALL NtGdiCreatePalette(CONST PLOGPALETTE palette)
164 {
165 PPALGDI PalGDI;
166
167 HPALETTE NewPalette = PALETTE_AllocPalette(
168 PAL_INDEXED,
169 palette->palNumEntries,
170 (PULONG)palette->palPalEntry,
171 0, 0, 0);
172
173 PalGDI = (PPALGDI) PALETTE_LockPalette(NewPalette);
174 /* FIXME - Handle PalGDI == NULL!!!! */
175
176 PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors);
177 PalGDI->logicalToSystem = NULL;
178
179 PALETTE_UnlockPalette(NewPalette);
180
181 return NewPalette;
182 }
183
184 BOOL STDCALL NtGdiGetColorAdjustment(HDC hDC,
185 LPCOLORADJUSTMENT ca)
186 {
187 UNIMPLEMENTED;
188 return FALSE;
189 }
190
191 unsigned short GetNumberOfBits(unsigned int dwMask)
192 {
193 unsigned short wBits;
194 for (wBits = 0; dwMask; dwMask = dwMask & (dwMask - 1))
195 wBits++;
196 return wBits;
197 }
198
199 COLORREF STDCALL NtGdiGetNearestColor(HDC hDC, COLORREF Color)
200 {
201 COLORREF nearest = CLR_INVALID;
202 PDC dc;
203 PPALGDI palGDI;
204 LONG RBits, GBits, BBits;
205
206 dc = DC_LockDc(hDC);
207 if (NULL != dc)
208 {
209 HPALETTE hpal = dc->w.hPalette;
210 palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
211 if (!palGDI)
212 {
213 DC_UnlockDc(hDC);
214 return nearest;
215 }
216
217 switch (palGDI->Mode)
218 {
219 case PAL_INDEXED:
220 nearest = COLOR_LookupNearestColor(palGDI->IndexedColors,
221 palGDI->NumColors, Color);
222 break;
223 case PAL_BGR:
224 case PAL_RGB:
225 nearest = Color;
226 break;
227 case PAL_BITFIELDS:
228 RBits = 8 - GetNumberOfBits(palGDI->RedMask);
229 GBits = 8 - GetNumberOfBits(palGDI->GreenMask);
230 BBits = 8 - GetNumberOfBits(palGDI->BlueMask);
231 nearest = RGB(
232 (GetRValue(Color) >> RBits) << RBits,
233 (GetGValue(Color) >> GBits) << GBits,
234 (GetBValue(Color) >> BBits) << BBits);
235 break;
236 }
237 PALETTE_UnlockPalette(hpal);
238 DC_UnlockDc(hDC);
239 }
240
241 return nearest;
242 }
243
244 UINT STDCALL NtGdiGetNearestPaletteIndex(HPALETTE hpal,
245 COLORREF Color)
246 {
247 PPALGDI palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
248 UINT index = 0;
249
250 if (NULL != palGDI)
251 {
252 /* Return closest match for the given RGB color */
253 index = COLOR_PaletteLookupPixel(palGDI->IndexedColors, palGDI->NumColors, NULL, Color, FALSE);
254 PALETTE_UnlockPalette(hpal);
255 }
256
257 return index;
258 }
259
260 UINT STDCALL NtGdiGetPaletteEntries(HPALETTE hpal,
261 UINT StartIndex,
262 UINT Entries,
263 LPPALETTEENTRY pe)
264 {
265 PPALGDI palGDI;
266 UINT numEntries;
267
268 palGDI = (PPALGDI) PALETTE_LockPalette(hpal);
269 if (NULL == palGDI)
270 {
271 return 0;
272 }
273
274 numEntries = palGDI->NumColors;
275 if (numEntries < StartIndex + Entries)
276 {
277 Entries = numEntries - StartIndex;
278 }
279 if (NULL != pe)
280 {
281 if (numEntries <= StartIndex)
282 {
283 PALETTE_UnlockPalette(hpal);
284 return 0;
285 }
286 memcpy(pe, palGDI->IndexedColors + StartIndex, Entries * sizeof(PALETTEENTRY));
287 for (numEntries = 0; numEntries < Entries; numEntries++)
288 {
289 if (pe[numEntries].peFlags & 0xF0)
290 {
291 pe[numEntries].peFlags = 0;
292 }
293 }
294 }
295
296 PALETTE_UnlockPalette(hpal);
297 return Entries;
298 }
299
300 UINT STDCALL NtGdiGetSystemPaletteEntries(HDC hDC,
301 UINT StartIndex,
302 UINT Entries,
303 LPPALETTEENTRY pe)
304 {
305 //UINT i;
306 //PDC dc;
307 /*
308 if (!(dc = AccessUserObject(hdc))) return 0;
309
310 if (!pe)
311 {
312 Entries = dc->GDIInfo->ulNumPalReg;
313 goto done;
314 }
315
316 if (StartIndex >= dc->GDIInfo->ulNumPalReg)
317 {
318 Entries = 0;
319 goto done;
320 }
321
322 if (StartIndex + Entries >= dc->GDIInfo->ulNumPalReg) Entries = dc->GDIInfo->ulNumPalReg - StartIndex;
323
324 for (i = 0; i < Entries; i++)
325 {
326 *(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry(StartIndex + i);
327 }
328
329 done:
330 // GDI_ReleaseObj(hdc);
331 return count; */
332 // FIXME UNIMPLEMENTED;
333 return 0;
334 }
335
336 UINT STDCALL NtGdiGetSystemPaletteUse(HDC hDC)
337 {
338 return SystemPaletteUse;
339 }
340
341 /*!
342 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.
343
344 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.
345
346 1= IF DRAWING TO A DEVICE
347 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
348 the system palette.
349 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the system palette.
350
351 2= IF DRAWING TO A MEMORY DC\BITMAP
352 -- If it is a paletted bitmap, and is not an identity palette, then an XLATEOBJ is created between the logical palette and
353 the dc palette.
354 -- If it is an RGB palette, then an XLATEOBJ is created between the RGB values and the dc palette.
355 */
356 UINT STDCALL NtGdiRealizePalette(HDC hDC)
357 {
358 /*
359 * This function doesn't do any real work now and there's plenty
360 * of bugd in it (calling SetPalette for high/true-color modes,
361 * using DEFAULT_PALETTE instead of the device palette, ...).
362 */
363
364 PALOBJ *palPtr, *sysPtr;
365 PPALGDI palGDI, sysGDI;
366 int realized = 0;
367 PDC dc;
368 HPALETTE systemPalette;
369 BOOLEAN success;
370 USHORT sysMode, palMode;
371
372 dc = DC_LockDc(hDC);
373 if (!dc)
374 return 0;
375
376 systemPalette = NtGdiGetStockObject((INT)DEFAULT_PALETTE);
377 palGDI = PALETTE_LockPalette(dc->w.hPalette);
378 palPtr = (PALOBJ*) palGDI;
379 /* FIXME - Handle palGDI == NULL!!!! */
380
381 // Step 1: Create mapping of system palette\DC palette
382 #ifndef NO_MAPPING
383 realized = PALETTE_SetMapping(palPtr, 0, palGDI->NumColors,
384 (dc->w.hPalette != hPrimaryPalette) ||
385 (dc->w.hPalette == NtGdiGetStockObject(DEFAULT_PALETTE)));
386 #else
387 realized = 0;
388 #endif
389
390 sysGDI = PALETTE_LockPalette(systemPalette);
391 sysPtr = (PALOBJ*) sysGDI;
392 /* FIXME - Handle sysGDI == NULL!!!!! */
393
394 // Step 2:
395 // The RealizePalette function modifies the palette for the device associated with the specified device context. If the
396 // device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
397 // context is a display DC, the physical palette for that device is modified.
398 if(dc->w.flags == DC_MEMORY)
399 {
400 // Memory managed DC
401 DbgPrint("win32k: realizepalette unimplemented step 2 for DC_MEMORY");
402 } else {
403 if( ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette)
404 {
405 ASSERT(palGDI->NumColors <= 256);
406 success = ((GDIDEVICE *)dc->GDIDevice)->DriverFunctions.SetPalette(
407 dc->PDev, palPtr, 0, 0, palGDI->NumColors);
408 }
409 }
410
411 // need to pass this to IntEngCreateXlate with palettes unlocked
412 sysMode = sysGDI->Mode;
413 palMode = palGDI->Mode;
414 PALETTE_UnlockPalette(systemPalette);
415 PALETTE_UnlockPalette(dc->w.hPalette);
416
417 // Step 3: Create the XLATEOBJ for device managed DCs
418 if(dc->w.flags != DC_MEMORY)
419 {
420 // Device managed DC
421 palGDI->logicalToSystem = IntEngCreateXlate(sysMode, palMode, systemPalette, dc->w.hPalette);
422 }
423
424 DC_UnlockDc(hDC);
425
426 return realized;
427 }
428
429 BOOL STDCALL NtGdiResizePalette(HPALETTE hpal,
430 UINT Entries)
431 {
432 /* PALOBJ *palPtr = (PALOBJ*)AccessUserObject(hPal);
433 UINT cPrevEnt, prevVer;
434 INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
435 XLATEOBJ *XlateObj = NULL;
436
437 if(!palPtr) return FALSE;
438 cPrevEnt = palPtr->logpalette->palNumEntries;
439 prevVer = palPtr->logpalette->palVersion;
440 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
441 size += sizeof(int*) + sizeof(GDIOBJHDR);
442 XlateObj = palPtr->logicalToSystem;
443
444 if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
445
446 if(XlateObj)
447 {
448 XLATEOBJ *NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
449 if(NewXlateObj == NULL)
450 {
451 ERR("Can not resize logicalToSystem -- out of memory!");
452 GDI_ReleaseObj( hPal );
453 return FALSE;
454 }
455 palPtr->logicalToSystem = NewXlateObj;
456 }
457
458 if(cEntries > cPrevEnt)
459 {
460 if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
461 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
462 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
463 }
464 palPtr->logpalette->palNumEntries = cEntries;
465 palPtr->logpalette->palVersion = prevVer;
466 // GDI_ReleaseObj( hPal );
467 return TRUE; */
468
469 UNIMPLEMENTED;
470 return FALSE;
471 }
472
473 /*!
474 * Select logical palette into device context.
475 * \param hDC handle to the device context
476 * \param hpal handle to the palette
477 * \param ForceBackground If this value is FALSE the logical palette will be copied to the device palette only when the applicatioon
478 * is in the foreground. If this value is TRUE then map the colors in the logical palette to the device
479 * palette colors in the best way.
480 * \return old palette
481 *
482 * \todo implement ForceBackground == TRUE
483 */
484 HPALETTE STDCALL NtGdiSelectPalette(HDC hDC,
485 HPALETTE hpal,
486 BOOL ForceBackground)
487 {
488 PDC dc;
489 HPALETTE oldPal = NULL;
490 PPALGDI PalGDI;
491
492 // FIXME: mark the palette as a [fore\back]ground pal
493 dc = DC_LockDc(hDC);
494 if (NULL != dc)
495 {
496 /* Check if this is a valid palette handle */
497 PalGDI = PALETTE_LockPalette(hpal);
498 if (NULL != PalGDI)
499 {
500 /* Is this a valid palette for this depth? */
501 if ((dc->w.bitsPerPixel <= 8 && PAL_INDEXED == PalGDI->Mode)
502 || (8 < dc->w.bitsPerPixel && PAL_INDEXED != PalGDI->Mode))
503 {
504 PALETTE_UnlockPalette(hpal);
505 oldPal = dc->w.hPalette;
506 dc->w.hPalette = hpal;
507 }
508 else
509 {
510 PALETTE_UnlockPalette(hpal);
511 oldPal = NULL;
512 }
513 }
514 else
515 {
516 oldPal = NULL;
517 }
518 DC_UnlockDc(hDC);
519 }
520
521 return oldPal;
522 }
523
524 BOOL STDCALL NtGdiSetColorAdjustment(HDC hDC,
525 CONST LPCOLORADJUSTMENT ca)
526 {
527 UNIMPLEMENTED;
528 return FALSE;
529 }
530
531 UINT STDCALL NtGdiSetPaletteEntries(HPALETTE hpal,
532 UINT Start,
533 UINT Entries,
534 CONST LPPALETTEENTRY pe)
535 {
536 PPALGDI palGDI;
537 WORD numEntries;
538
539 palGDI = PALETTE_LockPalette(hpal);
540 if (!palGDI) return 0;
541
542 numEntries = palGDI->NumColors;
543 if (Start >= numEntries)
544 {
545 PALETTE_UnlockPalette(hpal);
546 return 0;
547 }
548 if (numEntries < Start + Entries)
549 {
550 Entries = numEntries - Start;
551 }
552 memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY));
553 PALETTE_ValidateFlags(palGDI->IndexedColors, palGDI->NumColors);
554 ExFreePool(palGDI->logicalToSystem);
555 palGDI->logicalToSystem = NULL;
556 PALETTE_UnlockPalette(hpal);
557
558 return Entries;
559 }
560
561 UINT STDCALL
562 NtGdiSetSystemPaletteUse(HDC hDC, UINT Usage)
563 {
564 UINT old = SystemPaletteUse;
565
566 /* Device doesn't support colour palettes */
567 if (!(NtGdiGetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE)) {
568 return SYSPAL_ERROR;
569 }
570
571 switch (Usage)
572 {
573 case SYSPAL_NOSTATIC:
574 case SYSPAL_NOSTATIC256:
575 case SYSPAL_STATIC:
576 SystemPaletteUse = Usage;
577 break;
578
579 default:
580 old=SYSPAL_ERROR;
581 break;
582 }
583
584 return old;
585 }
586
587 BOOL STDCALL
588 NtGdiUnrealizeObject(HGDIOBJ hgdiobj)
589 {
590 UNIMPLEMENTED;
591 return FALSE;
592 }
593
594 BOOL STDCALL
595 NtGdiUpdateColors(HDC hDC)
596 {
597 HWND hWnd;
598
599 hWnd = (HWND)NtUserCallOneParam((DWORD)hDC, ONEPARAM_ROUTINE_WINDOWFROMDC);
600 if (hWnd == NULL)
601 {
602 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
603 return FALSE;
604 }
605 return NtUserRedrawWindow(hWnd, NULL, 0, RDW_INVALIDATE);
606 }
607
608 INT STDCALL COLOR_PaletteLookupPixel(PALETTEENTRY *palPalEntry, INT size,
609 XLATEOBJ *XlateObj, COLORREF col, BOOL skipReserved)
610 {
611 int i, best = 0, diff = 0x7fffffff;
612 int r, g, b;
613
614 for( i = 0; i < size && diff ; i++ )
615 {
616 #if 0
617 if(!(palPalEntry[i].peFlags & PC_SYS_USED) || (skipReserved && palPalEntry[i].peFlags & PC_SYS_RESERVED))
618 continue;
619 #endif
620
621 r = abs((SHORT)palPalEntry[i].peRed - GetRValue(col));
622 g = abs((SHORT)palPalEntry[i].peGreen - GetGValue(col));
623 b = abs((SHORT)palPalEntry[i].peBlue - GetBValue(col));
624
625 r = r*r + g*g + b*b;
626
627 if( r < diff ) { best = i; diff = r; }
628 }
629
630 if (XlateObj == NULL)
631 return best;
632 else
633 return (XlateObj->pulXlate) ? (INT)XlateObj->pulXlate[best] : best;
634 }
635
636 COLORREF STDCALL COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
637 {
638 INT index;
639
640 index = COLOR_PaletteLookupPixel(palPalEntry, size, NULL, color, FALSE);
641 return RGB(
642 palPalEntry[index].peRed,
643 palPalEntry[index].peGreen,
644 palPalEntry[index].peBlue);
645 }
646
647 int STDCALL COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
648 COLORREF col )
649 {
650 int i;
651 BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
652 for( i = 0; i < size; i++ )
653 {
654 if( palPalEntry[i].peFlags & PC_SYS_USED ) /* skips gap */
655 if(palPalEntry[i].peRed == r && palPalEntry[i].peGreen == g && palPalEntry[i].peBlue == b) return i;
656 }
657 return -1;
658 }
659 /* EOF */