[CMAKE]
[reactos.git] / subsystems / win32 / win32k / objects / cliprgn.c
index 09a237e..532d766 100644 (file)
@@ -17,7 +17,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -26,47 +26,53 @@ int FASTCALL
 CLIPPING_UpdateGCRegion(DC* Dc)
 {
    PROSRGNDATA CombinedRegion;
-   HRGN hRgnVis = NULL;
+   HRGN hRgnVis;
+   PREGION prgnClip, prgnGCClip;
 
     // would prefer this, but the rest of the code sucks
 //    ASSERT(Dc->rosdc.hGCClipRgn);
 //    ASSERT(Dc->rosdc.hClipRgn);
-   if (!Dc->prgnVis)
-   {
-      DPRINT1("Warning, prgnVis is NULL!\n");
-   }
-   else
-   {
-       hRgnVis = ((PROSRGNDATA)Dc->prgnVis)->BaseObject.hHmgr ;
-   }
-
+   ASSERT(Dc->prgnVis);
+   hRgnVis = Dc->prgnVis->BaseObject.hHmgr;
 
    if (Dc->rosdc.hGCClipRgn == NULL)
       Dc->rosdc.hGCClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
 
+   prgnGCClip = REGION_LockRgn(Dc->rosdc.hGCClipRgn);
+   ASSERT(prgnGCClip);
+
    if (Dc->rosdc.hClipRgn == NULL)
-      NtGdiCombineRgn(Dc->rosdc.hGCClipRgn, ((PROSRGNDATA)Dc->prgnVis)->BaseObject.hHmgr, 0, RGN_COPY);
-   else // FYI: Vis == NULL! source of "IntGdiCombineRgn requires hSrc2 != NULL for combine mode 1!"
-      NtGdiCombineRgn(Dc->rosdc.hGCClipRgn, Dc->rosdc.hClipRgn, hRgnVis, RGN_AND);
+      IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, NULL, RGN_COPY);
+   else
+   {
+      prgnClip = REGION_LockRgn(Dc->rosdc.hClipRgn); // FIXME: locking order, ugh
+      IntGdiCombineRgn(prgnGCClip, Dc->prgnVis, prgnClip, RGN_AND);
+      REGION_UnlockRgn(prgnClip);
+   }
+   REGION_UnlockRgn(prgnGCClip);
+
    NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);
 
    if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
    {
-     if (Dc->rosdc.CombinedClip != NULL)
-        IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
+     CLIPOBJ *CombinedClip;
 
-     Dc->rosdc.CombinedClip = IntEngCreateClipRegion(
-        CombinedRegion->rdh.nCount,
+     CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
         CombinedRegion->Buffer,
         &CombinedRegion->rdh.rcBound);
 
      RGNOBJAPI_Unlock(CombinedRegion);
-   }
 
-   if ( NULL == Dc->rosdc.CombinedClip )
-   {
+     if ( !CombinedClip )
+     {
        DPRINT1("IntEngCreateClipRegion() failed\n");
        return ERROR;
+     }
+
+     if(Dc->rosdc.CombinedClip != NULL)
+       IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
+
+      Dc->rosdc.CombinedClip = CombinedClip ;
    }
 
    return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y);
