2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Palette Functions
5 * FILE: subsys/win32k/eng/palette.c
6 * PROGRAMERS: Jason Filby
15 static UINT SystemPaletteUse
= SYSPAL_NOSTATIC
; /* the program need save the pallete and restore it */
17 PALETTE gpalRGB
, gpalBGR
;
19 const PALETTEENTRY g_sysPalTemplate
[NB_RESERVED_COLORS
] =
21 // first 10 entries in the system palette
22 // red green blue flags
23 { 0x00, 0x00, 0x00, PC_SYS_USED
},
24 { 0x80, 0x00, 0x00, PC_SYS_USED
},
25 { 0x00, 0x80, 0x00, PC_SYS_USED
},
26 { 0x80, 0x80, 0x00, PC_SYS_USED
},
27 { 0x00, 0x00, 0x80, PC_SYS_USED
},
28 { 0x80, 0x00, 0x80, PC_SYS_USED
},
29 { 0x00, 0x80, 0x80, PC_SYS_USED
},
30 { 0xc0, 0xc0, 0xc0, PC_SYS_USED
},
31 { 0xc0, 0xdc, 0xc0, PC_SYS_USED
},
32 { 0xa6, 0xca, 0xf0, PC_SYS_USED
},
34 // ... c_min/2 dynamic colorcells
35 // ... gap (for sparse palettes)
36 // ... c_min/2 dynamic colorcells
38 { 0xff, 0xfb, 0xf0, PC_SYS_USED
},
39 { 0xa0, 0xa0, 0xa4, PC_SYS_USED
},
40 { 0x80, 0x80, 0x80, PC_SYS_USED
},
41 { 0xff, 0x00, 0x00, PC_SYS_USED
},
42 { 0x00, 0xff, 0x00, PC_SYS_USED
},
43 { 0xff, 0xff, 0x00, PC_SYS_USED
},
44 { 0x00, 0x00, 0xff, PC_SYS_USED
},
45 { 0xff, 0x00, 0xff, PC_SYS_USED
},
46 { 0x00, 0xff, 0xff, PC_SYS_USED
},
47 { 0xff, 0xff, 0xff, PC_SYS_USED
} // last 10
50 unsigned short GetNumberOfBits(unsigned int dwMask
)
53 for (wBits
= 0; dwMask
; dwMask
= dwMask
& (dwMask
- 1))
58 // Create the system palette
59 HPALETTE FASTCALL
PALETTE_Init(VOID
)
68 // create default palette (20 system colors)
69 palPtr
= ExAllocatePoolWithTag(PagedPool
,
71 (NB_RESERVED_COLORS
* sizeof(PALETTEENTRY
)),
73 if (!palPtr
) return FALSE
;
75 palPtr
->palVersion
= 0x300;
76 palPtr
->palNumEntries
= NB_RESERVED_COLORS
;
77 for (i
=0; i
<NB_RESERVED_COLORS
; i
++)
79 palPtr
->palPalEntry
[i
].peRed
= g_sysPalTemplate
[i
].peRed
;
80 palPtr
->palPalEntry
[i
].peGreen
= g_sysPalTemplate
[i
].peGreen
;
81 palPtr
->palPalEntry
[i
].peBlue
= g_sysPalTemplate
[i
].peBlue
;
82 palPtr
->palPalEntry
[i
].peFlags
= 0;
85 hpalette
= NtGdiCreatePaletteInternal(palPtr
,NB_RESERVED_COLORS
);
86 ExFreePoolWithTag(palPtr
, TAG_PALETTE
);
89 palObj
= (PALOBJ
*)PALETTE_LockPalette(hpalette
);
92 if (!(palObj
->mapping
= ExAllocatePool(PagedPool
, sizeof(int) * 20)))
94 DbgPrint("Win32k: Can not create palette mapping -- out of memory!");
97 PALETTE_UnlockPalette(palObj
);
101 /* palette_size = visual->map_entries; */
103 gpalRGB
.Mode
= PAL_RGB
;
104 gpalRGB
.RedMask
= RGB(0xFF, 0x00, 0x00);
105 gpalRGB
.GreenMask
= RGB(0x00, 0xFF, 0x00);
106 gpalRGB
.BlueMask
= RGB(0x00, 0x00, 0xFF);
108 gpalBGR
.Mode
= PAL_BGR
;
109 gpalBGR
.RedMask
= RGB(0x00, 0x00, 0xFF);
110 gpalBGR
.GreenMask
= RGB(0x00, 0xFF, 0x00);
111 gpalBGR
.BlueMask
= RGB(0xFF, 0x00, 0x00);
116 VOID FASTCALL
PALETTE_ValidateFlags(PALETTEENTRY
* lpPalE
, INT size
)
120 lpPalE
[i
].peFlags
= PC_SYS_USED
| (lpPalE
[i
].peFlags
& 0x07);
125 PALETTE_AllocPalette(ULONG Mode
,
135 PalGDI
= (PPALETTE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PALETTE
);
141 NewPalette
= PalGDI
->BaseObject
.hHmgr
;
143 PalGDI
->Self
= NewPalette
;
148 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
,
149 sizeof(PALETTEENTRY
) * NumColors
,
151 if (NULL
== PalGDI
->IndexedColors
)
153 PALETTE_UnlockPalette(PalGDI
);
154 PALETTE_FreePaletteByHandle(NewPalette
);
157 RtlCopyMemory(PalGDI
->IndexedColors
, Colors
, sizeof(PALETTEENTRY
) * NumColors
);
160 if (PAL_INDEXED
== Mode
)
162 PalGDI
->NumColors
= NumColors
;
164 else if (PAL_BITFIELDS
== Mode
)
166 PalGDI
->RedMask
= Red
;
167 PalGDI
->GreenMask
= Green
;
168 PalGDI
->BlueMask
= Blue
;
171 PALETTE_UnlockPalette(PalGDI
);
178 PALETTE_AllocPaletteIndexedRGB(ULONG NumColors
,
179 CONST RGBQUAD
*Colors
)
185 PalGDI
= (PPALETTE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PALETTE
);
191 NewPalette
= PalGDI
->BaseObject
.hHmgr
;
193 PalGDI
->Self
= NewPalette
;
194 PalGDI
->Mode
= PAL_INDEXED
;
196 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
,
197 sizeof(PALETTEENTRY
) * NumColors
,
199 if (NULL
== PalGDI
->IndexedColors
)
201 PALETTE_UnlockPalette(PalGDI
);
202 PALETTE_FreePaletteByHandle(NewPalette
);
206 for (i
= 0; i
< NumColors
; i
++)
208 PalGDI
->IndexedColors
[i
].peRed
= Colors
[i
].rgbRed
;
209 PalGDI
->IndexedColors
[i
].peGreen
= Colors
[i
].rgbGreen
;
210 PalGDI
->IndexedColors
[i
].peBlue
= Colors
[i
].rgbBlue
;
211 PalGDI
->IndexedColors
[i
].peFlags
= 0;
214 PalGDI
->NumColors
= NumColors
;
216 PALETTE_UnlockPalette(PalGDI
);
222 PALETTE_Cleanup(PVOID ObjectBody
)
224 PPALETTE pPal
= (PPALETTE
)ObjectBody
;
225 if (NULL
!= pPal
->IndexedColors
)
227 ExFreePool(pPal
->IndexedColors
);
234 PALETTE_GetObject(PPALETTE ppal
, INT cbCount
, LPLOGBRUSH lpBuffer
)
241 if ((UINT
)cbCount
< sizeof(WORD
)) return 0;
242 *((WORD
*)lpBuffer
) = (WORD
)ppal
->NumColors
;
248 PALETTE_ulGetNearestPaletteIndex(PALETTE
* ppal
, ULONG iColor
)
250 ULONG ulDiff
, ulColorDiff
, ulMinimalDiff
= 0xFFFFFF;
251 ULONG i
, ulBestIndex
= 0;
252 PALETTEENTRY peColor
= *(PPALETTEENTRY
)&iColor
;
254 /* Loop all palette entries, break on exact match */
255 for (i
= 0; i
< ppal
->NumColors
&& ulMinimalDiff
!= 0; i
++)
257 /* Calculate distance in the color cube */
258 ulDiff
= peColor
.peRed
- ppal
->IndexedColors
[i
].peRed
;
259 ulColorDiff
= ulDiff
* ulDiff
;
260 ulDiff
= peColor
.peGreen
- ppal
->IndexedColors
[i
].peGreen
;
261 ulColorDiff
+= ulDiff
* ulDiff
;
262 ulDiff
= peColor
.peBlue
- ppal
->IndexedColors
[i
].peBlue
;
263 ulColorDiff
+= ulDiff
* ulDiff
;
265 /* Check for a better match */
266 if (ulColorDiff
< ulMinimalDiff
)
269 ulMinimalDiff
= ulColorDiff
;
278 PALETTE_vGetBitMasks(PPALETTE ppal
, PULONG pulColors
)
286 pulColors
[0] = RGB(0xFF, 0x00, 0x00);
287 pulColors
[1] = RGB(0x00, 0xFF, 0x00);
288 pulColors
[2] = RGB(0x00, 0x00, 0xFF);
292 pulColors
[0] = RGB(0x00, 0x00, 0xFF);
293 pulColors
[1] = RGB(0x00, 0xFF, 0x00);
294 pulColors
[2] = RGB(0xFF, 0x00, 0x00);
298 pulColors
[0] = ppal
->RedMask
;
299 pulColors
[1] = ppal
->GreenMask
;
300 pulColors
[2] = ppal
->BlueMask
;
307 ColorCorrection(PPALETTE PalGDI
, PPALETTEENTRY PaletteEntry
, ULONG Colors
)
309 PPDEVOBJ ppdev
= (PPDEVOBJ
)PalGDI
->hPDev
;
313 if (ppdev
->flFlags
& PDEV_GAMMARAMP_TABLE
)
316 PGAMMARAMP GammaRamp
= (PGAMMARAMP
)ppdev
->pvGammaRamp
;
317 for ( i
= 0; i
< Colors
; i
++)
319 PaletteEntry
[i
].peRed
+= GammaRamp
->Red
[i
];
320 PaletteEntry
[i
].peGreen
+= GammaRamp
->Green
[i
];
321 PaletteEntry
[i
].peBlue
+= GammaRamp
->Blue
[i
];
327 /** Display Driver Interface **************************************************/
344 Palette
= PALETTE_AllocPalette(Mode
, NumColors
, Colors
, Red
, Green
, Blue
);
347 GDIOBJ_SetOwnership(Palette
, NULL
);
358 EngDeletePalette(IN HPALETTE Palette
)
360 GDIOBJ_SetOwnership(Palette
, PsGetCurrentProcess());
362 return PALETTE_FreePaletteByHandle(Palette
);
370 PALOBJ_cGetColors(PALOBJ
*PalObj
, ULONG Start
, ULONG Colors
, ULONG
*PaletteEntry
)
374 PalGDI
= (PALETTE
*)PalObj
;
375 /* PalGDI = (PALETTE*)AccessInternalObjectFromUserObject(PalObj); */
377 if (Start
>= PalGDI
->NumColors
)
380 Colors
= min(Colors
, PalGDI
->NumColors
- Start
);
382 /* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */
383 RtlCopyMemory(PaletteEntry
, PalGDI
->IndexedColors
+ Start
, sizeof(ULONG
) * Colors
);
385 if (PalGDI
->Mode
& PAL_GAMMACORRECTION
)
386 ColorCorrection(PalGDI
, (PPALETTEENTRY
)PaletteEntry
, Colors
);
392 /** Systemcall Interface ******************************************************/
398 NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal
, IN UINT cEntries
)
403 pLogPal
->palNumEntries
= cEntries
;
404 NewPalette
= PALETTE_AllocPalette( PAL_INDEXED
,
406 (PULONG
)pLogPal
->palPalEntry
,
409 if (NewPalette
== NULL
)
414 PalGDI
= (PPALETTE
) PALETTE_LockPalette(NewPalette
);
417 PALETTE_ValidateFlags(PalGDI
->IndexedColors
, PalGDI
->NumColors
);
418 PalGDI
->logicalToSystem
= NULL
;
419 PALETTE_UnlockPalette(PalGDI
);
423 /* FIXME - Handle PalGDI == NULL!!!! */
424 DPRINT1("waring PalGDI is NULL \n");
429 HPALETTE APIENTRY
NtGdiCreateHalftonePalette(HDC hDC
)
434 WORD NumberOfEntries
;
435 PALETTEENTRY aEntries
[256];
438 Palette
.Version
= 0x300;
439 Palette
.NumberOfEntries
= 256;
440 if (IntGetSystemPaletteEntries(hDC
, 0, 256, Palette
.aEntries
) == 0)
442 /* from wine, more that 256 color math */
443 Palette
.NumberOfEntries
= 20;
444 for (i
= 0; i
< Palette
.NumberOfEntries
; i
++)
446 Palette
.aEntries
[i
].peRed
=0xff;
447 Palette
.aEntries
[i
].peGreen
=0xff;
448 Palette
.aEntries
[i
].peBlue
=0xff;
449 Palette
.aEntries
[i
].peFlags
=0x00;
452 Palette
.aEntries
[0].peRed
=0x00;
453 Palette
.aEntries
[0].peBlue
=0x00;
454 Palette
.aEntries
[0].peGreen
=0x00;
457 for (i
=1; i
<= 6; i
++)
459 Palette
.aEntries
[i
].peRed
=(i
%2)?0x80:0;
460 Palette
.aEntries
[i
].peGreen
=(i
==2)?0x80:(i
==3)?0x80:(i
==6)?0x80:0;
461 Palette
.aEntries
[i
].peBlue
=(i
>3)?0x80:0;
464 for (i
=7; i
<= 12; i
++)
469 Palette
.aEntries
[i
].peRed
=0xc0;
470 Palette
.aEntries
[i
].peBlue
=0xc0;
471 Palette
.aEntries
[i
].peGreen
=0xc0;
474 Palette
.aEntries
[i
].peRed
=0xc0;
475 Palette
.aEntries
[i
].peGreen
=0xdc;
476 Palette
.aEntries
[i
].peBlue
=0xc0;
479 Palette
.aEntries
[i
].peRed
=0xa6;
480 Palette
.aEntries
[i
].peGreen
=0xca;
481 Palette
.aEntries
[i
].peBlue
=0xf0;
484 Palette
.aEntries
[i
].peRed
=0xff;
485 Palette
.aEntries
[i
].peGreen
=0xfb;
486 Palette
.aEntries
[i
].peBlue
=0xf0;
489 Palette
.aEntries
[i
].peRed
=0xa0;
490 Palette
.aEntries
[i
].peGreen
=0xa0;
491 Palette
.aEntries
[i
].peBlue
=0xa4;
494 Palette
.aEntries
[i
].peRed
=0x80;
495 Palette
.aEntries
[i
].peGreen
=0x80;
496 Palette
.aEntries
[i
].peBlue
=0x80;
500 for (i
=13; i
<= 18; i
++)
502 Palette
.aEntries
[i
].peRed
=(i
%2)?0xff:0;
503 Palette
.aEntries
[i
].peGreen
=(i
==14)?0xff:(i
==15)?0xff:(i
==18)?0xff:0;
504 Palette
.aEntries
[i
].peBlue
=(i
>15)?0xff:0x00;
509 /* 256 color table */
510 for (r
= 0; r
< 6; r
++)
511 for (g
= 0; g
< 6; g
++)
512 for (b
= 0; b
< 6; b
++)
514 i
= r
+ g
*6 + b
*36 + 10;
515 Palette
.aEntries
[i
].peRed
= r
* 51;
516 Palette
.aEntries
[i
].peGreen
= g
* 51;
517 Palette
.aEntries
[i
].peBlue
= b
* 51;
520 for (i
= 216; i
< 246; i
++)
522 int v
= (i
- 216) << 3;
523 Palette
.aEntries
[i
].peRed
= v
;
524 Palette
.aEntries
[i
].peGreen
= v
;
525 Palette
.aEntries
[i
].peBlue
= v
;
529 return NtGdiCreatePaletteInternal((LOGPALETTE
*)&Palette
, Palette
.NumberOfEntries
);
538 /* PALOBJ *palPtr = (PALOBJ*)AccessUserObject(hPal);
539 UINT cPrevEnt, prevVer;
540 INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
541 XLATEOBJ *XlateObj = NULL;
543 if(!palPtr) return FALSE;
544 cPrevEnt = palPtr->logpalette->palNumEntries;
545 prevVer = palPtr->logpalette->palVersion;
546 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
547 size += sizeof(int*) + sizeof(GDIOBJHDR);
548 XlateObj = palPtr->logicalToSystem;
550 if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
554 XLATEOBJ *NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
555 if(NewXlateObj == NULL)
557 ERR("Can not resize logicalToSystem -- out of memory!");
558 GDI_ReleaseObj( hPal );
561 palPtr->logicalToSystem = NewXlateObj;
564 if(cEntries > cPrevEnt)
566 if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
567 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
568 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
570 palPtr->logpalette->palNumEntries = cEntries;
571 palPtr->logpalette->palVersion = prevVer;
572 // GDI_ReleaseObj( hPal );
581 NtGdiGetColorAdjustment(
583 LPCOLORADJUSTMENT pca
)
591 NtGdiSetColorAdjustment(
593 LPCOLORADJUSTMENT pca
)
599 COLORREF APIENTRY
NtGdiGetNearestColor(HDC hDC
, COLORREF Color
)
601 COLORREF nearest
= CLR_INVALID
;
604 LONG RBits
, GBits
, BBits
;
609 HPALETTE hpal
= dc
->dclevel
.hpal
;
610 palGDI
= (PPALETTE
) PALETTE_LockPalette(hpal
);
617 switch (palGDI
->Mode
)
622 index
= PALETTE_ulGetNearestPaletteIndex(palGDI
, Color
);
623 nearest
= PALETTE_ulGetRGBColorFromIndex(palGDI
, index
);
631 RBits
= 8 - GetNumberOfBits(palGDI
->RedMask
);
632 GBits
= 8 - GetNumberOfBits(palGDI
->GreenMask
);
633 BBits
= 8 - GetNumberOfBits(palGDI
->BlueMask
);
635 (GetRValue(Color
) >> RBits
) << RBits
,
636 (GetGValue(Color
) >> GBits
) << GBits
,
637 (GetBValue(Color
) >> BBits
) << BBits
);
640 PALETTE_UnlockPalette(palGDI
);
649 NtGdiGetNearestPaletteIndex(
653 PPALETTE ppal
= (PPALETTE
) PALETTE_LockPalette(hpal
);
658 /* Return closest match for the given RGB color */
659 index
= PALETTE_ulGetNearestPaletteIndex(ppal
, crColor
);
660 PALETTE_UnlockPalette(ppal
);
668 IntGdiRealizePalette(HDC hDC
)
671 * This function doesn't do any real work now and there's plenty
675 PPALETTE palGDI
, sysGDI
;
678 HPALETTE systemPalette
;
679 USHORT sysMode
, palMode
;
684 systemPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
685 palGDI
= PALETTE_LockPalette(dc
->dclevel
.hpal
);
689 DPRINT1("IntGdiRealizePalette(): palGDI is NULL, exiting\n");
694 sysGDI
= PALETTE_LockPalette(systemPalette
);
698 DPRINT1("IntGdiRealizePalette(): sysGDI is NULL, exiting\n");
699 PALETTE_UnlockPalette(palGDI
);
704 // The RealizePalette function modifies the palette for the device associated with the specified device context. If the
705 // device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
706 // context is a display DC, the physical palette for that device is modified.
707 if(dc
->dctype
== DC_TYPE_MEMORY
)
710 DPRINT1("RealizePalette unimplemented for memory managed DCs\n");
713 DPRINT1("RealizePalette unimplemented for device DCs\n");
716 // need to pass this to IntEngCreateXlate with palettes unlocked
717 sysMode
= sysGDI
->Mode
;
718 palMode
= palGDI
->Mode
;
719 PALETTE_UnlockPalette(sysGDI
);
720 PALETTE_UnlockPalette(palGDI
);
722 // Create the XLATEOBJ for device managed DCs
723 if(dc
->dctype
!= DC_TYPE_MEMORY
)
725 if (palGDI
->logicalToSystem
!= NULL
)
727 EngDeleteXlate(palGDI
->logicalToSystem
);
729 palGDI
->logicalToSystem
= IntEngCreateXlate(sysMode
, palMode
, systemPalette
, dc
->dclevel
.hpal
);
738 IntAnimatePalette(HPALETTE hPal
,
741 CONST PPALETTEENTRY PaletteColors
)
745 if( hPal
!= NtGdiGetStockObject(DEFAULT_PALETTE
) )
752 const PALETTEENTRY
*pptr
= PaletteColors
;
754 palPtr
= (PPALETTE
)PALETTE_LockPalette(hPal
);
755 if (!palPtr
) return FALSE
;
757 pal_entries
= palPtr
->NumColors
;
758 if (StartIndex
>= pal_entries
)
760 PALETTE_UnlockPalette(palPtr
);
763 if (StartIndex
+NumEntries
> pal_entries
) NumEntries
= pal_entries
- StartIndex
;
765 for (NumEntries
+= StartIndex
; StartIndex
< NumEntries
; StartIndex
++, pptr
++)
767 /* According to MSDN, only animate PC_RESERVED colours */
768 if (palPtr
->IndexedColors
[StartIndex
].peFlags
& PC_RESERVED
)
770 memcpy( &palPtr
->IndexedColors
[StartIndex
], pptr
,
771 sizeof(PALETTEENTRY
) );
773 PALETTE_ValidateFlags(&palPtr
->IndexedColors
[StartIndex
], 1);
777 PALETTE_UnlockPalette(palPtr
);
779 /* Immediately apply the new palette if current window uses it */
780 Wnd
= UserGetDesktopWindow();
781 hDC
= UserGetWindowDC(Wnd
);
785 if (dc
->dclevel
.hpal
== hPal
)
788 IntGdiRealizePalette(hDC
);
793 UserReleaseDC(Wnd
,hDC
, FALSE
);
799 IntGetPaletteEntries(
808 palGDI
= (PPALETTE
) PALETTE_LockPalette(hpal
);
814 numEntries
= palGDI
->NumColors
;
817 if (numEntries
< StartIndex
+ Entries
)
819 Entries
= numEntries
- StartIndex
;
821 if (numEntries
<= StartIndex
)
823 PALETTE_UnlockPalette(palGDI
);
826 memcpy(pe
, palGDI
->IndexedColors
+ StartIndex
, Entries
* sizeof(PALETTEENTRY
));
827 for (numEntries
= 0; numEntries
< Entries
; numEntries
++)
829 if (pe
[numEntries
].peFlags
& 0xF0)
831 pe
[numEntries
].peFlags
= 0;
837 Entries
= numEntries
;
840 PALETTE_UnlockPalette(palGDI
);
845 IntGetSystemPaletteEntries(HDC hDC
,
850 PPALETTE palGDI
= NULL
;
852 UINT EntriesSize
= 0;
857 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
863 EntriesSize
= Entries
* sizeof(pe
[0]);
864 if (Entries
!= EntriesSize
/ sizeof(pe
[0]))
866 /* Integer overflow! */
867 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
872 if (!(dc
= DC_LockDc(hDC
)))
874 SetLastWin32Error(ERROR_INVALID_HANDLE
);
878 palGDI
= PALETTE_LockPalette(dc
->dclevel
.hpal
);
883 if (StartIndex
>= palGDI
->NumColors
)
885 else if (Entries
> palGDI
->NumColors
- StartIndex
)
886 Entries
= palGDI
->NumColors
- StartIndex
;
889 palGDI
->IndexedColors
+ StartIndex
,
890 Entries
* sizeof(pe
[0]));
896 Ret
= dc
->ppdev
->GDIInfo
.ulNumPalReg
;
901 PALETTE_UnlockPalette(palGDI
);
911 IntSetPaletteEntries(
915 CONST LPPALETTEENTRY pe
)
920 if ((UINT
)hpal
& GDI_HANDLE_STOCK_MASK
)
925 palGDI
= PALETTE_LockPalette(hpal
);
926 if (!palGDI
) return 0;
928 numEntries
= palGDI
->NumColors
;
929 if (Start
>= numEntries
)
931 PALETTE_UnlockPalette(palGDI
);
934 if (numEntries
< Start
+ Entries
)
936 Entries
= numEntries
- Start
;
938 memcpy(palGDI
->IndexedColors
+ Start
, pe
, Entries
* sizeof(PALETTEENTRY
));
939 PALETTE_ValidateFlags(palGDI
->IndexedColors
, palGDI
->NumColors
);
940 if (palGDI
->logicalToSystem
)
941 ExFreePool(palGDI
->logicalToSystem
);
942 palGDI
->logicalToSystem
= NULL
;
943 PALETTE_UnlockPalette(palGDI
);
955 IN LPVOID pUnsafeEntries
,
960 LPVOID pEntries
= NULL
;
962 /* FIXME: Handle bInbound correctly */
965 (pUnsafeEntries
== NULL
|| cEntries
== 0))
972 pEntries
= ExAllocatePool(PagedPool
, cEntries
* sizeof(PALETTEENTRY
));
979 ProbeForRead(pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
), 1);
980 memcpy(pEntries
, pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
));
982 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
984 ExFreePool(pEntries
);
985 _SEH2_YIELD(return 0);
996 ret
= IntAnimatePalette((HPALETTE
)hObj
, iStart
, cEntries
, (CONST PPALETTEENTRY
)pEntries
);
999 case GdiPalSetEntries
:
1001 ret
= IntSetPaletteEntries((HPALETTE
)hObj
, iStart
, cEntries
, (CONST LPPALETTEENTRY
)pEntries
);
1004 case GdiPalGetEntries
:
1005 ret
= IntGetPaletteEntries((HPALETTE
)hObj
, iStart
, cEntries
, (LPPALETTEENTRY
)pEntries
);
1008 case GdiPalGetSystemEntries
:
1009 ret
= IntGetSystemPaletteEntries((HDC
)hObj
, iStart
, cEntries
, (LPPALETTEENTRY
)pEntries
);
1012 case GdiPalSetColorTable
:
1014 ret
= IntSetDIBColorTable((HDC
)hObj
, iStart
, cEntries
, (RGBQUAD
*)pEntries
);
1017 case GdiPalGetColorTable
:
1019 ret
= IntGetDIBColorTable((HDC
)hObj
, iStart
, cEntries
, (RGBQUAD
*)pEntries
);
1029 ProbeForWrite(pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
), 1);
1030 memcpy(pUnsafeEntries
, pEntries
, cEntries
* sizeof(PALETTEENTRY
));
1032 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1038 ExFreePool(pEntries
);
1045 NtGdiSetSystemPaletteUse(HDC hDC
, UINT Usage
)
1047 UINT old
= SystemPaletteUse
;
1049 /* Device doesn't support colour palettes */
1050 if (!(NtGdiGetDeviceCaps(hDC
, RASTERCAPS
) & RC_PALETTE
)) {
1051 return SYSPAL_ERROR
;
1056 case SYSPAL_NOSTATIC
:
1057 case SYSPAL_NOSTATIC256
:
1059 SystemPaletteUse
= Usage
;
1072 NtGdiGetSystemPaletteUse(HDC hDC
)
1074 return SystemPaletteUse
;
1079 NtGdiUpdateColors(HDC hDC
)
1082 BOOL calledFromUser
, ret
;
1083 USER_REFERENCE_ENTRY Ref
;
1085 calledFromUser
= UserIsEntered();
1087 if (!calledFromUser
){
1088 UserEnterExclusive();
1091 Wnd
= UserGetWindowObject(IntWindowFromDC(hDC
));
1094 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1096 if (!calledFromUser
){
1103 UserRefObjectCo(Wnd
, &Ref
);
1104 ret
= co_UserRedrawWindow(Wnd
, NULL
, 0, RDW_INVALIDATE
);
1105 UserDerefObjectCo(Wnd
);
1107 if (!calledFromUser
){
1116 NtGdiUnrealizeObject(HGDIOBJ hgdiobj
)
1122 ((UINT
)hgdiobj
& GDI_HANDLE_STOCK_MASK
) ||
1123 !GDI_HANDLE_IS_TYPE(hgdiobj
, GDI_OBJECT_TYPE_PALETTE
) )
1126 palGDI
= PALETTE_LockPalette(hgdiobj
);
1127 if (!palGDI
) return FALSE
;
1130 // Need to do something!!!
1131 // Zero out Current and Old Translated pointers?
1134 PALETTE_UnlockPalette(palGDI
);