[WIN32K]
[reactos.git] / reactos / win32ss / gdi / ntgdi / region.c
index d9965d8..4032c79 100644 (file)
@@ -114,6 +114,7 @@ SOFTWARE.
  */
 
 #include <win32k.h>
+#include <suppress.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -488,12 +489,12 @@ IntDumpRegion(HRGN hRgn)
 
 INT
 FASTCALL
-REGION_Complexity( PROSRGNDATA obj )
+REGION_Complexity(PREGION prgn)
 {
-    if (!obj) return NULLREGION;
-    switch(obj->rdh.nCount)
+    if (!prgn) return NULLREGION;
+    switch(prgn->rdh.nCount)
     {
-       DPRINT("Region Complexity -> %d",obj->rdh.nCount);
+       DPRINT("Region Complexity -> %lu", prgn->rdh.nCount);
        case 0:  return NULLREGION;
        case 1:  return SIMPLEREGION;
        default: return COMPLEXREGION;
@@ -580,13 +581,13 @@ REGION_SetExtents(ROSRGNDATA *pReg)
 /***********************************************************************
  *           REGION_CropAndOffsetRegion
  */
-BOOL FASTCALL
+INT
+FASTCALL
 REGION_CropAndOffsetRegion(
-    PROSRGNDATA rgnDst,
-    PROSRGNDATA rgnSrc,
+    PREGION rgnDst,
+    PREGION rgnSrc,
     const RECTL *rect,
-    const POINTL *offset
-)
+    const POINTL *offset) // FIXME: we should probably remove offset from here
 {
     POINT pt = {0,0};
     const POINT *off = offset;
@@ -601,13 +602,13 @@ REGION_CropAndOffsetRegion(
             if (off->x || off->y)
                 xrect = rgnDst->Buffer;
             else
-                return TRUE;
+                return REGION_Complexity(rgnDst);
         }
         else
         {
             xrect = ExAllocatePoolWithTag(PagedPool, rgnSrc->rdh.nCount * sizeof(RECT), TAG_REGION);
                        if(!xrect)
-                               return FALSE;
+                               return ERROR;
             if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
                 ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // Free the old buffer. Will be assigned to xrect below.
         }
@@ -668,7 +669,7 @@ REGION_CropAndOffsetRegion(
             PRECTL temp;
             temp = ExAllocatePoolWithTag(PagedPool, i * sizeof(RECT), TAG_REGION);
             if (!temp)
-                return FALSE;
+                return ERROR;
 
             if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
                 ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // free the old buffer
@@ -726,7 +727,7 @@ REGION_CropAndOffsetRegion(
         rgnDst->rdh.iType = RDH_RECTANGLES;
     }
 
-    return TRUE;
+    return REGION_Complexity(rgnDst);
 
 empty:
     if (!rgnDst->Buffer)
@@ -738,10 +739,10 @@ empty:
             rgnDst->rdh.nRgnSize = RGN_DEFAULT_RECTS * sizeof(RECT);
         }
         else
-            return FALSE;
+            return ERROR;
     }
     EMPTY_REGION(rgnDst);
-    return TRUE;
+    return NULLREGION;
 }
 
 
@@ -1772,6 +1773,23 @@ REGION_UnionRectWithRgn(
     REGION_UnionRegion(rgn, rgn, &region);
 }
 
