reactos/win32ss/gdi/ntgdi/brush.c
David Quintana d5e23caf7a Sync with trunk r63430.
svn path=/branches/shell-experiments/; revision=63433
2014-05-24 20:29:19 +00:00

465 lines
9.9 KiB
C

/*
* 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>
#define GDIOBJATTRFREE 170
typedef struct _GDI_OBJ_ATTR_FREELIST
{
LIST_ENTRY Entry;
DWORD nEntries;
PVOID AttrList[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST;
typedef struct _GDI_OBJ_ATTR_ENTRY
{
RGN_ATTR Attr[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
BOOL
FASTCALL
IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner)
{
// FIXME:
if (pbr->flAttrs & BR_IS_GLOBAL) return TRUE;
if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) || ulOwner == GDI_OBJ_HMGR_NONE)
{
// Deny user access to User Data.
GDIOBJ_vSetObjectAttr(&pbr->BaseObject, NULL);
// FIXME: deallocate brush attr
}
if (ulOwner == GDI_OBJ_HMGR_POWNED)
{
// Allow user access to User Data.
GDIOBJ_vSetObjectAttr(&pbr->BaseObject, pbr->pBrushAttr);
// FIXME: Allocate brush attr
}
GDIOBJ_vSetObjectOwner(&pbr->BaseObject, ulOwner);
return TRUE;
}
BOOL
FASTCALL
GreSetBrushOwner(HBRUSH hBrush, ULONG ulOwner)
{
BOOL Ret;
PBRUSH pbrush;
pbrush = BRUSH_ShareLockBrush(hBrush);
Ret = IntGdiSetBrushOwner(pbrush, ulOwner);
BRUSH_ShareUnlockBrush(pbrush);
return Ret;
}
BOOL
NTAPI
BRUSH_bAllocBrushAttr(PBRUSH pbr)
{
PPROCESSINFO ppi;
BRUSH_ATTR *pBrushAttr;
ppi = PsGetCurrentProcessWin32Process();
ASSERT(ppi);
pBrushAttr = GdiPoolAllocate(ppi->pPoolDcAttr);
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;
}
VOID
NTAPI
BRUSH_vFreeBrushAttr(PBRUSH pbr)
{
#if 0
PPROCESSINFO ppi;
if (pbrush->pBrushAttr == &pbrush->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);
#endif
/* Reset to kmode brush attribute */
pbr->pBrushAttr = &pbr->BrushAttr;
}
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);
}
}
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->ulStyle;
}
else if (pbrush->flAttrs & BR_IS_DIB)
{
plogbrush->lbStyle = BS_DIBPATTERN;
plogbrush->lbHatch = (ULONG_PTR)pbrush->hbmClient;
}
else if (pbrush->flAttrs & BR_IS_BITMAP)
{
plogbrush->lbStyle = BS_PATTERN;
}
else
{
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 ColorSpec,
UINT BitmapInfoSize,
CONST VOID *PackedDIB)
{
HBRUSH hBrush;
PBRUSH pbrush;
HBITMAP hPattern;
ULONG_PTR DataPtr;
PVOID pvDIBits;
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0);
if (hPattern == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
RtlCopyMemory(pvDIBits,
(PVOID)DataPtr,
DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth,
BitmapInfo->bmiHeader.biHeight,
BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes));
pbrush = BRUSH_AllocBrushWithHandle();
if (pbrush == NULL)
{
GreDeleteObject(hPattern);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
hBrush = pbrush->BaseObject.hHmgr;
pbrush->flAttrs |= BR_IS_BITMAP | BR_IS_DIB;
pbrush->hbmPattern = hPattern;
pbrush->hbmClient = (HBITMAP)PackedDIB;
/* 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->ulStyle = 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
FASTCALL
IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color)
{
PBRUSH pbrush;
pbrush = BRUSH_ShareLockBrush(hBrush);
if (pbrush->flAttrs & BR_IS_SOLID)
{
pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
}
BRUSH_ShareUnlockBrush(pbrush);
}
/* PUBLIC FUNCTIONS ***********************************************************/
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);
}
/* EOF */