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
, gpalMono
, gpalRGB555
, gpalRGB565
, *gppalDefault
;
18 PPALETTE appalSurfaceDefault
[11];
20 const PALETTEENTRY g_sysPalTemplate
[NB_RESERVED_COLORS
] =
22 // first 10 entries in the system palette
23 // red green blue flags
24 { 0x00, 0x00, 0x00, PC_SYS_USED
},
25 { 0x80, 0x00, 0x00, PC_SYS_USED
},
26 { 0x00, 0x80, 0x00, PC_SYS_USED
},
27 { 0x80, 0x80, 0x00, PC_SYS_USED
},
28 { 0x00, 0x00, 0x80, PC_SYS_USED
},
29 { 0x80, 0x00, 0x80, PC_SYS_USED
},
30 { 0x00, 0x80, 0x80, PC_SYS_USED
},
31 { 0xc0, 0xc0, 0xc0, PC_SYS_USED
},
32 { 0xc0, 0xdc, 0xc0, PC_SYS_USED
},
33 { 0xa6, 0xca, 0xf0, PC_SYS_USED
},
35 // ... c_min/2 dynamic colorcells
36 // ... gap (for sparse palettes)
37 // ... c_min/2 dynamic colorcells
39 { 0xff, 0xfb, 0xf0, PC_SYS_USED
},
40 { 0xa0, 0xa0, 0xa4, PC_SYS_USED
},
41 { 0x80, 0x80, 0x80, PC_SYS_USED
},
42 { 0xff, 0x00, 0x00, PC_SYS_USED
},
43 { 0x00, 0xff, 0x00, PC_SYS_USED
},
44 { 0xff, 0xff, 0x00, PC_SYS_USED
},
45 { 0x00, 0x00, 0xff, PC_SYS_USED
},
46 { 0xff, 0x00, 0xff, PC_SYS_USED
},
47 { 0x00, 0xff, 0xff, PC_SYS_USED
},
48 { 0xff, 0xff, 0xff, PC_SYS_USED
} // last 10
51 unsigned short GetNumberOfBits(unsigned int dwMask
)
54 for (wBits
= 0; dwMask
; dwMask
= dwMask
& (dwMask
- 1))
59 // Create the system palette
60 HPALETTE FASTCALL
PALETTE_Init(VOID
)
69 // create default palette (20 system colors)
70 palPtr
= ExAllocatePoolWithTag(PagedPool
,
72 (NB_RESERVED_COLORS
* sizeof(PALETTEENTRY
)),
74 if (!palPtr
) return FALSE
;
76 palPtr
->palVersion
= 0x300;
77 palPtr
->palNumEntries
= NB_RESERVED_COLORS
;
78 for (i
=0; i
<NB_RESERVED_COLORS
; i
++)
80 palPtr
->palPalEntry
[i
].peRed
= g_sysPalTemplate
[i
].peRed
;
81 palPtr
->palPalEntry
[i
].peGreen
= g_sysPalTemplate
[i
].peGreen
;
82 palPtr
->palPalEntry
[i
].peBlue
= g_sysPalTemplate
[i
].peBlue
;
83 palPtr
->palPalEntry
[i
].peFlags
= 0;
86 hpalette
= NtGdiCreatePaletteInternal(palPtr
,NB_RESERVED_COLORS
);
87 ExFreePoolWithTag(palPtr
, TAG_PALETTE
);
90 palObj
= (PALOBJ
*)PALETTE_LockPalette(hpalette
);
93 if (!(palObj
->mapping
= ExAllocatePool(PagedPool
, sizeof(int) * 20)))
95 DbgPrint("Win32k: Can not create palette mapping -- out of memory!");
98 PALETTE_UnlockPalette(palObj
);
102 /* palette_size = visual->map_entries; */
104 gpalRGB
.Mode
= PAL_RGB
;
105 gpalRGB
.RedMask
= RGB(0xFF, 0x00, 0x00);
106 gpalRGB
.GreenMask
= RGB(0x00, 0xFF, 0x00);
107 gpalRGB
.BlueMask
= RGB(0x00, 0x00, 0xFF);
108 gpalRGB
.BaseObject
.ulShareCount
= 0;
109 gpalRGB
.BaseObject
.BaseFlags
= 0 ;
111 gpalBGR
.Mode
= PAL_BGR
;
112 gpalBGR
.RedMask
= RGB(0x00, 0x00, 0xFF);
113 gpalBGR
.GreenMask
= RGB(0x00, 0xFF, 0x00);
114 gpalBGR
.BlueMask
= RGB(0xFF, 0x00, 0x00);
115 gpalBGR
.BaseObject
.ulShareCount
= 0;
116 gpalBGR
.BaseObject
.BaseFlags
= 0 ;
118 gpalRGB555
.Mode
= PAL_RGB16_555
| PAL_BITFIELDS
;
119 gpalRGB555
.RedMask
= 0x7C00;
120 gpalRGB555
.GreenMask
= 0x3E0;
121 gpalRGB555
.BlueMask
= 0x1F;
122 gpalRGB555
.BaseObject
.ulShareCount
= 0;
123 gpalRGB555
.BaseObject
.BaseFlags
= 0 ;
125 gpalRGB565
.Mode
= PAL_RGB16_565
| PAL_BITFIELDS
;
126 gpalRGB565
.RedMask
= 0xF800;
127 gpalRGB565
.GreenMask
= 0x7E0;
128 gpalRGB565
.BlueMask
= 0x1F;
129 gpalRGB565
.BaseObject
.ulShareCount
= 0;
130 gpalRGB565
.BaseObject
.BaseFlags
= 0 ;
132 memset(&gpalMono
, 0, sizeof(PALETTE
));
133 gpalMono
.Mode
= PAL_MONOCHROME
;
134 gpalMono
.BaseObject
.ulShareCount
= 0;
135 gpalMono
.BaseObject
.BaseFlags
= 0 ;
137 /* Initialize default surface palettes */
138 gppalDefault
= PALETTE_ShareLockPalette(hpalette
);
139 appalSurfaceDefault
[BMF_1BPP
] = &gpalMono
;
140 appalSurfaceDefault
[BMF_4BPP
] = gppalDefault
;
141 appalSurfaceDefault
[BMF_8BPP
] = gppalDefault
;
142 appalSurfaceDefault
[BMF_16BPP
] = &gpalRGB565
;
143 appalSurfaceDefault
[BMF_24BPP
] = &gpalRGB
;
144 appalSurfaceDefault
[BMF_32BPP
] = &gpalRGB
;
145 appalSurfaceDefault
[BMF_4RLE
] = gppalDefault
;
146 appalSurfaceDefault
[BMF_8RLE
] = gppalDefault
;
147 appalSurfaceDefault
[BMF_JPEG
] = &gpalRGB
;
148 appalSurfaceDefault
[BMF_PNG
] = &gpalRGB
;
153 VOID FASTCALL
PALETTE_ValidateFlags(PALETTEENTRY
* lpPalE
, INT size
)
157 lpPalE
[i
].peFlags
= PC_SYS_USED
| (lpPalE
[i
].peFlags
& 0x07);
162 PALETTE_AllocPalette(ULONG Mode
,
172 PalGDI
= (PPALETTE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PALETTE
);
178 NewPalette
= PalGDI
->BaseObject
.hHmgr
;
180 PalGDI
->Self
= NewPalette
;
185 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
,
186 sizeof(PALETTEENTRY
) * NumColors
,
188 if (NULL
== PalGDI
->IndexedColors
)
190 PALETTE_UnlockPalette(PalGDI
);
191 PALETTE_FreePaletteByHandle(NewPalette
);
194 RtlCopyMemory(PalGDI
->IndexedColors
, Colors
, sizeof(PALETTEENTRY
) * NumColors
);
197 if (PAL_INDEXED
== Mode
)
199 PalGDI
->NumColors
= NumColors
;
201 else if (PAL_BITFIELDS
== Mode
)
203 PalGDI
->RedMask
= Red
;
204 PalGDI
->GreenMask
= Green
;
205 PalGDI
->BlueMask
= Blue
;
207 if (Red
== 0x7c00 && Green
== 0x3E0 && Blue
== 0x1F)
208 PalGDI
->Mode
|= PAL_RGB16_555
;
209 else if (Red
== 0xF800 && Green
== 0x7E0 && Blue
== 0x1F)
210 PalGDI
->Mode
|= PAL_RGB16_565
;
213 PALETTE_UnlockPalette(PalGDI
);
220 PALETTE_AllocPaletteIndexedRGB(ULONG NumColors
,
221 CONST RGBQUAD
*Colors
)
227 PalGDI
= (PPALETTE
)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_PALETTE
);
233 NewPalette
= PalGDI
->BaseObject
.hHmgr
;
235 PalGDI
->Self
= NewPalette
;
236 PalGDI
->Mode
= PAL_INDEXED
;
238 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
,
239 sizeof(PALETTEENTRY
) * NumColors
,
241 if (NULL
== PalGDI
->IndexedColors
)
243 PALETTE_UnlockPalette(PalGDI
);
244 PALETTE_FreePaletteByHandle(NewPalette
);
248 for (i
= 0; i
< NumColors
; i
++)
250 PalGDI
->IndexedColors
[i
].peRed
= Colors
[i
].rgbRed
;
251 PalGDI
->IndexedColors
[i
].peGreen
= Colors
[i
].rgbGreen
;
252 PalGDI
->IndexedColors
[i
].peBlue
= Colors
[i
].rgbBlue
;
253 PalGDI
->IndexedColors
[i
].peFlags
= 0;
256 PalGDI
->NumColors
= NumColors
;
258 PALETTE_UnlockPalette(PalGDI
);
264 PALETTE_Cleanup(PVOID ObjectBody
)
266 PPALETTE pPal
= (PPALETTE
)ObjectBody
;
267 if (NULL
!= pPal
->IndexedColors
)
269 ExFreePool(pPal
->IndexedColors
);
276 PALETTE_GetObject(PPALETTE ppal
, INT cbCount
, LPLOGBRUSH lpBuffer
)
283 if ((UINT
)cbCount
< sizeof(WORD
)) return 0;
284 *((WORD
*)lpBuffer
) = (WORD
)ppal
->NumColors
;
290 PALETTE_ulGetNearestPaletteIndex(PALETTE
* ppal
, ULONG iColor
)
292 ULONG ulDiff
, ulColorDiff
, ulMinimalDiff
= 0xFFFFFF;
293 ULONG i
, ulBestIndex
= 0;
294 PALETTEENTRY peColor
= *(PPALETTEENTRY
)&iColor
;
296 /* Loop all palette entries, break on exact match */
297 for (i
= 0; i
< ppal
->NumColors
&& ulMinimalDiff
!= 0; i
++)
299 /* Calculate distance in the color cube */
300 ulDiff
= peColor
.peRed
- ppal
->IndexedColors
[i
].peRed
;
301 ulColorDiff
= ulDiff
* ulDiff
;
302 ulDiff
= peColor
.peGreen
- ppal
->IndexedColors
[i
].peGreen
;
303 ulColorDiff
+= ulDiff
* ulDiff
;
304 ulDiff
= peColor
.peBlue
- ppal
->IndexedColors
[i
].peBlue
;
305 ulColorDiff
+= ulDiff
* ulDiff
;
307 /* Check for a better match */
308 if (ulColorDiff
< ulMinimalDiff
)
311 ulMinimalDiff
= ulColorDiff
;
320 PALETTE_ulGetNearestBitFieldsIndex(PALETTE
* ppal
, ULONG ulColor
)
324 // FIXME: HACK, should be stored already
325 ppal
->ulRedShift
= CalculateShift(RGB(0xff,0,0), ppal
->RedMask
);
326 ppal
->ulGreenShift
= CalculateShift(RGB(0,0xff,0), ppal
->GreenMask
);
327 ppal
->ulBlueShift
= CalculateShift(RGB(0,0,0xff), ppal
->BlueMask
);
329 ulNewColor
= _rotl(ulColor
, ppal
->ulRedShift
) & ppal
->RedMask
;
330 ulNewColor
|= _rotl(ulColor
, ppal
->ulGreenShift
) & ppal
->GreenMask
;
331 ulNewColor
|= _rotl(ulColor
, ppal
->ulBlueShift
) & ppal
->BlueMask
;
338 PALETTE_ulGetNearestIndex(PALETTE
* ppal
, ULONG ulColor
)
340 if (ppal
->Mode
& PAL_INDEXED
) // use fl & PALINDEXED
341 return PALETTE_ulGetNearestPaletteIndex(ppal
, ulColor
);
343 return PALETTE_ulGetNearestBitFieldsIndex(ppal
, ulColor
);
348 PALETTE_vGetBitMasks(PPALETTE ppal
, PULONG pulColors
)
352 if (ppal
->Mode
& PAL_INDEXED
|| ppal
->Mode
& PAL_RGB
)
354 pulColors
[0] = RGB(0xFF, 0x00, 0x00);
355 pulColors
[1] = RGB(0x00, 0xFF, 0x00);
356 pulColors
[2] = RGB(0x00, 0x00, 0xFF);
358 else if (ppal
->Mode
& PAL_BGR
)
360 pulColors
[0] = RGB(0x00, 0x00, 0xFF);
361 pulColors
[1] = RGB(0x00, 0xFF, 0x00);
362 pulColors
[2] = RGB(0xFF, 0x00, 0x00);
364 else if (ppal
->Mode
& PAL_BITFIELDS
)
366 pulColors
[0] = ppal
->RedMask
;
367 pulColors
[1] = ppal
->GreenMask
;
368 pulColors
[2] = ppal
->BlueMask
;
374 ColorCorrection(PPALETTE PalGDI
, PPALETTEENTRY PaletteEntry
, ULONG Colors
)
376 PPDEVOBJ ppdev
= (PPDEVOBJ
)PalGDI
->hPDev
;
380 if (ppdev
->flFlags
& PDEV_GAMMARAMP_TABLE
)
383 PGAMMARAMP GammaRamp
= (PGAMMARAMP
)ppdev
->pvGammaRamp
;
384 for ( i
= 0; i
< Colors
; i
++)
386 PaletteEntry
[i
].peRed
+= GammaRamp
->Red
[i
];
387 PaletteEntry
[i
].peGreen
+= GammaRamp
->Green
[i
];
388 PaletteEntry
[i
].peBlue
+= GammaRamp
->Blue
[i
];
394 /** Display Driver Interface **************************************************/
411 Palette
= PALETTE_AllocPalette(Mode
, NumColors
, Colors
, Red
, Green
, Blue
);
414 GDIOBJ_SetOwnership(Palette
, NULL
);
425 EngDeletePalette(IN HPALETTE Palette
)
427 GDIOBJ_SetOwnership(Palette
, PsGetCurrentProcess());
429 return PALETTE_FreePaletteByHandle(Palette
);
437 PALOBJ_cGetColors(PALOBJ
*PalObj
, ULONG Start
, ULONG Colors
, ULONG
*PaletteEntry
)
441 PalGDI
= (PALETTE
*)PalObj
;
442 /* PalGDI = (PALETTE*)AccessInternalObjectFromUserObject(PalObj); */
444 if (Start
>= PalGDI
->NumColors
)
447 Colors
= min(Colors
, PalGDI
->NumColors
- Start
);
449 /* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */
450 RtlCopyMemory(PaletteEntry
, PalGDI
->IndexedColors
+ Start
, sizeof(ULONG
) * Colors
);
452 if (PalGDI
->Mode
& PAL_GAMMACORRECTION
)
453 ColorCorrection(PalGDI
, (PPALETTEENTRY
)PaletteEntry
, Colors
);
459 /** Systemcall Interface ******************************************************/
465 NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal
, IN UINT cEntries
)
470 pLogPal
->palNumEntries
= cEntries
;
471 NewPalette
= PALETTE_AllocPalette( PAL_INDEXED
,
473 (PULONG
)pLogPal
->palPalEntry
,
476 if (NewPalette
== NULL
)
481 PalGDI
= (PPALETTE
) PALETTE_LockPalette(NewPalette
);
484 PALETTE_ValidateFlags(PalGDI
->IndexedColors
, PalGDI
->NumColors
);
485 PALETTE_UnlockPalette(PalGDI
);
489 /* FIXME - Handle PalGDI == NULL!!!! */
490 DPRINT1("waring PalGDI is NULL \n");
495 HPALETTE APIENTRY
NtGdiCreateHalftonePalette(HDC hDC
)
500 WORD NumberOfEntries
;
501 PALETTEENTRY aEntries
[256];
504 Palette
.Version
= 0x300;
505 Palette
.NumberOfEntries
= 256;
506 if (IntGetSystemPaletteEntries(hDC
, 0, 256, Palette
.aEntries
) == 0)
508 /* from wine, more that 256 color math */
509 Palette
.NumberOfEntries
= 20;
510 for (i
= 0; i
< Palette
.NumberOfEntries
; i
++)
512 Palette
.aEntries
[i
].peRed
=0xff;
513 Palette
.aEntries
[i
].peGreen
=0xff;
514 Palette
.aEntries
[i
].peBlue
=0xff;
515 Palette
.aEntries
[i
].peFlags
=0x00;
518 Palette
.aEntries
[0].peRed
=0x00;
519 Palette
.aEntries
[0].peBlue
=0x00;
520 Palette
.aEntries
[0].peGreen
=0x00;
523 for (i
=1; i
<= 6; i
++)
525 Palette
.aEntries
[i
].peRed
=(i
%2)?0x80:0;
526 Palette
.aEntries
[i
].peGreen
=(i
==2)?0x80:(i
==3)?0x80:(i
==6)?0x80:0;
527 Palette
.aEntries
[i
].peBlue
=(i
>3)?0x80:0;
530 for (i
=7; i
<= 12; i
++)
535 Palette
.aEntries
[i
].peRed
=0xc0;
536 Palette
.aEntries
[i
].peBlue
=0xc0;
537 Palette
.aEntries
[i
].peGreen
=0xc0;
540 Palette
.aEntries
[i
].peRed
=0xc0;
541 Palette
.aEntries
[i
].peGreen
=0xdc;
542 Palette
.aEntries
[i
].peBlue
=0xc0;
545 Palette
.aEntries
[i
].peRed
=0xa6;
546 Palette
.aEntries
[i
].peGreen
=0xca;
547 Palette
.aEntries
[i
].peBlue
=0xf0;
550 Palette
.aEntries
[i
].peRed
=0xff;
551 Palette
.aEntries
[i
].peGreen
=0xfb;
552 Palette
.aEntries
[i
].peBlue
=0xf0;
555 Palette
.aEntries
[i
].peRed
=0xa0;
556 Palette
.aEntries
[i
].peGreen
=0xa0;
557 Palette
.aEntries
[i
].peBlue
=0xa4;
560 Palette
.aEntries
[i
].peRed
=0x80;
561 Palette
.aEntries
[i
].peGreen
=0x80;
562 Palette
.aEntries
[i
].peBlue
=0x80;
566 for (i
=13; i
<= 18; i
++)
568 Palette
.aEntries
[i
].peRed
=(i
%2)?0xff:0;
569 Palette
.aEntries
[i
].peGreen
=(i
==14)?0xff:(i
==15)?0xff:(i
==18)?0xff:0;
570 Palette
.aEntries
[i
].peBlue
=(i
>15)?0xff:0x00;
575 /* 256 color table */
576 for (r
= 0; r
< 6; r
++)
577 for (g
= 0; g
< 6; g
++)
578 for (b
= 0; b
< 6; b
++)
580 i
= r
+ g
*6 + b
*36 + 10;
581 Palette
.aEntries
[i
].peRed
= r
* 51;
582 Palette
.aEntries
[i
].peGreen
= g
* 51;
583 Palette
.aEntries
[i
].peBlue
= b
* 51;
586 for (i
= 216; i
< 246; i
++)
588 int v
= (i
- 216) << 3;
589 Palette
.aEntries
[i
].peRed
= v
;
590 Palette
.aEntries
[i
].peGreen
= v
;
591 Palette
.aEntries
[i
].peBlue
= v
;
595 return NtGdiCreatePaletteInternal((LOGPALETTE
*)&Palette
, Palette
.NumberOfEntries
);
604 /* PALOBJ *palPtr = (PALOBJ*)AccessUserObject(hPal);
605 UINT cPrevEnt, prevVer;
606 INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
607 XLATEOBJ *XlateObj = NULL;
609 if(!palPtr) return FALSE;
610 cPrevEnt = palPtr->logpalette->palNumEntries;
611 prevVer = palPtr->logpalette->palVersion;
612 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
613 size += sizeof(int*) + sizeof(GDIOBJHDR);
614 XlateObj = palPtr->logicalToSystem;
616 if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
620 XLATEOBJ *NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
621 if(NewXlateObj == NULL)
623 ERR("Can not resize logicalToSystem -- out of memory!");
624 GDI_ReleaseObj( hPal );
627 palPtr->logicalToSystem = NewXlateObj;
630 if(cEntries > cPrevEnt)
632 if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
633 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
634 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
636 palPtr->logpalette->palNumEntries = cEntries;
637 palPtr->logpalette->palVersion = prevVer;
638 // GDI_ReleaseObj( hPal );
647 NtGdiGetColorAdjustment(
649 LPCOLORADJUSTMENT pca
)
657 NtGdiSetColorAdjustment(
659 LPCOLORADJUSTMENT pca
)
665 COLORREF APIENTRY
NtGdiGetNearestColor(HDC hDC
, COLORREF Color
)
667 COLORREF nearest
= CLR_INVALID
;
670 LONG RBits
, GBits
, BBits
;
675 HPALETTE hpal
= dc
->dclevel
.hpal
;
676 palGDI
= (PPALETTE
) PALETTE_LockPalette(hpal
);
683 if (palGDI
->Mode
& PAL_INDEXED
)
686 index
= PALETTE_ulGetNearestPaletteIndex(palGDI
, Color
);
687 nearest
= PALETTE_ulGetRGBColorFromIndex(palGDI
, index
);
689 else if (palGDI
->Mode
& PAL_RGB
|| palGDI
->Mode
& PAL_BGR
)
693 else if (palGDI
->Mode
& PAL_BITFIELDS
)
695 RBits
= 8 - GetNumberOfBits(palGDI
->RedMask
);
696 GBits
= 8 - GetNumberOfBits(palGDI
->GreenMask
);
697 BBits
= 8 - GetNumberOfBits(palGDI
->BlueMask
);
699 (GetRValue(Color
) >> RBits
) << RBits
,
700 (GetGValue(Color
) >> GBits
) << GBits
,
701 (GetBValue(Color
) >> BBits
) << BBits
);
703 PALETTE_UnlockPalette(palGDI
);
712 NtGdiGetNearestPaletteIndex(
716 PPALETTE ppal
= (PPALETTE
) PALETTE_LockPalette(hpal
);
721 if (ppal
->Mode
& PAL_INDEXED
)
723 /* Return closest match for the given RGB color */
724 index
= PALETTE_ulGetNearestPaletteIndex(ppal
, crColor
);
726 // else SetLastError ?
727 PALETTE_UnlockPalette(ppal
);
735 IntGdiRealizePalette(HDC hDC
)
738 * This function doesn't do any real work now and there's plenty
742 PPALETTE palGDI
, sysGDI
;
745 HPALETTE systemPalette
;
746 USHORT sysMode
, palMode
;
751 systemPalette
= NtGdiGetStockObject(DEFAULT_PALETTE
);
752 palGDI
= PALETTE_LockPalette(dc
->dclevel
.hpal
);
756 DPRINT1("IntGdiRealizePalette(): palGDI is NULL, exiting\n");
761 sysGDI
= PALETTE_LockPalette(systemPalette
);
765 DPRINT1("IntGdiRealizePalette(): sysGDI is NULL, exiting\n");
766 PALETTE_UnlockPalette(palGDI
);
771 // The RealizePalette function modifies the palette for the device associated with the specified device context. If the
772 // device context is a memory DC, the color table for the bitmap selected into the DC is modified. If the device
773 // context is a display DC, the physical palette for that device is modified.
774 if(dc
->dctype
== DC_TYPE_MEMORY
)
777 DPRINT1("RealizePalette unimplemented for memory managed DCs\n");
780 DPRINT1("RealizePalette unimplemented for device DCs\n");
783 // need to pass this to IntEngCreateXlate with palettes unlocked
784 sysMode
= sysGDI
->Mode
;
785 palMode
= palGDI
->Mode
;
786 PALETTE_UnlockPalette(sysGDI
);
787 PALETTE_UnlockPalette(palGDI
);
795 IntAnimatePalette(HPALETTE hPal
,
798 CONST PPALETTEENTRY PaletteColors
)
802 if( hPal
!= NtGdiGetStockObject(DEFAULT_PALETTE
) )
809 const PALETTEENTRY
*pptr
= PaletteColors
;
811 palPtr
= (PPALETTE
)PALETTE_LockPalette(hPal
);
812 if (!palPtr
) return FALSE
;
814 pal_entries
= palPtr
->NumColors
;
815 if (StartIndex
>= pal_entries
)
817 PALETTE_UnlockPalette(palPtr
);
820 if (StartIndex
+NumEntries
> pal_entries
) NumEntries
= pal_entries
- StartIndex
;
822 for (NumEntries
+= StartIndex
; StartIndex
< NumEntries
; StartIndex
++, pptr
++)
824 /* According to MSDN, only animate PC_RESERVED colours */
825 if (palPtr
->IndexedColors
[StartIndex
].peFlags
& PC_RESERVED
)
827 memcpy( &palPtr
->IndexedColors
[StartIndex
], pptr
,
828 sizeof(PALETTEENTRY
) );
830 PALETTE_ValidateFlags(&palPtr
->IndexedColors
[StartIndex
], 1);
834 PALETTE_UnlockPalette(palPtr
);
836 /* Immediately apply the new palette if current window uses it */
837 Wnd
= UserGetDesktopWindow();
838 hDC
= UserGetWindowDC(Wnd
);
842 if (dc
->dclevel
.hpal
== hPal
)
845 IntGdiRealizePalette(hDC
);
850 UserReleaseDC(Wnd
,hDC
, FALSE
);
856 IntGetPaletteEntries(
865 palGDI
= (PPALETTE
) PALETTE_LockPalette(hpal
);
871 numEntries
= palGDI
->NumColors
;
874 if (numEntries
< StartIndex
+ Entries
)
876 Entries
= numEntries
- StartIndex
;
878 if (numEntries
<= StartIndex
)
880 PALETTE_UnlockPalette(palGDI
);
883 memcpy(pe
, palGDI
->IndexedColors
+ StartIndex
, Entries
* sizeof(PALETTEENTRY
));
887 Entries
= numEntries
;
890 PALETTE_UnlockPalette(palGDI
);
895 IntGetSystemPaletteEntries(HDC hDC
,
900 PPALETTE palGDI
= NULL
;
902 UINT EntriesSize
= 0;
907 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
913 EntriesSize
= Entries
* sizeof(pe
[0]);
914 if (Entries
!= EntriesSize
/ sizeof(pe
[0]))
916 /* Integer overflow! */
917 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
922 if (!(dc
= DC_LockDc(hDC
)))
924 SetLastWin32Error(ERROR_INVALID_HANDLE
);
928 palGDI
= PALETTE_LockPalette(dc
->dclevel
.hpal
);
933 if (StartIndex
>= palGDI
->NumColors
)
935 else if (Entries
> palGDI
->NumColors
- StartIndex
)
936 Entries
= palGDI
->NumColors
- StartIndex
;
939 palGDI
->IndexedColors
+ StartIndex
,
940 Entries
* sizeof(pe
[0]));
946 Ret
= dc
->ppdev
->gdiinfo
.ulNumPalReg
;
951 PALETTE_UnlockPalette(palGDI
);
961 IntSetPaletteEntries(
965 CONST LPPALETTEENTRY pe
)
970 if ((UINT
)hpal
& GDI_HANDLE_STOCK_MASK
)
975 palGDI
= PALETTE_LockPalette(hpal
);
976 if (!palGDI
) return 0;
978 numEntries
= palGDI
->NumColors
;
979 if (Start
>= numEntries
)
981 PALETTE_UnlockPalette(palGDI
);
984 if (numEntries
< Start
+ Entries
)
986 Entries
= numEntries
- Start
;
988 memcpy(palGDI
->IndexedColors
+ Start
, pe
, Entries
* sizeof(PALETTEENTRY
));
989 PALETTE_UnlockPalette(palGDI
);
1001 IN LPVOID pUnsafeEntries
,
1006 LPVOID pEntries
= NULL
;
1008 /* FIXME: Handle bInbound correctly */
1011 (pUnsafeEntries
== NULL
|| cEntries
== 0))
1018 pEntries
= ExAllocatePool(PagedPool
, cEntries
* sizeof(PALETTEENTRY
));
1025 ProbeForRead(pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
), 1);
1026 memcpy(pEntries
, pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
));
1028 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1030 ExFreePool(pEntries
);
1031 _SEH2_YIELD(return 0);
1042 ret
= IntAnimatePalette((HPALETTE
)hObj
, iStart
, cEntries
, (CONST PPALETTEENTRY
)pEntries
);
1045 case GdiPalSetEntries
:
1047 ret
= IntSetPaletteEntries((HPALETTE
)hObj
, iStart
, cEntries
, (CONST LPPALETTEENTRY
)pEntries
);
1050 case GdiPalGetEntries
:
1051 ret
= IntGetPaletteEntries((HPALETTE
)hObj
, iStart
, cEntries
, (LPPALETTEENTRY
)pEntries
);
1054 case GdiPalGetSystemEntries
:
1055 ret
= IntGetSystemPaletteEntries((HDC
)hObj
, iStart
, cEntries
, (LPPALETTEENTRY
)pEntries
);
1058 case GdiPalSetColorTable
:
1060 ret
= IntSetDIBColorTable((HDC
)hObj
, iStart
, cEntries
, (RGBQUAD
*)pEntries
);
1063 case GdiPalGetColorTable
:
1065 ret
= IntGetDIBColorTable((HDC
)hObj
, iStart
, cEntries
, (RGBQUAD
*)pEntries
);
1075 ProbeForWrite(pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
), 1);
1076 memcpy(pUnsafeEntries
, pEntries
, cEntries
* sizeof(PALETTEENTRY
));
1078 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1084 ExFreePool(pEntries
);
1091 NtGdiSetSystemPaletteUse(HDC hDC
, UINT Usage
)
1093 UINT old
= SystemPaletteUse
;
1095 /* Device doesn't support colour palettes */
1096 if (!(NtGdiGetDeviceCaps(hDC
, RASTERCAPS
) & RC_PALETTE
)) {
1097 return SYSPAL_ERROR
;
1102 case SYSPAL_NOSTATIC
:
1103 case SYSPAL_NOSTATIC256
:
1105 SystemPaletteUse
= Usage
;
1118 NtGdiGetSystemPaletteUse(HDC hDC
)
1120 return SystemPaletteUse
;
1125 NtGdiUpdateColors(HDC hDC
)
1128 BOOL calledFromUser
, ret
;
1129 USER_REFERENCE_ENTRY Ref
;
1131 calledFromUser
= UserIsEntered();
1133 if (!calledFromUser
){
1134 UserEnterExclusive();
1137 Wnd
= UserGetWindowObject(IntWindowFromDC(hDC
));
1140 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
1142 if (!calledFromUser
){
1149 UserRefObjectCo(Wnd
, &Ref
);
1150 ret
= co_UserRedrawWindow(Wnd
, NULL
, 0, RDW_INVALIDATE
);
1151 UserDerefObjectCo(Wnd
);
1153 if (!calledFromUser
){
1162 NtGdiUnrealizeObject(HGDIOBJ hgdiobj
)
1168 ((UINT
)hgdiobj
& GDI_HANDLE_STOCK_MASK
) ||
1169 !GDI_HANDLE_IS_TYPE(hgdiobj
, GDI_OBJECT_TYPE_PALETTE
) )
1172 palGDI
= PALETTE_LockPalette(hgdiobj
);
1173 if (!palGDI
) return FALSE
;
1176 // Need to do something!!!
1177 // Zero out Current and Old Translated pointers?
1180 PALETTE_UnlockPalette(palGDI
);