@@ -77,30 +83,29 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn)
 {
   int retval;
   DC *dc;
+  PREGION prgn;
 
   if (!hrgn)
   {
-       SetLastWin32Error(ERROR_INVALID_PARAMETER);
+       EngSetLastError(ERROR_INVALID_PARAMETER);
        return ERROR;
   }
   if (!(dc = DC_LockDc(hdc)))
   {
-       SetLastWin32Error(ERROR_INVALID_HANDLE);
+       EngSetLastError(ERROR_INVALID_HANDLE);
        return ERROR;
   }
 
   dc->fs &= ~DC_FLAG_DIRTY_RAO;
 
-  if (dc->prgnVis == NULL)
-  {
-    dc->prgnVis = IntSysCreateRectpRgn(0, 0, 0, 0);
-    GDIOBJ_CopyOwnership(hdc, ((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr);
-  }
+  ASSERT (dc->prgnVis != NULL);
 
-  retval = NtGdiCombineRgn(((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr, hrgn, 0, RGN_COPY);
+  prgn = RGNOBJAPI_Lock(hrgn, NULL);
+  retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR;
+  RGNOBJAPI_Unlock(prgn);
   if ( retval != ERROR )
   {
-    NtGdiOffsetRgn(((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
+    IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
     CLIPPING_UpdateGCRegion(dc);
   }
   DC_UnlockDc(dc);
@@ -121,13 +126,13 @@ int FASTCALL GdiExtSelectClipRgn(PDC dc,
     {
       if (dc->rosdc.hClipRgn != NULL)
       {
-        REGION_FreeRgnByHandle(dc->rosdc.hClipRgn);
+        GreDeleteObject(dc->rosdc.hClipRgn);
         dc->rosdc.hClipRgn = NULL;
       }
     }
     else
     {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      EngSetLastError(ERROR_INVALID_PARAMETER);
       return ERROR;
     }
   }
@@ -135,12 +140,10 @@ int FASTCALL GdiExtSelectClipRgn(PDC dc,
   {
     if (!dc->rosdc.hClipRgn)
     {
-      PROSRGNDATA Rgn;
       RECTL rect;
-      if((Rgn = RGNOBJAPI_Lock(((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr, NULL)))
+      if(dc->prgnVis)
       {
-        REGION_GetRgnBox(Rgn, &rect);
-        RGNOBJAPI_Unlock(Rgn);
+               REGION_GetRgnBox(dc->prgnVis, &rect);
         dc->rosdc.hClipRgn = IntSysCreateRectRgnIndirect(&rect);
       }
       else
@@ -169,7 +172,7 @@ int APIENTRY NtGdiExtSelectClipRgn(HDC  hDC,
 
   if (!(dc = DC_LockDc(hDC)))
   {
-       SetLastWin32Error(ERROR_INVALID_HANDLE);
+       EngSetLastError(ERROR_INVALID_HANDLE);
        return ERROR;
   }
 
@@ -182,22 +185,54 @@ int APIENTRY NtGdiExtSelectClipRgn(HDC  hDC,
 INT FASTCALL
 GdiGetClipBox(HDC hDC, PRECTL rc)
 {
-   PROSRGNDATA Rgn;
    INT retval;
    PDC dc;
+   PROSRGNDATA pRgnNew, pRgn = NULL;
+   BOOL Unlock = FALSE; //Small hack
 
    if (!(dc = DC_LockDc(hDC)))
    {
       return ERROR;
    }
 
-   if (!(Rgn = RGNOBJAPI_Lock(dc->rosdc.hGCClipRgn, NULL)))
+   /* FIXME! Rao and Vis only! */
+   if (dc->prgnAPI) // APIRGN
+   {
+      pRgn = dc->prgnAPI;
+   }
+   else if (dc->dclevel.prgnMeta) // METARGN
+   {
+      pRgn = dc->dclevel.prgnMeta;
+   }
+   else if (dc->rosdc.hClipRgn)
+   {
+          Unlock = TRUE ;
+       pRgn = REGION_LockRgn(dc->rosdc.hClipRgn); // CLIPRGN
+   }
+
+   if (pRgn)
    {
+      pRgnNew = IntSysCreateRectpRgn( 0, 0, 0, 0 );
+
+         if (!pRgnNew)
+      {
+         DC_UnlockDc(dc);
+                if(Unlock) REGION_UnlockRgn(pRgn);
+         return ERROR;
+      }
+
+      IntGdiCombineRgn(pRgnNew, dc->prgnVis, pRgn, RGN_AND);
+
+      retval = REGION_GetRgnBox(pRgnNew, rc);
+
+         REGION_Delete(pRgnNew);
+
       DC_UnlockDc(dc);
-      return ERROR;
+         if(Unlock) REGION_UnlockRgn(pRgn);
+      return retval;
    }
-   retval = REGION_GetRgnBox(Rgn, rc);
-   RGNOBJAPI_Unlock(Rgn);
+
+   retval = REGION_GetRgnBox(dc->prgnVis, rc);
    IntDPtoLP(dc, (LPPOINT)rc, 2);
    DC_UnlockDc(dc);
 
@@ -243,12 +278,12 @@ int APIENTRY NtGdiExcludeClipRect(HDC  hDC,
 {
    INT Result;
    RECTL Rect;
-   HRGN NewRgn;
+   PREGION prgnNew, prgnClip;
    PDC dc = DC_LockDc(hDC);
 
    if (!dc)
    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
+      EngSetLastError(ERROR_INVALID_HANDLE);
       return ERROR;
    }
 
@@ -259,8 +294,8 @@ int APIENTRY NtGdiExcludeClipRect(HDC  hDC,
 
    IntLPtoDP(dc, (LPPOINT)&Rect, 2);
 
-   NewRgn = IntSysCreateRectRgnIndirect(&Rect);
-   if (!NewRgn)
+   prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
+   if (!prgnNew)
    {
       Result = ERROR;
    }
@@ -269,14 +304,18 @@ int APIENTRY NtGdiExcludeClipRect(HDC  hDC,
       if (!dc->rosdc.hClipRgn)
       {
          dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
-         NtGdiCombineRgn(dc->rosdc.hClipRgn, ((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr, NewRgn, RGN_DIFF);
+         prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
+         IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
+         REGION_UnlockRgn(prgnClip);
          Result = SIMPLEREGION;
       }
       else
       {
-         Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_DIFF);
+         prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
+         Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF);
+         REGION_UnlockRgn(prgnClip);
       }
-      REGION_FreeRgnByHandle(NewRgn);
+      REGION_Delete(prgnNew);
    }
    if (Result != ERROR)
       CLIPPING_UpdateGCRegion(dc);
@@ -302,7 +341,7 @@ int APIENTRY NtGdiIntersectClipRect(HDC  hDC,
 
    if (!dc)
    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
+      EngSetLastError(ERROR_INVALID_HANDLE);
       return ERROR;
    }
 
@@ -326,7 +365,7 @@ int APIENTRY NtGdiIntersectClipRect(HDC  hDC,
    else
    {
       Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_AND);
-      REGION_FreeRgnByHandle(NewRgn);
+      GreDeleteObject(NewRgn);
    }
    if (Result != ERROR)
       CLIPPING_UpdateGCRegion(dc);
@@ -345,7 +384,7 @@ int APIENTRY NtGdiOffsetClipRgn(HDC  hDC,
 
   if(!(dc = DC_LockDc(hDC)))
   {
-    SetLastWin32Error(ERROR_INVALID_HANDLE);
+    EngSetLastError(ERROR_INVALID_HANDLE);
     return ERROR;
   }
 
@@ -374,7 +413,7 @@ BOOL APIENTRY NtGdiPtVisible(HDC  hDC,
 
   if(!(dc = DC_LockDc(hDC)))
   {
-    SetLastWin32Error(ERROR_INVALID_HANDLE);
+    EngSetLastError(ERROR_INVALID_HANDLE);
     return FALSE;
   }
 
@@ -395,7 +434,7 @@ BOOL APIENTRY NtGdiRectVisible(HDC  hDC,
 
    if (!dc)
    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
+      EngSetLastError(ERROR_INVALID_HANDLE);
       return FALSE;
    }
 
@@ -444,7 +483,7 @@ IntGdiSetMetaRgn(PDC pDC)
   {
      if ( pDC->dclevel.prgnClip )
      {
-        TempRgn = IntSysCreateRectRgn(0,0,0,0);
+        TempRgn = IntSysCreateRectpRgn(0,0,0,0);
         if (TempRgn)
         {
            Ret = IntGdiCombineRgn( TempRgn,
@@ -453,13 +492,13 @@ IntGdiSetMetaRgn(PDC pDC)
                                    RGN_AND);
            if ( Ret )
            {
-              GDIOBJ_ShareUnlockObjByPtr(pDC->dclevel.prgnMeta);
+              GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnMeta->BaseObject);
               if (!((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.ulShareCount)
                  REGION_Delete(pDC->dclevel.prgnMeta);
 
               pDC->dclevel.prgnMeta = TempRgn;
 
-              GDIOBJ_ShareUnlockObjByPtr(pDC->dclevel.prgnClip);
+              GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnClip->BaseObject);
               if (!((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.ulShareCount)
                  REGION_Delete(pDC->dclevel.prgnClip);
 
@@ -496,7 +535,7 @@ int APIENTRY NtGdiSetMetaRgn(HDC  hDC)
 
   if (!pDC)
   {
-     SetLastWin32Error(ERROR_INVALID_PARAMETER);
+     EngSetLastError(ERROR_INVALID_PARAMETER);
      return ERROR;
   }
   Ret = IntGdiSetMetaRgn(pDC);
@@ -510,56 +549,76 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC)
 {
   CLIPOBJ * co;
 
-  if (!pDC->prgnVis) return 0;
+  /* Must have VisRgn set to a valid state! */
+  ASSERT (pDC->prgnVis);
 
   if (pDC->prgnAPI)
   {
      REGION_Delete(pDC->prgnAPI);
-     pDC->prgnAPI = IntSysCreateRectRgn(0,0,0,0);
+     pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
   }
 
   if (pDC->prgnRao)
   {
      REGION_Delete(pDC->prgnRao);
-     pDC->prgnRao = IntSysCreateRectRgn(0,0,0,0);
+     pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
   }
 
   if (pDC->dclevel.prgnMeta && pDC->dclevel.prgnClip)
   {
      IntGdiCombineRgn( pDC->prgnAPI,
-              pDC->dclevel.prgnClip,
-              pDC->dclevel.prgnMeta,
-                            RGN_AND);
+                       pDC->dclevel.prgnClip,
+                       pDC->dclevel.prgnMeta,
+                       RGN_AND);
   }
   else
   {
      if (pDC->dclevel.prgnClip)
+     {
         IntGdiCombineRgn( pDC->prgnAPI,
-                 pDC->dclevel.prgnClip,
-                                  NULL,
-                              RGN_COPY);
+                          pDC->dclevel.prgnClip,
+                          NULL,
+                          RGN_COPY);
+     }
      else if (pDC->dclevel.prgnMeta)
+     {
         IntGdiCombineRgn( pDC->prgnAPI,
-                 pDC->dclevel.prgnMeta,
-                                  NULL,
-                              RGN_COPY);
+                          pDC->dclevel.prgnMeta,
+                          NULL,
+                          RGN_COPY);
+     }
   }
 
   IntGdiCombineRgn( pDC->prgnRao,
                     pDC->prgnVis,
                     pDC->prgnAPI,
-                         RGN_AND);
+                    RGN_AND);
+
+  RtlCopyMemory(&pDC->erclClip,
+                &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound,
+                sizeof(RECTL));
 
-  RtlCopyMemory(&pDC->erclClip, &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound , sizeof(RECTL));
   pDC->fs &= ~DC_FLAG_DIRTY_RAO;
 
-//  if (Dc->CombinedClip != NULL) IntEngDeleteClipRegion(Dc->CombinedClip);
+  IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
+
+  // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
+  // the rects from region objects rects in pClipRgn->Buffer.
+  // With pDC->co.pClipRgn->Buffer,
+  // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
 
   co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount,
-                           ((PROSRGNDATA)pDC->prgnRao)->Buffer,
+                               ((PROSRGNDATA)pDC->prgnRao)->Buffer,
                                  &pDC->erclClip);
+  if (co)
+  {
+    if (pDC->rosdc.CombinedClip != NULL)
+      IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
+
+    pDC->rosdc.CombinedClip = co;
+  }
 
-  return REGION_Complexity(pDC->prgnRao);
+  return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
 }
 
 /* EOF */