diff --git a/reactos/win32ss/gdi/ntgdi/dc.h b/reactos/win32ss/gdi/ntgdi/dc.h index 93bf60661ff..737bd32daba 100644 --- a/reactos/win32ss/gdi/ntgdi/dc.h +++ b/reactos/win32ss/gdi/ntgdi/dc.h @@ -138,9 +138,25 @@ typedef struct _DC ROS_DC_INFO rosdc; } DC; +extern PDC defaultDCstate; + /* Internal functions *********************************************************/ -extern PDC defaultDCstate; +/* dcobjs.c */ + +VOID FASTCALL DC_vUpdateFillBrush(PDC pdc); +VOID FASTCALL DC_vUpdateLineBrush(PDC pdc); +VOID FASTCALL DC_vUpdateTextBrush(PDC pdc); +VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc); + +HPALETTE +NTAPI +GdiSelectPalette( + HDC hDC, + HPALETTE hpal, + BOOL ForceBackground); + + INIT_FUNCTION NTSTATUS NTAPI InitDcImpl(VOID); PPDEVOBJ FASTCALL IntEnumHDev(VOID); @@ -152,10 +168,6 @@ BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL); BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest); VOID FASTCALL DC_vUpdateViewportExt(PDC pdc); VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL to); -VOID FASTCALL DC_vUpdateFillBrush(PDC pdc); -VOID FASTCALL DC_vUpdateLineBrush(PDC pdc); -VOID FASTCALL DC_vUpdateTextBrush(PDC pdc); -VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc); VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2); VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2); @@ -177,6 +189,7 @@ VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS); BOOL FASTCALL IntSetDefaultRegion(PDC); BOOL NTAPI GreSetDCOwner(HDC hdc, ULONG ulOwner); + FORCEINLINE PDC DC_LockDc(HDC hdc) diff --git a/reactos/win32ss/gdi/ntgdi/dcobjs.c b/reactos/win32ss/gdi/ntgdi/dcobjs.c index 29310c570fa..737cd671d96 100644 --- a/reactos/win32ss/gdi/ntgdi/dcobjs.c +++ b/reactos/win32ss/gdi/ntgdi/dcobjs.c @@ -139,7 +139,7 @@ DC_vUpdateBackgroundBrush(PDC pdc) } HPALETTE -FASTCALL +NTAPI GdiSelectPalette( HDC hDC, HPALETTE hpal, diff --git a/reactos/win32ss/gdi/ntgdi/palette.c b/reactos/win32ss/gdi/ntgdi/palette.c index 8105e6ad3c7..e7f70aef790 100644 --- a/reactos/win32ss/gdi/ntgdi/palette.c +++ b/reactos/win32ss/gdi/ntgdi/palette.c @@ -83,7 +83,8 @@ InitPaletteImpl() palPtr->palPalEntry[i].peFlags = 0; } - hpalette = NtGdiCreatePaletteInternal(palPtr,NB_RESERVED_COLORS); + hpalette = GreCreatePaletteInternal(palPtr,NB_RESERVED_COLORS); + ASSERT(hpalette); ExFreePoolWithTag(palPtr, TAG_PALETTE); /* palette_size = visual->map_entries; */ @@ -164,10 +165,9 @@ PALETTE_AllocPalette2(ULONG Mode, return NULL; } - PalGDI->Self = PalGDI->BaseObject.hHmgr; PalGDI->flFlags = Mode; - if (NULL != Colors) + if (NumColors > 0) { PalGDI->IndexedColors = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * NumColors, @@ -177,7 +177,7 @@ PALETTE_AllocPalette2(ULONG Mode, GDIOBJ_vDeleteObject(&PalGDI->BaseObject); return NULL; } - RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(PALETTEENTRY) * NumColors); + if (Colors) RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(PALETTEENTRY) * NumColors); } if (Mode & PAL_INDEXED) @@ -203,6 +203,33 @@ PALETTE_AllocPalette2(ULONG Mode, return PalGDI; } +PPALETTE +NTAPI +PALETTE_AllocPalWithHandle( + _In_ ULONG iMode, + _In_ ULONG cColors, + _In_ PULONG pulColors, + _In_ FLONG flRed, + _In_ FLONG flGreen, + _In_ FLONG flBlue) +{ + PPALETTE ppal; + + /* Allocate the palette without a handle */ + ppal = PALETTE_AllocPalette2(iMode, cColors, pulColors, flRed, flGreen, flBlue); + if (!ppal) return NULL; + + /* Insert the palette into the handle table */ + if (!GDIOBJ_hInsertObject(&ppal->BaseObject, GDI_OBJ_HMGR_POWNED)) + { + DPRINT1("Could not insert palette into handle table.\n"); + GDIOBJ_vFreeObject(&ppal->BaseObject); + return NULL; + } + + return ppal; +} + HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode, @@ -258,7 +285,6 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, NewPalette = PalGDI->BaseObject.hHmgr; - PalGDI->Self = NewPalette; PalGDI->flFlags = PAL_INDEXED; PalGDI->IndexedColors = ExAllocatePoolWithTag(PagedPool, @@ -285,11 +311,12 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, return NewPalette; } -BOOL NTAPI +BOOL +NTAPI PALETTE_Cleanup(PVOID ObjectBody) { PPALETTE pPal = (PPALETTE)ObjectBody; - if (NULL != pPal->IndexedColors) + if (pPal->IndexedColors && pPal->IndexedColors != pPal->apalColors) { ExFreePoolWithTag(pPal->IndexedColors, TAG_PALETTE); } @@ -297,7 +324,8 @@ PALETTE_Cleanup(PVOID ObjectBody) return TRUE; } -INT FASTCALL +INT +FASTCALL PALETTE_GetObject(PPALETTE ppal, INT cbCount, LPLOGBRUSH lpBuffer) { if (!lpBuffer) @@ -318,8 +346,8 @@ PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor) ULONG i, ulBestIndex = 0; PALETTEENTRY peColor = *(PPALETTEENTRY)&iColor; - /* Loop all palette entries, break on exact match */ - for (i = 0; i < ppal->NumColors && ulMinimalDiff != 0; i++) + /* Loop all palette entries */ + for (i = 0; i < ppal->NumColors; i++) { /* Calculate distance in the color cube */ ulDiff = peColor.peRed - ppal->IndexedColors[i].peRed; @@ -334,6 +362,9 @@ PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor) { ulBestIndex = i; ulMinimalDiff = ulColorDiff; + + /* Break on exact match */ + if (ulMinimalDiff == 0) break; } } @@ -476,7 +507,6 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG *PaletteEntry PALETTE *PalGDI; PalGDI = (PALETTE*)PalObj; - /* PalGDI = (PALETTE*)AccessInternalObjectFromUserObject(PalObj); */ if (Start >= PalGDI->NumColors) return 0; @@ -495,38 +525,74 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG *PaletteEntry /** Systemcall Interface ******************************************************/ +HPALETTE +NTAPI +GreCreatePaletteInternal( + IN LPLOGPALETTE pLogPal, + IN UINT cEntries) +{ + HPALETTE hpal = NULL; + PPALETTE ppal; + + pLogPal->palNumEntries = cEntries; + ppal = PALETTE_AllocPalWithHandle(PAL_INDEXED, + cEntries, + (PULONG)pLogPal->palPalEntry, + 0, 0, 0); + + if (ppal != NULL) + { + PALETTE_ValidateFlags(ppal->IndexedColors, ppal->NumColors); + + hpal = ppal->BaseObject.hHmgr; + PALETTE_UnlockPalette(ppal); + } + + return hpal; +} + /* * @implemented */ -HPALETTE APIENTRY -NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal, IN UINT cEntries ) +HPALETTE +APIENTRY +NtGdiCreatePaletteInternal( + IN LPLOGPALETTE plogpalUser, + IN UINT cEntries) { - PPALETTE PalGDI; - HPALETTE NewPalette; + HPALETTE hpal = NULL; + PPALETTE ppal; + ULONG i, cjSize; - pLogPal->palNumEntries = cEntries; - NewPalette = PALETTE_AllocPalette( PAL_INDEXED, - cEntries, - (PULONG)pLogPal->palPalEntry, - 0, 0, 0); - - if (NewPalette == NULL) + ppal = PALETTE_AllocPalWithHandle(PAL_INDEXED, cEntries, NULL, 0, 0, 0); + if (ppal == NULL) { return NULL; } - PalGDI = (PPALETTE) PALETTE_ShareLockPalette(NewPalette); - if (PalGDI != NULL) + cjSize = FIELD_OFFSET(LOGPALETTE, palPalEntry[cEntries]); + + _SEH2_TRY { - PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors); - PALETTE_ShareUnlockPalette(PalGDI); + ProbeForRead(plogpalUser, cjSize, 1); + + for (i = 0; i < cEntries; i++) + { + ppal->IndexedColors[i] = plogpalUser->palPalEntry[i]; + } } - else + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - /* FIXME: Handle PalGDI == NULL!!!! */ - DPRINT1("PalGDI is NULL\n"); + GDIOBJ_vDeleteObject(&ppal->BaseObject); + _SEH2_YIELD(return NULL); } - return NewPalette; + _SEH2_END; + + PALETTE_ValidateFlags(ppal->IndexedColors, cEntries); + hpal = ppal->BaseObject.hHmgr; + PALETTE_UnlockPalette(ppal); + + return hpal; } HPALETTE APIENTRY NtGdiCreateHalftonePalette(HDC hDC) @@ -629,7 +695,7 @@ HPALETTE APIENTRY NtGdiCreateHalftonePalette(HDC hDC) } } - return NtGdiCreatePaletteInternal((LOGPALETTE *)&Palette, Palette.NumberOfEntries); + return GreCreatePaletteInternal((LOGPALETTE *)&Palette, Palette.NumberOfEntries); } BOOL diff --git a/reactos/win32ss/gdi/ntgdi/palette.h b/reactos/win32ss/gdi/ntgdi/palette.h index 7e4aefeaeb4..e31178bb88e 100644 --- a/reactos/win32ss/gdi/ntgdi/palette.h +++ b/reactos/win32ss/gdi/ntgdi/palette.h @@ -1,11 +1,5 @@ #pragma once -#define PALETTE_FIXED 0x0001 /* read-only colormap - have to use XAllocColor (if not virtual) */ -#define PALETTE_VIRTUAL 0x0002 /* no mapping needed - pixel == pixel color */ - -#define PALETTE_PRIVATE 0x1000 /* private colormap, identity mapping */ -#define PALETTE_WHITESET 0x2000 - // Palette mode flags #ifndef __WINDDI_H // Defined in ddk/winddi.h #define PAL_INDEXED 0x00000001 // Indexed palette @@ -28,61 +22,101 @@ #define PAL_RGB16_565 0x00400000 // 16-bit RGB in 565 format #define PAL_GAMMACORRECTION 0x00800000 // Correct colors - typedef struct _PALETTE { - /* Header for all gdi objects in the handle table. - Do not (re)move this. */ - BASEOBJECT BaseObject; + /* Header for all gdi objects in the handle table. + Do not (re)move this. */ + BASEOBJECT BaseObject; - PALOBJ PalObj; - XLATEOBJ *logicalToSystem; - HPALETTE Self; - FLONG flFlags; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR - ULONG NumColors; - PALETTEENTRY *IndexedColors; - ULONG RedMask; - ULONG GreenMask; - ULONG BlueMask; - ULONG ulRedShift; - ULONG ulGreenShift; - ULONG ulBlueShift; - HDEV hPDev; + PALOBJ PalObj; + XLATEOBJ *logicalToSystem; + FLONG flFlags; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR + ULONG NumColors; + PALETTEENTRY *IndexedColors; + ULONG RedMask; + ULONG GreenMask; + ULONG BlueMask; + ULONG ulRedShift; + ULONG ulGreenShift; + ULONG ulBlueShift; + HDEV hPDev; + PALETTEENTRY apalColors[0]; } PALETTE; extern PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault; extern PPALETTE appalSurfaceDefault[]; -HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode, - ULONG NumColors, - ULONG *Colors, - ULONG Red, - ULONG Green, - ULONG Blue); -HPALETTE FASTCALL PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, - CONST RGBQUAD *Colors); -#define PALETTE_FreePalette(pPalette) GDIOBJ_FreeObj((POBJ)pPalette, GDIObjType_PAL_TYPE) -#define PALETTE_FreePaletteByHandle(hPalette) GDIOBJ_FreeObjByHandle((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE) #define PALETTE_UnlockPalette(pPalette) GDIOBJ_vUnlockObject((POBJ)pPalette) - #define PALETTE_ShareLockPalette(hpal) \ ((PPALETTE)GDIOBJ_ShareLockObj((HGDIOBJ)hpal, GDI_OBJECT_TYPE_PALETTE)) #define PALETTE_ShareUnlockPalette(ppal) \ GDIOBJ_vDereferenceObject(&ppal->BaseObject) -BOOL NTAPI PALETTE_Cleanup(PVOID ObjectBody); -INIT_FUNCTION NTSTATUS NTAPI InitPaletteImpl(VOID); -VOID FASTCALL PALETTE_ValidateFlags (PALETTEENTRY* lpPalE, INT size); -INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); +INIT_FUNCTION +NTSTATUS +NTAPI +InitPaletteImpl(VOID); -INT FASTCALL PALETTE_GetObject(PPALETTE pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer); -ULONG NTAPI PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor); -ULONG NTAPI PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG iColor); -ULONG NTAPI PALETTE_ulGetNearestBitFieldsIndex(PALETTE* ppal, ULONG ulColor); -VOID NTAPI PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors); +PPALETTE +NTAPI +PALETTE_AllocPalette2( + _In_ ULONG iMode, + _In_ ULONG cColors, + _In_ PULONG pulColors, + _In_ FLONG flRed, + _In_ FLONG flGreen, + _In_ FLONG flBlue); -PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID); -HPALETTE FASTCALL GdiSelectPalette(HDC, HPALETTE, BOOL); +PPALETTE +NTAPI +PALETTE_AllocPalWithHandle( + _In_ ULONG iMode, + _In_ ULONG cColors, + _In_ PULONG pulColors, + _In_ FLONG flRed, + _In_ FLONG flGreen, + _In_ FLONG flBlue); + +VOID +FASTCALL +PALETTE_ValidateFlags( + PALETTEENTRY* lpPalE, + INT size); + +INT +FASTCALL +PALETTE_GetObject( + PPALETTE pGdiObject, + INT cbCount, + LPLOGBRUSH lpBuffer); + +ULONG +NTAPI +PALETTE_ulGetNearestPaletteIndex( + PPALETTE ppal, + ULONG iColor); + +ULONG +NTAPI +PALETTE_ulGetNearestIndex( + PPALETTE ppal, + ULONG iColor); + +ULONG +NTAPI +PALETTE_ulGetNearestBitFieldsIndex( + PPALETTE ppal, + ULONG ulColor); + +VOID +NTAPI +PALETTE_vGetBitMasks( + PPALETTE ppal, + PULONG pulColors); + +BOOL +NTAPI +PALETTE_Cleanup(PVOID ObjectBody); ULONG FORCEINLINE @@ -106,3 +140,25 @@ PALETTE_ulGetRGBColorFromIndex(PPALETTE ppal, ULONG ulIndex) ppal->IndexedColors[ulIndex].peBlue); } +HPALETTE +NTAPI +GreCreatePaletteInternal( + IN LPLOGPALETTE pLogPal, + IN UINT cEntries); + +//// + +HPALETTE +FASTCALL +PALETTE_AllocPalette(ULONG Mode, + ULONG NumColors, + ULONG *Colors, + ULONG Red, + ULONG Green, + ULONG Blue); + +HPALETTE +FASTCALL +PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, + CONST RGBQUAD *Colors); +