mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
[WIN32K]
Rewrite brush code in C++ svn path=/trunk/; revision=66893
This commit is contained in:
parent
ec0f3d9ba9
commit
976a3274ad
|
@ -1,6 +1,11 @@
|
|||
|
||||
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 @@ list(APPEND SOURCE
|
|||
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 @@ if(USE_DIBLIB)
|
|||
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)
|
||||
|
|
109
reactos/win32ss/gdi/ntgdi/baseobj.hpp
Normal file
109
reactos/win32ss/gdi/ntgdi/baseobj.hpp
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -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 */
|
550
reactos/win32ss/gdi/ntgdi/brush.cpp
Normal file
550
reactos/win32ss/gdi/ntgdi/brush.cpp
Normal file
|
@ -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@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" */
|
121
reactos/win32ss/gdi/ntgdi/brush.hpp
Normal file
121
reactos/win32ss/gdi/ntgdi/brush.hpp
Normal file
|
@ -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@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);
|
|
@ -29,6 +29,19 @@
|
|||
* 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) + - - -
|
||||
*
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
@ -1590,5 +1603,16 @@ GDI_CleanupForProcess(struct _EPROCESS *Process)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/// HACK!
|
||||
PGDI_POOL
|
||||
GetBrushAttrPool(VOID)
|
||||
{
|
||||
PPROCESSINFO ppi;
|
||||
|
||||
ppi = PsGetCurrentProcessWin32Process();
|
||||
NT_ASSERT(ppi != NULL);
|
||||
|
||||
return ppi->pPoolBrushAttr;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -66,6 +66,10 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
|||
/* 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 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
|||
/* Internal Win32K header */
|
||||
#include "win32kp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __W32K_H */
|
||||
|
|
|
@ -144,9 +144,14 @@ UserInitialize(VOID)
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue