update for HEAD-2003091401
[reactos.git] / subsys / win32k / objects / region.c
index c71f2fe..36dc126 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ *  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>
@@ -9,7 +28,9 @@
 #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>
@@ -63,9 +84,10 @@ static inline int xmemcheck(ROSRGNDATA *reg, LPRECT *rect, LPRECT *firstrect ) {
     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
@@ -79,7 +101,7 @@ typedef struct _POINTBLOCK {
   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
   {
@@ -107,7 +129,7 @@ static BOOL REGION_CopyRegion(PROSRGNDATA dst, PROSRGNDATA src)
   return TRUE;
 }
 
-static void REGION_SetExtents (ROSRGNDATA *pReg)
+static void FASTCALL REGION_SetExtents (ROSRGNDATA *pReg)
 {
     RECT *pRect, *pRectEnd, *pExtents;
 
@@ -117,6 +139,7 @@ static void REGION_SetExtents (ROSRGNDATA *pReg)
                pReg->rdh.rcBound.top = 0;
                pReg->rdh.rcBound.right = 0;
                pReg->rdh.rcBound.bottom = 0;
+               pReg->rdh.iType = NULLREGION;
                return;
     }
 
@@ -144,13 +167,14 @@ static void REGION_SetExtents (ROSRGNDATA *pReg)
                    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
   {
@@ -170,7 +194,7 @@ static BOOL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT rect, PROSR
 
     if(xrect)
     {
-      INT i;
+      ULONG i;
 
       if(rgnDst != rgnSrc)
                RtlCopyMemory(rgnDst, rgnSrc, sizeof(ROSRGNDATA));
@@ -205,7 +229,7 @@ static BOOL REGION_CropAndOffsetRegion(const PPOINT off, const PRECT rect, PROSR
   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;
 
@@ -312,20 +336,26 @@ empty:
  *
  * \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;
 
@@ -347,7 +377,7 @@ HRGN REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt)
          }
     }
   }
-  GDIOBJ_UnlockMultipleObj( &Lock, 2 );
+  GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0]));
   return hRet;
 }
 
@@ -365,7 +395,7 @@ HRGN REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt)
  *          - 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 */
@@ -506,14 +536,16 @@ static INT REGION_Coalesce (
  *      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 */
@@ -521,14 +553,13 @@ static void REGION_RegionOp(
     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:
@@ -632,7 +663,7 @@ static void REGION_RegionOp(
                    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);
                    }
@@ -644,7 +675,7 @@ static void REGION_RegionOp(
                    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);
                    }