+INT
+FASTCALL
+REGION_SubtractRectFromRgn(
+    PREGION prgnDest,
+    PREGION prgnSrc,
+    const RECTL *prcl)
+{
+    REGION rgnLocal;
+
+    rgnLocal.Buffer = &rgnLocal.rdh.rcBound;
+    rgnLocal.rdh.nCount = 1;
+    rgnLocal.rdh.nRgnSize = sizeof(RECT);
+    rgnLocal.rdh.rcBound = *prcl;
+    REGION_SubtractRegion(prgnDest, prgnSrc, &rgnLocal);
+    return REGION_Complexity(prgnDest);
+}
+
 BOOL FASTCALL
 REGION_CreateSimpleFrameRgn(
     PROSRGNDATA rgn,
@@ -1782,7 +1800,7 @@ REGION_CreateSimpleFrameRgn(
     RECTL rc[4];
     PRECTL prc;
 
-    if (x != 0 || y != 0)
+    if ((x != 0) || (y != 0))
     {
         prc = rc;
 
@@ -1841,6 +1859,7 @@ REGION_CreateSimpleFrameRgn(
                 return FALSE;
             }
 
+            _PRAGMA_WARNING_SUPPRESS(__WARNING_MAYBE_UNINIT_VAR) // rc is initialized
             COPY_RECTS(rgn->Buffer, rc, rgn->rdh.nCount);
         }
     }
@@ -1954,46 +1973,35 @@ REGION_CreateFrameRgn(
 }
 
 
+static
 BOOL FASTCALL
 REGION_LPTODP(
-    PDC  dc,
-    HRGN hDest,
-    HRGN hSrc)
+    _In_ PDC  dc,
+    _Inout_ PREGION RgnDest,
+    _In_ PREGION RgnSrc)
 {
     RECTL *pCurRect, *pEndRect;
-    PROSRGNDATA srcObj = NULL;
-    PROSRGNDATA destObj = NULL;
-
     RECTL tmpRect;
-    BOOL ret = FALSE;
     PDC_ATTR pdcattr;
 
     if (!dc)
-        return ret;
+        return FALSE;
     pdcattr = dc->pdcattr;
 
     if (pdcattr->iMapMode == MM_TEXT) // Requires only a translation
     {
-        if (NtGdiCombineRgn(hDest, hSrc, 0, RGN_COPY) == ERROR)
-            goto done;
+        if (IntGdiCombineRgn(RgnDest, RgnSrc, 0, RGN_COPY) == ERROR)
+            return FALSE;
 
-        NtGdiOffsetRgn(hDest, pdcattr->ptlViewportOrg.x - pdcattr->ptlWindowOrg.x,
+        IntGdiOffsetRgn(RgnDest, pdcattr->ptlViewportOrg.x - pdcattr->ptlWindowOrg.x,
                        pdcattr->ptlViewportOrg.y - pdcattr->ptlWindowOrg.y);
-        ret = TRUE;
-        goto done;
+        return TRUE;
     }
 
-    if ( !(srcObj = RGNOBJAPI_Lock(hSrc, NULL)) )
-        goto done;
-    if ( !(destObj = RGNOBJAPI_Lock(hDest, NULL)) )
-    {
-        RGNOBJAPI_Unlock(srcObj);
-        goto done;
-    }
-    EMPTY_REGION(destObj);
+    EMPTY_REGION(RgnDest);
 
-    pEndRect = srcObj->Buffer + srcObj->rdh.nCount;
-    for (pCurRect = srcObj->Buffer; pCurRect < pEndRect; pCurRect++)
+    pEndRect = RgnSrc->Buffer + RgnSrc->rdh.nCount;
+    for (pCurRect = RgnSrc->Buffer; pCurRect < pEndRect; pCurRect++)
     {
         tmpRect = *pCurRect;
         tmpRect.left = XLPTODP(pdcattr, tmpRect.left);
@@ -2014,15 +2022,10 @@ REGION_LPTODP(
             tmpRect.bottom = tmp;
         }
 
-        REGION_UnionRectWithRgn(destObj, &tmpRect);
+        REGION_UnionRectWithRgn(RgnDest, &tmpRect);
     }
-    ret = TRUE;
-
-    RGNOBJAPI_Unlock(srcObj);
-    RGNOBJAPI_Unlock(destObj);
 
-done:
-    return ret;
+    return TRUE;
 }
 
 PROSRGNDATA
@@ -2162,6 +2165,7 @@ REGION_vSyncRegion(PREGION pRgn)
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
+            (void)0;
         }
         _SEH2_END;
      }
@@ -2210,6 +2214,7 @@ RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
+            (void)0;
         }
         _SEH2_END;
      }
