update for HEAD-2003091401
[reactos.git] / subsys / win32k / objects / region.c
index 161b8ad..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,9 +28,11 @@
 #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
+#define NDEBUG
 #include <win32k/debug1.h>
 
 BOOL STDCALL
@@ -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;
 
@@ -300,10 +324,8 @@ empty:
        return TRUE;
 }
 
-/***********************************************************************
- *           REGION_CropRgn
- *
- *
+/*!
+ * \param
  * hSrc:       Region to crop and offset.
  * lpRect:     Clipping rectangle. Can be NULL (no clipping).
  * lpPt:       Points to offset the cropped region. Can be NULL (no offset).
@@ -312,39 +334,33 @@ empty:
  *       Allowed to be the same region as hSrc in which case everything
  *      will be done in place, with no memory reallocations.
  *
- * Returns: hDst if success, 0 otherwise.
+ * \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 = RGNDATA_LockRgn(hSrc);
-  HRGN hNewDst;
-
-  if(objSrc)
-  {
-       PROSRGNDATA rgnDst;
+  PROSRGNDATA objSrc, rgnDst;
+  HRGN hNewDst, hRet = NULL;
+  GDIMULTILOCK Lock[2] = {{hDst, 0, GDI_OBJECT_TYPE_REGION}, {hSrc, 0, GDI_OBJECT_TYPE_REGION}};
 
-    if(hDst)
+  if( !hDst )
     {
-      if(!(rgnDst = RGNDATA_LockRgn(hDst)))
-      {
-        hDst = 0;
-        goto done;
-      }
+      if( !( hNewDst = RGNDATA_AllocRgn(1) ) )
+       {
+         return 0;
+       }
+      Lock[0].hObj = hNewDst;
     }
-       else{
-         if( !( hNewDst = RGNDATA_AllocRgn(1) ) ){
-               RGNDATA_UnlockRgn( hSrc );
-               return 0;
-         }
 
-      if(!(rgnDst = RGNDATA_LockRgn(hNewDst)))
-      {
-        RGNDATA_FreeRgn( hNewDst );
-               RGNDATA_UnlockRgn( hSrc );
-        return 0;
-      }
-       }
+  if ( !GDIOBJ_LockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0])) )
+    {
+      DPRINT1("GDIOBJ_LockMultipleObj() failed\n" );
+      return 0;
+    }
+  rgnDst = Lock[0].pObj;
+  objSrc = Lock[1].pObj;
 
+  if( objSrc && rgnDst )
+  {
     if(rgnDst)
     {
       POINT pt = { 0, 0 };
@@ -354,51 +370,32 @@ HRGN REGION_CropRgn(HRGN hDst, HRGN hSrc, const PRECT lpRect, PPOINT lpPt)
 
       if(REGION_CropAndOffsetRegion(lpPt, lpRect, objSrc, rgnDst) == FALSE)
          { // ve failed cleanup and return
-               RGNDATA_UnlockRgn( hSrc );
-
-               if(hDst) // unlock new region if allocated
-                 RGNDATA_UnlockRgn( hDst );
-               else
-                 RGNDATA_UnlockRgn( hNewDst );
-
-               return 0;
+               hRet = NULL;
       }
       else{ // ve are fine. unlock the correct pointer and return correct handle
-               RGNDATA_UnlockRgn( hSrc );
-
-               if(hDst == 0){
-                       RGNDATA_UnlockRgn( hNewDst );
-                       return hNewDst;
-               }
-               else {
-                       RGNDATA_UnlockRgn( hDst );
-                       return hDst;
-               }
+               hRet = Lock[0].hObj;
          }
     }
-done:
-       RGNDATA_UnlockRgn( hSrc );
   }
-  return 0;
+  GDIOBJ_UnlockMultipleObj(Lock, sizeof(Lock)/sizeof(Lock[0]));
+  return hRet;
 }
 
-/***********************************************************************
- *           REGION_Coalesce
- *
+/*!
  *      Attempt to merge the rects in the current band with those in the
  *      previous one. Used only by REGION_RegionOp.
  *
  * Results:
  *      The new index for the previous band.
  *
- * Side Effects:
+ * \note Side Effects:
  *      If coalescing takes place:
  *          - rectangles in the previous band will have their bottom fields
  *            altered.
  *          - 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 */
@@ -517,9 +514,7 @@ static INT REGION_Coalesce (
     return (curStart);
 }
 