@@ -703,7 +734,7 @@ static void REGION_RegionOp(
     curBand = newReg->rdh.nCount;
     if (r1 != r1End)
     {
-               if (nonOverlap1Func != (void (*)())NULL)
+               if (nonOverlap1Func != NULL)
                {
                    do
                    {
@@ -718,7 +749,7 @@ static void REGION_RegionOp(
                    } while (r1 != r1End);
                }
     }
-    else if ((r2 != r2End) && (nonOverlap2Func != (void (*)())NULL))
+    else if ((r2 != r2End) && (nonOverlap2Func != NULL))
     {
                do
                {
@@ -746,7 +777,7 @@ static void REGION_RegionOp(
      * 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))
                {
@@ -798,9 +829,16 @@ static void REGION_RegionOp(
  *      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;
@@ -855,16 +893,16 @@ static void REGION_IntersectO(ROSRGNDATA *pReg,  RECT *r1, RECT *r1End,
 /***********************************************************************
  *          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(&reg1->rdh.rcBound, &reg2->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(&reg1->rdh.rcBound, &reg2->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
@@ -894,8 +932,14 @@ static void REGION_IntersectRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
  *      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;
 
@@ -927,8 +971,16 @@ static void REGION_UnionNonO (ROSRGNDATA *pReg, RECT *r, RECT *rEnd,
  *      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;
 
@@ -986,65 +1038,77 @@ static void REGION_UnionO (ROSRGNDATA *pReg, RECT *r1, RECT *r1End,
 /***********************************************************************
  *          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);
 }
 
 /***********************************************************************
@@ -1062,8 +1126,14 @@ static void REGION_UnionRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
  *      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;
 
@@ -1095,8 +1165,16 @@ static void REGION_SubtractNonO1 (ROSRGNDATA *pReg, RECT *r, RECT *rEnd,
  *      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;
@@ -1221,7 +1299,7 @@ static void REGION_SubtractO (ROSRGNDATA *pReg, RECT *r1, RECT *r1End,
  *      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 */
@@ -1232,8 +1310,8 @@ static void REGION_SubtractRegion(ROSRGNDATA *regD, ROSRGNDATA *regM,
                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
@@ -1248,7 +1326,7 @@ static void REGION_SubtractRegion(ROSRGNDATA *regD, ROSRGNDATA *regM,
 /***********************************************************************
  *          REGION_XorRegion
  */
-static void REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
+static void FASTCALL REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
                                                        ROSRGNDATA *srb)
 {
        HRGN htra, htrb;
@@ -1259,16 +1337,16 @@ static void REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
        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;
        }
 
@@ -1278,8 +1356,8 @@ static void REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
        RGNDATA_UnlockRgn( htra );
        RGNDATA_UnlockRgn( htrb );
 
-    W32kDeleteObject( htra );
-    W32kDeleteObject( htrb );
+    NtGdiDeleteObject( htra );
+    NtGdiDeleteObject( htrb );
     return;
 }
 
@@ -1287,7 +1365,7 @@ static void REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
 /*!
  * 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;
 
@@ -1299,13 +1377,13 @@ static void REGION_UnionRectWithRegion(const RECT *rect, ROSRGNDATA *rgn)
 }
 
 
-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;
 
@@ -1314,10 +1392,10 @@ BOOL REGION_LPTODP(HDC hdc, HRGN hDest, HRGN hSrc)
 
   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;
   }
@@ -1353,18 +1431,19 @@ BOOL REGION_LPTODP(HDC hdc, HRGN hDest, HRGN hSrc)
   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);
@@ -1372,7 +1451,7 @@ HRGN RGNDATA_AllocRgn(INT n)
        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;
@@ -1380,12 +1459,12 @@ HRGN RGNDATA_AllocRgn(INT n)
 
        }
        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)
@@ -1393,66 +1472,74 @@ BOOL RGNDATA_InternalDelete( PROSRGNDATA pRgn )
   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)
@@ -1462,14 +1549,14 @@ W32kCreateEllipticRgn(INT  LeftRect,
 
 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)
 {
@@ -1478,7 +1565,7 @@ W32kCreatePolygonRgn(CONST PPOINT  pt,
 
 HRGN
 STDCALL
-W32kCreatePolyPolygonRgn(CONST PPOINT  pt,
+NtGdiCreatePolyPolygonRgn(CONST PPOINT  pt,
                                CONST PINT  PolyCounts,
                                INT  Count,
                                INT  PolyFillMode)
@@ -1488,39 +1575,49 @@ W32kCreatePolyPolygonRgn(CONST PPOINT  pt,
 
 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;
@@ -1530,18 +1627,18 @@ W32kCreateRectRgnIndirect(CONST PRECT rc)
     {
       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,
@@ -1553,12 +1650,12 @@ W32kCreateRoundRectRgn(INT  LeftRect,
 
 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)))
@@ -1601,7 +1698,7 @@ exit:
 
 HRGN
 STDCALL
-W32kExtCreateRegion(CONST PXFORM  Xform,
+NtGdiExtCreateRegion(CONST PXFORM  Xform,
                           DWORD  Count,
                           CONST PROSRGNDATA  RgnData)
 {
@@ -1617,16 +1714,37 @@ W32kExtCreateRegion(CONST PXFORM  Xform,
 
 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,
@@ -1636,7 +1754,7 @@ W32kFrameRgn(HDC  hDC,
 }
 
 INT STDCALL
-UnsafeW32kGetRgnBox(HRGN  hRgn,
+UnsafeIntGetRgnBox(HRGN  hRgn,
                    LPRECT  pRect)
 {
   PROSRGNDATA rgn = RGNDATA_LockRgn(hRgn);
@@ -1655,33 +1773,29 @@ UnsafeW32kGetRgnBox(HRGN  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;
@@ -1689,17 +1803,17 @@ W32kInvertRgn(HDC  hDC,
 
 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;
   }
 
@@ -1728,12 +1842,12 @@ W32kOffsetRgn(HRGN  hRgn,
 
 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;
@@ -1744,55 +1858,56 @@ W32kPaintRgn(HDC  hDC,
   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;
@@ -1810,20 +1925,14 @@ W32kPtInRegion(HRGN  hRgn,
 }
 
 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;
 
@@ -1846,7 +1955,23 @@ W32kRectInRegion(HRGN  hRgn,
 
 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,
@@ -1880,21 +2005,36 @@ W32kSetRectRgn(HRGN  hRgn,
   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);
 }
 
 /*!
@@ -1907,7 +2047,7 @@ W32kUnionRectWithRgn(HRGN hDest, const RECT* unsafeRect)
  *
  * 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 );
@@ -1938,4 +2078,4 @@ DWORD STDCALL W32kGetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
     RGNDATA_UnlockRgn( hrgn );
     return size + sizeof(RGNDATAHEADER);
 }
-
+/* EOF */