@@ -2232,7 +2237,7 @@ IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
     PREGION prgn;
 
     /* Allocate a region, witout a handle */
-    prgn = (PREGION)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE, sizeof(REGION), 0);
+    prgn = (PREGION)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE, sizeof(REGION), BASEFLAG_LOOKASIDE);
     if (!prgn)
     {
         return NULL;
@@ -2246,33 +2251,8 @@ IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
     return prgn;
 }
 
-HRGN
-FASTCALL
-IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
-{
-    PREGION prgn;
-    HRGN hrgn;
-
-    /* Allocate a region, witout a handle */
-    prgn = (PREGION)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION, sizeof(REGION));
-    if (!prgn)
-    {
-        return NULL;
-    }
-
-    /* Initialize it */
-    prgn->Buffer = &prgn->rdh.rcBound;
-    REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
-    hrgn = prgn->BaseObject.hHmgr;
-    prgn->prgnattr = &prgn->rgnattr;
-
-    REGION_UnlockRgn(prgn);
-
-    return hrgn;
-}
-
-BOOL NTAPI
-REGION_Cleanup(PVOID ObjectBody)
+VOID NTAPI
+REGION_vCleanup(PVOID ObjectBody)
 {
     PROSRGNDATA pRgn = (PROSRGNDATA)ObjectBody;
     PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
@@ -2284,7 +2264,6 @@ REGION_Cleanup(PVOID ObjectBody)
 
     if (pRgn->Buffer && pRgn->Buffer != &pRgn->rdh.rcBound)
         ExFreePoolWithTag(pRgn->Buffer, TAG_REGION);
-    return TRUE;
 }
 
 VOID FASTCALL
@@ -2297,11 +2276,13 @@ REGION_Delete(PROSRGNDATA pRgn)
 VOID FASTCALL
 IntGdiReleaseRaoRgn(PDC pDC)
 {
-  INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
-  PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
-  pDC->fs |= DC_FLAG_DIRTY_RAO;
-  Entry->Flags |= GDI_ENTRY_VALIDATE_VIS;
-  RECTL_vSetEmptyRect(&pDC->erclClip);
+    INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
+    PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
+    pDC->fs |= DC_FLAG_DIRTY_RAO;
+    Entry->Flags |= GDI_ENTRY_VALIDATE_VIS;
+    RECTL_vSetEmptyRect(&pDC->erclClip);
+    REGION_Delete(pDC->prgnRao);
+    pDC->prgnRao = NULL;
 }
 
 VOID FASTCALL
@@ -2359,23 +2340,22 @@ IntGdiSetRegionOwner(HRGN hRgn, DWORD OwnerMask)
     PRGN_ATTR prgnattr;
     PPROCESSINFO ppi;
 
-    prgn = REGION_LockRgn(hRgn);
+    prgn = RGNOBJAPI_Lock(hRgn, &prgnattr);
     if (!prgn)
     {
         return FALSE;
     }
 
-    prgnattr = GDIOBJ_pvGetObjectAttr(&prgn->BaseObject);
-    if (prgnattr)
+    if (prgnattr != &prgn->rgnattr)
     {
         GDIOBJ_vSetObjectAttr(&prgn->BaseObject, NULL);
-        prgn->prgnattr = NULL;
+        prgn->prgnattr = &prgn->rgnattr;
         ppi = PsGetCurrentProcessWin32Process();
         GdiPoolFree(ppi->pPoolRgnAttr, prgnattr);
     }
     RGNOBJAPI_Unlock(prgn);
 
-     return GreSetObjectOwner(hRgn, OwnerMask);
+    return GreSetObjectOwner(hRgn, OwnerMask);
 }
 
 INT