-/***********************************************************************
- *           REGION_RegionOp
- *
+/*!
  *      Apply an operation to two regions. Called by REGION_Union,
  *      REGION_Inverse, REGION_Subtract, REGION_Intersect...
  *
@@ -529,8 +524,7 @@ static INT REGION_Coalesce (
  * Side Effects:
  *      The new region is overwritten.
  *
- * Notes:
- *      The idea behind this function is to view the two regions as sets.
+ *\note The idea behind this function is to view the two regions as sets.
  *      Together they cover a rectangle of area that this function divides
  *      into horizontal bands where points are covered only by one region
  *      or by both. For the first case, the nonOverlapFunc is called with
@@ -542,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 */
@@ -557,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:
@@ -668,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);
                    }
@@ -680,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);
                    }
@@ -739,7 +734,7 @@ static void REGION_RegionOp(
     curBand = newReg->rdh.nCount;
     if (r1 != r1End)
     {
-               if (nonOverlap1Func != (void (*)())NULL)
+               if (nonOverlap1Func != NULL)
                {
                    do
                    {
@@ -754,7 +749,7 @@ static void REGION_RegionOp(
                    } while (r1 != r1End);
                }
     }
-    else if ((r2 != r2End) && (nonOverlap2Func != (void (*)())NULL))
+    else if ((r2 != r2End) && (nonOverlap2Func != NULL))
     {
                do
                {
@@ -782,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))
                {
@@ -824,21 +819,26 @@ static void REGION_RegionOp(
  ***********************************************************************/
 
 
-/***********************************************************************
- *          REGION_IntersectO
- *
+/*!
  * Handle an overlapping band for REGION_Intersect.
  *
  * Results:
  *      None.
  *
- * Side Effects:
+ * \note Side Effects:
  *      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;
@@ -893,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
@@ -919,9 +919,7 @@ static void REGION_IntersectRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
  *          Region Union
  ***********************************************************************/
 
-/***********************************************************************
- *          REGION_UnionNonO
- *
+/*!
  *      Handle a non-overlapping band for the union operation. Just
  *      Adds the rectangles into the region. Doesn't have to check for
  *      subsumption or anything.
@@ -929,13 +927,19 @@ static void REGION_IntersectRegion(ROSRGNDATA *newReg, ROSRGNDATA *reg1,
  * Results:
  *      None.
  *
- * Side Effects:
+ * \note Side Effects:
  *      pReg->numRects is incremented and the final rectangles overwritten
  *      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;
 
@@ -955,22 +959,28 @@ static void REGION_UnionNonO (ROSRGNDATA *pReg, RECT *r, RECT *rEnd,
     return;
 }
 
-/***********************************************************************
- *          REGION_UnionO
- *
+/*!
  *      Handle an overlapping band for the union operation. Picks the
  *      left-most rectangle each time and merges it into the region.
  *
  * Results:
  *      None.
  *
- * Side Effects:
+ * \note Side Effects:
  *      Rectangles are overwritten in pReg->rects and pReg->numRects will
  *      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;
 
@@ -1028,86 +1038,102 @@ 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);
 }
 
 /***********************************************************************
  *          Region Subtraction
  ***********************************************************************/
 
-/***********************************************************************
- *          REGION_SubtractNonO1
- *
+/*!
  *      Deal with non-overlapping band for subtraction. Any parts from
  *      region 2 we discard. Anything from region 1 we add to the region.
  *
  * Results:
  *      None.
  *
- * Side Effects:
+ * \note Side Effects:
  *      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;
 
@@ -1128,21 +1154,27 @@ static void REGION_SubtractNonO1 (ROSRGNDATA *pReg, RECT *r, RECT *rEnd,
 }
 
 
-/***********************************************************************
- *          REGION_SubtractO
- *
+/*!
  *      Overlapping band subtraction. x1 is the left-most point not yet
  *      checked.
  *
  * Results:
  *      None.
  *
- * Side Effects:
+ * \note Side Effects:
  *      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;
@@ -1256,20 +1288,18 @@ static void REGION_SubtractO (ROSRGNDATA *pReg, RECT *r1, RECT *r1End,
     return;
 }
 
-/***********************************************************************
- *          REGION_SubtractRegion
- *
+/*!
  *      Subtract regS from regM and leave the result in regD.
  *      S stands for subtrahend, M for minuend and D for difference.
  *
  * Results:
  *      TRUE.
  *
- * Side Effects:
+ * \note Side Effects:
  *      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 */
@@ -1280,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
@@ -1296,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;
@@ -1307,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;
        }
 
@@ -1326,17 +1356,16 @@ static void REGION_XorRegion(ROSRGNDATA *dr, ROSRGNDATA *sra,
        RGNDATA_UnlockRgn( htra );
        RGNDATA_UnlockRgn( htrb );
 
-    W32kDeleteObject( htra );
-    W32kDeleteObject( htrb );
+    NtGdiDeleteObject( htra );
+    NtGdiDeleteObject( htrb );
     return;
 }
 
 
-/***********************************************************************
- *           REGION_UnionRectWithRegion
- *           Adds a rectangle to a WINEREGION
+/*!
+ * 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;
 
@@ -1348,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;
 
@@ -1363,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;
   }
@@ -1402,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);
@@ -1421,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;
@@ -1429,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)
@@ -1442,64 +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;
-  PROSRGNDATA destRgn = RGNDATA_LockRgn(hDest);
-
-  if( destRgn ){
-       PROSRGNDATA src1Rgn = RGNDATA_LockRgn(hSrc1);
-
-       if( src1Rgn ){
-               if (CombineMode == RGN_COPY)
-               {
-                 if( !REGION_CopyRegion(destRgn, src1Rgn) )
-                               return ERROR;
-                 result = destRgn->rdh.iType;
-               }
-               else
-               {
-                 PROSRGNDATA src2Rgn = RGNDATA_LockRgn(hSrc2);
-                 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;
-                         RGNDATA_UnlockRgn( hSrc2 );
-                 }
-                 RGNDATA_UnlockRgn( hSrc1 );
-               }
-               RGNDATA_UnlockRgn( hDest );
-       }
-       else{
-               DPRINT("W32kCombineRgn: hDest unavailable\n");
-               return ERROR;
-       }
-  }
+  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;
+
+  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("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)
@@ -1509,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)
 {
@@ -1525,7 +1565,7 @@ W32kCreatePolygonRgn(CONST PPOINT  pt,
 
 HRGN
 STDCALL
-W32kCreatePolyPolygonRgn(CONST PPOINT  pt,
+NtGdiCreatePolyPolygonRgn(CONST PPOINT  pt,
                                CONST PINT  PolyCounts,
                                INT  Count,
                                INT  PolyFillMode)
@@ -1535,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;
@@ -1577,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,
@@ -1600,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)))
@@ -1648,7 +1698,7 @@ exit:
 
 HRGN
 STDCALL
-W32kExtCreateRegion(CONST PXFORM  Xform,
+NtGdiExtCreateRegion(CONST PXFORM  Xform,
                           DWORD  Count,
                           CONST PROSRGNDATA  RgnData)
 {
@@ -1664,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,
@@ -1683,7 +1754,7 @@ W32kFrameRgn(HDC  hDC,
 }
 
 INT STDCALL
-UnsafeW32kGetRgnBox(HRGN  hRgn,
+UnsafeIntGetRgnBox(HRGN  hRgn,
                    LPRECT  pRect)
 {
   PROSRGNDATA rgn = RGNDATA_LockRgn(hRgn);
@@ -1702,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;
@@ -1736,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;
   }
 
@@ -1775,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;
@@ -1791,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;
@@ -1857,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;
 
@@ -1893,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,
@@ -1927,26 +2005,39 @@ 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;
 
-       if( !NT_SUCCESS( MmCopyFromCaller( pRect, unsafeRect, sizeof( RECT ) ) ) )
-               return NULL;
+  pRgn = RGNDATA_LockRgn(hDest);
+  if (NULL == pRgn)
+    {
+      SetLastWin32Error(ERROR_INVALID_HANDLE);
+      return NULL;
+    }
 
-       if( !(pRgn = RGNDATA_LockRgn( hDest ) ) )
-               return NULL;
+  REGION_UnionRectWithRegion(Rect, pRgn);
+  RGNDATA_UnlockRgn(hDest);
 
-       REGION_UnionRectWithRegion( pRect, pRgn );
-       RGNDATA_UnlockRgn( hDest );
-       return hDest;
+  return hDest;
 }
 
-/***********************************************************************
- *           GetRegionData   (GDI32.@)
- *
+HRGN STDCALL
+NtGdiUnionRectWithRgn(HRGN hDest, CONST PRECT UnsafeRect)
+{
+  RECT SafeRect;
+
+  if (! NT_SUCCESS(MmCopyFromCaller(&SafeRect, UnsafeRect, sizeof(RECT))))
+    {
+      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      return NULL;
+    }
+
+  return UnsafeIntUnionRectWithRgn(hDest, &SafeRect);
+}
+
+/*!
  * MSDN: GetRegionData, Return Values:
  *
  * "If the function succeeds and dwCount specifies an adequate number of bytes,
@@ -1956,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 );
@@ -1987,4 +2078,4 @@ DWORD STDCALL W32kGetRegionData(HRGN hrgn, DWORD count, LPRGNDATA rgndata)
     RGNDATA_UnlockRgn( hrgn );
     return size + sizeof(RGNDATAHEADER);
 }
-
+/* EOF */