mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +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)
|
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.
|
# Give WIN32 subsystem its own project.
|
||||||
PROJECT(WIN32SS)
|
PROJECT(WIN32SS)
|
||||||
|
|
||||||
|
@ -146,7 +151,7 @@ list(APPEND SOURCE
|
||||||
gdi/ntgdi/bezier.c
|
gdi/ntgdi/bezier.c
|
||||||
gdi/ntgdi/bitblt.c
|
gdi/ntgdi/bitblt.c
|
||||||
gdi/ntgdi/bitmaps.c
|
gdi/ntgdi/bitmaps.c
|
||||||
gdi/ntgdi/brush.c
|
gdi/ntgdi/brush.cpp
|
||||||
gdi/ntgdi/cliprgn.c
|
gdi/ntgdi/cliprgn.c
|
||||||
gdi/ntgdi/coord.c
|
gdi/ntgdi/coord.c
|
||||||
gdi/ntgdi/dcattr.c
|
gdi/ntgdi/dcattr.c
|
||||||
|
@ -227,7 +232,7 @@ if(USE_DIBLIB)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_importlibs(win32k ntoskrnl hal ftfd)
|
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)
|
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)
|
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,
|
* object from being locked by another thread. A shared lock will simply fail,
|
||||||
* while an exclusive lock will succeed after the object was unlocked.
|
* 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 ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -1590,5 +1603,16 @@ GDI_CleanupForProcess(struct _EPROCESS *Process)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// HACK!
|
||||||
|
PGDI_POOL
|
||||||
|
GetBrushAttrPool(VOID)
|
||||||
|
{
|
||||||
|
PPROCESSINFO ppi;
|
||||||
|
|
||||||
|
ppi = PsGetCurrentProcessWin32Process();
|
||||||
|
NT_ASSERT(ppi != NULL);
|
||||||
|
|
||||||
|
return ppi->pPoolBrushAttr;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -66,6 +66,10 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
||||||
/* SEH support with PSEH */
|
/* SEH support with PSEH */
|
||||||
#include <pseh/pseh2.h>
|
#include <pseh/pseh2.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Public Win32K headers */
|
/* Public Win32K headers */
|
||||||
#include <include/ntgdityp.h>
|
#include <include/ntgdityp.h>
|
||||||
#include <ntgdi.h>
|
#include <ntgdi.h>
|
||||||
|
@ -91,4 +95,8 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
|
||||||
/* Internal Win32K header */
|
/* Internal Win32K header */
|
||||||
#include "win32kp.h"
|
#include "win32kp.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __W32K_H */
|
#endif /* __W32K_H */
|
||||||
|
|
|
@ -144,9 +144,14 @@ UserInitialize(VOID)
|
||||||
if (gpsi->hbrGray == NULL)
|
if (gpsi->hbrGray == NULL)
|
||||||
{
|
{
|
||||||
hPattern55AABitmap = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)wPattern55AA);
|
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);
|
gpsi->hbrGray = IntGdiCreatePatternBrush(hPattern55AABitmap);
|
||||||
GreDeleteObject(hPattern55AABitmap);
|
GreDeleteObject(hPattern55AABitmap);
|
||||||
GreSetBrushOwner(gpsi->hbrGray, GDI_OBJ_HMGR_PUBLIC);
|
if (gpsi->hbrGray == NULL)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
Loading…
Reference in a new issue