@@ -2474,45 +2454,42 @@ BOOL
 FASTCALL
 IntGdiPaintRgn(
     PDC dc,
-    HRGN hRgn
+    PREGION Rgn
 )
 {
-    HRGN tmpVisRgn;
-    PROSRGNDATA visrgn;
-    CLIPOBJ* ClipRegion;
+    PROSRGNDATA VisRgn;
+    XCLIPOBJ ClipRegion;
     BOOL bRet = FALSE;
     POINTL BrushOrigin;
     SURFACE *psurf;
     PDC_ATTR pdcattr;
 
-    if (!dc) return FALSE;
+    if (!dc || !Rgn)
+        return FALSE;
+
     pdcattr = dc->pdcattr;
 
     ASSERT(!(pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)));
 
-    if (!(tmpVisRgn = IntSysCreateRectRgn(0, 0, 0, 0))) return FALSE;
-
-    // Transform region into device co-ords
-    if (!REGION_LPTODP(dc, tmpVisRgn, hRgn) ||
-         NtGdiOffsetRgn(tmpVisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
+    VisRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
+    if (!VisRgn)
     {
-        GreDeleteObject(tmpVisRgn);
         return FALSE;
     }
 
-    NtGdiCombineRgn(tmpVisRgn, tmpVisRgn, dc->rosdc.hGCClipRgn, RGN_AND);
-
-    visrgn = RGNOBJAPI_Lock(tmpVisRgn, NULL);
-    if (visrgn == NULL)
+    // Transform region into device co-ords
+    if (!REGION_LPTODP(dc, VisRgn, Rgn) ||
+         IntGdiOffsetRgn(VisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
     {
-        GreDeleteObject(tmpVisRgn);
+        REGION_Delete(VisRgn);
         return FALSE;
     }
 
-    ClipRegion = IntEngCreateClipRegion(visrgn->rdh.nCount,
-                                        visrgn->Buffer,
-                                        &visrgn->rdh.rcBound );
-    ASSERT(ClipRegion);
+    if (dc->prgnRao)
+        IntGdiCombineRgn(VisRgn, VisRgn, dc->prgnRao, RGN_AND);
+
+    IntEngInitClipObj(&ClipRegion);
+    IntEngUpdateClipRegion(&ClipRegion, VisRgn->rdh.nCount, VisRgn->Buffer, &VisRgn->rdh.rcBound );
 
     BrushOrigin.x = pdcattr->ptlBrushOrigin.x;
     BrushOrigin.y = pdcattr->ptlBrushOrigin.y;
@@ -2520,18 +2497,41 @@ IntGdiPaintRgn(
     /* FIXME: Handle psurf == NULL !!!! */
 
     bRet = IntEngPaint(&psurf->SurfObj,
-                       ClipRegion,
+                       &ClipRegion.ClipObj,
                        &dc->eboFill.BrushObject,
                        &BrushOrigin,
                        0xFFFF); // FIXME: Don't know what to put here
 
-    RGNOBJAPI_Unlock(visrgn);
-    GreDeleteObject(tmpVisRgn);
+    REGION_Delete(VisRgn);
+    IntEngFreeClipResources(&ClipRegion);
 
     // Fill the region
     return bRet;
 }
 
+BOOL
+FASTCALL
+REGION_PtInRegion(
+    PREGION prgn,
+    INT X,
+    INT Y)
+{
+    ULONG i;
+    PRECT r;
+
+    if (prgn->rdh.nCount > 0 && INRECT(prgn->rdh.rcBound, X, Y))
+    {
+        r =  prgn->Buffer;
+        for (i = 0; i < prgn->rdh.nCount; i++)
+        {
+            if (INRECT(r[i], X, Y))
+                return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
 BOOL
 FASTCALL
 REGION_RectInRegion(
@@ -2879,7 +2879,7 @@ REGION_FreeStorage(ScanLineListBlock *pSLLBlock)
     while (pSLLBlock)
     {
         tmpSLLBlock = pSLLBlock->next;
-        ExFreePool(pSLLBlock);
+        ExFreePoolWithTag(pSLLBlock, TAG_REGION);
         pSLLBlock = tmpSLLBlock;
     }
 }
@@ -2908,6 +2908,12 @@ REGION_PtsToRegion(
 
     numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
 
+    /* Make sure, we have at least one rect */
+    if (numRects == 0)
+    {
+        numRects = 1;
+    }
+
     if (!(temp = ExAllocatePoolWithTag(PagedPool, numRects * sizeof(RECT), TAG_REGION)))
     {
         return 0;
@@ -3095,16 +3101,15 @@ REGION_CreateETandAET(
     }
 }
 
-HRGN FASTCALL
-IntCreatePolyPolygonRgn(
+BOOL FASTCALL
+IntSetPolyPolygonRgn(
     POINT *Pts,
     PULONG Count,
     INT nbpolygons,
-    INT mode
+    INT mode,
+    PREGION Rgn
 )
 {
-    HRGN hrgn;
-    ROSRGNDATA *region;
     EdgeTableEntry *pAET;                       /* Active Edge Table        */
     INT y;                                      /* Current scanline         */
     int iPts = 0;                               /* Number of pts in buffer  */
@@ -3124,10 +3129,6 @@ IntCreatePolyPolygonRgn(
 
     if (mode == 0 || mode > 2) return 0;
 
-    if (!(region = REGION_AllocUserRgnWithHandle(nbpolygons)))
-        return 0;
-    hrgn = region->BaseObject.hHmgr;
-
     /* Special case a rectangle */
 
     if (((nbpolygons == 1) && ((*Count == 4) ||
@@ -3141,18 +3142,19 @@ IntCreatePolyPolygonRgn(
               (Pts[2].x == Pts[3].x) &&
               (Pts[3].y == Pts[0].y))))
     {
-        RGNOBJAPI_Unlock(region);
-        NtGdiSetRectRgn(hrgn, min(Pts[0].x, Pts[2].x), min(Pts[0].y, Pts[2].y),
-                        max(Pts[0].x, Pts[2].x), max(Pts[0].y, Pts[2].y));
-        return hrgn;
+        REGION_SetRectRgn(Rgn,
+            min(Pts[0].x, Pts[2].x),
+            min(Pts[0].y, Pts[2].y),
+            max(Pts[0].x, Pts[2].x),
+            max(Pts[0].y, Pts[2].y));
+        return TRUE;
     }
 
     for (poly = total = 0; poly < nbpolygons; poly++)
         total += Count[poly];
     if (! (pETEs = ExAllocatePoolWithTag(PagedPool, sizeof(EdgeTableEntry) * total, TAG_REGION)) )
     {
-        GreDeleteObject(hrgn);
-        return 0;
+        return FALSE;
     }
     pts = FirstPtBlock.pts;
     REGION_CreateETandAET(Count, nbpolygons, Pts, &ET, &AET, pETEs, &SLLBlock);
@@ -3196,7 +3198,7 @@ IntCreatePolyPolygonRgn(
                     {
                         DPRINT1("Can't alloc tPB\n");
                         ExFreePoolWithTag(pETEs, TAG_REGION);
-                        return 0;
+                        return FALSE;
                     }
                     curPtBlock->next = tmpPtBlock;
                     curPtBlock = tmpPtBlock;
@@ -3255,8 +3257,7 @@ IntCreatePolyPolygonRgn(
                         {
                             DPRINT1("Can't alloc tPB\n");
                             ExFreePoolWithTag(pETEs, TAG_REGION);
-                            GreDeleteObject(hrgn);
-                            return 0;
+                            return FALSE;
                         }
                         curPtBlock->next = tmpPtBlock;
                         curPtBlock = tmpPtBlock;
@@ -3281,7 +3282,7 @@ IntCreatePolyPolygonRgn(
         }
     }
     REGION_FreeStorage(SLLBlock.next);
-    REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
+    REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, Rgn);
 
     for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;)
     {
@@ -3290,8 +3291,7 @@ IntCreatePolyPolygonRgn(
         curPtBlock = tmpPtBlock;
     }
     ExFreePoolWithTag(pETEs, TAG_REGION);
-    RGNOBJAPI_Unlock(region);
-    return hrgn;
+    return TRUE;
 }
 
 BOOL
@@ -3346,7 +3346,7 @@ NtGdiCombineRgn(
     ahrgn[0] = hrgnDst;
     ahrgn[1] = hrgnSrc1;
     ahrgn[2] = iMode != RGN_COPY ? hrgnSrc2 : NULL;
-    if (!GDIOBJ_bLockMultipleObjects(3, ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
+    if (!GDIOBJ_bLockMultipleObjects(3, (HGDIOBJ*)ahrgn, (PVOID*)aprgn, GDIObjType_RGN_TYPE))
     {
         DPRINT1("NtGdiCombineRgn: %p, %p, %p, %d\n",
                 hrgnDst, hrgnSrc1, hrgnSrc2, iMode);
@@ -3398,6 +3398,8 @@ NtGdiCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
     REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
     RGNOBJAPI_Unlock(pRgn);
 
+    DPRINT("Returning %p.\n", hRgn);
+
     return hRgn;
 }
 
@@ -3589,6 +3591,8 @@ NtGdiExtCreateRegion(
     DWORD nCount = 0;
     DWORD iType = 0;
     DWORD dwSize = 0;
+       UINT i;
+       RECT* rects;
     NTSTATUS Status = STATUS_SUCCESS;
     MATRIX matrix;
     XFORMOBJ xo;
@@ -3600,6 +3604,7 @@ NtGdiExtCreateRegion(
         nCount = RgnData->rdh.nCount;
         iType = RgnData->rdh.iType;
         dwSize = RgnData->rdh.dwSize;
+               rects = (RECT*)RgnData->Buffer;
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -3631,6 +3636,11 @@ NtGdiExtCreateRegion(
 
     _SEH2_TRY
     {
+               /* Insert the rectangles one by one */
+               for(i=0; i<nCount; i++)
+               {
+                       REGION_UnionRectWithRgn(Region, &rects[i]);
+               }
         if (Xform)
         {
             ULONG ret;
@@ -3646,21 +3656,14 @@ NtGdiExtCreateRegion(
                 /* Apply the coordinate transformation on the rects */
                 if (XFORMOBJ_bApplyXform(&xo,
                                          XF_LTOL,
-                                         nCount * 2,
-                                         RgnData->Buffer,
+                                         Region->rdh.nCount * 2,
+                                         Region->Buffer,
                                          Region->Buffer))
                 {
                     Status = STATUS_SUCCESS;
                 }
             }
         }
-        else
-        {
-            /* Copy rect coordinates */
-            RtlCopyMemory(Region->Buffer,
-                          RgnData->Buffer,
-                          nCount * sizeof(RECT));
-        }
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -3727,7 +3730,7 @@ NtGdiFrameRgn(
     HRGN FrameRgn;
     BOOL Ret;
 
-    if (!(FrameRgn = IntSysCreateRectRgn(0, 0, 0, 0)))
+    if (!(FrameRgn = NtGdiCreateRectRgn(0, 0, 0, 0)))
     {
         return FALSE;
     }
@@ -3829,7 +3832,7 @@ NtGdiOffsetRgn(
     PROSRGNDATA rgn = RGNOBJAPI_Lock(hRgn, NULL);
     INT ret;
 
-    DPRINT("NtGdiOffsetRgn: hRgn %d Xoffs %d Yoffs %d rgn %x\n", hRgn, XOffset, YOffset, rgn );
+    DPRINT("NtGdiOffsetRgn: hRgn %p Xoffs %d Yoffs %d rgn %p\n", hRgn, XOffset, YOffset, rgn );
 
     if (!rgn)
     {
@@ -3851,28 +3854,16 @@ NtGdiPtInRegion(
     INT Y
 )
 {
-    PROSRGNDATA rgn;
-    ULONG i;
-    PRECTL r;
+    PREGION prgn;
+    BOOL ret;
 
-    if (!(rgn = RGNOBJAPI_Lock(hRgn, NULL) ) )
+    if (!(prgn = RGNOBJAPI_Lock(hRgn, NULL) ) )
         return FALSE;
 
-    if (rgn->rdh.nCount > 0 && INRECT(rgn->rdh.rcBound, X, Y))
-    {
-        r =  rgn->Buffer;
-        for (i = 0; i < rgn->rdh.nCount; i++)
-        {
-            if (INRECT(*r, X, Y))
-            {
-                RGNOBJAPI_Unlock(rgn);
-                return TRUE;
-            }
-            r++;
-        }
-    }
-    RGNOBJAPI_Unlock(rgn);
-    return FALSE;
+    ret = REGION_PtInRegion(prgn, X, Y);
+
+    RGNOBJAPI_Unlock(prgn);
+    return ret;
 }
 
 BOOL
@@ -3978,51 +3969,60 @@ NtGdiUnionRectWithRgn(
  *
  * If the function fails, the return value is zero."
  */
-DWORD APIENTRY
+_Success_(return!=0)
+ULONG
+APIENTRY
 NtGdiGetRegionData(
-    HRGN hrgn,
-    DWORD count,
-    LPRGNDATA rgndata
-)
+    _In_ HRGN hrgn,
+    _In_ ULONG cjBuffer,
+    _Out_opt_bytecap_(cjBuffer) LPRGNDATA lpRgnData)
 {
-    DWORD size;
-    PROSRGNDATA obj = RGNOBJAPI_Lock(hrgn, NULL);
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    if (!obj)
-        return 0;
+    ULONG cjRects, cjSize;
+    PREGION prgn;
 
-    size = obj->rdh.nCount * sizeof(RECT);
-    if (count < (size + sizeof(RGNDATAHEADER)) || rgndata == NULL)
+    /* Lock the region */
+    prgn = RGNOBJAPI_Lock(hrgn, NULL);
+    if (!prgn)
     {
-        RGNOBJAPI_Unlock(obj);
-        if (rgndata) /* Buffer is too small, signal it by return 0 */
-            return 0;
-        else         /* User requested buffer size with rgndata NULL */
-            return size + sizeof(RGNDATAHEADER);
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return 0;
     }
 
-    _SEH2_TRY
-    {
-        ProbeForWrite(rgndata, count, 1);
-        RtlCopyMemory(rgndata, &obj->rdh, sizeof(RGNDATAHEADER));
-        RtlCopyMemory(rgndata->Buffer, obj->Buffer, size);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        Status = _SEH2_GetExceptionCode();
-    }
-    _SEH2_END;
+    /* Calculate the region sizes */
+    cjRects = prgn->rdh.nCount * sizeof(RECT);
+    cjSize = cjRects + sizeof(RGNDATAHEADER);
 
-    if (!NT_SUCCESS(Status))
+    /* Check if region data is requested */
+    if (lpRgnData)
     {
-        SetLastNtError(Status);
-        RGNOBJAPI_Unlock(obj);
-        return 0;
+        /* Check if the buffer is large enough */
+        if (cjBuffer >= cjSize)
+        {
+            /* Probe the buffer and copy the data */
+            _SEH2_TRY
+            {
+                ProbeForWrite(lpRgnData, cjSize, sizeof(ULONG));
+                RtlCopyMemory(lpRgnData, &prgn->rdh, sizeof(RGNDATAHEADER));
+                RtlCopyMemory(lpRgnData->Buffer, prgn->Buffer, cjRects);
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                EngSetLastError(ERROR_INVALID_PARAMETER);
+                cjSize = 0;
+            }
+            _SEH2_END;
+        }
+        else
+        {
+            /* Buffer is too small */
+            EngSetLastError(ERROR_INVALID_PARAMETER);
+            cjSize = 0;
+        }
     }
 
-    RGNOBJAPI_Unlock(obj);
-    return size + sizeof(RGNDATAHEADER);
+    /* Unlock the region and return the size */
+    RGNOBJAPI_Unlock(prgn);
+    return cjSize;
 }
 
 /* EOF */