Author: tkreuzer
Date: Wed Mar 25 22:38:20 2015
New Revision: 66893
URL:
http://svn.reactos.org/svn/reactos?rev=66893&view=rev
Log:
[WIN32K]
Rewrite brush code in C++
Added:
trunk/reactos/win32ss/gdi/ntgdi/baseobj.hpp (with props)
trunk/reactos/win32ss/gdi/ntgdi/brush.cpp (with props)
trunk/reactos/win32ss/gdi/ntgdi/brush.hpp (with props)
Removed:
trunk/reactos/win32ss/gdi/ntgdi/brush.c
Modified:
trunk/reactos/win32ss/CMakeLists.txt
trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
trunk/reactos/win32ss/pch.h
trunk/reactos/win32ss/user/ntuser/ntuser.c
Modified: trunk/reactos/win32ss/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/CMakeLists.txt?rev…
==============================================================================
--- trunk/reactos/win32ss/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/win32ss/CMakeLists.txt [iso-8859-1] Wed Mar 25 22:38:20 2015
@@ -1,5 +1,10 @@
set(USE_DIBLIB FALSE)
+
+if(NOT MSVC)
+ # HACK: this should be enabled globally!
+ add_compile_flags_language("-std=c++11" "CXX")
+endif()
# Give WIN32 subsystem its own project.
PROJECT(WIN32SS)
@@ -146,7 +151,7 @@
gdi/ntgdi/bezier.c
gdi/ntgdi/bitblt.c
gdi/ntgdi/bitmaps.c
- gdi/ntgdi/brush.c
+ gdi/ntgdi/brush.cpp
gdi/ntgdi/cliprgn.c
gdi/ntgdi/coord.c
gdi/ntgdi/dcattr.c
@@ -227,7 +232,7 @@
endif()
add_importlibs(win32k ntoskrnl hal ftfd)
-add_pch(win32k pch.h SOURCE)
+#add_pch(win32k pch.h SOURCE)
add_cd_file(TARGET win32k DESTINATION reactos/system32 FOR all)
set_source_files_properties(sys-stubs.S PROPERTIES OBJECT_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/w32ksvc.h)
Added: trunk/reactos/win32ss/gdi/ntgdi/baseobj.hpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/baseobj.…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/baseobj.hpp (added)
+++ trunk/reactos/win32ss/gdi/ntgdi/baseobj.hpp [iso-8859-1] Wed Mar 25 22:38:20 2015
@@ -0,0 +1,109 @@
+
+#pragma once
+
+#define GDIOBJ_POOL_TAG(type) ('00hG' + (((type) & 0x1f) << 24))
+
+#define BASEOBJECT CBASEOBJECT
+
+class BASEOBJECT : private _BASEOBJECT
+{
+public:
+
+ enum OWNER
+ {
+ POWNED = GDI_OBJ_HMGR_POWNED,
+ PUBLIC = GDI_OBJ_HMGR_PUBLIC,
+ NONE = GDI_OBJ_HMGR_NONE
+ };
+
+protected:
+
+ BASEOBJECT(
+ _In_ GDILOOBJTYPE loobjtype)
+ {
+ /* Initialize the object */
+ _BASEOBJECT::hHmgr = (HGDIOBJ)(ULONG_PTR)loobjtype;
+ this->cExclusiveLock = 0;
+ this->ulShareCount = 1;
+ this->BaseFlags = 0;//fl & 0xffff;
+ DBG_INITLOG(&this->slhLog);
+ DBG_LOGEVENT(&this->slhLog, EVENT_ALLOCATE, 0);
+ #if DBG_ENABLE_GDIOBJ_BACKTRACES
+ DbgCaptureStackBackTace(this->apvBackTrace, 1, GDI_OBJECT_STACK_LEVELS);
+ #endif /* GDI_DEBUG */
+ }
+
+ static
+ BASEOBJECT*
+ LockExclusive(
+ HGDIOBJ hobj,
+ GDIOBJTYPE objtype);
+
+ static
+ BASEOBJECT*
+ LockExclusive(
+ HGDIOBJ hobj,
+ GDILOOBJTYPE loobjtype);
+
+ static
+ BASEOBJECT*
+ LockShared(
+ HGDIOBJ hobj,
+ GDILOOBJTYPE loobjtype,
+ OWNER owner)
+ {
+ return 0;
+ }
+
+ VOID
+ vSetObjectAttr(
+ _In_opt_ PVOID pvUserAttr)
+ {
+ GDIOBJ_vSetObjectAttr((POBJ)this, pvUserAttr);
+ }
+
+
+public:
+
+ static
+ inline
+ PVOID
+ pvAllocate(
+ _In_ GDIOBJTYPE objtype,
+ _In_ SIZE_T cjSize)
+ {
+ return ExAllocatePoolWithTag(PagedPool, cjSize, GDIOBJ_POOL_TAG(objtype));
+ }
+
+ VOID
+ vUnlock(
+ VOID)
+ {
+ if (this->cExclusiveLock > 0)
+ {
+ GDIOBJ_vUnlockObject(this);
+ }
+ else
+ {
+ GDIOBJ_vDereferenceObject(this);
+ }
+ }
+
+ inline
+ HGDIOBJ
+ hHmgr(
+ VOID)
+ {
+ return _BASEOBJECT::hHmgr;
+ }
+
+ HGDIOBJ
+ hInsertObject(
+ OWNER owner)
+ {
+ return GDIOBJ_hInsertObject(this, owner);
+ }
+
+};
+
+
Propchange: trunk/reactos/win32ss/gdi/ntgdi/baseobj.hpp
------------------------------------------------------------------------------
svn:eol-style = native
Removed: trunk/reactos/win32ss/gdi/ntgdi/brush.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/brush.c?…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/brush.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/brush.c (removed)
@@ -1,563 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS win32 subsystem
- * PURPOSE: Functions for brushes
- * FILE: subsystem/win32/win32k/objects/brush.c
- * PROGRAMER:
- */
-
-#include <win32k.h>
-
-#define NDEBUG
-#include <debug.h>
-
-static
-VOID
-BRUSH_vInit(
- PBRUSH pbr)
-{
- /* Start with kmode brush attribute */
- pbr->pBrushAttr = &pbr->BrushAttr;
-}
-
-static
-PBRUSH
-BRUSH_AllocBrushWithHandle(
- VOID)
-{
- PBRUSH pbr;
-
- pbr = (PBRUSH)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_BRUSH_TYPE, sizeof(BRUSH));
- if (pbr == NULL)
- {
- return NULL;
- }
-
- BRUSH_vInit(pbr);
- return pbr;
-}
-
-static
-BOOL
-BRUSH_bAllocBrushAttr(PBRUSH pbr)
-{
- PPROCESSINFO ppi;
- BRUSH_ATTR *pBrushAttr;
- NT_ASSERT(pbr->pBrushAttr == &pbr->BrushAttr);
-
- ppi = PsGetCurrentProcessWin32Process();
- NT_ASSERT(ppi);
- __analysis_assume(ppi);
-
- pBrushAttr = GdiPoolAllocate(ppi->pPoolBrushAttr);
- if (!pBrushAttr)
- {
- DPRINT1("Could not allocate brush attr\n");
- return FALSE;
- }
-
- /* Copy the content from the kernel mode dc attr */
- pbr->pBrushAttr = pBrushAttr;
- *pbr->pBrushAttr = pbr->BrushAttr;
-
- /* Set the object attribute in the handle table */
- GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pBrushAttr);
-
- DPRINT("BRUSH_bAllocBrushAttr: pbr=%p, pbr->pdcattr=%p\n", pbr,
pbr->pBrushAttr);
- return TRUE;
-}
-
-static
-VOID
-BRUSH_vFreeBrushAttr(PBRUSH pbr)
-{
- PPROCESSINFO ppi;
-
- if (pbr->pBrushAttr == &pbr->BrushAttr) return;
-
- /* Reset the object attribute in the handle table */
- GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
-
- /* Free memory from the process gdi pool */
- ppi = PsGetCurrentProcessWin32Process();
- ASSERT(ppi);
- GdiPoolFree(ppi->pPoolBrushAttr, pbr->pBrushAttr);
-
- /* Reset to kmode brush attribute */
- pbr->pBrushAttr = &pbr->BrushAttr;
-}
-
-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)
- {
- /* Free user mode attribute, if any */
- BRUSH_vFreeBrushAttr(pbr);
-
- // Deny user access to User Data.
- GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
- }
-
- if (ulOwner == GDI_OBJ_HMGR_POWNED)
- {
- /* Allocate a user mode attribute */
- BRUSH_bAllocBrushAttr(pbr);
-
- // Allow user access to User Data.
- GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pbr->pBrushAttr);
- }
-
- 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;
-}
-
-VOID
-NTAPI
-BRUSH_vCleanup(PVOID ObjectBody)
-{
- PBRUSH pbrush = (PBRUSH)ObjectBody;
- if (pbrush->hbmPattern)
- {
- GreSetObjectOwner(pbrush->hbmPattern, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(pbrush->hbmPattern);
- }
-
- /* Check if there is a usermode attribute */
- if (pbrush->pBrushAttr != &pbrush->BrushAttr)
- {
- BRUSH_vFreeBrushAttr(pbrush);
- }
-
- /* Free the kmode styles array of EXTPENS */
- if (pbrush->pStyle)
- {
- ExFreePool(pbrush->pStyle);
- }
-}
-
-VOID
-NTAPI
-BRUSH_vDeleteObject(
- PVOID pvObject)
-{
- BRUSH_vCleanup(pvObject);
- ExFreePoolWithTag(pvObject, GDITAG_HMGR_BRUSH_TYPE);
-}
-
-
-INT
-FASTCALL
-BRUSH_GetObject(PBRUSH pbrush, INT cjSize, LPLOGBRUSH plogbrush)
-{
- /* Check if only size is requested */
- if (plogbrush == NULL) return sizeof(LOGBRUSH);
-
- /* Check if size is ok */
- if (cjSize == 0) return 0;
-
- /* Set colour */
- 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->iHatch;
- }
- 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
- {
- plogbrush->lbStyle = 0; // ???
- }
-
- /* FIXME
- else if (pbrush->flAttrs & )
- {
- plogbrush->lbStyle = BS_INDEXED;
- }
- else if (pbrush->flAttrs & )
- {
- plogbrush->lbStyle = BS_DIBPATTERNPT;
- }
- */
-
- /* FIXME */
- return sizeof(LOGBRUSH);
-}
-
-HBRUSH
-APIENTRY
-IntGdiCreateDIBBrush(
- const BITMAPINFO *BitmapInfo,
- UINT uUsage,
- UINT BitmapInfoSize,
- const VOID* pvClient)
-{
- 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, uUsage);
-
- hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, uUsage, &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;
- if (uUsage == DIB_PAL_COLORS)
- pbrush->flAttrs |= BR_IS_DIBPALCOLORS;
- pbrush->hbmPattern = hPattern;
- pbrush->hbmClient = (HBITMAP)pvClient;
- /* FIXME: Fill in the rest of fields!!! */
-
- GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
-
- GDIOBJ_vUnlockObject(&pbrush->BaseObject);
-
- return hBrush;
-}
-
-HBRUSH
-APIENTRY
-IntGdiCreateHatchBrush(
- INT Style,
- COLORREF Color)
-{
- HBRUSH hBrush;
- PBRUSH pbrush;
-
- if (Style < 0 || Style >= NB_HATCH_STYLES)
- {
- 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->iHatch = Style;
-
- GDIOBJ_vUnlockObject(&pbrush->BaseObject);
-
- return hBrush;
-}
-
-HBRUSH
-APIENTRY
-IntGdiCreatePatternBrush(
- HBITMAP hBitmap)
-{
- HBRUSH hBrush;
- PBRUSH pbrush;
- HBITMAP hPattern;
-
- hPattern = BITMAP_CopyBitmap(hBitmap);
- if (hPattern == 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
-NTAPI
-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 ***********************************************************/
-
-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)
- {
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- }
-
- _SEH2_TRY
- {
- ProbeForRead(BitmapInfoAndData, BitmapInfoSize, 1);
- RtlCopyMemory(SafeBitmapInfoAndData, BitmapInfoAndData, BitmapInfoSize);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _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);
-}
-
-HBITMAP
-APIENTRY
-NtGdiGetObjectBitmapHandle(
- _In_ HBRUSH hbr,
- _Out_ UINT *piUsage)
-{
- HBITMAP hbmPattern;
- PBRUSH pbr;
-
- /* Lock the brush */
- pbr = BRUSH_ShareLockBrush(hbr);
- if (pbr == NULL)
- {
- DPRINT1("Could not lock brush\n");
- return NULL;
- }
-
- /* Get the pattern bitmap handle */
- hbmPattern = pbr->hbmPattern;
-
- _SEH2_TRY
- {
- ProbeForWrite(piUsage, sizeof(*piUsage), sizeof(*piUsage));
-
- /* Set usage according to flags */
- if (pbr->flAttrs & BR_IS_DIBPALCOLORS)
- *piUsage = DIB_PAL_COLORS;
- else
- *piUsage = DIB_RGB_COLORS;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- DPRINT1("Got exception!\n");
- hbmPattern = NULL;
- }
- _SEH2_END;
-
- /* Unlock the brush */
- BRUSH_ShareUnlockBrush(pbr);
-
- /* Return the pattern bitmap handle */
- return hbmPattern;
-}
-
-/*
- * @unimplemented
- */
-HBRUSH
-APIENTRY
-NtGdiSetBrushAttributes(
- IN HBRUSH hbm,
- IN DWORD dwFlags)
-{
- UNIMPLEMENTED;
- return NULL;
-}
-
-
-/*
- * @unimplemented
- */
-HBRUSH
-APIENTRY
-NtGdiClearBrushAttributes(
- IN HBRUSH hbr,
- IN DWORD dwFlags)
-{
- UNIMPLEMENTED;
- return NULL;
-}
-
-
-/* EOF */
Added: trunk/reactos/win32ss/gdi/ntgdi/brush.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/brush.cp…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/brush.cpp (added)
+++ trunk/reactos/win32ss/gdi/ntgdi/brush.cpp [iso-8859-1] Wed Mar 25 22:38:20 2015
@@ -0,0 +1,550 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS win32 subsystem
+ * PURPOSE: BRUSH class implementation
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ *
+ * REFERENCES:
http://support.microsoft.com/kb/kbview/108497
+ */
+
+#include "brush.hpp"
+
+DBG_DEFAULT_CHANNEL(GdiBrush);
+
+BRUSH::BRUSH(
+ _In_ FLONG flAttrs,
+ _In_ COLORREF crColor,
+ _In_ ULONG iHatch,
+ _In_opt_ HBITMAP hbmPattern,
+ _In_opt_ PVOID pvClient,
+ _In_ GDILOOBJTYPE loobjtype = GDILoObjType_LO_BRUSH_TYPE)
+ : BASEOBJECT(loobjtype)
+{
+ static ULONG ulGlobalBrushUnique = 0;
+
+ /* Get a unique value */
+ this->ulBrushUnique = InterlockedIncrementUL(&ulGlobalBrushUnique);
+
+ /* Start with kmode brush attribute */
+ this->pBrushAttr = &this->BrushAttr;
+
+ /* Set parameters */
+ this->flAttrs = flAttrs;
+ this->iHatch = iHatch;
+ this->hbmPattern = hbmPattern;
+ this->hbmClient = (HBITMAP)pvClient;
+ this->pBrushAttr->lbColor = crColor;
+
+ /* Initialize the other fields */
+ this->ptOrigin.x = 0;
+ this->ptOrigin.y = 0;
+ this->bCacheGrabbed = FALSE;
+ this->crBack = 0;
+ this->crFore = 0;
+ this->ulPalTime = 0;
+ this->ulSurfTime = 0;
+ this->pvRBrush = NULL;
+ this->hdev = NULL;
+}
+
+BRUSH::~BRUSH(
+ VOID)
+{
+ /* Check if we have a user mode brush attribute */
+ if (this->pBrushAttr != &this->BrushAttr)
+ {
+ /* Free memory to the process GDI pool */
+ GdiPoolFree(GetBrushAttrPool(), this->pBrushAttr);
+ }
+
+ /* Delete the pattern bitmap */
+ if (this->hbmPattern != NULL)
+ {
+ GreSetBitmapOwner(this->hbmPattern, BASEOBJECT::OWNER::POWNED);
+ GreDeleteObject(this->hbmPattern);
+ }
+}
+
+VOID
+BRUSH::vDeleteObject(
+ _In_ PVOID pvObject)
+{
+ PBRUSH pbr = static_cast<PBRUSH>(pvObject);
+ NT_ASSERT((GDI_HANDLE_GET_TYPE(pbr->hHmgr()) == GDILoObjType_LO_BRUSH_TYPE) ||
+ (GDI_HANDLE_GET_TYPE(pbr->hHmgr()) == GDILoObjType_LO_PEN_TYPE) ||
+ (GDI_HANDLE_GET_TYPE(pbr->hHmgr()) == GDILoObjType_LO_EXTPEN_TYPE));
+ delete pbr;
+}
+
+BOOL
+BRUSH::bAllocateBrushAttr(
+ VOID)
+{
+ PBRUSH_ATTR pBrushAttr;
+ NT_ASSERT(this->pBrushAttr == &this->BrushAttr);
+
+ /* Allocate a brush attribute from the pool */
+ pBrushAttr = static_cast<PBRUSH_ATTR>(GdiPoolAllocate(GetBrushAttrPool()));
+ if (pBrushAttr == NULL)
+ {
+ ERR("Could not allocate brush attr\n");
+ return FALSE;
+ }
+
+ /* Copy the content from the kernel mode brush attribute */
+ this->pBrushAttr = pBrushAttr;
+ *this->pBrushAttr = this->BrushAttr;
+
+ /* Set the object attribute in the handle table */
+ vSetObjectAttr(pBrushAttr);
+
+ return TRUE;
+}
+
+VOID
+BRUSH::vSetSolidColor(
+ _In_ COLORREF crColor)
+{
+ NT_ASSERT(this->flAttrs & BR_IS_SOLID);
+
+ /* Set new color and reset the pal times */
+ this->pBrushAttr->lbColor = crColor & 0xFFFFFF;
+ this->ulPalTime = -1;
+ this->ulSurfTime = -1;
+}
+
+HBITMAP
+BRUSH::hbmGetBitmapHandle(
+ _Out_ PUINT puUsage) const
+{
+ /* Return the color usage based on flags */
+ *puUsage = (this->flAttrs & BR_IS_DIBPALCOLORS) ? DIB_PAL_COLORS :
+ (this->flAttrs & BR_IS_DIBPALINDICES) ? DIB_PAL_INDICES :
+ DIB_RGB_COLORS;
+
+ return this->hbmPattern;
+}
+
+UINT
+BRUSH::cjGetObject(
+ _In_ UINT cjSize,
+ _Out_bytecap_(cjSize) PLOGBRUSH plb) const
+{
+ /* Check if only size is requested */
+ if (plb == NULL)
+ return sizeof(LOGBRUSH);
+
+ /* Check if size is ok */
+ if (cjSize == 0)
+ return 0;
+
+ /* Set color */
+ plb->lbColor = this->BrushAttr.lbColor;
+
+ /* Set style and hatch based on the attribute flags */
+ if (this->flAttrs & BR_IS_SOLID)
+ {
+ plb->lbStyle = BS_SOLID;
+ plb->lbHatch = 0;
+ }
+ else if (this->flAttrs & BR_IS_HATCH)
+ {
+ plb->lbStyle = BS_HATCHED;
+ plb->lbHatch = this->iHatch;
+ }
+ else if (this->flAttrs & BR_IS_DIB)
+ {
+ plb->lbStyle = BS_DIBPATTERN;
+ plb->lbHatch = (ULONG_PTR)this->hbmClient;
+ }
+ else if (this->flAttrs & BR_IS_BITMAP)
+ {
+ plb->lbStyle = BS_PATTERN;
+ plb->lbHatch = (ULONG_PTR)this->hbmClient;
+ }
+ else if (this->flAttrs & BR_IS_NULL)
+ {
+ plb->lbStyle = BS_NULL;
+ plb->lbHatch = 0;
+ }
+ else
+ {
+ NT_ASSERT(FALSE);
+ }
+
+ return sizeof(LOGBRUSH);
+}
+
+static
+HBRUSH
+CreateBrushInternal(
+ _In_ ULONG flAttrs,
+ _In_ COLORREF crColor,
+ _In_ ULONG iHatch,
+ _In_opt_ HBITMAP hbmPattern,
+ _In_opt_ PVOID pvClient)
+{
+ BASEOBJECT::OWNER owner;
+ PBRUSH pbr;
+ HBRUSH hbr;
+
+ NT_ASSERT(((flAttrs & BR_IS_BITMAP) == 0) || (hbmPattern != NULL));
+
+ /* Create the brush (brush takes ownership of the bitmap) */
+ pbr = new BRUSH(flAttrs, crColor, iHatch, hbmPattern, pvClient);
+ if (pbr == NULL)
+ {
+ ERR("Failed to allocate a brush\n");
+ GreSetBitmapOwner(hbmPattern, BASEOBJECT::OWNER::POWNED);
+ GreDeleteObject(hbmPattern);
+ return NULL;
+ }
+
+ /* Check if this is a global brush */
+ if (!(flAttrs & BR_IS_GLOBAL))
+ {
+ /* Not a global brush, so allocate a user mode brush attribute */
+ if (!pbr->bAllocateBrushAttr())
+ {
+ ERR("Failed to allocate brush attribute\n");
+ delete pbr;
+ return NULL;
+ }
+ }
+
+ /* Set the owner, either public or process owned */
+ owner = (flAttrs & BR_IS_GLOBAL) ? BASEOBJECT::OWNER::PUBLIC :
+ BASEOBJECT::OWNER::POWNED;
+
+ /* Insert the object into the GDI handle table */
+ hbr = static_cast<HBRUSH>(pbr->hInsertObject(owner));
+ if (hbr == NULL)
+ {
+ ERR("Failed to insert brush\n");
+ delete pbr;
+ return NULL;
+ }
+
+ /* Unlock the brush */
+ pbr->vUnlock();
+
+ return hbr;
+}
+
+
+/* C interface ***************************************************************/
+
+extern "C" {
+
+VOID
+NTAPI
+BRUSH_vDeleteObject(
+ PVOID pvObject)
+{
+ BRUSH::vDeleteObject(pvObject);
+}
+
+INT
+FASTCALL
+BRUSH_GetObject(
+ PBRUSH pbr,
+ INT cjBuffer,
+ LPLOGBRUSH plbBuffer)
+{
+ return pbr->cjGetObject(cjBuffer, plbBuffer);
+}
+
+HBRUSH
+NTAPI
+IntGdiCreateNullBrush(
+ VOID)
+{
+ /* Call the internal function */
+ return CreateBrushInternal(BR_IS_NULL | BR_IS_GLOBAL, 0, 0, NULL, NULL);
+}
+
+HBRUSH
+APIENTRY
+IntGdiCreateSolidBrush(
+ COLORREF crColor)
+{
+ /* Call the internal function */
+ return CreateBrushInternal(BR_IS_SOLID | BR_IS_GLOBAL,
+ crColor,
+ 0,
+ NULL,
+ NULL);
+}
+
+HBRUSH
+NTAPI
+IntGdiCreatePatternBrush(
+ HBITMAP hbmPattern)
+{
+ NT_ASSERT(hbmPattern != NULL);
+ GreSetBitmapOwner(hbmPattern, BASEOBJECT::OWNER::PUBLIC);
+ return CreateBrushInternal(BR_IS_BITMAP | BR_IS_GLOBAL,
+ 0,
+ 0,
+ hbmPattern,
+ NULL);
+}
+
+VOID
+NTAPI
+IntGdiSetSolidBrushColor(
+ _In_ HBRUSH hbr,
+ _In_ COLORREF crColor)
+{
+ PBRUSH pbr;
+
+ /* Lock the brush */
+ pbr = BRUSH::LockAny(hbr);
+ if (pbr == NULL)
+ {
+ ERR("Failed to lock brush %p\n", hbr);
+ return;
+ }
+
+ /* Call the member function */
+ pbr->vSetSolidColor(crColor);
+
+ /* Unlock the brush */
+ pbr->vUnlock();
+}
+
+__kernel_entry
+HBRUSH
+APIENTRY
+NtGdiCreateSolidBrush(
+ _In_ COLORREF crColor,
+ _In_opt_ HBRUSH hbr)
+{
+ if (hbr != NULL)
+ {
+ WARN("hbr is not supported, ignoring\n");
+ }
+
+ /* Call the internal function */
+ return CreateBrushInternal(BR_IS_SOLID, crColor, 0, NULL, NULL);
+}
+
+__kernel_entry
+HBRUSH
+APIENTRY
+NtGdiCreateHatchBrushInternal(
+ _In_ ULONG iHatch,
+ _In_ COLORREF crColor,
+ _In_ BOOL bPen)
+{
+ FLONG flAttr;
+
+ if (bPen)
+ {
+ WARN("bPen is not supported, ignoring\n");
+ }
+
+ /* Check what kind if hatch style this is */
+ if (iHatch < HS_DDI_MAX)
+ {
+ flAttr = BR_IS_HATCH;
+ }
+ else if (iHatch < HS_API_MAX)
+ {
+ flAttr = BR_IS_SOLID;
+ }
+ else
+ {
+ ERR("Invalid iHatch: %lu\n", iHatch);
+ return NULL;
+ }
+
+ /* Call the internal function */
+ return CreateBrushInternal(flAttr, crColor, iHatch, NULL, NULL);
+}
+
+__kernel_entry
+HBRUSH
+APIENTRY
+NtGdiCreatePatternBrushInternal(
+ _In_ HBITMAP hbmClient,
+ _In_ BOOL bPen,
+ _In_ BOOL b8X8)
+{
+ HBITMAP hbmPattern;
+
+ if (b8X8)
+ {
+ WARN("b8X8 is not supported, ignoring\n");
+ }
+
+ if (bPen)
+ {
+ WARN("bPen is not supported, ignoring\n");
+ }
+
+ /* Copy the bitmap */
+ hbmPattern = BITMAP_CopyBitmap(hbmClient);
+ if (hbmPattern == NULL)
+ {
+ ERR("Failed to copy the bitmap %p\n", hbmPattern);
+ return NULL;
+ }
+
+ /* Call the internal function (will delete hbmPattern on failure) */
+ return CreateBrushInternal(BR_IS_BITMAP, 0, 0, hbmPattern, hbmClient);
+}
+
+__kernel_entry
+HBRUSH
+APIENTRY
+NtGdiCreateDIBBrush(
+ _In_reads_bytes_(cj) PVOID pv,
+ _In_ FLONG uUsage,
+ _In_ UINT cj,
+ _In_ BOOL b8X8,
+ _In_ BOOL bPen,
+ _In_ PVOID pvClient)
+{
+ PVOID pvPackedDIB;
+ FLONG flAttrs;
+ HBITMAP hbm;
+ HBRUSH hbr = NULL;
+
+ if (b8X8)
+ {
+ WARN("b8X8 is not supported, ignoring\n");
+ }
+
+ if (bPen)
+ {
+ WARN("bPen is not supported, ignoring\n");
+ }
+
+ if (uUsage > DIB_PAL_INDICES)
+ {
+ ERR("Invalid uUsage value: %lu\n", uUsage);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* Allocate a buffer for the packed DIB */
+ pvPackedDIB = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_TEMP);
+ if (pvPackedDIB == NULL)
+ {
+ ERR("Failed to allocate temp buffer of %u bytes\n", cj);
+ return NULL;
+ }
+
+ /* Probe and copy the packed DIB */
+ _SEH2_TRY
+ {
+ ProbeForRead(pv, cj, 1);
+ RtlCopyMemory(pvPackedDIB, pv, cj);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ERR("Got exception, pv = %p, cj = %lu\n", pv, cj);
+ goto cleanup;
+ }
+ _SEH2_END;
+
+ flAttrs = BR_IS_BITMAP | BR_IS_DIB;
+
+ /* Check what kind of color table we have */
+ if (uUsage == DIB_PAL_COLORS)
+ {
+ /* Remember it and use DIB_PAL_BRUSHHACK to create a "special" palette
*/
+ flAttrs |= BR_IS_DIBPALCOLORS;
+ uUsage = DIB_PAL_BRUSHHACK;
+ }
+ else if (uUsage == DIB_PAL_INDICES)
+ {
+ /* No color table, bitmap contains device palette indices */
+ flAttrs |= BR_IS_DIBPALINDICES;
+
+ /* FIXME: This makes tests pass, but needs investigation. */
+ flAttrs |= BR_IS_NULL;
+ }
+
+ /* Create a bitmap from the DIB */
+ hbm = GreCreateDIBitmapFromPackedDIB(pvPackedDIB, cj, uUsage);
+ if (hbm == NULL)
+ {
+ ERR("Failed to create bitmap from DIB\n");
+ goto cleanup;
+ }
+
+ /* Call the internal function (will delete hbm on failure) */
+ hbr = CreateBrushInternal(flAttrs, 0, 0, hbm, pvClient);
+
+cleanup:
+
+ ExFreePoolWithTag(pvPackedDIB, GDITAG_TEMP);
+
+ return hbr;
+}
+
+__kernel_entry
+HBITMAP
+APIENTRY
+NtGdiGetObjectBitmapHandle(
+ _In_ HBRUSH hbr,
+ _Out_ UINT *piUsage)
+{
+ PBRUSH pbr;
+ HBITMAP hbm;
+ UINT uUsage;
+
+ /* Lock the brush */
+ pbr = BRUSH::LockForRead(hbr);
+ if (pbr == NULL)
+ {
+ ERR("Failed to lock brush %p\n", hbr);
+ return NULL;
+ }
+
+ /* Call the member function */
+ hbm = pbr->hbmGetBitmapHandle(&uUsage);
+
+ /* Unlock the brush */
+ pbr->vUnlock();
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(piUsage, sizeof(*piUsage), 1);
+ *piUsage = uUsage;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ERR("Got exception! piUsage = %p\n", piUsage);
+ hbm = NULL;
+ }
+ _SEH2_END;
+
+ return hbm;
+}
+
+__kernel_entry
+HBRUSH
+APIENTRY
+NtGdiSetBrushAttributes(
+ _In_ HBRUSH hbr,
+ _In_ DWORD dwFlags)
+{
+ __debugbreak();
+ return NULL;
+}
+
+__kernel_entry
+HBRUSH
+APIENTRY
+NtGdiClearBrushAttributes(
+ _In_ HBRUSH hbr,
+ _In_ DWORD dwFlags)
+{
+ __debugbreak();
+ return NULL;
+}
+
+} /* extern "C" */
Propchange: trunk/reactos/win32ss/gdi/ntgdi/brush.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/win32ss/gdi/ntgdi/brush.hpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/brush.hp…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/brush.hpp (added)
+++ trunk/reactos/win32ss/gdi/ntgdi/brush.hpp [iso-8859-1] Wed Mar 25 22:38:20 2015
@@ -0,0 +1,121 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS win32 subsystem
+ * PURPOSE: BRUSH class definition
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ */
+
+#pragma once
+
+#include <win32k.h>
+#include "baseobj.hpp"
+
+__prefast_operator_new_null
+
+class BRUSH : public BASEOBJECT, protected _BRUSHBODY
+{
+
+public:
+ _Analysis_mode_(_Analysis_operator_new_null_)
+
+ inline
+ void*
+ __cdecl
+ operator new(
+ _In_ size_t cjSize) throw()
+ {
+ return ExAllocatePoolWithTag(PagedPool, cjSize, GDITAG_HMGR_BRUSH_TYPE);
+ //return BASEOBJECT::pvAllocate(GDIObjType_BRUSH_TYPE, cjSize);
+ }
+
+ inline
+ void
+ operator delete(
+ void *pvObject)
+ {
+ /// HACK! better would be to extract the exact object type's tag
+ ExFreePool(pvObject);
+ //ExFreePoolWithTag(pvObject, GDITAG_HMGR_BRUSH_TYPE);
+ //BASEOBJECT::pvFree(GDIObjType_BRUSH_TYPE, cjSize);
+ }
+
+ BRUSH(
+ _In_ FLONG flAttrs,
+ _In_ COLORREF crColor,
+ _In_ ULONG iHatch,
+ _In_opt_ HBITMAP hbmPattern,
+ _In_opt_ PVOID pvClient,
+ _In_ GDILOOBJTYPE objtype);
+
+ ~BRUSH(
+ VOID);
+
+ static
+ VOID
+ vDeleteObject(
+ _In_ PVOID pvObject);
+
+ BOOL
+ bAllocateBrushAttr(
+ VOID);
+
+ _Check_return_
+ _Ret_opt_bytecount_(sizeof(BRUSH))
+ static
+ inline
+ PBRUSH
+ LockForRead(
+ _In_ HBRUSH hbr)
+ {
+ return static_cast<PBRUSH>(
+ BASEOBJECT::LockShared(hbr,
+ GDILoObjType_LO_BRUSH_TYPE,
+ BASEOBJECT::OWNER::PUBLIC));
+ }
+
+ _Check_return_
+ _Ret_opt_bytecount_(sizeof(BRUSH))
+ static
+ inline
+ PBRUSH
+ LockForWrite(
+ _In_ HBRUSH hbr)
+ {
+ return static_cast<PBRUSH>(
+ BASEOBJECT::LockShared(hbr,
+ GDILoObjType_LO_BRUSH_TYPE,
+ BASEOBJECT::OWNER::POWNED));
+ }
+
+ _Check_return_
+ _Ret_opt_bytecap_(sizeof(BRUSH))
+ static
+ inline
+ PBRUSH
+ LockAny(
+ _In_ HBRUSH hbr)
+ {
+ return static_cast<PBRUSH>(
+ BASEOBJECT::LockShared(hbr,
+ GDILoObjType_LO_BRUSH_TYPE,
+ BASEOBJECT::OWNER::NONE));
+ }
+
+ UINT
+ cjGetObject(
+ _In_ UINT cjBuffer,
+ _Out_bytecap_(cjBuffer) PLOGBRUSH plbBuffer) const;
+
+ HBITMAP
+ hbmGetBitmapHandle(
+ _Out_ PUINT puUsage) const;
+
+ VOID
+ vSetSolidColor(
+ _In_ COLORREF crColor);
+};
+
+/* HACK! */
+extern "C"
+PGDI_POOL
+GetBrushAttrPool(VOID);
Propchange: trunk/reactos/win32ss/gdi/ntgdi/brush.hpp
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] Wed Mar 25 22:38:20 2015
@@ -28,6 +28,19 @@
* this is the only way it can ever be exclusively locked. It prevents the
* object from being locked by another thread. A shared lock will simply fail,
* while an exclusive lock will succeed after the object was unlocked.
+ *
+ * Ownership:
+ *
+ * Owner: POWNED PUBLIC NONE spec
+ * ---------------------------------------------------
+ * LockForRead + + - PUBLIC
+ * LockForWrite + - - POWNED
+ * LockAny + + + NONE
+ * NtGdiDeleteObjectApp + - - PUBLIC
+ * GreDeleteObject + + + NONE
+ * GreSetOwner(POWNED) - - + -
+ * GreSetOwner(PUBLIC) + - + -
+ * GreSetOwner(NONE) + - - -
*
*/
@@ -1590,5 +1603,16 @@
return TRUE;
}
+/// HACK!
+PGDI_POOL
+GetBrushAttrPool(VOID)
+{
+ PPROCESSINFO ppi;
+
+ ppi = PsGetCurrentProcessWin32Process();
+ NT_ASSERT(ppi != NULL);
+
+ return ppi->pPoolBrushAttr;
+}
/* EOF */
Modified: trunk/reactos/win32ss/pch.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/pch.h?rev=66893&am…
==============================================================================
--- trunk/reactos/win32ss/pch.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/pch.h [iso-8859-1] Wed Mar 25 22:38:20 2015
@@ -66,6 +66,10 @@
/* SEH support with PSEH */
#include <pseh/pseh2.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Public Win32K headers */
#include <include/ntgdityp.h>
#include <ntgdi.h>
@@ -91,4 +95,8 @@
/* Internal Win32K header */
#include "win32kp.h"
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
#endif /* __W32K_H */
Modified: trunk/reactos/win32ss/user/ntuser/ntuser.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/ntuser…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/ntuser.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/ntuser.c [iso-8859-1] Wed Mar 25 22:38:20 2015
@@ -144,9 +144,14 @@
if (gpsi->hbrGray == NULL)
{
hPattern55AABitmap = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)wPattern55AA);
+ if (hPattern55AABitmap == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ //NT_VERIFY(GreSetBitmapOwner(hPattern55AABitmap, GDI_OBJ_HMGR_PUBLIC));
gpsi->hbrGray = IntGdiCreatePatternBrush(hPattern55AABitmap);
GreDeleteObject(hPattern55AABitmap);
- GreSetBrushOwner(gpsi->hbrGray, GDI_OBJ_HMGR_PUBLIC);
+ if (gpsi->hbrGray == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_SUCCESS;