+/*
+ * ReactOS W32 Subsystem
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id$ */
#undef WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ddk/ntddk.h>
#include <win32k/cliprgn.h>
#include <win32k/brush.h>
#include <include/rect.h>
-
+#include <include/object.h>
+#include <include/inteng.h>
+#include <include/error.h>
#define NDEBUG
#include <win32k/debug1.h>
return 1;
}
-#define MEMCHECK(reg, rect, firstrect) xmemcheck(reg,&(rect),&(firstrect))
+#define MEMCHECK(reg, rect, firstrect) xmemcheck(reg,&(rect),(LPRECT *)&(firstrect))
-typedef void (*voidProcp)();
+typedef void FASTCALL (*overlapProcp)(PROSRGNDATA, PRECT, PRECT, PRECT, PRECT, INT, INT);
+typedef void FASTCALL (*nonOverlapProcp)(PROSRGNDATA, PRECT, PRECT, INT, INT);
// Number of points to buffer before sending them off to scanlines() : Must be an even number
#define NUMPTSTOBUFFER 200
struct _POINTBLOCK *next;
} POINTBLOCK;
-static BOOL REGION_CopyRegion(PROSRGNDATA dst, PROSRGNDATA src)
+static BOOL FASTCALL REGION_CopyRegion(PROSRGNDATA dst, PROSRGNDATA src)
{
if(dst != src) // don't want to copy to itself
{
return TRUE;
}
-static void REGION_SetExtents (ROSRGNDATA *pReg)
+static void FASTCALL REGION_SetExtents (ROSRGNDATA *pReg)
{
RECT *pRect, *pRectEnd, *pExtents;
pReg->rdh.rcBound.top = 0;
pReg->rdh.rcBound.right = 0;
pReg->rdh.rcBound.bottom = 0;
+ pReg->rdh.iType = NULLREGION;
return;
}
pExtents->right = pRect->right;
pRect++;
}
+ pReg->rdh.iType = (1 == pReg->rdh.nCount ? SIMPLEREGION : COMPLEXREGION);
}
/***********************************************************************
* REGION_CropAndOffsetRegion
*/
-static BOOL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT rect, PROSRGNDATA rgnSrc, PROSRGNDATA rgnDst)
+static BOOL FASTCALL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT rect, PROSRGNDATA rgnSrc, PROSRGNDATA rgnDst)
{
if(!rect) // just copy and offset
{
if(xrect)
{
- INT i;
+ ULONG i;
if(rgnDst != rgnSrc)
RtlCopyMemory(rgnDst, rgnSrc, sizeof(ROSRGNDATA));
else // region box and clipping rect appear to intersect
{
PRECT lpr, rpr;
- INT i, j, clipa, clipb;
+ ULONG i, j, clipa, clipb;
INT left = rgnSrc->rdh.rcBound.right + off->x;
INT right = rgnSrc->rdh.rcBound.left + off->x;
*
* \return hDst if success, 0 otherwise.
*/
-HRGN REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt)
+HRGN STDCALL REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt)
{
PROSRGNDATA objSrc, rgnDst;
HRGN hNewDst, hRet = NULL;
- GDIMULTILOCK Lock[2] = {{hDst, 0, GO_REGION_MAGIC}, {hSrc, 0, GO_REGION_MAGIC}};
+ GDIMULTILOCK Lock[2] = {{hDst, 0, GDI_OBJECT_TYPE_REGION}, {hSrc, 0, GDI_OBJECT_TYPE_REGION}};
- if( !hDst ){
- if( !( hNewDst = RGNDATA_AllocRgn(1) ) ){
- return 0;
- }
- Lock[0].hObj = hNewDst;
- }
+ if( !hDst )
+ {
+ if( !( hNewDst = RGNDATA_AllocRgn(1) ) )
+ {
+ return 0;
+ }
+ Lock[0].hObj = hNewDst;
+ }
- GDIOBJ_LockMultipleObj( &Lock, 2 );
+ if ( !GDIOBJ_LockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0])) )
+ {
+ DPRINT1("GDIOBJ_LockMultipleObj() failed\n" );
+ return 0;
+ }
rgnDst = Lock[0].pObj;
objSrc = Lock[1].pObj;
}
}
}
- GDIOBJ_UnlockMultipleObj( &Lock, 2 );
+ GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0]));
return hRet;
}
* - pReg->numRects will be decreased.
*
*/
-static INT REGION_Coalesce (
+static INT FASTCALL REGION_Coalesce (
PROSRGNDATA pReg, /* Region to coalesce */
INT prevStart, /* Index of start of previous band */
INT curStart /* Index of start of current band */
* to reduce the number of rectangles in the region.
*
*/
-static void REGION_RegionOp(
- ROSRGNDATA *newReg, /* Place to store result */
- ROSRGNDATA *reg1, /* First region in operation */
- ROSRGNDATA *reg2, /* 2nd region in operation */
- void (*overlapFunc)(), /* Function to call for over-lapping bands */
- void (*nonOverlap1Func)(), /* Function to call for non-overlapping bands in region 1 */
- void (*nonOverlap2Func)() /* Function to call for non-overlapping bands in region 2 */
-) {
+static void FASTCALL
+REGION_RegionOp(
+ ROSRGNDATA *newReg, /* Place to store result */
+ ROSRGNDATA *reg1, /* First region in operation */
+ ROSRGNDATA *reg2, /* 2nd region in operation */
+ overlapProcp overlapFunc, /* Function to call for over-lapping bands */
+ nonOverlapProcp nonOverlap1Func, /* Function to call for non-overlapping bands in region 1 */
+ nonOverlapProcp nonOverlap2Func /* Function to call for non-overlapping bands in region 2 */
+ )
+{
RECT *r1; /* Pointer into first region */
RECT *r2; /* Pointer into 2d region */
RECT *r1End; /* End of 1st region */
INT ybot; /* Bottom of intersection */
INT ytop; /* Top of intersection */
RECT *oldRects; /* Old rects for newReg */
- INT prevBand; /* Index of start of
+ ULONG prevBand; /* Index of start of
* previous band in newReg */
- INT curBand; /* Index of start of current
- * band in newReg */
+ ULONG curBand; /* Index of start of current band in newReg */
RECT *r1BandEnd; /* End of current band in r1 */
RECT *r2BandEnd; /* End of current band in r2 */
- INT top; /* Top of non-overlapping band */
- INT bot; /* Bottom of non-overlapping band */
+ ULONG top; /* Top of non-overlapping band */
+ ULONG bot; /* Bottom of non-overlapping band */
/*
* Initialization:
top = max(r1->top,ybot);
bot = min(r1->bottom,r2->top);
- if ((top != bot) && (nonOverlap1Func != (void (*)())NULL))
+ if ((top != bot) && (nonOverlap1Func != NULL))
{
(* nonOverlap1Func) (newReg, r1, r1BandEnd, top, bot);
}
top = max(r2->top,ybot);
bot = min(r2->bottom,r1->top);
- if ((top != bot) && (nonOverlap2Func != (void (*)())NULL))
+ if ((top != bot) && (nonOverlap2Func != NULL))
{
(* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot);
}
curBand = newReg->rdh.nCount;
if (r1 != r1End)
{
- if (nonOverlap1Func != (void (*)())NULL)
+ if (nonOverlap1Func != NULL)
{
do
{
} while (r1 != r1End);
}
}
- else if ((r2 != r2End) && (nonOverlap2Func != (void (*)())NULL))
+ else if ((r2 != r2End) && (nonOverlap2Func != NULL))
{
do
{
* Only do this stuff if the number of rectangles allocated is more than
* twice the number of rectangles in the region (a simple optimization...).
*/
- if ((newReg->rdh.nCount*sizeof(RECT) < 2*newReg->rdh.nRgnSize && (newReg->rdh.nCount > 2)))
+ if ((2 * newReg->rdh.nCount*sizeof(RECT) < newReg->rdh.nRgnSize && (newReg->rdh.nCount > 2)))
{
if (REGION_NOT_EMPTY(newReg))
{
* Rectangles may be added to the region.
*
*/
-static void REGION_IntersectO(ROSRGNDATA *pReg, RECT *r1, RECT *r1End,
- RECT *r2, RECT *r2End, INT top, INT bottom)
-
+static void FASTCALL
+REGION_IntersectO (
+ PROSRGNDATA pReg,
+ PRECT r1,
+ PRECT r1End,
+ PRECT r2,
+ PRECT r2End,
+ INT top,
+ INT bottom
+ )
{
INT left, right;
RECT *pNextRect;
/***********************************************************************
* REGION_IntersectRegion
*/
-static void REGION_IntersectRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
+static void FASTCALL REGION_IntersectRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
ROSRGNDATA *reg2)
{
- /* check for trivial reject */
- if ( (!(reg1->rdh.nCount)) || (!(reg2->rdh.nCount)) ||
- (!EXTENTCHECK(®1->rdh.rcBound, ®2->rdh.rcBound)))
- newReg->rdh.nCount = 0;
- else
- REGION_RegionOp (newReg, reg1, reg2,
- (voidProcp) REGION_IntersectO, (voidProcp) NULL, (voidProcp) NULL);
+ /* check for trivial reject */
+ if ( (!(reg1->rdh.nCount)) || (!(reg2->rdh.nCount)) ||
+ (!EXTENTCHECK(®1->rdh.rcBound, ®2->rdh.rcBound)))
+ newReg->rdh.nCount = 0;
+ else
+ REGION_RegionOp (newReg, reg1, reg2,
+ REGION_IntersectO, NULL, NULL);
/*
* Can't alter newReg's extents before we call miRegionOp because
* with the rectangles we're passed.
*
*/
-static void REGION_UnionNonO (ROSRGNDATA *pReg, RECT *r, RECT *rEnd,
- INT top, INT bottom)
+static void FASTCALL
+REGION_UnionNonO (
+ PROSRGNDATA pReg,
+ PRECT r,
+ PRECT rEnd,
+ INT top,
+ INT bottom
+ )
{
RECT *pNextRect;
* be changed.
*
*/
-static void REGION_UnionO (ROSRGNDATA *pReg, RECT *r1, RECT *r1End,
- RECT *r2, RECT *r2End, INT top, INT bottom)
+static void FASTCALL
+REGION_UnionO (
+ PROSRGNDATA pReg,
+ PRECT r1,
+ PRECT r1End,
+ PRECT r2,
+ PRECT r2End,
+ INT top,
+ INT bottom
+ )
{
RECT *pNextRect;
/***********************************************************************
* REGION_UnionRegion
*/
-static void REGION_UnionRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
+static void FASTCALL REGION_UnionRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
ROSRGNDATA *reg2)
{
- /* checks all the simple cases */
-
- /*
- * Region 1 and 2 are the same or region 1 is empty
- */
- if ( (reg1 == reg2) || (!(reg1->rdh.nCount)) )
+ /* checks all the simple cases */
+
+ /*
+ * Region 1 and 2 are the same or region 1 is empty
+ */
+ if (reg1 == reg2 || 0 == reg1->rdh.nCount ||
+ reg1->rdh.rcBound.right <= reg1->rdh.rcBound.left ||
+ reg1->rdh.rcBound.bottom <= reg1->rdh.rcBound.top)
{
- if (newReg != reg2)
- REGION_CopyRegion(newReg, reg2);
- return;
+ if (newReg != reg2)
+ {
+ REGION_CopyRegion(newReg, reg2);
+ }
+ return;
}
/*
* if nothing to union (region 2 empty)
*/
- if (!(reg2->rdh.nCount))
+ if (0 == reg2->rdh.nCount ||
+ reg2->rdh.rcBound.right <= reg2->rdh.rcBound.left ||
+ reg2->rdh.rcBound.bottom <= reg2->rdh.rcBound.top)
{
- if (newReg != reg1)
- REGION_CopyRegion(newReg, reg1);
- return;
+ if (newReg != reg1)
+ {
+ REGION_CopyRegion(newReg, reg1);
+ }
+ return;
}
- /*
- * Region 1 completely subsumes region 2
- */
- if ((reg1->rdh.nCount == 1) &&
- (reg1->rdh.rcBound.left <= reg2->rdh.rcBound.left) &&
- (reg1->rdh.rcBound.top <= reg2->rdh.rcBound.top) &&
- (reg1->rdh.rcBound.right >= reg2->rdh.rcBound.right) &&
- (reg1->rdh.rcBound.bottom >= reg2->rdh.rcBound.bottom))
+ /*
+ * Region 1 completely subsumes region 2
+ */
+ if (1 == reg1->rdh.nCount &&
+ reg1->rdh.rcBound.left <= reg2->rdh.rcBound.left &&
+ reg1->rdh.rcBound.top <= reg2->rdh.rcBound.top &&
+ reg2->rdh.rcBound.right <= reg1->rdh.rcBound.right &&
+ reg2->rdh.rcBound.bottom <= reg1->rdh.rcBound.bottom)
{
- if (newReg != reg1)
- REGION_CopyRegion(newReg, reg1);
- return;
+ if (newReg != reg1)
+ {
+ REGION_CopyRegion(newReg, reg1);
+ }
+ return;
}
- /*
- * Region 2 completely subsumes region 1
- */
- if ((reg2->rdh.nCount == 1) &&
- (reg2->rdh.rcBound.left <= reg1->rdh.rcBound.left) &&
- (reg2->rdh.rcBound.top <= reg1->rdh.rcBound.top) &&
- (reg2->rdh.rcBound.right >= reg1->rdh.rcBound.right) &&
- (reg2->rdh.rcBound.bottom >= reg1->rdh.rcBound.bottom))
+ /*
+ * Region 2 completely subsumes region 1
+ */
+ if (1 == reg2->rdh.nCount &&
+ reg2->rdh.rcBound.left <= reg1->rdh.rcBound.left &&
+ reg2->rdh.rcBound.top <= reg1->rdh.rcBound.top &&
+ reg1->rdh.rcBound.right <= reg2->rdh.rcBound.right &&
+ reg1->rdh.rcBound.bottom <= reg2->rdh.rcBound.bottom)
{
- if (newReg != reg2)
- REGION_CopyRegion(newReg, reg2);
- return;
+ if (newReg != reg2)
+ {
+ REGION_CopyRegion(newReg, reg2);
+ }
+ return;
}
- REGION_RegionOp (newReg, reg1, reg2, (voidProcp) REGION_UnionO,
- (voidProcp) REGION_UnionNonO, (voidProcp) REGION_UnionNonO);
- newReg->rdh.rcBound.left = min(reg1->rdh.rcBound.left, reg2->rdh.rcBound.left);
- newReg->rdh.rcBound.top = min(reg1->rdh.rcBound.top, reg2->rdh.rcBound.top);
- newReg->rdh.rcBound.right = max(reg1->rdh.rcBound.right, reg2->rdh.rcBound.right);
- newReg->rdh.rcBound.bottom = max(reg1->rdh.rcBound.bottom, reg2->rdh.rcBound.bottom);
+ REGION_RegionOp ( newReg, reg1, reg2, REGION_UnionO,
+ REGION_UnionNonO, REGION_UnionNonO );
+ newReg->rdh.rcBound.left = min(reg1->rdh.rcBound.left, reg2->rdh.rcBound.left);
+ newReg->rdh.rcBound.top = min(reg1->rdh.rcBound.top, reg2->rdh.rcBound.top);
+ newReg->rdh.rcBound.right = max(reg1->rdh.rcBound.right, reg2->rdh.rcBound.right);
+ newReg->rdh.rcBound.bottom = max(reg1->rdh.rcBound.bottom, reg2->rdh.rcBound.bottom);
}
/***********************************************************************
* pReg may be affected.
*
*/
-static void REGION_SubtractNonO1 (ROSRGNDATA *pReg, RECT *r, RECT *rEnd,
- INT top, INT bottom)
+static void FASTCALL
+REGION_SubtractNonO1 (
+ PROSRGNDATA pReg,
+ PRECT r,
+ PRECT rEnd,
+ INT top,
+ INT bottom
+ )
{
RECT *pNextRect;
* pReg may have rectangles added to it.
*
*/
-static void REGION_SubtractO (ROSRGNDATA *pReg, RECT *r1, RECT *r1End,
- RECT *r2, RECT *r2End, INT top, INT bottom)
+static void FASTCALL
+REGION_SubtractO (
+ PROSRGNDATA pReg,
+ PRECT r1,
+ PRECT r1End,
+ PRECT r2,
+ PRECT r2End,
+ INT top,
+ INT bottom
+ )
{
RECT *pNextRect;
INT left;
* regD is overwritten.
*
*/
-static void REGION_SubtractRegion(ROSRGNDATA *regD, ROSRGNDATA *regM,
+static void FASTCALL REGION_SubtractRegion(ROSRGNDATA *regD, ROSRGNDATA *regM,
ROSRGNDATA *regS )
{
/* check for trivial reject */
return;
}
- REGION_RegionOp (regD, regM, regS, (voidProcp) REGION_SubtractO,
- (voidProcp) REGION_SubtractNonO1, (voidProcp) NULL);
+ REGION_RegionOp (regD, regM, regS, REGION_SubtractO,
+ REGION_SubtractNonO1, NULL);
/*
* Can't alter newReg's extents before we call miRegionOp because
/***********************************************************************
* REGION_XorRegion
*/
-static void REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
+static void FASTCALL REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
ROSRGNDATA *srb)
{
HRGN htra, htrb;
return;
tra = RGNDATA_LockRgn( htra );
if( !tra ){
- W32kDeleteObject( htra );
- W32kDeleteObject( htrb );
+ NtGdiDeleteObject( htra );
+ NtGdiDeleteObject( htrb );
return;
}
trb = RGNDATA_LockRgn( htrb );
if( !trb ){
RGNDATA_UnlockRgn( htra );
- W32kDeleteObject( htra );
- W32kDeleteObject( htrb );
+ NtGdiDeleteObject( htra );
+ NtGdiDeleteObject( htrb );
return;
}
RGNDATA_UnlockRgn( htra );
RGNDATA_UnlockRgn( htrb );
- W32kDeleteObject( htra );
- W32kDeleteObject( htrb );
+ NtGdiDeleteObject( htra );
+ NtGdiDeleteObject( htrb );
return;
}
/*!
* Adds a rectangle to a REGION
*/
-static void REGION_UnionRectWithRegion(const RECT *rect, ROSRGNDATA *rgn)
+static void FASTCALL REGION_UnionRectWithRegion(const RECT *rect, ROSRGNDATA *rgn)
{
ROSRGNDATA region;
}
-BOOL REGION_LPTODP(HDC hdc, HRGN hDest, HRGN hSrc)
+BOOL STDCALL REGION_LPTODP(HDC hdc, HRGN hDest, HRGN hSrc)
{
RECT *pCurRect, *pEndRect;
PROSRGNDATA srcObj = NULL;
PROSRGNDATA destObj = NULL;
- DC * dc = DC_HandleToPtr(hdc);
+ DC * dc = DC_LockDc(hdc);
RECT tmpRect;
BOOL ret = FALSE;
if(dc->w.MapMode == MM_TEXT) // Requires only a translation
{
- if(W32kCombineRgn(hDest, hSrc, 0, RGN_COPY) == ERROR)
- goto done;
+ if(NtGdiCombineRgn(hDest, hSrc, 0, RGN_COPY) == ERROR)
+ goto done;
- W32kOffsetRgn(hDest, dc->vportOrgX - dc->wndOrgX, dc->vportOrgY - dc->wndOrgY);
+ NtGdiOffsetRgn(hDest, dc->vportOrgX - dc->wndOrgX, dc->vportOrgY - dc->wndOrgY);
ret = TRUE;
goto done;
}
RGNDATA_UnlockRgn( hDest );
done:
- DC_ReleasePtr( hdc );
+ DC_UnlockDc( hdc );
return ret;
}
-HRGN RGNDATA_AllocRgn(INT n)
+HRGN FASTCALL RGNDATA_AllocRgn(INT n)
{
HRGN hReg;
PROSRGNDATA pReg;
BOOL bRet;
- if((hReg = (HRGN)GDIOBJ_AllocObj(sizeof(ROSRGNDATA), GO_REGION_MAGIC))){
- if( (pReg = GDIOBJ_LockObj( hReg, GO_REGION_MAGIC )) ){
+ if((hReg = (HRGN)GDIOBJ_AllocObj(sizeof(ROSRGNDATA), GDI_OBJECT_TYPE_REGION,
+ (GDICLEANUPPROC) RGNDATA_InternalDelete))){
+ if( (pReg = RGNDATA_LockRgn(hReg)) ){
if ((pReg->Buffer = ExAllocatePool(PagedPool, n * sizeof(RECT)))){
EMPTY_REGION(pReg);
pReg->rdh.nCount = n;
pReg->rdh.nRgnSize = n*sizeof(RECT);
- bRet = GDIOBJ_UnlockObj( hReg, GO_REGION_MAGIC );
+ bRet = RGNDATA_UnlockRgn(hReg);
ASSERT(bRet);
return hReg;
}
else
- GDIOBJ_FreeObj( hReg, GO_REGION_MAGIC, GDIOBJFLAG_DEFAULT );
+ RGNDATA_FreeRgn(hReg);
}
return NULL;
}
-BOOL RGNDATA_InternalDelete( PROSRGNDATA pRgn )
+BOOL FASTCALL RGNDATA_InternalDelete( PROSRGNDATA pRgn )
{
ASSERT(pRgn);
if(pRgn->Buffer)
return TRUE;
}
-// W32k Exported Functions
+// NtGdi Exported Functions
INT
STDCALL
-W32kCombineRgn(HRGN hDest,
+NtGdiCombineRgn(HRGN hDest,
HRGN hSrc1,
HRGN hSrc2,
INT CombineMode)
{
INT result = ERROR;
- GDIMULTILOCK Lock[3] = {{hDest, 0, GO_REGION_MAGIC}, {hSrc1, 0, GO_REGION_MAGIC}, {hSrc2, 0, GO_REGION_MAGIC}};
+ GDIMULTILOCK Lock[3] = {{hDest, 0, GDI_OBJECT_TYPE_REGION}, {hSrc1, 0, GDI_OBJECT_TYPE_REGION}, {hSrc2, 0, GDI_OBJECT_TYPE_REGION}};
PROSRGNDATA destRgn, src1Rgn, src2Rgn;
- GDIOBJ_LockMultipleObj( &Lock, 3 );
+ if ( !GDIOBJ_LockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0])) )
+ {
+ DPRINT1("GDIOBJ_LockMultipleObj() failed\n" );
+ return ERROR;
+ }
destRgn = (PROSRGNDATA) Lock[0].pObj;
src1Rgn = (PROSRGNDATA) Lock[1].pObj;
src2Rgn = (PROSRGNDATA) Lock[2].pObj;
- if( destRgn ){
- if( src1Rgn ){
- if (CombineMode == RGN_COPY)
- {
- if( !REGION_CopyRegion(destRgn, src1Rgn) )
- return ERROR;
- result = destRgn->rdh.iType;
- }
- else
- {
- if( src2Rgn ){
- switch (CombineMode)
- {
- case RGN_AND:
- REGION_IntersectRegion(destRgn, src1Rgn, src2Rgn);
- break;
- case RGN_OR:
- REGION_UnionRegion(destRgn, src1Rgn, src2Rgn);
- break;
- case RGN_XOR:
- REGION_XorRegion(destRgn, src1Rgn, src2Rgn);
- break;
- case RGN_DIFF:
- REGION_SubtractRegion(destRgn, src1Rgn, src2Rgn);
- break;
- }
- result = destRgn->rdh.iType;
- }
- }
- }
- }
- else{
- DPRINT("W32kCombineRgn: hDest unavailable\n");
- result = ERROR;
- }
- GDIOBJ_UnlockMultipleObj( &Lock, 3 );
+ if( destRgn )
+ {
+ if( src1Rgn )
+ {
+ if (CombineMode == RGN_COPY)
+ {
+ if( !REGION_CopyRegion(destRgn, src1Rgn) )
+ return ERROR;
+ result = destRgn->rdh.iType;
+ }
+ else
+ {
+ if( src2Rgn )
+ {
+ switch (CombineMode)
+ {
+ case RGN_AND:
+ REGION_IntersectRegion(destRgn, src1Rgn, src2Rgn);
+ break;
+ case RGN_OR:
+ REGION_UnionRegion(destRgn, src1Rgn, src2Rgn);
+ break;
+ case RGN_XOR:
+ REGION_XorRegion(destRgn, src1Rgn, src2Rgn);
+ break;
+ case RGN_DIFF:
+ REGION_SubtractRegion(destRgn, src1Rgn, src2Rgn);
+ break;
+ }
+ result = destRgn->rdh.iType;
+ }
+ }
+ }
+ }
+ else
+ {
+ DPRINT("NtGdiCombineRgn: hDest unavailable\n");
+ result = ERROR;
+ }
+ GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0]));
return result;
}
HRGN
STDCALL
-W32kCreateEllipticRgn(INT LeftRect,
+NtGdiCreateEllipticRgn(INT LeftRect,
INT TopRect,
INT RightRect,
INT BottomRect)
HRGN
STDCALL
-W32kCreateEllipticRgnIndirect(CONST PRECT rc)
+NtGdiCreateEllipticRgnIndirect(CONST PRECT rc)
{
UNIMPLEMENTED;
}
HRGN
STDCALL
-W32kCreatePolygonRgn(CONST PPOINT pt,
+NtGdiCreatePolygonRgn(CONST PPOINT pt,
INT Count,
INT PolyFillMode)
{
HRGN
STDCALL
-W32kCreatePolyPolygonRgn(CONST PPOINT pt,
+NtGdiCreatePolyPolygonRgn(CONST PPOINT pt,
CONST PINT PolyCounts,
INT Count,
INT PolyFillMode)
HRGN
STDCALL
-W32kCreateRectRgn(INT LeftRect,
- INT TopRect,
- INT RightRect,
- INT BottomRect)
+NtGdiCreateRectRgn(INT LeftRect,
+ INT TopRect,
+ INT RightRect,
+ INT BottomRect)
{
HRGN hRgn;
PROSRGNDATA pRgnData;
PRECT pRect;
- // Allocate region data structure with space for 1 RECT
- if( ( hRgn = RGNDATA_AllocRgn(1) ) ){
- if( ( pRgnData = RGNDATA_LockRgn( hRgn ) ) ){
- pRect = (PRECT)pRgnData->Buffer;
- ASSERT(pRect);
+ if (RightRect < LeftRect || BottomRect < TopRect)
+ {
+ DPRINT1("Invalid parameters (%d, %d) - (%d, %d)\n", LeftRect, TopRect, RightRect, BottomRect);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* Allocate region data structure with space for 1 RECT */
+ if ((hRgn = RGNDATA_AllocRgn(1)))
+ {
+ if ((pRgnData = RGNDATA_LockRgn(hRgn)))
+ {
+ pRect = (PRECT)pRgnData->Buffer;
+ ASSERT(pRect);
- // Fill in the region data header
- pRgnData->rdh.iType = SIMPLEREGION;
- W32kSetRect(&(pRgnData->rdh.rcBound), LeftRect, TopRect, RightRect, BottomRect);
+ /* Fill in the region data header */
+ pRgnData->rdh.iType = (LeftRect == RightRect || TopRect == BottomRect) ? NULLREGION : SIMPLEREGION;
+ NtGdiSetRect(&(pRgnData->rdh.rcBound), LeftRect, TopRect, RightRect, BottomRect);
- // use W32kCopyRect when implemented
- W32kSetRect(pRect, LeftRect, TopRect, RightRect, BottomRect);
- RGNDATA_UnlockRgn( hRgn );
+ /* use NtGdiCopyRect when implemented */
+ NtGdiSetRect(pRect, LeftRect, TopRect, RightRect, BottomRect);
+ RGNDATA_UnlockRgn(hRgn);
- return hRgn;
+ return hRgn;
}
- W32kDeleteObject( hRgn );
- }
- DPRINT("W32kCreateRectRgn: can't allocate region\n");
+ NtGdiDeleteObject( hRgn );
+ }
+
+ DPRINT1("NtGdiCreateRectRgn: can't allocate region\n");
return NULL;
}
HRGN STDCALL
-W32kCreateRectRgnIndirect(CONST PRECT rc)
+NtGdiCreateRectRgnIndirect(CONST PRECT rc)
{
RECT SafeRc;
NTSTATUS Status;
{
return(NULL);
}
- return(UnsafeW32kCreateRectRgnIndirect(&SafeRc));
+ return(UnsafeIntCreateRectRgnIndirect(&SafeRc));
}
HRGN STDCALL
-UnsafeW32kCreateRectRgnIndirect(CONST PRECT rc)
+UnsafeIntCreateRectRgnIndirect(CONST PRECT rc)
{
- return(W32kCreateRectRgn(rc->left, rc->top, rc->right, rc->bottom));
+ return(NtGdiCreateRectRgn(rc->left, rc->top, rc->right, rc->bottom));
}
HRGN
STDCALL
-W32kCreateRoundRectRgn(INT LeftRect,
+NtGdiCreateRoundRectRgn(INT LeftRect,
INT TopRect,
INT RightRect,
INT BottomRect,
BOOL
STDCALL
-W32kEqualRgn(HRGN hSrcRgn1,
+NtGdiEqualRgn(HRGN hSrcRgn1,
HRGN hSrcRgn2)
{
PROSRGNDATA rgn1, rgn2;
PRECT tRect1, tRect2;
- int i;
+ ULONG i;
BOOL bRet = FALSE;
if( !(rgn1 = RGNDATA_LockRgn(hSrcRgn1)))
HRGN
STDCALL
-W32kExtCreateRegion(CONST PXFORM Xform,
+NtGdiExtCreateRegion(CONST PXFORM Xform,
DWORD Count,
CONST PROSRGNDATA RgnData)
{
BOOL
STDCALL
-W32kFillRgn(HDC hDC,
- HRGN hRgn,
- HBRUSH hBrush)
+NtGdiFillRgn(HDC hDC, HRGN hRgn, HBRUSH hBrush)
{
- UNIMPLEMENTED;
+ HBRUSH oldhBrush;
+ PROSRGNDATA rgn;
+ PRECTL r;
+
+ if (NULL == (rgn = RGNDATA_LockRgn(hRgn)))
+ {
+ return FALSE;
+ }
+
+ if (NULL == (oldhBrush = NtGdiSelectObject(hDC, hBrush)))
+ {
+ RGNDATA_UnlockRgn(hRgn);
+ return FALSE;
+ }
+
+ for (r = (PRECT) rgn->Buffer; r < ((PRECT) rgn->Buffer) + rgn->rdh.nCount; r++)
+ {
+ NtGdiPatBlt(hDC, r->left, r->top, r->right - r->left, r->bottom - r->top, PATCOPY);
+ }
+
+ NtGdiSelectObject(hDC, oldhBrush);
+ RGNDATA_UnlockRgn( hRgn );
+
+ return TRUE;
}
BOOL
STDCALL
-W32kFrameRgn(HDC hDC,
+NtGdiFrameRgn(HDC hDC,
HRGN hRgn,
HBRUSH hBrush,
INT Width,
}
INT STDCALL
-UnsafeW32kGetRgnBox(HRGN hRgn,
+UnsafeIntGetRgnBox(HRGN hRgn,
LPRECT pRect)
{
PROSRGNDATA rgn = RGNDATA_LockRgn(hRgn);
INT STDCALL
-W32kGetRgnBox(HRGN hRgn,
+NtGdiGetRgnBox(HRGN hRgn,
LPRECT pRect)
{
- PROSRGNDATA rgn = RGNDATA_LockRgn(hRgn);
+ RECT SafeRect;
DWORD ret;
- if (rgn)
+ ret = UnsafeIntGetRgnBox(hRgn, &SafeRect);
+ if (ERROR == ret)
{
- RECT SafeRect;
- SafeRect.left = rgn->rdh.rcBound.left;
- SafeRect.top = rgn->rdh.rcBound.top;
- SafeRect.right = rgn->rdh.rcBound.right;
- SafeRect.bottom = rgn->rdh.rcBound.bottom;
- ret = rgn->rdh.iType;
- RGNDATA_UnlockRgn( hRgn );
-
- if(!NT_SUCCESS(MmCopyToCaller(pRect, &SafeRect, sizeof(RECT))))
- return 0;
-
return ret;
}
- return 0; //if invalid region return zero
+
+ if (!NT_SUCCESS(MmCopyToCaller(pRect, &SafeRect, sizeof(RECT))))
+ {
+ return ERROR;
+ }
+
+ return ret;
}
BOOL
STDCALL
-W32kInvertRgn(HDC hDC,
+NtGdiInvertRgn(HDC hDC,
HRGN hRgn)
{
UNIMPLEMENTED;
INT
STDCALL
-W32kOffsetRgn(HRGN hRgn,
+NtGdiOffsetRgn(HRGN hRgn,
INT XOffset,
INT YOffset)
{
PROSRGNDATA rgn = RGNDATA_LockRgn(hRgn);
INT ret;
- DPRINT("W32kOffsetRgn: hRgn %d Xoffs %d Yoffs %d rgn %x\n", hRgn, XOffset, YOffset, rgn );
+ DPRINT("NtGdiOffsetRgn: hRgn %d Xoffs %d Yoffs %d rgn %x\n", hRgn, XOffset, YOffset, rgn );
if( !rgn ){
- DPRINT("W32kOffsetRgn: hRgn error\n");
+ DPRINT("NtGdiOffsetRgn: hRgn error\n");
return ERROR;
}
BOOL
STDCALL
-W32kPaintRgn(HDC hDC,
+NtGdiPaintRgn(HDC hDC,
HRGN hRgn)
{
- RECT box;
- HRGN tmpVisRgn, prevVisRgn;
- DC *dc = DC_HandleToPtr(hDC);
+ //RECT box;
+ HRGN tmpVisRgn; //, prevVisRgn;
+ DC *dc = DC_LockDc(hDC);
PROSRGNDATA visrgn;
CLIPOBJ* ClipRegion;
BOOL bRet = FALSE;
if( !dc )
return FALSE;
- if(!(tmpVisRgn = W32kCreateRectRgn(0, 0, 0, 0))){
- DC_ReleasePtr( hDC );
+ if(!(tmpVisRgn = NtGdiCreateRectRgn(0, 0, 0, 0))){
+ DC_UnlockDc( hDC );
return FALSE;
}
/* ei enable later
// Transform region into device co-ords
- if(!REGION_LPTODP(hDC, tmpVisRgn, hRgn) || W32kOffsetRgn(tmpVisRgn, dc->w.DCOrgX, dc->w.DCOrgY) == ERROR) {
- W32kDeleteObject( tmpVisRgn );
- DC_ReleasePtr( hDC );
+ if(!REGION_LPTODP(hDC, tmpVisRgn, hRgn) || NtGdiOffsetRgn(tmpVisRgn, dc->w.DCOrgX, dc->w.DCOrgY) == ERROR) {
+ NtGdiDeleteObject( tmpVisRgn );
+ DC_UnlockDc( hDC );
return FALSE;
}
*/
/* enable when clipping is implemented
- W32kCombineRgn(tmpVisRgn, tmpVisRgn, dc->w.hGCClipRgn, RGN_AND);
+ NtGdiCombineRgn(tmpVisRgn, tmpVisRgn, dc->w.hGCClipRgn, RGN_AND);
*/
//visrgn = RGNDATA_LockRgn(tmpVisRgn);
visrgn = RGNDATA_LockRgn(hRgn);
- ClipRegion = IntEngCreateClipRegion( visrgn->rdh.nCount, visrgn->Buffer, visrgn->rdh.rcBound );
+ ClipRegion = IntEngCreateClipRegion (
+ visrgn->rdh.nCount, (PRECTL)visrgn->Buffer, visrgn->rdh.rcBound );
ASSERT( ClipRegion );
pBrush = BRUSHOBJ_LockBrush(dc->w.hBrush);
ASSERT(pBrush);
BrushOrigin.x = dc->w.brushOrgX;
BrushOrigin.y = dc->w.brushOrgY;
- SurfObj = (SURFOBJ*)AccessUserObject(dc->Surface);
+ SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
bRet = IntEngPaint(SurfObj,
ClipRegion,
pBrush,
&BrushOrigin,
- 0xFFFF);//don't know what to put here
+ 0xFFFF);//FIXME:don't know what to put here
RGNDATA_UnlockRgn( tmpVisRgn );
// Fill the region
- DC_ReleasePtr( hDC );
+ DC_UnlockDc( hDC );
return TRUE;
}
BOOL
STDCALL
-W32kPtInRegion(HRGN hRgn,
+NtGdiPtInRegion(HRGN hRgn,
INT X,
INT Y)
{
PROSRGNDATA rgn;
- int i;
+ ULONG i;
if( (rgn = RGNDATA_LockRgn(hRgn) ) )
return FALSE;
}
BOOL
-STDCALL
-W32kRectInRegion(HRGN hRgn,
- CONST LPRECT unsaferc)
+FASTCALL
+UnsafeIntRectInRegion(HRGN hRgn,
+ CONST LPRECT rc)
{
PROSRGNDATA rgn;
PRECT pCurRect, pRectEnd;
- PRECT rc;
BOOL bRet = FALSE;
- if( !NT_SUCCESS( MmCopyFromCaller( rc, unsaferc, sizeof( RECT ) ) ) ){
- DPRINT("W32kRectInRegion: bogus rc\n");
- return ERROR;
- }
-
if( !( rgn = RGNDATA_LockRgn(hRgn) ) )
return ERROR;
BOOL
STDCALL
-W32kSetRectRgn(HRGN hRgn,
+NtGdiRectInRegion(HRGN hRgn,
+ CONST LPRECT unsaferc)
+{
+ RECT rc;
+
+ if (!NT_SUCCESS(MmCopyFromCaller(&rc, unsaferc, sizeof(RECT))))
+ {
+ DPRINT1("NtGdiRectInRegion: bogus rc\n");
+ return ERROR;
+ }
+
+ return UnsafeIntRectInRegion(hRgn, &rc);
+}
+
+BOOL
+STDCALL
+NtGdiSetRectRgn(HRGN hRgn,
INT LeftRect,
INT TopRect,
INT RightRect,
return TRUE;
}
-HRGN STDCALL
-W32kUnionRectWithRgn(HRGN hDest, const RECT* unsafeRect)
+HRGN FASTCALL
+UnsafeIntUnionRectWithRgn(HRGN hDest, CONST PRECT Rect)
{
- PRECT pRect;
- PROSRGNDATA pRgn;
+ PROSRGNDATA pRgn;
+
+ pRgn = RGNDATA_LockRgn(hDest);
+ if (NULL == pRgn)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
+ }
+
+ REGION_UnionRectWithRegion(Rect, pRgn);
+ RGNDATA_UnlockRgn(hDest);
- if( !NT_SUCCESS( MmCopyFromCaller( pRect, unsafeRect, sizeof( RECT ) ) ) )
- return NULL;
+ return hDest;
+}
- if( !(pRgn = RGNDATA_LockRgn( hDest ) ) )
- return NULL;
+HRGN STDCALL
+NtGdiUnionRectWithRgn(HRGN hDest, CONST PRECT UnsafeRect)
+{
+ RECT SafeRect;
- REGION_UnionRectWithRegion( pRect, pRgn );
- RGNDATA_UnlockRgn( hDest );
- return hDest;
+ if (! NT_SUCCESS(MmCopyFromCaller(&SafeRect, UnsafeRect, sizeof(RECT))))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ return UnsafeIntUnionRectWithRgn(hDest, &SafeRect);
}
/*!
*
* If the function fails, the return value is zero."
*/
-DWORD STDCALL W32kGetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
+DWORD STDCALL NtGdiGetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
{
DWORD size;
PROSRGNDATA obj = RGNDATA_LockRgn( hrgn );
RGNDATA_UnlockRgn( hrgn );
return size + sizeof(RGNDATAHEADER);
}
-
+/* EOF */