Author: tkreuzer Date: Wed May 9 20:36:16 2012 New Revision: 56555
URL: http://svn.reactos.org/svn/reactos?rev=56555&view=rev Log: [WIN32K] - Start of the rewrite for DIB bitmaps and sections - Rewrite of brush code
Added: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c (with props) branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h (with props) Modified: branches/dib_rewrite/win32ss/CMakeLists.txt branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.c branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.h branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c branches/dib_rewrite/win32ss/gdi/ntgdi/brush.h branches/dib_rewrite/win32ss/user/ntuser/clipboard.c branches/dib_rewrite/win32ss/user/ntuser/misc/file.c branches/dib_rewrite/win32ss/win32kp.h
Modified: branches/dib_rewrite/win32ss/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/CMakeLists.t... ============================================================================== --- branches/dib_rewrite/win32ss/CMakeLists.txt [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/CMakeLists.txt [iso-8859-1] Wed May 9 20:36:16 2012 @@ -147,7 +147,7 @@ gdi/ntgdi/dcstate.c gdi/ntgdi/dcutil.c gdi/ntgdi/device.c - gdi/ntgdi/dibobj.c + gdi/ntgdi/dibitmap.c gdi/ntgdi/drawing.c gdi/ntgdi/fillshap.c gdi/ntgdi/font.c
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/bi... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.c [iso-8859-1] Wed May 9 20:36:16 2012 @@ -323,6 +323,8 @@ } }
+ __debugbreak(); +#if 0 Bmp = DIB_CreateDIBSection(Dc, bi, DIB_RGB_COLORS, @@ -330,6 +332,7 @@ NULL, 0, 0); +#endif return Bmp; } }
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.h URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/bi... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.h [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/bitmaps.h [iso-8859-1] Wed May 9 20:36:16 2012 @@ -24,16 +24,3 @@ _In_opt_ PVOID pvBits, _In_ FLONG flags);
-HBITMAP -NTAPI -GreCreateDIBitmapInternal( - IN HDC hDc, - IN INT cx, - IN INT cy, - IN DWORD fInit, - IN OPTIONAL LPBYTE pjInit, - IN OPTIONAL PBITMAPINFO pbmi, - IN DWORD iUsage, - IN FLONG fl, - IN UINT cjMaxBits, - IN HANDLE hcmXform);
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/br... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c [iso-8859-1] Wed May 9 20:36:16 2012 @@ -3,7 +3,7 @@ * PROJECT: ReactOS win32 subsystem * PURPOSE: Functions for brushes * FILE: subsystem/win32/win32k/objects/brush.c - * PROGRAMER: + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) */
#include <win32k.h> @@ -11,58 +11,7 @@ #define NDEBUG #include <debug.h>
-#define GDIOBJATTRFREE 170 - -typedef struct _GDI_OBJ_ATTR_FREELIST -{ - LIST_ENTRY Entry; - DWORD nEntries; - PVOID AttrList[GDIOBJATTRFREE]; -} GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST; - -typedef struct _GDI_OBJ_ATTR_ENTRY -{ - RGN_ATTR Attr[GDIOBJATTRFREE]; -} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY; - -BOOL -FASTCALL -IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner) -{ - // FIXME: - if (pbr->flAttrs & BR_IS_GLOBAL) return TRUE; - - if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) || ulOwner == GDI_OBJ_HMGR_NONE) - { - // Deny user access to User Data. - GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL); - // FIXME: deallocate brush attr - } - - if (ulOwner == GDI_OBJ_HMGR_POWNED) - { - // Allow user access to User Data. - GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pbr->pBrushAttr); - // FIXME: Allocate brush attr - } - - GDIOBJ_vSetObjectOwner(&pbr->BaseObject, ulOwner); - - return TRUE; -} - -BOOL -FASTCALL -GreSetBrushOwner(HBRUSH hBrush, ULONG ulOwner) -{ - BOOL Ret; - PBRUSH pbrush; - - pbrush = BRUSH_ShareLockBrush(hBrush); - Ret = IntGdiSetBrushOwner(pbrush, ulOwner); - BRUSH_ShareUnlockBrush(pbrush); - return Ret; -} +ULONG gulBrushUnique;
BOOL NTAPI @@ -71,20 +20,30 @@ PPROCESSINFO ppi; BRUSH_ATTR *pBrushAttr;
+ // HACK: this currently does not work + return 1; + + /* Get the PROCESSINFO pointer */ ppi = PsGetCurrentProcessWin32Process(); ASSERT(ppi);
- pBrushAttr = GdiPoolAllocate(ppi->pPoolDcAttr); + /* Allocate a brush attribute from the gdi pool */ + pBrushAttr = GdiPoolAllocate(ppi->pPoolBrushAttr); if (!pBrushAttr) { DPRINT1("Could not allocate brush attr\n"); return FALSE; }
- /* Copy the content from the kernel mode dc attr */ + /* Set the new brush attribute and copy the kernel mode data */ pbr->pBrushAttr = pBrushAttr; *pbr->pBrushAttr = pbr->BrushAttr;
+ /* Default hatch style is -1 */ + pbr->ulStyle = -1; + + pbr->ulBrushUnique = InterlockedIncrementUL(&gulBrushUnique); + /* Set the object attribute in the handle table */ GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pBrushAttr);
@@ -92,35 +51,156 @@ return TRUE; }
- VOID NTAPI BRUSH_vFreeBrushAttr(PBRUSH pbr) { -#if 0 PPROCESSINFO ppi;
- if (pbrush->pBrushAttr == &pbrush->BrushAttr) return; + /* Don't do anything, when the kernel mode brush attribute is in use */ + if (pbr->pBrushAttr == &pbr->BrushAttr) return; + + if (pbr->pBrushAttr == NULL) return; // FIXME
/* Reset the object attribute in the handle table */ GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL); + + /* Copy state back from user attribute to kernel */ + *pbr->pBrushAttr = pbr->BrushAttr;
/* Free memory from the process gdi pool */ ppi = PsGetCurrentProcessWin32Process(); ASSERT(ppi); + + /* Free the user mode attribute to the gdi pool */ GdiPoolFree(ppi->pPoolBrushAttr, pbr->pBrushAttr); -#endif + /* Reset to kmode brush attribute */ pbr->pBrushAttr = &pbr->BrushAttr; }
+PBRUSH +NTAPI +BRUSH_AllocBrushOrPen(UCHAR objt) +{ + PBRUSH pbrush; + ASSERT((objt == GDIObjType_BRUSH_TYPE) || + (objt == GDIObjType_PEN_TYPE) || + (objt == GDIObjType_EXTPEN_TYPE)); + + /* Allocate a brush object */ + pbrush = (PBRUSH)GDIOBJ_AllocateObject(objt, sizeof(BRUSH), 0); + if (!pbrush) + { + return NULL; + } + + /* Set the kernel mode brush attribute */ + pbrush->pBrushAttr = &pbrush->BrushAttr; + + // need more? + return pbrush; +} + +PBRUSH +NTAPI +BRUSH_AllocBrushOrPenWithHandle(UCHAR objt, ULONG ulOwner) +{ + PBRUSH pbrush; + + /* Allocate a brush without a handle */ + pbrush = BRUSH_AllocBrushOrPen(objt); + if (!pbrush) + { + return NULL; + } + + /* Insert the brush into the handle table */ + if (!GDIOBJ_hInsertObject(&pbrush->BaseObject, ulOwner)) + { + DPRINT1("Could not insert brush into handle table.\n"); + GDIOBJ_vFreeObject(&pbrush->BaseObject); + return NULL; + } + + /* Check if a global brush is requested */ + if (ulOwner == GDI_OBJ_HMGR_PUBLIC) + { + pbrush->flAttrs |= BR_IS_GLOBAL; + } + else if (ulOwner == GDI_OBJ_HMGR_POWNED) + { + /* Allocate a brush attribute */ + if (!BRUSH_bAllocBrushAttr(pbrush)) + { + DPRINT1("Could not allocate brush attr.\n"); + GDIOBJ_vDeleteObject(&pbrush->BaseObject); + return NULL; + } + } + + return pbrush; +} + BOOL NTAPI +BRUSH_bSetBrushOwner(PBRUSH pbr, ULONG ulOwner) +{ + // FIXME: + if (pbr->flAttrs & BR_IS_GLOBAL) return TRUE; + + /* Set ownership of the pattern bitmap */ + if (pbr->hbmPattern) + GreSetObjectOwner(pbr->hbmPattern, ulOwner); + + if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) || ulOwner == GDI_OBJ_HMGR_NONE) + { + /* Free the brush attribute */ + BRUSH_vFreeBrushAttr(pbr); + } + else if (ulOwner == GDI_OBJ_HMGR_POWNED) + { + /* Check if there is no usermode attribute */ + if (pbr->pBrushAttr == &pbr->BrushAttr) + { + /* Free the brush attribute */ + BRUSH_bAllocBrushAttr(pbr); + } + } + + GDIOBJ_vSetObjectOwner(&pbr->BaseObject, ulOwner); + + return TRUE; +} + +BOOL +NTAPI +GreSetBrushOwner(HBRUSH hBrush, ULONG ulOwner) +{ + BOOL bResult; + PBRUSH pbrush; + + /* Reference the brush */ + pbrush = BRUSH_ShareLockBrush(hBrush); + + /* Set the brush owner */ + bResult = BRUSH_bSetBrushOwner(pbrush, ulOwner); + + /* Dereference the brush */ + BRUSH_ShareUnlockBrush(pbrush); + return bResult; +} + +BOOL +NTAPI BRUSH_Cleanup(PVOID ObjectBody) { PBRUSH pbrush = (PBRUSH)ObjectBody; - if (pbrush->hbmPattern) - { + + /* We need to free bitmaps for pattern brushes, not for hatch brushes */ + if (pbrush->flAttrs & (BR_IS_BITMAP|BR_IS_DIB)) + { + ASSERT(pbrush->hbmPattern); GreSetObjectOwner(pbrush->hbmPattern, GDI_OBJ_HMGR_POWNED); GreDeleteObject(pbrush->hbmPattern); } @@ -142,57 +222,53 @@
INT FASTCALL -BRUSH_GetObject(PBRUSH pbrush, INT Count, LPLOGBRUSH Buffer) -{ - if (Buffer == NULL) return sizeof(LOGBRUSH); - if (Count == 0) return 0; +BRUSH_GetObject(PBRUSH pbrush, INT cjSize, LPLOGBRUSH plogbrush) +{ + /* Check if only size is requested */ + if ((plogbrush == NULL) || (cjSize == 0)) return sizeof(LOGBRUSH);
/* Set colour */ - Buffer->lbColor = pbrush->BrushAttr.lbColor; - - /* Set Hatch */ - if ((pbrush->flAttrs & BR_IS_HATCH)!=0) - { - /* FIXME: This is not the right value */ - Buffer->lbHatch = (LONG)pbrush->hbmPattern; + plogbrush->lbColor = pbrush->BrushAttr.lbColor; + + /* Default to 0 */ + plogbrush->lbHatch = 0; + + /* Get the type of style */ + if (pbrush->flAttrs & BR_IS_SOLID) + { + plogbrush->lbStyle = BS_SOLID; + } + else if (pbrush->flAttrs & BR_IS_NULL) + { + plogbrush->lbStyle = BS_NULL; // BS_HOLLOW + } + else if (pbrush->flAttrs & BR_IS_HATCH) + { + plogbrush->lbStyle = BS_HATCHED; + plogbrush->lbHatch = pbrush->ulStyle; + } + else if (pbrush->flAttrs & BR_IS_DIB) + { + plogbrush->lbStyle = BS_DIBPATTERN; + plogbrush->lbHatch = (ULONG_PTR)pbrush->hbmClient; + } + else if (pbrush->flAttrs & BR_IS_BITMAP) + { + plogbrush->lbStyle = BS_PATTERN; } else { - Buffer->lbHatch = 0; - } - - Buffer->lbStyle = 0; - - /* Get the type of style */ - if ((pbrush->flAttrs & BR_IS_SOLID)!=0) - { - Buffer->lbStyle = BS_SOLID; - } - else if ((pbrush->flAttrs & BR_IS_NULL)!=0) - { - Buffer->lbStyle = BS_NULL; // BS_HOLLOW - } - else if ((pbrush->flAttrs & BR_IS_HATCH)!=0) - { - Buffer->lbStyle = BS_HATCHED; - } - else if ((pbrush->flAttrs & BR_IS_BITMAP)!=0) - { - Buffer->lbStyle = BS_PATTERN; - } - else if ((pbrush->flAttrs & BR_IS_DIB)!=0) - { - Buffer->lbStyle = BS_DIBPATTERN; + plogbrush->lbStyle = 0; // ??? }
/* FIXME - else if ((pbrush->flAttrs & )!=0) - { - Buffer->lbStyle = BS_INDEXED; - } - else if ((pbrush->flAttrs & )!=0) - { - Buffer->lbStyle = BS_DIBPATTERNPT; + else if (pbrush->flAttrs & ) + { + plogbrush->lbStyle = BS_INDEXED; + } + else if (pbrush->flAttrs & ) + { + plogbrush->lbStyle = BS_DIBPATTERNPT; } */
@@ -200,266 +276,224 @@ return sizeof(LOGBRUSH); }
+VOID +NTAPI +GreSetSolidBrushColor(HBRUSH hbr, COLORREF crColor) +{ + PBRUSH pbrush; + + pbrush = BRUSH_ShareLockBrush(hbr); + if (!pbrush) return; + + if (pbrush->flAttrs & BR_IS_SOLID) + { + pbrush->BrushAttr.lbColor = crColor & 0xFFFFFF; + } + BRUSH_ShareUnlockBrush(pbrush); +} + +HBRUSH +NTAPI +GreCreateBrushInternal( + _In_ ULONG ulStyle, + _In_ HBITMAP hbmPattern, + _In_ HBITMAP hbmClient, + _In_ COLORREF crColor, + _In_ FLONG flAttrib) +{ + PBRUSH pbr; + HBRUSH hbr; + ULONG ulOwner; + UCHAR objt; + + /* Set the desired object type */ + if (flAttrib & BR_IS_OLDSTYLEPEN) objt = GDIObjType_PEN_TYPE; + else if (flAttrib & BR_IS_PEN) objt = GDIObjType_EXTPEN_TYPE; + else objt = GDIObjType_BRUSH_TYPE; + + /* Set object owner */ + if (flAttrib & BR_IS_GLOBAL) ulOwner = GDI_OBJ_HMGR_PUBLIC; + else ulOwner = GDI_OBJ_HMGR_POWNED; + + /* Allocate a brush */ + pbr = BRUSH_AllocBrushOrPenWithHandle(objt, ulOwner); + if (pbr == NULL) + { + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + /* Set brush properties */ + pbr->flAttrs = flAttrib; + pbr->hbmPattern = hbmPattern; + pbr->hbmClient = hbmClient; + pbr->ulStyle = ulStyle; + pbr->BrushAttr.lbColor = crColor; + + /* Get the handle and unlock the brush */ + hbr = pbr->BaseObject.hHmgr; + GDIOBJ_vUnlockObject(&pbr->BaseObject); + + return hbr; +} + +HBRUSH +NTAPI +GreCreateNullBrush(VOID) +{ + /* Call the internal worker function */ + return GreCreateBrushInternal(0, NULL, NULL, 0, BR_IS_NULL|BR_IS_GLOBAL); +} + +/* SYSTEM CALLS **************************************************************/ + HBRUSH APIENTRY -IntGdiCreateDIBBrush( - CONST BITMAPINFO *BitmapInfo, - UINT ColorSpec, - UINT BitmapInfoSize, - CONST VOID *PackedDIB) -{ - HBRUSH hBrush; - PBRUSH pbrush; - HBITMAP hPattern; - ULONG_PTR DataPtr; - PVOID pvDIBits; - - if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec); - - hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0); - if (hPattern == NULL) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - RtlCopyMemory(pvDIBits, - (PVOID)DataPtr, - DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth, - BitmapInfo->bmiHeader.biHeight, - BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes)); - - pbrush = BRUSH_AllocBrushWithHandle(); - if (pbrush == NULL) - { - GreDeleteObject(hPattern); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - hBrush = pbrush->BaseObject.hHmgr; - - pbrush->flAttrs |= BR_IS_BITMAP | BR_IS_DIB; - pbrush->hbmPattern = hPattern; - /* FIXME: Fill in the rest of fields!!! */ - - GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC); - - GDIOBJ_vUnlockObject(&pbrush->BaseObject); - - return hBrush; +NtGdiCreateSolidBrush( + _In_ COLORREF crColor, + _In_opt_ HBRUSH hbr) +{ + /* Call the internal worker function */ + return GreCreateBrushInternal(0, NULL, NULL, crColor, BR_IS_SOLID); }
HBRUSH APIENTRY -IntGdiCreateHatchBrush( - INT Style, - COLORREF Color) -{ - HBRUSH hBrush; - PBRUSH pbrush; - - if (Style < 0 || Style >= NB_HATCH_STYLES) +NtGdiCreateHatchBrushInternal( + _In_ ULONG ulStyle, + _In_ COLORREF crColor, + _In_ BOOL bPen) +{ + FLONG flAttr = BR_IS_HATCH | (bPen ? BR_IS_PEN : 0); + + /* Check parameters */ + if ((ulStyle < 0) || (ulStyle >= HS_DDI_MAX)) { return 0; }
- pbrush = BRUSH_AllocBrushWithHandle(); - if (pbrush == NULL) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - hBrush = pbrush->BaseObject.hHmgr; - - pbrush->flAttrs |= BR_IS_HATCH; - pbrush->BrushAttr.lbColor = Color & 0xFFFFFF; - pbrush->ulStyle = Style; - - GDIOBJ_vUnlockObject(&pbrush->BaseObject); - - return hBrush; + /* Call the internal worker function */ + return GreCreateBrushInternal(ulStyle, NULL, NULL, crColor, flAttr); }
HBRUSH APIENTRY -IntGdiCreatePatternBrush( - HBITMAP hBitmap) -{ - HBRUSH hBrush; - PBRUSH pbrush; - HBITMAP hPattern; - - hPattern = BITMAP_CopyBitmap(hBitmap); - if (hPattern == NULL) +NtGdiCreatePatternBrushInternal( + _In_ HBITMAP hBitmap, + _In_ BOOL bPen, + _In_ BOOL b8x8) +{ + HBITMAP hbmPattern; + FLONG flAttr = BR_IS_BITMAP | (bPen ? BR_IS_PEN : 0); + + /* Make a copy of the given bitmap */ + hbmPattern = BITMAP_CopyBitmap(hBitmap); + if (hbmPattern == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; }
- pbrush = BRUSH_AllocBrushWithHandle(); - if (pbrush == NULL) - { - GreDeleteObject(hPattern); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - hBrush = pbrush->BaseObject.hHmgr; - - pbrush->flAttrs |= BR_IS_BITMAP; - pbrush->hbmPattern = hPattern; - /* FIXME: Fill in the rest of fields!!! */ - - GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC); - - GDIOBJ_vUnlockObject(&pbrush->BaseObject); - - return hBrush; -} - -HBRUSH -APIENTRY -IntGdiCreateSolidBrush( - COLORREF Color) -{ - HBRUSH hBrush; - PBRUSH pbrush; - - pbrush = BRUSH_AllocBrushWithHandle(); - if (pbrush == NULL) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - hBrush = pbrush->BaseObject.hHmgr; - - pbrush->flAttrs |= BR_IS_SOLID; - - pbrush->BrushAttr.lbColor = Color & 0x00FFFFFF; - /* FIXME: Fill in the rest of fields!!! */ - - GDIOBJ_vUnlockObject(&pbrush->BaseObject); - - return hBrush; -} - -HBRUSH -APIENTRY -IntGdiCreateNullBrush(VOID) -{ - HBRUSH hBrush; - PBRUSH pbrush; - - pbrush = BRUSH_AllocBrushWithHandle(); - if (pbrush == NULL) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - hBrush = pbrush->BaseObject.hHmgr; - - pbrush->flAttrs |= BR_IS_NULL; - GDIOBJ_vUnlockObject(&pbrush->BaseObject); - - return hBrush; -} - -VOID -FASTCALL -IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color) -{ - PBRUSH pbrush; - - pbrush = BRUSH_ShareLockBrush(hBrush); - if (pbrush->flAttrs & BR_IS_SOLID) - { - pbrush->BrushAttr.lbColor = Color & 0xFFFFFF; - } - BRUSH_ShareUnlockBrush(pbrush); -} - - -/* PUBLIC FUNCTIONS ***********************************************************/ + /* Call the internal worker function */ + return GreCreateBrushInternal(0, hbmPattern, hBitmap, 0, flAttr); +}
HBRUSH APIENTRY NtGdiCreateDIBBrush( - IN PVOID BitmapInfoAndData, - IN FLONG ColorSpec, - IN UINT BitmapInfoSize, - IN BOOL b8X8, - IN BOOL bPen, - IN PVOID PackedDIB) -{ - BITMAPINFO *SafeBitmapInfoAndData; - NTSTATUS Status = STATUS_SUCCESS; - HBRUSH hBrush; - - SafeBitmapInfoAndData = EngAllocMem(FL_ZERO_MEMORY, BitmapInfoSize, TAG_DIB); - if (SafeBitmapInfoAndData == NULL) + _In_ PVOID pvPackedDIB, + _In_ ULONG iUsage,// FLONG flColorSpec, + _In_ UINT cjDIBSize, + _In_ BOOL b8x8, + _In_ BOOL bPen, + _In_ PVOID pClient) +{ + FLONG flAttr = BR_IS_DIB | (bPen ? BR_IS_PEN : 0); + PVOID pvSaveDIB, pvSafeBits; + PBITMAPINFO pbmi; + HBITMAP hbmPattern; + ULONG cjInfoSize; + + /* Parameter check */ + if (iUsage > 2) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* Allocate a buffer large enough to hold the complete packed DIB */ + pvSaveDIB = ExAllocatePoolWithTag(PagedPool, cjDIBSize, TAG_DIB); + if (pvSaveDIB == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; }
+ /* Enter SEH for buffer transfer */ _SEH2_TRY { - ProbeForRead(BitmapInfoAndData, BitmapInfoSize, 1); - RtlCopyMemory(SafeBitmapInfoAndData, BitmapInfoAndData, BitmapInfoSize); + /* Probe and copy the whole DIB */ + ProbeForRead(pvPackedDIB, cjDIBSize, 1); + RtlCopyMemory(pvSaveDIB, pvPackedDIB, cjDIBSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status = _SEH2_GetExceptionCode(); + /* Got an exception, cleanup, set error and return 0 */ + ExFreePoolWithTag(pvSaveDIB, TAG_DIB); + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(return 0;) } _SEH2_END;
- if (!NT_SUCCESS(Status)) - { - EngFreeMem(SafeBitmapInfoAndData); - SetLastNtError(Status); - return 0; - } - - hBrush = IntGdiCreateDIBBrush(SafeBitmapInfoAndData, - ColorSpec, - BitmapInfoSize, - PackedDIB); - - EngFreeMem(SafeBitmapInfoAndData); - - return hBrush; -} - -HBRUSH -APIENTRY -NtGdiCreateHatchBrushInternal( - ULONG Style, - COLORREF Color, - BOOL bPen) -{ - return IntGdiCreateHatchBrush(Style, Color); -} - -HBRUSH -APIENTRY -NtGdiCreatePatternBrushInternal( - HBITMAP hBitmap, - BOOL bPen, - BOOL b8x8) -{ - return IntGdiCreatePatternBrush(hBitmap); -} - -HBRUSH -APIENTRY -NtGdiCreateSolidBrush(COLORREF Color, - IN OPTIONAL HBRUSH hbr) -{ - return IntGdiCreateSolidBrush(Color); + /* Calculate the size of the bitmap info */ + cjInfoSize = GreGetBitmapInfoSize(pvSaveDIB, iUsage); + + /* Check sanity of the sizes */ + if ((cjInfoSize < sizeof(BITMAPCOREHEADER)) || // info? + (cjInfoSize > cjDIBSize)) + { + /* Something is wrong with the bitmap */ + ExFreePoolWithTag(pvSaveDIB, TAG_DIB); + return NULL; + } + + /* Get pointers to BITMAPINFO and to the bits */ + pbmi = pvSaveDIB; + pvSafeBits = (PUCHAR)pvSaveDIB + cjInfoSize; + + /* When DIB_PAL_COLORS is requested, we don't create the RGB palette + entries directly, instead we need to create a fake palette containing + pal indices, which is converted into a real palette when the brush + is realized. */ + if (iUsage == DIB_PAL_COLORS) iUsage = DIB_PAL_BRUSHHACK; + + /* Create the pattern bitmap from the DIB. */ + hbmPattern = GreCreateDIBitmapInternal(NULL, + pbmi->bmiHeader.biWidth, + abs(pbmi->bmiHeader.biHeight), + CBM_INIT, + pvSafeBits, + pbmi, + iUsage,// FIXME!!! + 0, + cjDIBSize - cjInfoSize, + NULL); + + /* Free the buffer already */ + ExFreePoolWithTag(pvSaveDIB, TAG_DIB); + + /* Check for failure */ + if (!hbmPattern) + { + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + /* Remember if the palette consists of palette indices */ + if (iUsage == DIB_PAL_COLORS) flAttr |= BR_IS_DIBPALCOLORS; + + /* Call the internal worker function */ + return GreCreateBrushInternal(0, hbmPattern, pvPackedDIB, 0, flAttr); }
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/brush.h URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/br... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/brush.h [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/brush.h [iso-8859-1] Wed May 9 20:36:16 2012 @@ -1,8 +1,4 @@ #pragma once - -/* Internal interface */ - -#define NB_HATCH_STYLES 6
/* * The layout of this structure is taken from "Windows Graphics Programming" @@ -19,7 +15,7 @@
ULONG ulStyle; HBITMAP hbmPattern; - HBITMAP hbmClient; + HANDLE hbmClient; ULONG flAttrs;
ULONG ulBrushUnique; @@ -55,9 +51,9 @@ // DWORD dwUnknown2c; // DWORD dwUnknown30; SURFACE * psurfTrg; - struct _PALETTE * ppalSurf; - struct _PALETTE * ppalDC; - struct _PALETTE * ppalDIB; + PPALETTE ppalSurf; + PPALETTE ppalDC; + PPALETTE ppalDIB; // DWORD dwUnknown44; BRUSH * pbrush; FLONG flattrs; @@ -86,15 +82,14 @@ #define BR_CACHED_ENGINE 0x00040000 #define BR_CACHED_IS_SOLID 0x80000000
-#define BRUSH_AllocBrush() ((PBRUSH) GDIOBJ_AllocObj(GDIObjType_BRUSH_TYPE)) -#define BRUSH_AllocBrushWithHandle() ((PBRUSH) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BRUSH, sizeof(BRUSH))) -#define BRUSH_FreeBrush(pBrush) GDIOBJ_FreeObj((POBJ)pBrush, GDIObjType_BRUSH_TYPE) -#define BRUSH_FreeBrushByHandle(hBrush) GDIOBJ_FreeObjByHandle((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH) #define BRUSH_ShareLockBrush(hBrush) ((PBRUSH)GDIOBJ_ShareLockObj((HGDIOBJ)hBrush, GDI_OBJECT_TYPE_BRUSH)) #define BRUSH_ShareUnlockBrush(pBrush) GDIOBJ_vDereferenceObject((POBJ)pBrush)
-INT FASTCALL BRUSH_GetObject (PBRUSH GdiObject, INT Count, LPLOGBRUSH Buffer); -BOOL NTAPI BRUSH_Cleanup(PVOID ObjectBody); +#define GDIObjType_PEN_TYPE 0x30 +#define GDIObjType_EXTPEN_TYPE 0x50 + +#define DIB_DEFPAL_COLORS 2 /* Colors are indices into the default palette */ +#define DIB_PAL_BRUSHHACK 3 /* Used as iUsage to create a PAL_BRUSHHACK palete */
extern HSURF gahsurfHatch[HS_DDI_MAX];
@@ -145,19 +140,69 @@ return iOldColor; }
-BOOL FASTCALL IntGdiSetBrushOwner(PBRUSH,DWORD); -BOOL FASTCALL GreSetBrushOwner(HBRUSH,DWORD); - -HBRUSH APIENTRY -IntGdiCreatePatternBrush( - HBITMAP hBitmap); - -HBRUSH APIENTRY -IntGdiCreateSolidBrush( - COLORREF Color); - -HBRUSH APIENTRY -IntGdiCreateNullBrush(VOID); - -VOID FASTCALL -IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color); + +PBRUSH +NTAPI +BRUSH_AllocBrushOrPen(UCHAR objt); + +#define BRUSH_AllocBrush() \ + BRUSH_AllocBrushOrPen(GDIObjType_BRUSH_TYPE) + +PBRUSH +NTAPI +BRUSH_AllocBrushOrPenWithHandle(UCHAR objt, ULONG ulOwner); + +#define BRUSH_AllocBrushWithHandle(ulOwner) \ + BRUSH_AllocBrushOrPenWithHandle(GDIObjType_BRUSH_TYPE, ulOwner) + +INT +FASTCALL +BRUSH_GetObject(PBRUSH GdiObject, INT Count, LPLOGBRUSH Buffer); + +BOOL +NTAPI +BRUSH_Cleanup(PVOID ObjectBody); + +BOOL +NTAPI +BRUSH_bSetBrushOwner(PBRUSH pbr, ULONG ulOwner); + +BOOL +NTAPI +GreSetBrushOwner(HBRUSH,DWORD); + +HBRUSH +NTAPI +GreCreatePatternBrushEx( + _In_ HBITMAP hbmPattern, + _In_ FLONG flAttrs, + _In_ BOOL bPen, + _In_ BOOL b8X8, // FIXME: do we need this? + _In_ BOOL bGlobal); + +HBRUSH +FORCEINLINE +GreCreatePatternBrush( + _In_ HBITMAP hbmPattern, + _In_ BOOL bGlobal) +{ + return GreCreatePatternBrushEx(hbmPattern, 0, 0, 0, bGlobal); +} + +HBRUSH +NTAPI +GreCreateNullBrush(VOID); + +VOID +NTAPI +GreSetSolidBrushColor(HBRUSH hbr, COLORREF crColor); + +#define InterlockedIncrementUL(x) InterlockedIncrement((LONG*)(x)) +#define GreGetBitmapInfoSize(pbmi, iUsage) DIB_BitmapInfoSize(pbmi, (WORD)iUsage) + +#define IntGdiSetBrushOwner BRUSH_bSetBrushOwner +#define IntGdiCreatePatternBrush(hbmp) NtGdiCreatePatternBrushInternal(hbmp, 0, 0) +#define IntGdiCreateSolidBrush(color) NtGdiCreateSolidBrush(color, 0) +#define IntGdiSetSolidBrushColor GreSetSolidBrushColor +#define IntGdiCreateNullBrush GreCreateNullBrush +
Added: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/di... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c (added) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c [iso-8859-1] Wed May 9 20:36:16 2012 @@ -1,0 +1,979 @@ +/* + * COPYRIGHT: GNU GPL, see COPYING in the top level directory + * PROJECT: ReactOS Win32 kernelmode subsystem + * PURPOSE: GDI functions for device independent bitmaps + * FILE: subsystems/win32/win32k/objects/dibitmap.c + * PROGRAMER: Timo Kreuzer + */ + +#include <win32k.h> + +#define NDEBUG +#include <debug.h> + +static +BOOL +DibGetBitmapFormat( + _In_ const BITMAPINFO *pbmi, + _Out_ PBITMAPFORMAT pbmf) +{ + /* Check for BITMAPCOREINFO */ + if (pbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) + { + PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmi; + + pbmf->sizel.cx = pbch->bcWidth; + pbmf->sizel.cy = pbch->bcHeight; + pbmf->cBitsPixel = pbch->bcBitCount * pbch->bcPlanes; + pbmf->iCompression = BI_RGB; + } + else + { + pbmf->sizel.cx = pbmi->bmiHeader.biWidth; + pbmf->sizel.cy = pbmi->bmiHeader.biHeight; + pbmf->cBitsPixel = pbmi->bmiHeader.biBitCount * pbmi->bmiHeader.biPlanes; + pbmf->iCompression = pbmi->bmiHeader.biCompression; + } + + /* Get the bitmap format */ + pbmf->iFormat = BitmapFormat(pbmf->cBitsPixel, pbmf->iCompression); + + /* Check if we have a valid bitmap format */ + if (pbmf->iFormat == 0) + { + DPRINT1("Invalid format\n"); + return FALSE; + } + + /* Check compressed format and top-down */ + if ((pbmf->iFormat > BMF_32BPP) && (pbmf->sizel.cy < 0)) + { + DPRINT1("Compressed bitmaps cannot be top-down.\n"); + return FALSE; + } + + // FIXME: check bitmap extensions / size + + return TRUE; +} + +static +ULONG +DibGetImageSize( + _In_ const BITMAPINFO *pbmi) +{ + LONG lWidth, lHeight; + ULONG cBitsPixel; + + /* Check for BITMAPCOREINFO */ + if (pbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) + { + PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmi; + lWidth = pbch->bcWidth; + lHeight = pbch->bcHeight; + cBitsPixel = pbch->bcBitCount * pbch->bcPlanes; + } + else + { + lWidth = pbmi->bmiHeader.biWidth; + lHeight = pbmi->bmiHeader.biHeight; + cBitsPixel = pbmi->bmiHeader.biBitCount * pbmi->bmiHeader.biPlanes; + } + + return WIDTH_BYTES_ALIGN32(lWidth, cBitsPixel) * abs(lHeight); +} + +ULONG +NTAPI +DibGetBitmapInfoSize( + _In_ const BITMAPINFO *pbmi, + _In_ ULONG iUsage) +{ + ULONG cjHeaderSize, cBitsPixel, cColors, cMaxColors; + + cjHeaderSize = pbmi->bmiHeader.biSize; + + if ((cjHeaderSize < sizeof(BITMAPCOREHEADER)) || + ((LONG)cjHeaderSize < 0)) + { + return 0; + } + + /* Check for BITMAPCOREINFO */ + if (cjHeaderSize < sizeof(BITMAPINFOHEADER)) + { + PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmi; + + cBitsPixel = pbch->bcBitCount; + cColors = (cBitsPixel <= 8) ? (1 << cBitsPixel) : 0; + return sizeof(BITMAPCOREHEADER) + cColors * + ((iUsage == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD)); + } + else /* Use BITMAPINFOHEADER */ + { + /* Check if the DIB uses bitfields */ + if (pbmi->bmiHeader.biCompression == BI_BITFIELDS) + { + /* Check for V4/v5 info */ + if (cjHeaderSize >= sizeof(BITMAPV4HEADER)) + { + /* There are no colors or masks */ + return cjHeaderSize; + } + else + { + /* The color table is 3 masks */ + return cjHeaderSize + 3 * sizeof(RGBQUAD); + } + } + + cBitsPixel = pbmi->bmiHeader.biBitCount; + if (cBitsPixel > 8) + return cjHeaderSize; + + cMaxColors = (1 << cBitsPixel); + cColors = pbmi->bmiHeader.biClrUsed; + if ((cColors == 0) || (cColors > cMaxColors)) cColors = cMaxColors; + + if (iUsage == DIB_RGB_COLORS) + return cjHeaderSize + cColors * sizeof(RGBQUAD); + else + return cjHeaderSize + cColors * sizeof(WORD); + } +} + +PBITMAPINFO +NTAPI +DibProbeAndCaptureBitmapInfo( + _In_ const BITMAPINFO *pbmiUnsafe, + _In_ ULONG iUsage, + _In_ PULONG pcjInfo) +{ + BITMAPINFO *pbmi; + ULONG cjInfo = *pcjInfo; + + /* Normalize the size to the maximum possible */ + cjInfo = min(cjInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD)); + + /* Check if the size is at least big enough for a core info */ + if (cjInfo < sizeof(BITMAPCOREHEADER)) + { + return NULL; + } + + /* Allocate a buffer for the bitmap info */ + pbmi = ExAllocatePoolWithTag(PagedPool, cjInfo, GDITAG_BITMAPINFO); + if (!pbmi) + { + return NULL; + } + + /* Enter SEH for copy */ + _SEH2_TRY + { + /* Probe and copy the data from user mode */ + ProbeForRead(pbmiUnsafe, cjInfo, 1); + RtlCopyMemory(pbmi, pbmiUnsafe, cjInfo); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return NULL); + } + _SEH2_END; + + /* Check if we have at least as much as the actual header size */ + if (cjInfo >= pbmi->bmiHeader.biSize) + { + /* Calculate the real size of the bitmap info */ + cjInfo = DibGetBitmapInfoSize(pbmi, iUsage); + + /* Make sure the real size is not larger than our buffer */ + if (cjInfo <= *pcjInfo) + { + /* Update the real info size */ + *pcjInfo = cjInfo; + + /* Return the new bitmap info */ + return pbmi; + } + } + + /* Failure, free the buffer and return NULL */ + ExFreePoolWithTag(pbmi, GDITAG_BITMAPINFO); + return NULL; +} + +VOID +FORCEINLINE +DibFreeBitmapInfo( + _In_ PBITMAPINFO pbmi) +{ + ExFreePoolWithTag(pbmi, GDITAG_BITMAPINFO); +} + +PPALETTE +NTAPI +CreateDIBPalette( + _In_ const BITMAPINFO *pbmi, + _In_ PDC pdc, + _In_ ULONG iUsage) +{ + PPALETTE ppal; + ULONG i, cBitsPixel, cColors; + + if (pbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) + { + PBITMAPCOREINFO pbci = (PBITMAPCOREINFO)pbmi; + cBitsPixel = pbci->bmciHeader.bcBitCount; + } + else + { + cBitsPixel = pbmi->bmiHeader.biBitCount; + } + + /* Check if the colors are indexed */ + if (cBitsPixel <= 8) + { + /* We create a "full" palette */ + cColors = 1 << cBitsPixel; + + /* Allocate the palette */ + ppal = PALETTE_AllocPalette(PAL_INDEXED, + cColors, + NULL, + 0, + 0, + 0); + + /* Check if the BITMAPINFO specifies how many colors to use */ + if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && + (pbmi->bmiHeader.biClrUsed != 0)) + { + /* This is how many colors we can actually process */ + cColors = min(cColors, pbmi->bmiHeader.biClrUsed); + } + + /* Check how to use the colors */ + if (iUsage == DIB_PAL_COLORS) + { + COLORREF crColor; + + /* The colors are an array of WORD indices into the DC palette */ + PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize); + + /* Use the DCs palette or, if no DC is given, the default one */ + PPALETTE ppalDC = pdc ? pdc->dclevel.ppal : gppalDefault; + + /* Loop all color indices in the DIB */ + for (i = 0; i < cColors; i++) + { + /* Get the palette index and handle wraparound when exceeding + the number of colors in the DC palette */ + WORD wIndex = pwColors[i] % ppalDC->NumColors; + + /* USe the RGB value from the DC palette */ + crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, wIndex); + PALETTE_vSetRGBColorForIndex(ppal, i, crColor); + } + } + else if (iUsage == DIB_PAL_BRUSHHACK) + { + /* The colors are an array of WORD indices into the DC palette */ + PWORD pwColors = (PWORD)((PCHAR)pbmi + pbmi->bmiHeader.biSize); + + /* Loop all color indices in the DIB */ + for (i = 0; i < cColors; i++) + { + /* Set the index directly as the RGB color, the real palette + containing RGB values will be calculated when the brush is + realized */ + PALETTE_vSetRGBColorForIndex(ppal, i, pwColors[i]); + } + + /* Mark the palette as a brush hack palette */ + ppal->flFlags |= PAL_BRUSHHACK; + } +// else if (iUsage == 2) +// { + // FIXME: this one is undocumented +// ASSERT(FALSE); +// } + else if (pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) + { + /* The colors are an array of RGBQUAD values */ + RGBQUAD *prgb = (RGBQUAD*)((PCHAR)pbmi + pbmi->bmiHeader.biSize); + + // FIXME: do we need to handle PALETTEINDEX / PALETTERGB macro? + + /* Loop all color indices in the DIB */ + for (i = 0; i < cColors; i++) + { + /* Get the color value and translate it to a COLORREF */ + RGBQUAD rgb = prgb[i]; + COLORREF crColor = RGB(rgb.rgbRed, rgb.rgbGreen, rgb.rgbBlue); + + /* Set the RGB value in the palette */ + PALETTE_vSetRGBColorForIndex(ppal, i, crColor); + } + } + else + { + /* The colors are an array of RGBTRIPLE values */ + RGBTRIPLE *prgb = (RGBTRIPLE*)((PCHAR)pbmi + pbmi->bmiHeader.biSize); + + /* Loop all color indices in the DIB */ + for (i = 0; i < cColors; i++) + { + /* Get the color value and translate it to a COLORREF */ + RGBTRIPLE rgb = prgb[i]; + COLORREF crColor = RGB(rgb.rgbtRed, rgb.rgbtGreen, rgb.rgbtBlue); + + /* Set the RGB value in the palette */ + PALETTE_vSetRGBColorForIndex(ppal, i, crColor); + } + } + } + else + { + /* This is a bitfield / RGB palette */ + ULONG flRedMask, flGreenMask, flBlueMask; + + /* Check if the DIB contains bitfield values */ + if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && + (pbmi->bmiHeader.biCompression == BI_BITFIELDS)) + { + /* Check if we have a v4/v5 header */ + if (pbmi->bmiHeader.biSize >= sizeof(BITMAPV4HEADER)) + { + /* The masks are dedicated fields in the header */ + PBITMAPV4HEADER pbmV4Header = (PBITMAPV4HEADER)&pbmi->bmiHeader; + flRedMask = pbmV4Header->bV4RedMask; + flGreenMask = pbmV4Header->bV4GreenMask; + flBlueMask = pbmV4Header->bV4BlueMask; + } + else + { + /* The masks are the first 3 values in the DIB color table */ + PDWORD pdwColors = (PVOID)((PCHAR)pbmi + pbmi->bmiHeader.biSize); + flRedMask = pdwColors[0]; + flGreenMask = pdwColors[1]; + flBlueMask = pdwColors[2]; + } + } + else + { + /* Check what bit depth we have. Note: optimization flags are + calculated in PALETTE_AllocPalette() */ + if (cBitsPixel == 16) + { + /* This is an RGB 555 palette */ + flRedMask = 0x7C00; + flGreenMask = 0x03E0; + flBlueMask = 0x001F; + } + else + { + /* This is an RGB 888 palette */ + flRedMask = 0xFF0000; + flGreenMask = 0x00FF00; + flBlueMask = 0x0000FF; + } + } + + /* Allocate the bitfield palette */ + ppal = PALETTE_AllocPalette(PAL_BITFIELDS, + 0, + NULL, + flRedMask, + flGreenMask, + flBlueMask); + } + + /* We're done, return the palette */ + return ppal; +} + +PSURFACE +NTAPI +DibCreateDIBSurface( + _In_ const BITMAPINFO *pbmi, + _In_opt_ PDC pdc, + _In_ ULONG iUsage, + _In_ ULONG fjBitmap, + _In_ PVOID pvBits, + _In_ ULONG cjMaxBits) +{ + BITMAPFORMAT bitmapformat; + PSURFACE psurf; + PPALETTE ppal; + + /* Get the format of the DIB */ + if (!DibGetBitmapFormat(pbmi, &bitmapformat)) + { + /* Invalid BITMAPINFO */ + return NULL; + } + + /* Handle top-down bitmaps */ + if (bitmapformat.sizel.cy < 0) fjBitmap |= BMF_TOPDOWN; + + /* Allocate a surface for the DIB */ + psurf = SURFACE_AllocSurface(STYPE_BITMAP, + bitmapformat.sizel.cx, + abs(bitmapformat.sizel.cy), + bitmapformat.iFormat, + fjBitmap, + 0, + pvBits); + if (!psurf) + { + return NULL; + } + + /* Create a palette from the color info */ + ppal = CreateDIBPalette(pbmi, pdc, iUsage); + if (!ppal) + { + /* Free the surface and return NULL */ + GDIOBJ_vDeleteObject(&psurf->BaseObject); + return NULL; + } + + /* Dereference the old palette and set the new */ + PALETTE_ShareUnlockPalette(psurf->ppal); + psurf->ppal = ppal; + + /* Return the surface */ + return psurf; +} + + +/* SYSTEM CALLS **************************************************************/ + +HBITMAP +APIENTRY +NtGdiCreateDIBSection( + _In_ HDC hdc, + _In_ OPTIONAL HANDLE hSectionApp, + _In_ DWORD dwOffset, + _In_ LPBITMAPINFO pbmiUser, + _In_ DWORD iUsage, + _In_ UINT cjInfo, + _In_ FLONG fl, + _In_ ULONG_PTR dwColorSpace, + _Out_opt_ PVOID *ppvBits) +{ + PBITMAPINFO pbmi; + PSURFACE psurfDIBSection; + PVOID pvBits = NULL; + PDC pdc; + HANDLE hSecure; + HBITMAP hbmp = NULL; + + /* Capture a safe copy of the bitmap info */ + pbmi = DibProbeAndCaptureBitmapInfo(pbmiUser, iUsage, &cjInfo); + if (!pbmi) + { + /* Could not get bitmapinfo, fail. */ + return NULL; + } + + /* Check if we got a DC */ + if (hdc) + { + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + /* Fail */ + goto cleanup; + } + } + else + { + /* No DC */ + pdc = NULL; + } + + /* Check if the caller passed a section handle */ + if (hSectionApp) + { + /* Get the size of the image */ + SIZE_T cjSize = DibGetImageSize(pbmi); + + /* Map the section */ + pvBits = EngMapSectionView(hSectionApp, cjSize, dwOffset, &hSecure); + if (!pvBits) + { + /* Fail */ + goto cleanup; + } + } + + /* Create the DIB section surface */ + psurfDIBSection = DibCreateDIBSurface(pbmi, + pdc, + iUsage, + BMF_USERMEM, + pvBits, + 0); + if (psurfDIBSection) + { + /* Check if we used a section */ + if (hSectionApp) + { + /* Update section and secure handle */ + psurfDIBSection->hDIBSection = hSectionApp; + psurfDIBSection->hSecure = hSecure; + } + + /* Return the base address if requested */ + if (ppvBits) *ppvBits = psurfDIBSection->SurfObj.pvBits; + + /* Save the handle and unlock the bitmap */ + hbmp = psurfDIBSection->BaseObject.hHmgr; + SURFACE_UnlockSurface(psurfDIBSection); + } + else + { + /* Unmap the section view, if we had any */ + if (hSectionApp) EngUnmapSectionView(pvBits, dwOffset, hSecure); + } + +cleanup: + /* Unlock the DC */ + if (pdc) DC_UnlockDc(pdc); + + /* Free the bitmap info buffer */ + DibFreeBitmapInfo(pbmi); + + return hbmp; +} + +HBITMAP +NTAPI +GreCreateDIBitmapInternal( + _In_ HDC hdc, + _In_ INT cx, + _In_ INT cy, + _In_ DWORD fInit, + _In_opt_ LPBYTE pjInit, + _In_opt_ PBITMAPINFO pbmi, + _In_ DWORD iUsage, + _In_ UINT cjMaxBits, + _In_ FLONG fl, + _In_ HANDLE hcmXform) +{ + PDC pdc; + PSURFACE psurfDIB; + + /* Check if we got a DC */ + if (hdc) + { + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + return NULL; + } + } + else + { + /* No DC */ + pdc = NULL; + } + + if (pjInit) + { + psurfDIB = DibCreateDIBSurface(pbmi, + pdc, + iUsage, + 0, + pjInit, + cjMaxBits); + } + + + return 0; +} + +HBITMAP +APIENTRY +NtGdiCreateDIBitmapInternal( + _In_ HDC hdc, + _In_ INT cx, + _In_ INT cy, + _In_ DWORD fInit, + _In_opt_ LPBYTE pjInit, + _In_opt_ LPBITMAPINFO pbmiUser, + _In_ DWORD iUsage, + _In_ UINT cjMaxInitInfo, + _In_ UINT cjMaxBits, + _In_ FLONG fl, + _In_ HANDLE hcmXform) +{ + PBITMAPINFO pbmi = NULL; + HANDLE hSecure; + HBITMAP hbmp; + + if (fInit & CBM_INIT) + { + if (pjInit) + { + hSecure = EngSecureMem(pjInit, cjMaxBits); + if (!hSecure) + return NULL; + } + } + else + { + pjInit = NULL; + } + + if (pbmiUser) + { + pbmi = DibProbeAndCaptureBitmapInfo(pbmiUser, iUsage, &cjMaxInitInfo); + if (!pbmi) goto cleanup; + } + + + hbmp = GreCreateDIBitmapInternal(hdc, + cx, + cy, + fInit, + pjInit, + pbmi, + iUsage, + cjMaxBits, + fl, + hcmXform); + + if (pbmi) + { + DibFreeBitmapInfo(pbmi); + } + +cleanup: + + if (fInit & CBM_INIT) + { + EngUnsecureMem(hSecure); + } + + return hbmp; +} + +INT +APIENTRY +GreGetDIBitsInternal( + _In_ HDC hdc, + _In_ HBITMAP hbm, + _In_ UINT iStartScan, + _In_ UINT cScans, + _Out_opt_ LPBYTE pjBits, + _Inout_ LPBITMAPINFO pbmi, + _In_ UINT iUsage, + _In_ UINT cjMaxBits, + _In_ UINT cjMaxInfo) +{ + + __debugbreak(); + + + return 0; +} + +INT +APIENTRY +NtGdiGetDIBitsInternal( + _In_ HDC hdc, + _In_ HBITMAP hbm, + _In_ UINT iStartScan, + _In_ UINT cScans, + _Out_opt_ LPBYTE pjBits, + _Inout_ LPBITMAPINFO pbmi, + _In_ UINT iUsage, + _In_ UINT cjMaxBits, + _In_ UINT cjMaxInfo) +{ + __debugbreak(); + return 0; +} + +INT +NTAPI +GreStretchDIBitsInternal( + _In_ HDC hdc, + _In_ INT xDst, + _In_ INT yDst, + _In_ INT cxDst, + _In_ INT cyDst, + _In_ INT xSrc, + _In_ INT ySrc, + _In_ INT cxSrc, + _In_ INT cySrc, + _In_opt_ LPBYTE pjInit, + _In_ LPBITMAPINFO pbmi, + _In_ ULONG iUsage, + _In_ DWORD dwRop, + _In_ ULONG cjMaxInfo, + _In_ ULONG cjMaxBits, + _In_ BOOL bTransformCoordinates, + _In_ HANDLE hcmXform) +{ + PDC pdc; + RECTL rcSrc, rcDst; + EXLATEOBJ exlo; + PSURFACE psurfDIB, psurfDst; + BOOL bResult; + + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + return 0; + } + + /* Get the dest surface */ + psurfDst = pdc->dclevel.pSurface; + if (!psurfDst) + { + DC_UnlockDc(pdc); + return 0; + } + + /* Create the DIB surface */ + psurfDIB = DibCreateDIBSurface(pbmi, + pdc, + iUsage, + 0, + pjInit, + cjMaxBits); + if (!psurfDIB) + { + DC_UnlockDc(pdc); + return 0; + } + + /* Calculate source and destination rect */ + rcSrc.left = xSrc; + rcSrc.top = ySrc; + rcSrc.right = xSrc + cxSrc; + rcSrc.bottom = ySrc + cySrc; + rcDst.left = xDst; + rcDst.top = yDst; + + if (bTransformCoordinates) + { + /* Use the size in logical units */ + rcDst.right = rcDst.left + cxDst; + rcDst.bottom = rcDst.top + cyDst; + + /* Transform destination rect to device coordinates */ + IntLPtoDP(pdc, (POINTL*)&rcDst, 2); + + /* Get the new dest size in device units */ + cxDst = rcDst.right - rcDst.left; + cyDst = rcDst.bottom - rcDst.top; + } + else + { + /* Transform destination start point to device coordinates */ + IntLPtoDP(pdc, (POINTL*)&rcDst, 1); + + /* Use the size in device units */ + rcDst.right = rcDst.left + cxDst; + rcDst.bottom = rcDst.top + cyDst; + } + + /* Compensate for the DC origin */ + RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y); + + /* Initialize XLATEOBJ */ + EXLATEOBJ_vInitialize(&exlo, + psurfDIB->ppal, + psurfDst->ppal, + RGB(0xff, 0xff, 0xff), + pdc->pdcattr->crBackgroundClr, + pdc->pdcattr->crForegroundClr); + + /* Prepare DC for blit */ + DC_vPrepareDCsForBlit(pdc, rcDst, NULL, rcSrc); + + /* Perform the stretch operation (note: this will go to + EngBitBlt when no stretching is needed) */ + bResult = IntEngStretchBlt(&psurfDst->SurfObj, + &psurfDIB->SurfObj, + NULL, + pdc->rosdc.CombinedClip, + &exlo.xlo, + &rcDst, + &rcSrc, + NULL, + &pdc->eboFill.BrushObject, + NULL, + ROP3_TO_ROP4(dwRop)); + + /* Cleanup */ + DC_vFinishBlit(pdc, NULL); + EXLATEOBJ_vCleanup(&exlo); + GDIOBJ_vDeleteObject(&psurfDIB->BaseObject); + DC_UnlockDc(pdc); + + return bResult ? cySrc : 0; +} + +INT +APIENTRY +NtGdiSetDIBitsToDeviceInternal( + _In_ HDC hdcDest, + _In_ INT xDst, + _In_ INT yDst, + _In_ DWORD cx, + _In_ DWORD cy, + _In_ INT xSrc, + _In_ INT ySrc, + _In_ DWORD iStartScan, + _In_ DWORD cNumScan, + _In_ LPBYTE pjInitBits, + _In_ LPBITMAPINFO pbmiUser, + _In_ DWORD iUsage, + _In_ UINT cjMaxBits, + _In_ UINT cjMaxInfo, + _In_ BOOL bTransformCoordinates, + _In_opt_ HANDLE hcmXform) +{ + PBITMAPINFO pbmi; + HANDLE hSecure; + INT iResult = 0; + + /* Capture a safe copy of the bitmap info */ + pbmi = DibProbeAndCaptureBitmapInfo(pbmiUser, iUsage, &cjMaxInfo); + if (!pbmi) + { + /* Could not get bitmapinfo, fail. */ + return 0; + } + + /* Secure the user mode buffer for the bits */ + hSecure = EngSecureMemForRead(pjInitBits, cjMaxBits); + if (hSecure) + { + /* Call the internal function with the secure pointers */ + iResult = GreStretchDIBitsInternal(hdcDest, + xDst, + yDst, + cx, + cy, + xSrc, + ySrc, + cx, + cy, + pjInitBits, + pbmi, + iUsage, + MAKEROP4(SRCCOPY, SRCCOPY), + cjMaxInfo, + cjMaxBits, + bTransformCoordinates, + hcmXform); + + /* Unsecure the memory */ + EngUnsecureMem(hSecure); + } + + /* Free the bitmap info */ + DibFreeBitmapInfo(pbmi); + + /* Return the result */ + return iResult; +} + + +INT +APIENTRY +NtGdiStretchDIBitsInternal( + _In_ HDC hdc, + _In_ INT xDst, + _In_ INT yDst, + _In_ INT cxDst, + _In_ INT cyDst, + _In_ INT xSrc, + _In_ INT ySrc, + _In_ INT cxSrc, + _In_ INT cySrc, + _In_opt_ LPBYTE pjInit, + _In_ LPBITMAPINFO pbmiUser, + _In_ DWORD iUsage, + _In_ DWORD dwRop, // ms ntgdi.h says dwRop4(?) + _In_ UINT cjMaxInfo, + _In_ UINT cjMaxBits, + _In_ HANDLE hcmXform) +{ + PBITMAPINFO pbmi; + HANDLE hSecure; + INT iResult = 0; + + /* Capture a safe copy of the bitmap info */ + pbmi = DibProbeAndCaptureBitmapInfo(pbmiUser, iUsage, &cjMaxInfo); + if (!pbmi) + { + /* Could not get bitmapinfo, fail. */ + return 0; + } + + /* Secure the user mode buffer for the bits */ + hSecure = EngSecureMemForRead(pjInit, cjMaxBits); + if (hSecure) + { + /* Call the internal function with the secure pointers */ + iResult = GreStretchDIBitsInternal(hdc, + xDst, + yDst, + cxDst, + cyDst, + xSrc, + ySrc, + cxSrc, + cySrc, + pjInit, + pbmi, + iUsage, + dwRop, + cjMaxInfo, + cjMaxBits, + TRUE, + hcmXform); + + /* Unsecure the memory */ + EngUnsecureMem(hSecure); + } + + /* Free the bitmap info */ + DibFreeBitmapInfo(pbmi); + + /* Return the result */ + return iResult; +} + + +/////////////////////////////////////////////////////////////// + +// old stuff + +BITMAPINFO* +FASTCALL +DIB_ConvertBitmapInfo(CONST BITMAPINFO* pbmi, DWORD Usage) +{ + __debugbreak(); + return 0; +} + +VOID +FASTCALL +DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig) +{ + if(converted != orig) + ExFreePoolWithTag(converted, TAG_DIB); +} +
Propchange: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/di... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h (added) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h [iso-8859-1] Wed May 9 20:36:16 2012 @@ -1,0 +1,86 @@ + +/* Used as iUsage to create a PAL_BRUSHHACK palete */ +#define DIB_PAL_BRUSHHACK 3 + +#define GDITAG_BITMAPINFO 'imbG' + +typedef struct _BITMAPFORMAT +{ + SIZEL sizel; + ULONG cBitsPixel; + ULONG iCompression; + ULONG iFormat; +} BITMAPFORMAT, *PBITMAPFORMAT; + +ULONG +NTAPI +DibGetBitmapInfoSize( + _In_ const BITMAPINFO *pbmi, + _In_ ULONG iUsage); + +INT +NTAPI +GreGetDIBitsInternal( + _In_ HDC hdc, + _In_ HBITMAP hbm, + _In_ UINT iStartScan, + _In_ UINT cScans, + _Out_opt_ LPBYTE pjBits, + _Inout_ LPBITMAPINFO pbmi, + _In_ UINT iUsage, + _In_ UINT cjMaxBits, + _In_ UINT cjMaxInfo); + +HBITMAP +NTAPI +GreCreateDIBitmapInternal( + _In_ HDC hdc, + _In_ INT cx, + _In_ INT cy, + _In_ DWORD fInit, + _In_opt_ LPBYTE pjInit, + _In_opt_ PBITMAPINFO pbmi, + _In_ DWORD iUsage, + _In_ UINT cjMaxBits, + _In_ FLONG fl, + _In_ HANDLE hcmXform); + + +// other stuff + +HANDLE +APIENTRY +EngSecureMemForRead(PVOID Address, ULONG Length); + +#define ROP3_TO_ROP4(dwRop3) \ + ((((dwRop3) & 0xFF0000) >> 8) | (((dwRop3) & 0xFF0000) >> 16)) + + +// old stuff + +BITMAPINFO* +FASTCALL +DIB_ConvertBitmapInfo(CONST BITMAPINFO* pbmi, DWORD Usage); + +VOID +FASTCALL +DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig); + +INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse); + +INT +FORCEINLINE +DIB_GetDIBImageBytes(INT width, INT height, INT depth) +{ + return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height); +} + +UINT +APIENTRY +IntGetDIBColorTable( + HDC hDC, + UINT StartIndex, + UINT Entries, + RGBQUAD *Colors); + +#define DIB_BitmapInfoSize
Propchange: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: branches/dib_rewrite/win32ss/user/ntuser/clipboard.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/user/ntuser/... ============================================================================== --- branches/dib_rewrite/win32ss/user/ntuser/clipboard.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/user/ntuser/clipboard.c [iso-8859-1] Wed May 9 20:36:16 2012 @@ -147,6 +147,8 @@ hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); if (!hdc) return; + + // FIXME: use a less cheesy way to calculate the size of the bitmap!
psurf = SURFACE_ShareLockSurface(hBm); if (!psurf) @@ -165,7 +167,7 @@ bi.bmiHeader.biYPelsPerMeter = 0; bi.bmiHeader.biClrUsed = 0;
- NtGdiGetDIBitsInternal(hdc, hBm, 0, bm.bmHeight, NULL, &bi, DIB_RGB_COLORS, 0, 0); + GreGetDIBitsInternal(hdc, hBm, 0, bm.bmHeight, NULL, &bi, DIB_RGB_COLORS, 0, 0);
pMemObj = (PCLIPBOARDDATA)UserCreateObject(gHandleTable, NULL, &hMem, otClipBoardData, sizeof(BITMAPINFOHEADER) + bi.bmiHeader.biSizeImage); @@ -173,7 +175,7 @@ { pMemObj->cbData = sizeof(BITMAPINFOHEADER) + bi.bmiHeader.biSizeImage; memcpy(pMemObj->Data, &bi, sizeof(BITMAPINFOHEADER)); - NtGdiGetDIBitsInternal(hdc, hBm, 0, bm.bmHeight, (LPBYTE)pMemObj->Data + sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS, 0, 0); + GreGetDIBitsInternal(hdc, hBm, 0, bm.bmHeight, (LPBYTE)pMemObj->Data + sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS, 0, 0); IntAddFormatedData(pWinStaObj, CF_DIB, hMem, TRUE, TRUE); }
@@ -230,6 +232,7 @@
if (hBm) { + // FIXME: this is broken! GreSetObjectOwner(hBm, GDI_OBJ_HMGR_PUBLIC); pBmEl->hData = hBm; }
Modified: branches/dib_rewrite/win32ss/user/ntuser/misc/file.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/user/ntuser/... ============================================================================== --- branches/dib_rewrite/win32ss/user/ntuser/misc/file.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/user/ntuser/misc/file.c [iso-8859-1] Wed May 9 20:36:16 2012 @@ -155,8 +155,8 @@ NTSTATUS Status = STATUS_SUCCESS; HANDLE hFile, hSection; BITMAPFILEHEADER *pbmfh; - LPBITMAPINFO pbmi; - PVOID pvBits; + // LPBITMAPINFO pbmi; + // PVOID pvBits; HBITMAP hbmp = 0;
DPRINT("Enter UserLoadImage(%ls)\n", pwszName); @@ -184,19 +184,23 @@ return NULL; }
- /* Get a pointer to the BITMAPINFO */ - pbmi = (LPBITMAPINFO)(pbmfh + 1); - +__debugbreak(); +#if 0 _SEH2_TRY { ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1); ProbeForRead(pbmfh, pbmfh->bfSize, 1); + cjHeader = } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END + + /* Get a pointer to the BITMAPINFO */ + pbmi = ProbeAndConvertBitmapInfo((LPBITMAPINFO)(pbmfh + 1), cjHeader); + (LPBITMAPINFO)(pbmfh + 1);
if(!NT_SUCCESS(Status)) { @@ -239,8 +243,8 @@ { DPRINT1("Unknown file type!\n"); } - -leave: +#endif +//leave: /* Unmap our section, we don't need it anymore */ ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
Modified: branches/dib_rewrite/win32ss/win32kp.h URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/win32kp.h?re... ============================================================================== --- branches/dib_rewrite/win32ss/win32kp.h [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/win32kp.h [iso-8859-1] Wed May 9 20:36:16 2012 @@ -57,7 +57,7 @@ #include "gdi/ntgdi/palette.h" #include "gdi/ntgdi/region.h" #include "gdi/ntgdi/dc.h" -#include "gdi/ntgdi/dib.h" +#include "gdi/ntgdi/dibitmap.h" #include "gdi/ntgdi/cliprgn.h" #include "gdi/ntgdi/intgdi.h" #include "gdi/ntgdi/paint.h"