2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: GDI Palette Functions
5 * FILE: subsystems/win32/win32k/objects/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
69 // Create default palette (20 system colors)
70 palPtr
= ExAllocatePoolWithTag(PagedPool
,
72 (NB_RESERVED_COLORS
* sizeof(PALETTEENTRY
)),
74 if (!palPtr
) return STATUS_NO_MEMORY
;
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
= GreCreatePaletteInternal(palPtr
,NB_RESERVED_COLORS
);
88 ExFreePoolWithTag(palPtr
, TAG_PALETTE
);
90 /* palette_size = visual->map_entries; */
92 gpalRGB
.flFlags
= PAL_RGB
;
93 gpalRGB
.RedMask
= RGB(0xFF, 0x00, 0x00);
94 gpalRGB
.GreenMask
= RGB(0x00, 0xFF, 0x00);
95 gpalRGB
.BlueMask
= RGB(0x00, 0x00, 0xFF);
96 gpalRGB
.BaseObject
.ulShareCount
= 1;
97 gpalRGB
.BaseObject
.BaseFlags
= 0 ;
99 gpalBGR
.flFlags
= PAL_BGR
;
100 gpalBGR
.RedMask
= RGB(0x00, 0x00, 0xFF);
101 gpalBGR
.GreenMask
= RGB(0x00, 0xFF, 0x00);
102 gpalBGR
.BlueMask
= RGB(0xFF, 0x00, 0x00);
103 gpalBGR
.BaseObject
.ulShareCount
= 1;
104 gpalBGR
.BaseObject
.BaseFlags
= 0 ;
106 gpalRGB555
.flFlags
= PAL_RGB16_555
| PAL_BITFIELDS
;
107 gpalRGB555
.RedMask
= 0x7C00;
108 gpalRGB555
.GreenMask
= 0x3E0;
109 gpalRGB555
.BlueMask
= 0x1F;
110 gpalRGB555
.BaseObject
.ulShareCount
= 1;
111 gpalRGB555
.BaseObject
.BaseFlags
= 0 ;
113 gpalRGB565
.flFlags
= PAL_RGB16_565
| PAL_BITFIELDS
;
114 gpalRGB565
.RedMask
= 0xF800;
115 gpalRGB565
.GreenMask
= 0x7E0;
116 gpalRGB565
.BlueMask
= 0x1F;
117 gpalRGB565
.BaseObject
.ulShareCount
= 1;
118 gpalRGB565
.BaseObject
.BaseFlags
= 0 ;
120 memset(&gpalMono
, 0, sizeof(PALETTE
));
121 gpalMono
.flFlags
= PAL_MONOCHROME
;
122 gpalMono
.BaseObject
.ulShareCount
= 1;
123 gpalMono
.BaseObject
.BaseFlags
= 0 ;
125 /* Initialize default surface palettes */
126 gppalDefault
= PALETTE_ShareLockPalette(hpalette
);
127 appalSurfaceDefault
[BMF_1BPP
] = &gpalMono
;
128 appalSurfaceDefault
[BMF_4BPP
] = gppalDefault
;
129 appalSurfaceDefault
[BMF_8BPP
] = gppalDefault
;
130 appalSurfaceDefault
[BMF_16BPP
] = &gpalRGB565
;
131 appalSurfaceDefault
[BMF_24BPP
] = &gpalBGR
;
132 appalSurfaceDefault
[BMF_32BPP
] = &gpalBGR
;
133 appalSurfaceDefault
[BMF_4RLE
] = gppalDefault
;
134 appalSurfaceDefault
[BMF_8RLE
] = gppalDefault
;
135 appalSurfaceDefault
[BMF_JPEG
] = &gpalRGB
;
136 appalSurfaceDefault
[BMF_PNG
] = &gpalRGB
;
138 return STATUS_SUCCESS
;
141 VOID FASTCALL
PALETTE_ValidateFlags(PALETTEENTRY
* lpPalE
, INT size
)
145 lpPalE
[i
].peFlags
= PC_SYS_USED
| (lpPalE
[i
].peFlags
& 0x07);
150 PALETTE_AllocPalette2(ULONG Mode
,
159 PalGDI
= (PPALETTE
)GDIOBJ_AllocateObject(GDIObjType_PAL_TYPE
,
164 DPRINT1("Could not allocate a palette.\n");
168 PalGDI
->flFlags
= Mode
;
172 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
,
173 sizeof(PALETTEENTRY
) * NumColors
,
175 if (NULL
== PalGDI
->IndexedColors
)
177 GDIOBJ_vDeleteObject(&PalGDI
->BaseObject
);
180 if (Colors
) RtlCopyMemory(PalGDI
->IndexedColors
, Colors
, sizeof(PALETTEENTRY
) * NumColors
);
183 if (Mode
& PAL_INDEXED
)
185 PalGDI
->NumColors
= NumColors
;
187 else if (Mode
& PAL_BITFIELDS
)
189 PalGDI
->RedMask
= Red
;
190 PalGDI
->GreenMask
= Green
;
191 PalGDI
->BlueMask
= Blue
;
193 if (Red
== 0x7c00 && Green
== 0x3E0 && Blue
== 0x1F)
194 PalGDI
->flFlags
|= PAL_RGB16_555
;
195 else if (Red
== 0xF800 && Green
== 0x7E0 && Blue
== 0x1F)
196 PalGDI
->flFlags
|= PAL_RGB16_565
;
197 else if (Red
== 0xFF0000 && Green
== 0xFF00 && Blue
== 0xFF)
198 PalGDI
->flFlags
|= PAL_BGR
;
199 else if (Red
== 0xFF && Green
== 0xFF00 && Blue
== 0xFF0000)
200 PalGDI
->flFlags
|= PAL_RGB
;
208 PALETTE_AllocPalWithHandle(
211 _In_ PULONG pulColors
,
218 /* Allocate the palette without a handle */
219 ppal
= PALETTE_AllocPalette2(iMode
, cColors
, pulColors
, flRed
, flGreen
, flBlue
);
220 if (!ppal
) return NULL
;
222 /* Insert the palette into the handle table */
223 if (!GDIOBJ_hInsertObject(&ppal
->BaseObject
, GDI_OBJ_HMGR_POWNED
))
225 DPRINT1("Could not insert palette into handle table.\n");
226 GDIOBJ_vFreeObject(&ppal
->BaseObject
);
235 PALETTE_AllocPalette(ULONG Mode
,
245 ppal
= PALETTE_AllocPalette2(Mode
, NumColors
, Colors
, Red
, Green
, Blue
);
246 if (!ppal
) return NULL
;
248 hpal
= GDIOBJ_hInsertObject(&ppal
->BaseObject
, GDI_OBJ_HMGR_POWNED
);
251 DPRINT1("Could not insert palette into handle table.\n");
252 GDIOBJ_vFreeObject(&ppal
->BaseObject
);
256 PALETTE_UnlockPalette(ppal
);
263 PALETTE_AllocPaletteIndexedRGB(ULONG NumColors
,
264 CONST RGBQUAD
*Colors
)
270 PalGDI
= (PPALETTE
)GDIOBJ_AllocateObject(GDIObjType_PAL_TYPE
,
275 DPRINT1("Could not allocate a palette.\n");
279 if (!GDIOBJ_hInsertObject(&PalGDI
->BaseObject
, GDI_OBJ_HMGR_POWNED
))
281 DPRINT1("Could not insert palette into handle table.\n");
282 GDIOBJ_vFreeObject(&PalGDI
->BaseObject
);
286 NewPalette
= PalGDI
->BaseObject
.hHmgr
;
288 PalGDI
->flFlags
= PAL_INDEXED
;
290 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
,
291 sizeof(PALETTEENTRY
) * NumColors
,
293 if (NULL
== PalGDI
->IndexedColors
)
295 GDIOBJ_vDeleteObject(&PalGDI
->BaseObject
);
299 for (i
= 0; i
< NumColors
; i
++)
301 PalGDI
->IndexedColors
[i
].peRed
= Colors
[i
].rgbRed
;
302 PalGDI
->IndexedColors
[i
].peGreen
= Colors
[i
].rgbGreen
;
303 PalGDI
->IndexedColors
[i
].peBlue
= Colors
[i
].rgbBlue
;
304 PalGDI
->IndexedColors
[i
].peFlags
= 0;
307 PalGDI
->NumColors
= NumColors
;
309 PALETTE_UnlockPalette(PalGDI
);
316 PALETTE_Cleanup(PVOID ObjectBody
)
318 PPALETTE pPal
= (PPALETTE
)ObjectBody
;
319 if (pPal
->IndexedColors
&& pPal
->IndexedColors
!= pPal
->apalColors
)
321 ExFreePoolWithTag(pPal
->IndexedColors
, TAG_PALETTE
);
329 PALETTE_GetObject(PPALETTE ppal
, INT cbCount
, LPLOGBRUSH lpBuffer
)
336 if ((UINT
)cbCount
< sizeof(WORD
)) return 0;
337 *((WORD
*)lpBuffer
) = (WORD
)ppal
->NumColors
;
343 PALETTE_ulGetNearestPaletteIndex(PALETTE
* ppal
, ULONG iColor
)
345 ULONG ulDiff
, ulColorDiff
, ulMinimalDiff
= 0xFFFFFF;
346 ULONG i
, ulBestIndex
= 0;
347 PALETTEENTRY peColor
= *(PPALETTEENTRY
)&iColor
;
349 /* Loop all palette entries */
350 for (i
= 0; i
< ppal
->NumColors
; i
++)
352 /* Calculate distance in the color cube */
353 ulDiff
= peColor
.peRed
- ppal
->IndexedColors
[i
].peRed
;
354 ulColorDiff
= ulDiff
* ulDiff
;
355 ulDiff
= peColor
.peGreen
- ppal
->IndexedColors
[i
].peGreen
;
356 ulColorDiff
+= ulDiff
* ulDiff
;
357 ulDiff
= peColor
.peBlue
- ppal
->IndexedColors
[i
].peBlue
;
358 ulColorDiff
+= ulDiff
* ulDiff
;
360 /* Check for a better match */
361 if (ulColorDiff
< ulMinimalDiff
)
364 ulMinimalDiff
= ulColorDiff
;
366 /* Break on exact match */
367 if (ulMinimalDiff
== 0) break;
376 PALETTE_ulGetNearestBitFieldsIndex(PALETTE
* ppal
, ULONG ulColor
)
380 // FIXME: HACK, should be stored already
381 ppal
->ulRedShift
= CalculateShift(RGB(0xff,0,0), ppal
->RedMask
);
382 ppal
->ulGreenShift
= CalculateShift(RGB(0,0xff,0), ppal
->GreenMask
);
383 ppal
->ulBlueShift
= CalculateShift(RGB(0,0,0xff), ppal
->BlueMask
);
385 ulNewColor
= _rotl(ulColor
, ppal
->ulRedShift
) & ppal
->RedMask
;
386 ulNewColor
|= _rotl(ulColor
, ppal
->ulGreenShift
) & ppal
->GreenMask
;
387 ulNewColor
|= _rotl(ulColor
, ppal
->ulBlueShift
) & ppal
->BlueMask
;
394 PALETTE_ulGetNearestIndex(PALETTE
* ppal
, ULONG ulColor
)
396 if (ppal
->flFlags
& PAL_INDEXED
) // Use fl & PALINDEXED
397 return PALETTE_ulGetNearestPaletteIndex(ppal
, ulColor
);
399 return PALETTE_ulGetNearestBitFieldsIndex(ppal
, ulColor
);
404 PALETTE_vGetBitMasks(PPALETTE ppal
, PULONG pulColors
)
408 if (ppal
->flFlags
& PAL_INDEXED
|| ppal
->flFlags
& PAL_RGB
)
410 pulColors
[0] = RGB(0xFF, 0x00, 0x00);
411 pulColors
[1] = RGB(0x00, 0xFF, 0x00);
412 pulColors
[2] = RGB(0x00, 0x00, 0xFF);
414 else if (ppal
->flFlags
& PAL_BGR
)
416 pulColors
[0] = RGB(0x00, 0x00, 0xFF);
417 pulColors
[1] = RGB(0x00, 0xFF, 0x00);
418 pulColors
[2] = RGB(0xFF, 0x00, 0x00);
420 else if (ppal
->flFlags
& PAL_BITFIELDS
)
422 pulColors
[0] = ppal
->RedMask
;
423 pulColors
[1] = ppal
->GreenMask
;
424 pulColors
[2] = ppal
->BlueMask
;
430 ColorCorrection(PPALETTE PalGDI
, PPALETTEENTRY PaletteEntry
, ULONG Colors
)
432 PPDEVOBJ ppdev
= (PPDEVOBJ
)PalGDI
->hPDev
;
436 if (ppdev
->flFlags
& PDEV_GAMMARAMP_TABLE
)
439 PGAMMARAMP GammaRamp
= (PGAMMARAMP
)ppdev
->pvGammaRamp
;
440 for ( i
= 0; i
< Colors
; i
++)
442 PaletteEntry
[i
].peRed
+= GammaRamp
->Red
[i
];
443 PaletteEntry
[i
].peGreen
+= GammaRamp
->Green
[i
];
444 PaletteEntry
[i
].peBlue
+= GammaRamp
->Blue
[i
];
450 /** Display Driver Interface **************************************************/
468 ppal
= PALETTE_AllocPalette2(iMode
, cColors
, pulColors
, flRed
, flGreen
, flBlue
);
469 if (!ppal
) return NULL
;
471 hpal
= GDIOBJ_hInsertObject(&ppal
->BaseObject
, GDI_OBJ_HMGR_PUBLIC
);
474 DPRINT1("Could not insert palette into handle table.\n");
475 GDIOBJ_vFreeObject(&ppal
->BaseObject
);
479 PALETTE_UnlockPalette(ppal
);
488 EngDeletePalette(IN HPALETTE hpal
)
492 ppal
= PALETTE_ShareLockPalette(hpal
);
493 if (!ppal
) return FALSE
;
495 GDIOBJ_vDeleteObject(&ppal
->BaseObject
);
505 PALOBJ_cGetColors(PALOBJ
*PalObj
, ULONG Start
, ULONG Colors
, ULONG
*PaletteEntry
)
509 PalGDI
= (PALETTE
*)PalObj
;
511 if (Start
>= PalGDI
->NumColors
)
514 Colors
= min(Colors
, PalGDI
->NumColors
- Start
);
516 /* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */
517 RtlCopyMemory(PaletteEntry
, PalGDI
->IndexedColors
+ Start
, sizeof(ULONG
) * Colors
);
519 if (PalGDI
->flFlags
& PAL_GAMMACORRECTION
)
520 ColorCorrection(PalGDI
, (PPALETTEENTRY
)PaletteEntry
, Colors
);
526 /** Systemcall Interface ******************************************************/
530 GreCreatePaletteInternal(
531 IN LPLOGPALETTE pLogPal
,
534 HPALETTE hpal
= NULL
;
537 pLogPal
->palNumEntries
= cEntries
;
538 ppal
= PALETTE_AllocPalWithHandle(PAL_INDEXED
,
540 (PULONG
)pLogPal
->palPalEntry
,
545 PALETTE_ValidateFlags(ppal
->IndexedColors
, ppal
->NumColors
);
547 hpal
= ppal
->BaseObject
.hHmgr
;
548 PALETTE_UnlockPalette(ppal
);
559 NtGdiCreatePaletteInternal(
560 IN LPLOGPALETTE plogpalUser
,
563 HPALETTE hpal
= NULL
;
567 ppal
= PALETTE_AllocPalWithHandle(PAL_INDEXED
, cEntries
, NULL
, 0, 0, 0);
573 cjSize
= FIELD_OFFSET(LOGPALETTE
, palPalEntry
[cEntries
]);
577 ProbeForRead(plogpalUser
, cjSize
, 1);
579 for (i
= 0; i
< cEntries
; i
++)
581 ppal
->IndexedColors
[i
] = plogpalUser
->palPalEntry
[i
];
584 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
586 GDIOBJ_vDeleteObject(&ppal
->BaseObject
);
587 _SEH2_YIELD(return NULL
);
591 PALETTE_ValidateFlags(ppal
->IndexedColors
, cEntries
);
592 hpal
= ppal
->BaseObject
.hHmgr
;
593 PALETTE_UnlockPalette(ppal
);
598 HPALETTE APIENTRY
NtGdiCreateHalftonePalette(HDC hDC
)
603 WORD NumberOfEntries
;
604 PALETTEENTRY aEntries
[256];
607 Palette
.Version
= 0x300;
608 Palette
.NumberOfEntries
= 256;
609 if (IntGetSystemPaletteEntries(hDC
, 0, 256, Palette
.aEntries
) == 0)
611 /* From WINE, more that 256 color math */
612 Palette
.NumberOfEntries
= 20;
613 for (i
= 0; i
< Palette
.NumberOfEntries
; i
++)
615 Palette
.aEntries
[i
].peRed
=0xff;
616 Palette
.aEntries
[i
].peGreen
=0xff;
617 Palette
.aEntries
[i
].peBlue
=0xff;
618 Palette
.aEntries
[i
].peFlags
=0x00;
621 Palette
.aEntries
[0].peRed
=0x00;
622 Palette
.aEntries
[0].peBlue
=0x00;
623 Palette
.aEntries
[0].peGreen
=0x00;
626 for (i
=1; i
<= 6; i
++)
628 Palette
.aEntries
[i
].peRed
=(i
%2)?0x80:0;
629 Palette
.aEntries
[i
].peGreen
=(i
==2)?0x80:(i
==3)?0x80:(i
==6)?0x80:0;
630 Palette
.aEntries
[i
].peBlue
=(i
>3)?0x80:0;
633 for (i
=7; i
<= 12; i
++)
638 Palette
.aEntries
[i
].peRed
=0xc0;
639 Palette
.aEntries
[i
].peBlue
=0xc0;
640 Palette
.aEntries
[i
].peGreen
=0xc0;
643 Palette
.aEntries
[i
].peRed
=0xc0;
644 Palette
.aEntries
[i
].peGreen
=0xdc;
645 Palette
.aEntries
[i
].peBlue
=0xc0;
648 Palette
.aEntries
[i
].peRed
=0xa6;
649 Palette
.aEntries
[i
].peGreen
=0xca;
650 Palette
.aEntries
[i
].peBlue
=0xf0;
653 Palette
.aEntries
[i
].peRed
=0xff;
654 Palette
.aEntries
[i
].peGreen
=0xfb;
655 Palette
.aEntries
[i
].peBlue
=0xf0;
658 Palette
.aEntries
[i
].peRed
=0xa0;
659 Palette
.aEntries
[i
].peGreen
=0xa0;
660 Palette
.aEntries
[i
].peBlue
=0xa4;
663 Palette
.aEntries
[i
].peRed
=0x80;
664 Palette
.aEntries
[i
].peGreen
=0x80;
665 Palette
.aEntries
[i
].peBlue
=0x80;
669 for (i
=13; i
<= 18; i
++)
671 Palette
.aEntries
[i
].peRed
=(i
%2)?0xff:0;
672 Palette
.aEntries
[i
].peGreen
=(i
==14)?0xff:(i
==15)?0xff:(i
==18)?0xff:0;
673 Palette
.aEntries
[i
].peBlue
=(i
>15)?0xff:0x00;
678 /* 256 color table */
679 for (r
= 0; r
< 6; r
++)
680 for (g
= 0; g
< 6; g
++)
681 for (b
= 0; b
< 6; b
++)
683 i
= r
+ g
*6 + b
*36 + 10;
684 Palette
.aEntries
[i
].peRed
= r
* 51;
685 Palette
.aEntries
[i
].peGreen
= g
* 51;
686 Palette
.aEntries
[i
].peBlue
= b
* 51;
689 for (i
= 216; i
< 246; i
++)
691 int v
= (i
- 216) << 3;
692 Palette
.aEntries
[i
].peRed
= v
;
693 Palette
.aEntries
[i
].peGreen
= v
;
694 Palette
.aEntries
[i
].peBlue
= v
;
698 return GreCreatePaletteInternal((LOGPALETTE
*)&Palette
, Palette
.NumberOfEntries
);
707 /* PALOBJ *palPtr = (PALOBJ*)AccessUserObject(hPal);
708 UINT cPrevEnt, prevVer;
709 INT prevsize, size = sizeof(LOGPALETTE) + (cEntries - 1) * sizeof(PALETTEENTRY);
710 XLATEOBJ *XlateObj = NULL;
712 if(!palPtr) return FALSE;
713 cPrevEnt = palPtr->logpalette->palNumEntries;
714 prevVer = palPtr->logpalette->palVersion;
715 prevsize = sizeof(LOGPALETTE) + (cPrevEnt - 1) * sizeof(PALETTEENTRY) + sizeof(int*) + sizeof(GDIOBJHDR);
716 size += sizeof(int*) + sizeof(GDIOBJHDR);
717 XlateObj = palPtr->logicalToSystem;
719 if (!(palPtr = GDI_ReallocObject(size, hPal, palPtr))) return FALSE;
723 XLATEOBJ *NewXlateObj = (int*) HeapReAlloc(GetProcessHeap(), 0, XlateObj, cEntries * sizeof(int));
724 if(NewXlateObj == NULL)
726 ERR("Can not resize logicalToSystem -- out of memory!");
727 GDI_ReleaseObj( hPal );
730 palPtr->logicalToSystem = NewXlateObj;
733 if(cEntries > cPrevEnt)
735 if(XlateObj) memset(palPtr->logicalToSystem + cPrevEnt, 0, (cEntries - cPrevEnt)*sizeof(int));
736 memset( (BYTE*)palPtr + prevsize, 0, size - prevsize );
737 PALETTE_ValidateFlags((PALETTEENTRY*)((BYTE*)palPtr + prevsize), cEntries - cPrevEnt );
739 palPtr->logpalette->palNumEntries = cEntries;
740 palPtr->logpalette->palVersion = prevVer;
741 // GDI_ReleaseObj( hPal );
750 NtGdiGetColorAdjustment(
752 LPCOLORADJUSTMENT pca
)
760 NtGdiSetColorAdjustment(
762 LPCOLORADJUSTMENT pca
)
768 COLORREF APIENTRY
NtGdiGetNearestColor(HDC hDC
, COLORREF Color
)
770 COLORREF nearest
= CLR_INVALID
;
773 LONG RBits
, GBits
, BBits
;
778 HPALETTE hpal
= dc
->dclevel
.hpal
;
779 palGDI
= PALETTE_ShareLockPalette(hpal
);
786 if (palGDI
->flFlags
& PAL_INDEXED
)
789 index
= PALETTE_ulGetNearestPaletteIndex(palGDI
, Color
);
790 nearest
= PALETTE_ulGetRGBColorFromIndex(palGDI
, index
);
792 else if (palGDI
->flFlags
& PAL_RGB
|| palGDI
->flFlags
& PAL_BGR
)
796 else if (palGDI
->flFlags
& PAL_BITFIELDS
)
798 RBits
= 8 - GetNumberOfBits(palGDI
->RedMask
);
799 GBits
= 8 - GetNumberOfBits(palGDI
->GreenMask
);
800 BBits
= 8 - GetNumberOfBits(palGDI
->BlueMask
);
802 (GetRValue(Color
) >> RBits
) << RBits
,
803 (GetGValue(Color
) >> GBits
) << GBits
,
804 (GetBValue(Color
) >> BBits
) << BBits
);
806 PALETTE_ShareUnlockPalette(palGDI
);
815 NtGdiGetNearestPaletteIndex(
819 PPALETTE ppal
= PALETTE_ShareLockPalette(hpal
);
824 if (ppal
->flFlags
& PAL_INDEXED
)
826 /* Return closest match for the given RGB color */
827 index
= PALETTE_ulGetNearestPaletteIndex(ppal
, crColor
);
829 // else SetLastError ?
830 PALETTE_ShareUnlockPalette(ppal
);
838 IntGdiRealizePalette(HDC hDC
)
842 PALETTE
*ppalSurf
, *ppalDC
;
844 pdc
= DC_LockDc(hDC
);
847 EngSetLastError(ERROR_INVALID_HANDLE
);
851 ppalSurf
= pdc
->dclevel
.pSurface
->ppal
;
852 ppalDC
= pdc
->dclevel
.ppal
;
854 if(!(ppalSurf
->flFlags
& PAL_INDEXED
))
860 ASSERT(ppalDC
->flFlags
& PAL_INDEXED
);
862 // FIXME: Should we resize ppalSurf if it's too small?
863 realize
= (ppalDC
->NumColors
< ppalSurf
->NumColors
) ? ppalDC
->NumColors
: ppalSurf
->NumColors
;
865 for(i
=0; i
<realize
; i
++)
867 InterlockedExchange((LONG
*)&ppalSurf
->IndexedColors
[i
], *(LONG
*)&ppalDC
->IndexedColors
[i
]);
876 IntAnimatePalette(HPALETTE hPal
,
879 CONST PPALETTEENTRY PaletteColors
)
883 if( hPal
!= NtGdiGetStockObject(DEFAULT_PALETTE
) )
890 const PALETTEENTRY
*pptr
= PaletteColors
;
892 palPtr
= PALETTE_ShareLockPalette(hPal
);
893 if (!palPtr
) return FALSE
;
895 pal_entries
= palPtr
->NumColors
;
896 if (StartIndex
>= pal_entries
)
898 PALETTE_ShareUnlockPalette(palPtr
);
901 if (StartIndex
+NumEntries
> pal_entries
) NumEntries
= pal_entries
- StartIndex
;
903 for (NumEntries
+= StartIndex
; StartIndex
< NumEntries
; StartIndex
++, pptr
++)
905 /* According to MSDN, only animate PC_RESERVED colours */
906 if (palPtr
->IndexedColors
[StartIndex
].peFlags
& PC_RESERVED
)
908 memcpy( &palPtr
->IndexedColors
[StartIndex
], pptr
,
909 sizeof(PALETTEENTRY
) );
911 PALETTE_ValidateFlags(&palPtr
->IndexedColors
[StartIndex
], 1);
915 PALETTE_ShareUnlockPalette(palPtr
);
917 /* Immediately apply the new palette if current window uses it */
918 Wnd
= UserGetDesktopWindow();
919 hDC
= UserGetWindowDC(Wnd
);
923 if (dc
->dclevel
.hpal
== hPal
)
926 IntGdiRealizePalette(hDC
);
931 UserReleaseDC(Wnd
,hDC
, FALSE
);
937 IntGetPaletteEntries(
946 palGDI
= (PPALETTE
) PALETTE_ShareLockPalette(hpal
);
952 numEntries
= palGDI
->NumColors
;
955 if (numEntries
< StartIndex
+ Entries
)
957 Entries
= numEntries
- StartIndex
;
959 if (numEntries
<= StartIndex
)
961 PALETTE_ShareUnlockPalette(palGDI
);
964 memcpy(pe
, palGDI
->IndexedColors
+ StartIndex
, Entries
* sizeof(PALETTEENTRY
));
968 Entries
= numEntries
;
971 PALETTE_ShareUnlockPalette(palGDI
);
976 IntGetSystemPaletteEntries(HDC hDC
,
981 PPALETTE palGDI
= NULL
;
983 UINT EntriesSize
= 0;
988 EngSetLastError(ERROR_INVALID_PARAMETER
);
994 EntriesSize
= Entries
* sizeof(pe
[0]);
995 if (Entries
!= EntriesSize
/ sizeof(pe
[0]))
997 /* Integer overflow! */
998 EngSetLastError(ERROR_INVALID_PARAMETER
);
1003 if (!(dc
= DC_LockDc(hDC
)))
1005 EngSetLastError(ERROR_INVALID_HANDLE
);
1009 palGDI
= PALETTE_ShareLockPalette(dc
->dclevel
.hpal
);
1014 if (StartIndex
>= palGDI
->NumColors
)
1016 else if (Entries
> palGDI
->NumColors
- StartIndex
)
1017 Entries
= palGDI
->NumColors
- StartIndex
;
1020 palGDI
->IndexedColors
+ StartIndex
,
1021 Entries
* sizeof(pe
[0]));
1027 Ret
= dc
->ppdev
->gdiinfo
.ulNumPalReg
;
1032 PALETTE_ShareUnlockPalette(palGDI
);
1042 IntSetPaletteEntries(
1046 CONST LPPALETTEENTRY pe
)
1051 if ((UINT
)hpal
& GDI_HANDLE_STOCK_MASK
)
1056 palGDI
= PALETTE_ShareLockPalette(hpal
);
1057 if (!palGDI
) return 0;
1059 numEntries
= palGDI
->NumColors
;
1060 if (Start
>= numEntries
)
1062 PALETTE_ShareUnlockPalette(palGDI
);
1065 if (numEntries
< Start
+ Entries
)
1067 Entries
= numEntries
- Start
;
1069 memcpy(palGDI
->IndexedColors
+ Start
, pe
, Entries
* sizeof(PALETTEENTRY
));
1070 PALETTE_ShareUnlockPalette(palGDI
);
1082 IN LPVOID pUnsafeEntries
,
1087 LPVOID pEntries
= NULL
;
1089 /* FIXME: Handle bInbound correctly */
1092 (pUnsafeEntries
== NULL
|| cEntries
== 0))
1099 pEntries
= ExAllocatePoolWithTag(PagedPool
, cEntries
* sizeof(PALETTEENTRY
), TAG_PALETTE
);
1106 ProbeForRead(pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
), 1);
1107 memcpy(pEntries
, pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
));
1109 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1111 ExFreePoolWithTag(pEntries
, TAG_PALETTE
);
1112 _SEH2_YIELD(return 0);
1123 ret
= IntAnimatePalette((HPALETTE
)hObj
, iStart
, cEntries
, (CONST PPALETTEENTRY
)pEntries
);
1126 case GdiPalSetEntries
:
1128 ret
= IntSetPaletteEntries((HPALETTE
)hObj
, iStart
, cEntries
, (CONST LPPALETTEENTRY
)pEntries
);
1131 case GdiPalGetEntries
:
1132 ret
= IntGetPaletteEntries((HPALETTE
)hObj
, iStart
, cEntries
, (LPPALETTEENTRY
)pEntries
);
1135 case GdiPalGetSystemEntries
:
1136 ret
= IntGetSystemPaletteEntries((HDC
)hObj
, iStart
, cEntries
, (LPPALETTEENTRY
)pEntries
);
1139 case GdiPalSetColorTable
:
1141 ret
= IntSetDIBColorTable((HDC
)hObj
, iStart
, cEntries
, (RGBQUAD
*)pEntries
);
1144 case GdiPalGetColorTable
:
1146 ret
= IntGetDIBColorTable((HDC
)hObj
, iStart
, cEntries
, (RGBQUAD
*)pEntries
);
1156 ProbeForWrite(pUnsafeEntries
, cEntries
* sizeof(PALETTEENTRY
), 1);
1157 memcpy(pUnsafeEntries
, pEntries
, cEntries
* sizeof(PALETTEENTRY
));
1159 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1165 ExFreePoolWithTag(pEntries
, TAG_PALETTE
);
1172 NtGdiSetSystemPaletteUse(HDC hDC
, UINT Usage
)
1174 UINT old
= SystemPaletteUse
;
1176 /* Device doesn't support colour palettes */
1177 if (!(NtGdiGetDeviceCaps(hDC
, RASTERCAPS
) & RC_PALETTE
)) {
1178 return SYSPAL_ERROR
;
1183 case SYSPAL_NOSTATIC
:
1184 case SYSPAL_NOSTATIC256
:
1186 SystemPaletteUse
= Usage
;
1199 NtGdiGetSystemPaletteUse(HDC hDC
)
1201 return SystemPaletteUse
;
1206 NtGdiUpdateColors(HDC hDC
)
1209 BOOL calledFromUser
, ret
;
1210 USER_REFERENCE_ENTRY Ref
;
1212 calledFromUser
= UserIsEntered();
1214 if (!calledFromUser
){
1215 UserEnterExclusive();
1218 Wnd
= UserGetWindowObject(IntWindowFromDC(hDC
));
1221 EngSetLastError(ERROR_INVALID_WINDOW_HANDLE
);
1223 if (!calledFromUser
){
1230 UserRefObjectCo(Wnd
, &Ref
);
1231 ret
= co_UserRedrawWindow(Wnd
, NULL
, 0, RDW_INVALIDATE
);
1232 UserDerefObjectCo(Wnd
);
1234 if (!calledFromUser
){
1243 NtGdiUnrealizeObject(HGDIOBJ hgdiobj
)
1249 ((UINT
)hgdiobj
& GDI_HANDLE_STOCK_MASK
) ||
1250 !GDI_HANDLE_IS_TYPE(hgdiobj
, GDI_OBJECT_TYPE_PALETTE
) )
1253 palGDI
= PALETTE_ShareLockPalette(hgdiobj
);
1254 if (!palGDI
) return FALSE
;
1257 // Need to do something!!!
1258 // Zero out Current and Old Translated pointers?
1261 PALETTE_ShareUnlockPalette(palGDI
);