[WIN32K]
authorJérôme Gardou <jerome.gardou@reactos.org>
Wed, 23 Jul 2014 16:05:47 +0000 (16:05 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Wed, 23 Jul 2014 16:05:47 +0000 (16:05 +0000)
     - Correctly use the Clip, Meta, Rao, API and Vis Regions in DCs
     - Update the DC clipping object on demand each time a blt is performed
     - Reduce the number of region allocated with handles when it's not needed
This commit fixes numerous bugs regarding clipping, most notably SetDIBitsToDevice overlapping foreground windows
CORE-8353 #resolve #comment There are still a few quirks in winetests which will get fixed in a next commit
CORE-7628 #comment should be fixed in rev 63731, please confirm.

svn path=/trunk/; revision=63731

20 files changed:
reactos/win32ss/gdi/ntgdi/arc.c
reactos/win32ss/gdi/ntgdi/bitblt.c
reactos/win32ss/gdi/ntgdi/cliprgn.c
reactos/win32ss/gdi/ntgdi/cliprgn.h
reactos/win32ss/gdi/ntgdi/dc.h
reactos/win32ss/gdi/ntgdi/dclife.c
reactos/win32ss/gdi/ntgdi/dcobjs.c
reactos/win32ss/gdi/ntgdi/dcstate.c
reactos/win32ss/gdi/ntgdi/dcutil.c
reactos/win32ss/gdi/ntgdi/dibobj.c
reactos/win32ss/gdi/ntgdi/fillshap.c
reactos/win32ss/gdi/ntgdi/freetype.c
reactos/win32ss/gdi/ntgdi/line.c
reactos/win32ss/gdi/ntgdi/path.c
reactos/win32ss/gdi/ntgdi/region.c
reactos/win32ss/gdi/ntgdi/region.h
reactos/win32ss/user/ntuser/cursoricon.c
reactos/win32ss/user/ntuser/cursoricon_new.c
reactos/win32ss/user/ntuser/dce.h
reactos/win32ss/user/ntuser/windc.c

index 0b6f421..5d65235 100644 (file)
@@ -335,8 +335,7 @@ NtGdiAngleArc(
 
   worker.l  = dwStartAngle;
   worker1.l = dwSweepAngle;
-  DC_vPrepareDCsForBlit(pDC, pDC->rosdc.CombinedClip->rclBounds,
-                           NULL, pDC->rosdc.CombinedClip->rclBounds);
+  DC_vPrepareDCsForBlit(pDC, NULL, NULL, NULL);
   if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
     DC_vUpdateFillBrush(pDC);
   if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
@@ -381,8 +380,7 @@ NtGdiArcInternal(
     return TRUE;
   }
 
-  DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
-                            NULL, dc->rosdc.CombinedClip->rclBounds);
+  DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
 
   if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
     DC_vUpdateFillBrush(dc);
index e27c5e2..7193d77 100644 (file)
@@ -107,7 +107,7 @@ NtGdiAlphaBlend(
 
     /* Prepare DCs for blit */
     TRACE("Preparing DCs for blit\n");
-    DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+    DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);
 
     /* Determine surfaces to be used in the bitblt */
     BitmapDest = DCDest->dclevel.pSurface;
@@ -268,7 +268,7 @@ NtGdiTransparentBlt(
     rcSrc.bottom += DCSrc->ptlDCOrig.y;
 
     /* Prepare for blit */
-    DC_vPrepareDCsForBlit(DCDest, rcDest, DCSrc, rcSrc);
+    DC_vPrepareDCsForBlit(DCDest, &rcDest, DCSrc, &rcSrc);
 
     BitmapDest = DCDest->dclevel.pSurface;
     if (!BitmapDest)
@@ -456,7 +456,7 @@ NtGdiMaskBlt(
     }
 
     /* Prepare blit */
-    DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+    DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);
 
     if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
         DC_vUpdateFillBrush(DCDest);
@@ -647,7 +647,7 @@ GreStretchBltMask(
     BrushOrigin.y = 0;
 
     /* Only prepare Source and Dest, hdcMask represents a DIB */
-    DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+    DC_vPrepareDCsForBlit(DCDest, &DestRect, DCSrc, &SourceRect);
 
     if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
         DC_vUpdateFillBrush(DCDest);
@@ -826,7 +826,7 @@ IntPatBlt(
     BrushOrigin.y = pbrush->ptOrigin.y + pdc->ptlDCOrig.y;
 #endif
 
-    DC_vPrepareDCsForBlit(pdc, DestRect, NULL, DestRect);
+    DC_vPrepareDCsForBlit(pdc, &DestRect, NULL, NULL);
 
     psurf = pdc->dclevel.pSurface;
 
index a6dd20e..a5699ab 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-int FASTCALL
-CLIPPING_UpdateGCRegion(DC* Dc)
-{
-   PROSRGNDATA CombinedRegion;
-   //HRGN hRgnVis;
-   PREGION prgnClip, prgnGCClip;
-
-    /* Would prefer this, but the rest of the code sucks... */
-    //ASSERT(Dc->rosdc.hGCClipRgn);
-    //ASSERT(Dc->rosdc.hClipRgn);
-   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)
-      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)))
-   {
-     CLIPOBJ *CombinedClip;
-
-     CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
-        CombinedRegion->Buffer,
-        &CombinedRegion->rdh.rcBound);
-
-     RGNOBJAPI_Unlock(CombinedRegion);
-
-     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);
-}
-
-INT FASTCALL
-GdiSelectVisRgn(HDC hdc, HRGN hrgn)
+VOID
+FASTCALL
+GdiSelectVisRgn(
+    HDC hdc,
+    PREGION prgn)
 {
-  int retval;
-  DC *dc;
-  PREGION prgn;
+    DC *dc;
 
-  if (!hrgn)
-  {
-       EngSetLastError(ERROR_INVALID_PARAMETER);
-       return ERROR;
-  }
-  if (!(dc = DC_LockDc(hdc)))
-  {
-       EngSetLastError(ERROR_INVALID_HANDLE);
-       return ERROR;
-  }
+    if (!(dc = DC_LockDc(hdc)))
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return;
+    }
 
-  dc->fs &= ~DC_FLAG_DIRTY_RAO;
+    dc->fs |= DC_FLAG_DIRTY_RAO;
 
-  ASSERT (dc->prgnVis != NULL);
+    ASSERT(dc->prgnVis != NULL);
+    ASSERT(prgn != NULL);
 
-  prgn = RGNOBJAPI_Lock(hrgn, NULL);
-  retval = prgn ? IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY) : ERROR;
-  RGNOBJAPI_Unlock(prgn);
-  if ( retval != ERROR )
-  {
+    IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY);
     IntGdiOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
-    CLIPPING_UpdateGCRegion(dc);
-  }
-  DC_UnlockDc(dc);
 
-  return retval;
+    DC_UnlockDc(dc);
 }
 
 
-int FASTCALL GdiExtSelectClipRgn(PDC dc,
-                                 HRGN hrgn,
-                                 int fnMode)
+int
+FASTCALL
+IntGdiExtSelectClipRgn(
+    PDC dc,
+    PREGION prgn,
+    int fnMode)
 {
-  // dc->fs &= ~DC_FLAG_DIRTY_RAO;
-
-  if (!hrgn)
-  {
-    if (fnMode == RGN_COPY)
+    if (!prgn)
     {
-      if (dc->rosdc.hClipRgn != NULL)
-      {
-        GreDeleteObject(dc->rosdc.hClipRgn);
-        dc->rosdc.hClipRgn = NULL;
-      }
-    }
-    else
-    {
-      EngSetLastError(ERROR_INVALID_PARAMETER);
-      return ERROR;
+        if (fnMode == RGN_COPY)
+        {
+            if (dc->dclevel.prgnClip != NULL)
+            {
+                REGION_Delete(dc->dclevel.prgnClip);
+                dc->dclevel.prgnClip = NULL;
+                dc->fs |= DC_FLAG_DIRTY_RAO;
+            }
+            return SIMPLEREGION;
+        }
+        else
+        {
+            EngSetLastError(ERROR_INVALID_PARAMETER);
+            return ERROR;
+        }
     }
-  }
-  else
-  {
-    if (!dc->rosdc.hClipRgn)
+
+    if (!dc->dclevel.prgnClip)
     {
-      RECTL rect;
-      if(dc->prgnVis)
-      {
+        RECTL rect;
+
         REGION_GetRgnBox(dc->prgnVis, &rect);
-        dc->rosdc.hClipRgn = IntSysCreateRectRgnIndirect(&rect);
-      }
-      else
-      {
-        dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
-      }
+        dc->dclevel.prgnClip = IntSysCreateRectpRgnIndirect(&rect);
     }
+
+    dc->fs |= DC_FLAG_DIRTY_RAO;
+
     if(fnMode == RGN_COPY)
-    {
-      NtGdiCombineRgn(dc->rosdc.hClipRgn, hrgn, 0, fnMode);
-    }
-    else
-      NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode);
-  }
+        return IntGdiCombineRgn(dc->dclevel.prgnClip, prgn, 0, fnMode);
 
-  return CLIPPING_UpdateGCRegion(dc);
+    return IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgn, fnMode);
 }
 
 
-int APIENTRY NtGdiExtSelectClipRgn(HDC  hDC,
-                                HRGN  hrgn,
-                               int  fnMode)
+int
+APIENTRY
+NtGdiExtSelectClipRgn(
+    HDC  hDC,
+    HRGN  hrgn,
+    int  fnMode)
 {
-  int retval;
-  DC *dc;
+    int retval;
+    DC *dc;
+    PREGION prgn;
 
-  if (!(dc = DC_LockDc(hDC)))
-  {
-       EngSetLastError(ERROR_INVALID_HANDLE);
-       return ERROR;
-  }
+    if (!(dc = DC_LockDc(hDC)))
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return ERROR;
+    }
+
+    prgn = REGION_LockRgn(hrgn);
+
+    /* IntGdiExtSelectClipRgn takes care of checking for NULL region */
+    retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
 
-  retval = GdiExtSelectClipRgn ( dc, hrgn, fnMode );
+    if (prgn)
+        REGION_UnlockRgn(prgn);
 
-  DC_UnlockDc(dc);
-  return retval;
+    DC_UnlockDc(dc);
+    return retval;
 }
 
 INT FASTCALL
@@ -177,7 +115,6 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
    INT retval;
    PDC dc;
    PROSRGNDATA pRgnNew, pRgn = NULL;
-   BOOL Unlock = FALSE; // Small HACK
 
    if (!(dc = DC_LockDc(hDC)))
    {
@@ -193,10 +130,9 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
    {
       pRgn = dc->dclevel.prgnMeta;
    }
-   else if (dc->rosdc.hClipRgn)
+   else if (dc->dclevel.prgnClip) // CLIPRGN
    {
-          Unlock = TRUE ;
-       pRgn = REGION_LockRgn(dc->rosdc.hClipRgn); // CLIPRGN
+       pRgn = dc->dclevel.prgnClip;
    }
 
    if (pRgn)
@@ -206,7 +142,6 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
          if (!pRgnNew)
       {
          DC_UnlockDc(dc);
-                if(Unlock) REGION_UnlockRgn(pRgn);
          return ERROR;
       }
 
@@ -217,12 +152,11 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
          REGION_Delete(pRgnNew);
 
       DC_UnlockDc(dc);
-         if(Unlock) REGION_UnlockRgn(pRgn);
       return retval;
    }
 
    retval = REGION_GetRgnBox(dc->prgnVis, rc);
-   IntDPtoLP(dc, (LPPOINT)rc, 2);
+
    DC_UnlockDc(dc);
 
    return retval;
@@ -265,53 +199,49 @@ int APIENTRY NtGdiExcludeClipRect(HDC  hDC,
                          int  RightRect,
                          int  BottomRect)
 {
-   INT Result;
-   RECTL Rect;
-   PREGION prgnNew, prgnClip;
-   PDC dc = DC_LockDc(hDC);
+    INT Result;
+    RECTL Rect;
+    PREGION prgnNew;
+    PDC dc = DC_LockDc(hDC);
 
-   if (!dc)
-   {
-      EngSetLastError(ERROR_INVALID_HANDLE);
-      return ERROR;
-   }
+    if (!dc)
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return ERROR;
+    }
 
-   Rect.left = LeftRect;
-   Rect.top = TopRect;
-   Rect.right = RightRect;
-   Rect.bottom = BottomRect;
+    Rect.left = LeftRect;
+    Rect.top = TopRect;
+    Rect.right = RightRect;
+    Rect.bottom = BottomRect;
 
-   IntLPtoDP(dc, (LPPOINT)&Rect, 2);
+    IntLPtoDP(dc, (LPPOINT)&Rect, 2);
 
-   prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
-   if (!prgnNew)
-   {
-      Result = ERROR;
-   }
-   else
-   {
-      if (!dc->rosdc.hClipRgn)
-      {
-         dc->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
-         prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
-         IntGdiCombineRgn(prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
-         REGION_UnlockRgn(prgnClip);
-         Result = SIMPLEREGION;
-      }
-      else
-      {
-         prgnClip = REGION_LockRgn(dc->rosdc.hClipRgn);
-         Result = IntGdiCombineRgn(prgnClip, prgnClip, prgnNew, RGN_DIFF);
-         REGION_UnlockRgn(prgnClip);
-      }
-      REGION_Delete(prgnNew);
-   }
-   if (Result != ERROR)
-      CLIPPING_UpdateGCRegion(dc);
+    prgnNew = IntSysCreateRectpRgnIndirect(&Rect);
+    if (!prgnNew)
+    {
+        Result = ERROR;
+    }
+    else
+    {
+        if (!dc->dclevel.prgnClip)
+        {
+            dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+            IntGdiCombineRgn(dc->dclevel.prgnClip, dc->prgnVis, prgnNew, RGN_DIFF);
+            Result = SIMPLEREGION;
+        }
+        else
+        {
+            Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgnNew, RGN_DIFF);
+        }
+        REGION_Delete(prgnNew);
+    }
+    if (Result != ERROR)
+        dc->fs |= DC_FLAG_DIRTY_RAO;
 
-   DC_UnlockDc(dc);
+    DC_UnlockDc(dc);
 
-   return Result;
+    return Result;
 }
 
 int APIENTRY NtGdiIntersectClipRect(HDC  hDC,
@@ -320,200 +250,191 @@ int APIENTRY NtGdiIntersectClipRect(HDC  hDC,
                            int  RightRect,
                            int  BottomRect)
 {
-   INT Result;
-   RECTL Rect;
-   HRGN NewRgn;
-   PDC dc = DC_LockDc(hDC);
+    INT Result;
+    RECTL Rect;
+    PREGION pNewRgn;
+    PDC dc = DC_LockDc(hDC);
 
-   DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
-      hDC, LeftRect, TopRect, RightRect, BottomRect);
+    DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
+            hDC, LeftRect, TopRect, RightRect, BottomRect);
 
-   if (!dc)
-   {
-      EngSetLastError(ERROR_INVALID_HANDLE);
-      return ERROR;
-   }
+    if (!dc)
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return ERROR;
+    }
 
-   Rect.left = LeftRect;
-   Rect.top = TopRect;
-   Rect.right = RightRect;
-   Rect.bottom = BottomRect;
+    Rect.left = LeftRect;
+    Rect.top = TopRect;
+    Rect.right = RightRect;
+    Rect.bottom = BottomRect;
 
-   IntLPtoDP(dc, (LPPOINT)&Rect, 2);
+    IntLPtoDP(dc, (LPPOINT)&Rect, 2);
 
-   NewRgn = IntSysCreateRectRgnIndirect(&Rect);
-   if (!NewRgn)
-   {
-      Result = ERROR;
-   }
-   else if (!dc->rosdc.hClipRgn)
-   {
-      dc->rosdc.hClipRgn = NewRgn;
-      Result = SIMPLEREGION;
-   }
-   else
-   {
-      Result = NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, NewRgn, RGN_AND);
-      GreDeleteObject(NewRgn);
-   }
-   if (Result != ERROR)
-      CLIPPING_UpdateGCRegion(dc);
+    pNewRgn = IntSysCreateRectpRgnIndirect(&Rect);
+    if (!pNewRgn)
+    {
+        Result = ERROR;
+    }
+    else if (!dc->dclevel.prgnClip)
+    {
+        dc->dclevel.prgnClip = pNewRgn;
+        Result = SIMPLEREGION;
+    }
+    else
+    {
+        Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, pNewRgn, RGN_AND);
+        REGION_Delete(pNewRgn);
+    }
+    if (Result != ERROR)
+        dc->fs |= DC_FLAG_DIRTY_RAO;
 
-   DC_UnlockDc(dc);
+    DC_UnlockDc(dc);
 
-   return Result;
+    return Result;
 }
 
 int APIENTRY NtGdiOffsetClipRgn(HDC  hDC,
                        int  XOffset,
                        int  YOffset)
 {
-  INT Result;
-  DC *dc;
+    INT Result;
+    DC *dc;
 
-  if(!(dc = DC_LockDc(hDC)))
-  {
-    EngSetLastError(ERROR_INVALID_HANDLE);
-    return ERROR;
-  }
+    if(!(dc = DC_LockDc(hDC)))
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return ERROR;
+    }
 
-  if(dc->rosdc.hClipRgn != NULL)
-  {
-    Result = NtGdiOffsetRgn(dc->rosdc.hClipRgn,
-                            XOffset,
-                            YOffset);
-    CLIPPING_UpdateGCRegion(dc);
-  }
-  else
-  {
-    Result = NULLREGION;
-  }
+    if(dc->dclevel.prgnClip != NULL)
+    {
+        Result = IntGdiOffsetRgn(dc->dclevel.prgnClip,
+                                XOffset,
+                                YOffset);
+        dc->fs |= DC_FLAG_DIRTY_RAO;
+    }
+    else
+    {
+        Result = NULLREGION;
+    }
 
-  DC_UnlockDc(dc);
-  return Result;
+    DC_UnlockDc(dc);
+    return Result;
 }
 
 BOOL APIENTRY NtGdiPtVisible(HDC  hDC,
                     int  X,
                     int  Y)
 {
-  HRGN rgn;
-  DC *dc;
+    BOOL ret = FALSE;
+    PDC dc;
 
-  if(!(dc = DC_LockDc(hDC)))
-  {
-    EngSetLastError(ERROR_INVALID_HANDLE);
-    return FALSE;
-  }
+    if(!(dc = DC_LockDc(hDC)))
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
 
-  rgn = dc->rosdc.hGCClipRgn;
-  DC_UnlockDc(dc);
+    if (dc->prgnRao)
+    {
+        POINT pt = {X, Y};
+        IntLPtoDP(dc, &pt, 1);
+        ret = REGION_PtInRegion(dc->prgnRao, pt.x, pt.y);
+    }
 
-  return (rgn ? NtGdiPtInRegion(rgn, X, Y) : FALSE);
+    DC_UnlockDc(dc);
+
+    return ret;
 }
 
-BOOL APIENTRY NtGdiRectVisible(HDC  hDC,
-                      LPRECT UnsafeRect)
+BOOL
+APIENTRY
+NtGdiRectVisible(
+    HDC hDC,
+    LPRECT UnsafeRect)
 {
-   NTSTATUS Status = STATUS_SUCCESS;
-   PROSRGNDATA Rgn;
-   PDC dc = DC_LockDc(hDC);
-   BOOL Result = FALSE;
-   RECTL Rect;
+    NTSTATUS Status = STATUS_SUCCESS;
+    PDC dc = DC_LockDc(hDC);
+    BOOL Result = FALSE;
+    RECTL Rect;
 
-   if (!dc)
-   {
-      EngSetLastError(ERROR_INVALID_HANDLE);
-      return FALSE;
-   }
+    if (!dc)
+    {
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
 
-   _SEH2_TRY
-   {
-      ProbeForRead(UnsafeRect,
+    _SEH2_TRY
+    {
+        ProbeForRead(UnsafeRect,
                    sizeof(RECT),
                    1);
-      Rect = *UnsafeRect;
-   }
-   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-   {
-      Status = _SEH2_GetExceptionCode();
-   }
-   _SEH2_END;
+        Rect = *UnsafeRect;
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
 
-   if(!NT_SUCCESS(Status))
-   {
-      DC_UnlockDc(dc);
-      SetLastNtError(Status);
-      return FALSE;
-   }
+    if(!NT_SUCCESS(Status))
+    {
+        DC_UnlockDc(dc);
+        SetLastNtError(Status);
+        return FALSE;
+    }
 
-   if (dc->rosdc.hGCClipRgn)
-   {
-      if((Rgn = (PROSRGNDATA)RGNOBJAPI_Lock(dc->rosdc.hGCClipRgn, NULL)))
-      {
+    if (dc->fs & DC_FLAG_DIRTY_RAO)
+        CLIPPING_UpdateGCRegion(dc);
+
+    if (dc->prgnRao)
+    {
          IntLPtoDP(dc, (LPPOINT)&Rect, 2);
-         Result = REGION_RectInRegion(Rgn, &Rect);
-         RGNOBJAPI_Unlock(Rgn);
-      }
-   }
-   DC_UnlockDc(dc);
+         Result = REGION_RectInRegion(dc->prgnRao, &Rect);
+    }
+    DC_UnlockDc(dc);
 
-   return Result;
+    return Result;
 }
 
 int
 FASTCALL
 IntGdiSetMetaRgn(PDC pDC)
 {
-  INT Ret = ERROR;
-  PROSRGNDATA TempRgn;
+    INT Ret = ERROR;
 
-  if ( pDC->dclevel.prgnMeta )
-  {
-     if ( pDC->dclevel.prgnClip )
-     {
-        TempRgn = IntSysCreateRectpRgn(0,0,0,0);
-        if (TempRgn)
+    if ( pDC->dclevel.prgnMeta )
+    {
+        if ( pDC->dclevel.prgnClip )
         {
-           Ret = IntGdiCombineRgn( TempRgn,
-                     pDC->dclevel.prgnMeta,
-                     pDC->dclevel.prgnClip,
-                                   RGN_AND);
-           if ( Ret )
-           {
-              GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnMeta->BaseObject);
-              if (!((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.ulShareCount)
-                 REGION_Delete(pDC->dclevel.prgnMeta);
-
-              pDC->dclevel.prgnMeta = TempRgn;
-
-              GDIOBJ_vDereferenceObject(&pDC->dclevel.prgnClip->BaseObject);
-              if (!((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.ulShareCount)
-                 REGION_Delete(pDC->dclevel.prgnClip);
-
-              pDC->dclevel.prgnClip = NULL;
-
-              IntGdiReleaseRaoRgn(pDC);
-           }
-           else
-              REGION_Delete(TempRgn);
+            Ret = IntGdiCombineRgn(pDC->dclevel.prgnMeta, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip, RGN_AND);
+            if (Ret != ERROR)
+            {
+                REGION_Delete(pDC->dclevel.prgnClip);
+                pDC->dclevel.prgnClip = NULL;
+                IntGdiReleaseRaoRgn(pDC);
+            }
         }
-     }
-     else
-        Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
-  }
-  else
-  {
-     if ( pDC->dclevel.prgnClip )
-     {
-        Ret = REGION_Complexity(pDC->dclevel.prgnClip);
-        pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
-        pDC->dclevel.prgnClip = NULL;
-     }
-     else
-       Ret = SIMPLEREGION;
-  }
-  return Ret;
+        else
+            Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
+    }
+    else
+    {
+        if ( pDC->dclevel.prgnClip )
+        {
+            Ret = REGION_Complexity(pDC->dclevel.prgnClip);
+            pDC->dclevel.prgnMeta = pDC->dclevel.prgnClip;
+            pDC->dclevel.prgnClip = NULL;
+        }
+        else
+            Ret = SIMPLEREGION;
+    }
+
+    if (Ret != ERROR)
+        pDC->fs |= DC_FLAG_DIRTY_RAO;
+
+    return Ret;
 }
 
 
@@ -533,88 +454,95 @@ int APIENTRY NtGdiSetMetaRgn(HDC  hDC)
   return Ret;
 }
 
-INT FASTCALL
-NEW_CLIPPING_UpdateGCRegion(PDC pDC)
+VOID
+FASTCALL
+CLIPPING_UpdateGCRegion(PDC pDC)
 {
-  CLIPOBJ * co;
+    CLIPOBJ * co;
 
-  /* Must have VisRgn set to a valid state! */
-  ASSERT (pDC->prgnVis);
+    /* Must have VisRgn set to a valid state! */
+    ASSERT (pDC->prgnVis);
 
-// FIXME: this seems to be broken!
+    if (pDC->prgnAPI)
+    {
+        REGION_Delete(pDC->prgnAPI);
+        pDC->prgnAPI = NULL;
+    }
 
-  if (pDC->prgnAPI)
-  {
-     REGION_Delete(pDC->prgnAPI);
-     pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
-  }
+    if (pDC->prgnRao)
+        REGION_Delete(pDC->prgnRao);
 
-  if (pDC->prgnRao)
-  {
-     REGION_Delete(pDC->prgnRao);
-     pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
-  }
+    pDC->prgnRao = IntSysCreateRectpRgn(0,0,0,0);
 
-  if (!pDC->prgnRao)
-  {
-     return ERROR;
-  }
+    ASSERT(pDC->prgnRao);
 
-  if (pDC->dclevel.prgnMeta && pDC->dclevel.prgnClip)
-  {
-     IntGdiCombineRgn( pDC->prgnAPI,
-                       pDC->dclevel.prgnClip,
-                       pDC->dclevel.prgnMeta,
-                       RGN_AND);
-  }
-  else
-  {
-     if (pDC->dclevel.prgnClip)
-     {
-        IntGdiCombineRgn( pDC->prgnAPI,
-                          pDC->dclevel.prgnClip,
-                          NULL,
-                          RGN_COPY);
-     }
-     else if (pDC->dclevel.prgnMeta)
-     {
-        IntGdiCombineRgn( pDC->prgnAPI,
-                          pDC->dclevel.prgnMeta,
-                          NULL,
-                          RGN_COPY);
-     }
-  }
+    if (pDC->dclevel.prgnMeta || pDC->dclevel.prgnClip)
+    {
+        pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
+        if (!pDC->dclevel.prgnMeta)
+        {
+            IntGdiCombineRgn(pDC->prgnAPI,
+                             pDC->dclevel.prgnClip,
+                             NULL,
+                             RGN_COPY);
+        }
+        else if (!pDC->dclevel.prgnClip)
+        {
+            IntGdiCombineRgn(pDC->prgnAPI,
+                             pDC->dclevel.prgnMeta,
+                             NULL,
+                             RGN_COPY);
+        }
+        else
+        {
+            IntGdiCombineRgn(pDC->prgnAPI,
+                             pDC->dclevel.prgnClip,
+                             pDC->dclevel.prgnMeta,
+                             RGN_AND);
+        }
+    }
+
+    if (pDC->prgnAPI)
+    {
+        IntGdiCombineRgn(pDC->prgnRao,
+                         pDC->prgnVis,
+                         pDC->prgnAPI,
+                         RGN_AND);
+    }
+    else
+    {
+        IntGdiCombineRgn(pDC->prgnRao,
+                         pDC->prgnVis,
+                         NULL,
+                         RGN_COPY);
+    }
 
-  IntGdiCombineRgn( pDC->prgnRao,
-                    pDC->prgnVis,
-                    pDC->prgnAPI,
-                    RGN_AND);
 
-  RtlCopyMemory(&pDC->erclClip,
+    IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
+
+    RtlCopyMemory(&pDC->erclClip,
                 &pDC->prgnRao->rdh.rcBound,
                 sizeof(RECTL));
 
-  pDC->fs &= ~DC_FLAG_DIRTY_RAO;
-
-  IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
+    pDC->fs &= ~DC_FLAG_DIRTY_RAO;
 
-  // 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;
+    // 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(pDC->prgnRao->rdh.nCount,
-                              pDC->prgnRao->Buffer,
-                                 &pDC->erclClip);
-  if (co)
-  {
-    if (pDC->rosdc.CombinedClip != NULL)
-      IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
+    co = IntEngCreateClipRegion(pDC->prgnRao->rdh.nCount,
+                                pDC->prgnRao->Buffer,
+                                &pDC->erclClip);
+    if (co)
+    {
+        if (pDC->rosdc.CombinedClip != NULL)
+            IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
 
-    pDC->rosdc.CombinedClip = co;
-  }
+        pDC->rosdc.CombinedClip = co;
+    }
 
-  return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
+    IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
 }
 
 /* EOF */
index b160392..64f4fb7 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
 INT FASTCALL GdiGetClipBox(HDC hDC, RECTL *rc);
-INT FASTCALL GdiSelectVisRgn(HDC hdc, HRGN hrgn);
-INT FASTCALL GdiExtSelectClipRgn (PDC dc, HRGN hrgn, int fnMode);
-int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
+VOID FASTCALL GdiSelectVisRgn(HDC hdc, PREGION prgn);
+INT FASTCALL IntGdiExtSelectClipRgn (PDC dc, PREGION prgn, int fnMode);
+VOID FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
index a65e7a3..fbb7677 100644 (file)
@@ -48,9 +48,6 @@ typedef enum _DCTYPE
 
 typedef struct _ROS_DC_INFO
 {
-  HRGN     hClipRgn;     /* Clip region (may be 0) */
-  HRGN     hGCClipRgn;   /* GC clip region (ClipRgn AND VisRgn) */
-
   CLIPOBJ     *CombinedClip;
 } ROS_DC_INFO;
 
@@ -199,9 +196,9 @@ BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
 
 BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);
 VOID FASTCALL DC_vUpdateViewportExt(PDC pdc);
-VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL to);
+VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To);
 VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2);
-VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2);
+VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdcDest, const RECT* rcDest, PDC pdcSrc, const RECT* rcSrc);
 
 VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
 
index 3a8a359..e9aa7b0 100644 (file)
@@ -95,22 +95,11 @@ DC_AllocDcWithHandle()
 void
 DC_InitHack(PDC pdc)
 {
-    HRGN hVisRgn;
-
     TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
     pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
 
     /* This should never fail */
     ASSERT(pdc->dclevel.ppal);
-
-    /* Select regions */
-    pdc->rosdc.hClipRgn = NULL;
-    pdc->rosdc.hGCClipRgn = NULL;
-
-    hVisRgn = IntSysCreateRectRgn(0, 0, 1, 1);
-    ASSERT(hVisRgn);
-    GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
-    GreDeleteObject(hVisRgn);
 }
 
 VOID
@@ -170,7 +159,7 @@ DC_vInitDc(
         pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
         pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
         pdc->erclClip = pdc->erclBounds;
-//        pdc->co
+        pdc->co = gxcoTrivial;
 
         pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
     }
@@ -185,7 +174,7 @@ DC_vInitDc(
         pdc->erclBounds.bottom = 0;
         pdc->erclBoundsApp = pdc->erclBounds;
         pdc->erclClip = pdc->erclWindow;
-        //pdc->co = NULL
+        pdc->co = gxcoTrivial;
     }
 
       //pdc->dcattr.VisRectRegion:
@@ -237,6 +226,8 @@ DC_vInitDc(
     /* Setup regions */
     pdc->prgnAPI = NULL;
        pdc->prgnRao = NULL;
+       pdc->dclevel.prgnClip = NULL;
+       pdc->dclevel.prgnMeta = NULL;
     /* Allocate a Vis region */
     pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
        ASSERT(pdc->prgnVis);
@@ -372,17 +363,17 @@ DC_vCleanup(PVOID ObjectBody)
     LFONT_ShareUnlockFont(pdc->dclevel.plfnt);
 
     /*  Free regions */
-    if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn))
-        GreDeleteObject(pdc->rosdc.hClipRgn);
+    if (pdc->dclevel.prgnClip)
+        REGION_Delete(pdc->dclevel.prgnClip);
+    if (pdc->dclevel.prgnMeta)
+        REGION_Delete(pdc->dclevel.prgnMeta);
     if (pdc->prgnVis)
-    {
         REGION_Delete(pdc->prgnVis);
-    }
-    if (pdc->rosdc.hGCClipRgn && GreIsHandleValid(pdc->rosdc.hGCClipRgn))
-    {
-        GreDeleteObject(pdc->rosdc.hGCClipRgn);
-    }
-    if (NULL != pdc->rosdc.CombinedClip)
+    if (pdc->prgnRao)
+        REGION_Delete(pdc->prgnRao);
+    if (pdc->prgnAPI)
+        REGION_Delete(pdc->prgnAPI);
+    if (pdc->rosdc.CombinedClip)
         IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
 
     PATH_Delete(pdc->dclevel.hPath);
@@ -397,17 +388,6 @@ VOID
 NTAPI
 DC_vSetOwner(PDC pdc, ULONG ulOwner)
 {
-
-    if (pdc->rosdc.hClipRgn)
-    {
-        IntGdiSetRegionOwner(pdc->rosdc.hClipRgn, ulOwner);
-    }
-
-    if (pdc->rosdc.hGCClipRgn)
-    {
-        IntGdiSetRegionOwner(pdc->rosdc.hGCClipRgn, ulOwner);
-    }
-
     if (pdc->dclevel.hPath)
     {
         GreSetObjectOwner(pdc->dclevel.hPath, ulOwner);
@@ -466,7 +446,7 @@ static
 void
 DC_vUpdateDC(PDC pdc)
 {
-    HRGN hVisRgn ;
+    // PREGION VisRgn ;
     PPDEVOBJ ppdev = pdc->ppdev ;
 
     pdc->dhpdev = ppdev->dhpdev;
@@ -475,10 +455,12 @@ DC_vUpdateDC(PDC pdc)
     pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
 
     PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl);
-    hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
-    ASSERT(hVisRgn);
-    GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
-    GreDeleteObject(hVisRgn);
+#if 0
+    VisRgn = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+    ASSERT(VisRgn);
+    GdiSelectVisRgn(pdc->BaseObject.hHmgr, VisRgn);
+    REGION_Delete(VisRgn);
+#endif
 
     pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
     pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
@@ -492,76 +474,107 @@ DC_vUpdateDC(PDC pdc)
  * from where we take pixels. */
 VOID
 FASTCALL
-DC_vPrepareDCsForBlit(PDC pdc1,
-                      RECT rc1,
-                      PDC pdc2,
-                      RECT rc2)
+DC_vPrepareDCsForBlit(
+    PDC pdcDest,
+    const RECT* rcDest,
+    PDC pdcSrc,
+    const RECT* rcSrc)
 {
     PDC pdcFirst, pdcSecond;
-    PRECT prcFirst, prcSecond;
+    const RECT *prcFirst, *prcSecond;
 
     /* Update brushes */
-    if (pdc1->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
-        DC_vUpdateFillBrush(pdc1);
-    if (pdc1->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
-        DC_vUpdateLineBrush(pdc1);
-    if(pdc1->pdcattr->ulDirty_ & DIRTY_TEXT)
-        DC_vUpdateTextBrush(pdc1);
+    if (pdcDest->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+        DC_vUpdateFillBrush(pdcDest);
+    if (pdcDest->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+        DC_vUpdateLineBrush(pdcDest);
+    if(pdcDest->pdcattr->ulDirty_ & DIRTY_TEXT)
+        DC_vUpdateTextBrush(pdcDest);
 
     /* Lock them in good order */
-    if(pdc2)
+    if(pdcSrc)
     {
-        if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock)
+        if((ULONG_PTR)pdcDest->ppdev->hsemDevLock >= (ULONG_PTR)pdcSrc->ppdev->hsemDevLock)
         {
-            pdcFirst = pdc1;
-            prcFirst = &rc1;
-            pdcSecond = pdc2;
-            prcSecond = &rc2;
+            pdcFirst = pdcDest;
+            prcFirst = rcDest;
+            pdcSecond = pdcSrc;
+            prcSecond = rcSrc;
         }
         else
         {
-            pdcFirst = pdc2;
-            prcFirst = &rc2;
-            pdcSecond = pdc1;
-            prcSecond = &rc1;
+            pdcFirst = pdcSrc;
+            prcFirst = rcSrc;
+            pdcSecond = pdcDest;
+            prcSecond = rcDest;
         }
     }
     else
     {
-        pdcFirst = pdc1 ;
-        prcFirst = &rc1;
+        pdcFirst = pdcDest ;
+        prcFirst = rcDest;
         pdcSecond = NULL;
         prcSecond = NULL;
     }
 
-    if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT)
+    /* Update clipping of dest DC if needed */
+    if (pdcDest->dctype == DCTYPE_DIRECT)
+    {
+        DCE* dce = DceGetDceFromDC(pdcDest->BaseObject.hHmgr);
+        if (dce)
+            DceUpdateVisRgn(dce, dce->pwndOrg, dce->DCXFlags);
+    }
+
+    if (pdcDest->fs & DC_FLAG_DIRTY_RAO)
+        CLIPPING_UpdateGCRegion(pdcDest);
+
+    /* Lock and update first DC */
+    if(pdcFirst->dctype == DCTYPE_DIRECT)
     {
         EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock);
-        MouseSafetyOnDrawStart(pdcFirst->ppdev,
-                                    prcFirst->left,
-                                    prcFirst->top,
-                                    prcFirst->right,
-                                    prcFirst->bottom) ;
         /* Update surface if needed */
         if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
         {
             DC_vUpdateDC(pdcFirst);
         }
     }
-    if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT)
+
+    if(pdcFirst->dctype == DCTYPE_DIRECT)
+    {
+        if (!prcFirst)
+            prcFirst = &pdcFirst->erclClip;
+
+        MouseSafetyOnDrawStart(pdcFirst->ppdev,
+                               prcFirst->left,
+                               prcFirst->top,
+                               prcFirst->right,
+                               prcFirst->bottom) ;
+    }
+
+    if (!pdcSecond)
+        return;
+
+    /* Lock and update second DC */
+    if(pdcSecond->dctype == DCTYPE_DIRECT)
     {
         EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock);
-        MouseSafetyOnDrawStart(pdcSecond->ppdev,
-                                    prcSecond->left,
-                                    prcSecond->top,
-                                    prcSecond->right,
-                                    prcSecond->bottom) ;
         /* Update surface if needed */
         if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
         {
             DC_vUpdateDC(pdcSecond);
         }
     }
+
+    if(pdcSecond->dctype == DCTYPE_DIRECT)
+    {
+        if (!prcSecond)
+            prcSecond = &pdcSecond->erclClip;
+        MouseSafetyOnDrawStart(pdcSecond->ppdev,
+                               prcSecond->left,
+                               prcSecond->top,
+                               prcSecond->right,
+                               prcSecond->bottom) ;
+    }
 }
 
 /* Finishes a blit for one or two DCs */
index be21fed..67de9c9 100644 (file)
@@ -330,7 +330,7 @@ NtGdiSelectBitmap(
     PDC pdc;
     HBITMAP hbmpOld;
     PSURFACE psurfNew, psurfOld;
-    HRGN hVisRgn;
+    PREGION VisRgn;
     HDC hdcOld;
     ULONG cBitsPixel;
     ASSERT_NOGDILOCKS();
@@ -452,15 +452,15 @@ NtGdiSelectBitmap(
     pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE;
 
     /* FIXME: Improve by using a region without a handle and selecting it */
-    hVisRgn = IntSysCreateRectRgn( 0,
+    VisRgn = IntSysCreateRectpRgn( 0,
                                    0,
                                    pdc->dclevel.sizl.cx,
                                    pdc->dclevel.sizl.cy);
 
-    if (hVisRgn)
+    if (VisRgn)
     {
-        GdiSelectVisRgn(hdc, hVisRgn);
-        GreDeleteObject(hVisRgn);
+        GdiSelectVisRgn(hdc, VisRgn);
+        REGION_Delete(VisRgn);
     }
 
     /* Unlock the DC */
@@ -509,7 +509,10 @@ NtGdiSelectClipPath(
     /* Construct a region from the path */
     else if (PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgnPath))
     {
-        success = GdiExtSelectClipRgn(pdc, hrgnPath, Mode) != ERROR;
+        PREGION prgnPath = REGION_LockRgn(hrgnPath);
+        ASSERT(prgnPath);
+        success = IntGdiExtSelectClipRgn(pdc, prgnPath, Mode) != ERROR;
+        REGION_UnlockRgn(prgnPath);
         GreDeleteObject( hrgnPath );
 
         /* Empty the path */
@@ -693,9 +696,7 @@ NtGdiGetRandomRgn(
 {
     INT ret = 0;
     PDC pdc;
-    HRGN hrgnSrc = NULL;
     PREGION prgnSrc = NULL;
-    POINTL ptlOrg;
 
     pdc = DC_LockDc(hdc);
     if (!pdc)
@@ -707,8 +708,7 @@ NtGdiGetRandomRgn(
     switch (iCode)
     {
         case CLIPRGN:
-            hrgnSrc = pdc->rosdc.hClipRgn;
-//            if (pdc->dclevel.prgnClip) prgnSrc = pdc->dclevel.prgnClip;
+            prgnSrc = pdc->dclevel.prgnClip;
             break;
 
         case METARGN:
@@ -716,14 +716,15 @@ NtGdiGetRandomRgn(
             break;
 
         case APIRGN:
+            if (pdc->fs & DC_FLAG_DIRTY_RAO)
+                CLIPPING_UpdateGCRegion(pdc);
             if (pdc->prgnAPI)
             {
                 prgnSrc = pdc->prgnAPI;
             }
-//            else if (pdc->dclevel.prgnClip) prgnSrc = pdc->dclevel.prgnClip;
-            else if (pdc->rosdc.hClipRgn)
+            else if (pdc->dclevel.prgnClip)
             {
-                hrgnSrc = pdc->rosdc.hClipRgn;
+                prgnSrc = pdc->dclevel.prgnClip;
             }
             else if (pdc->dclevel.prgnMeta)
             {
@@ -739,28 +740,20 @@ NtGdiGetRandomRgn(
             break;
     }
 
-    if (hrgnSrc)
-    {
-        ret = NtGdiCombineRgn(hrgnDest, hrgnSrc, 0, RGN_COPY) == ERROR ? -1 : 1;
-    }
-    else if (prgnSrc)
+    if (prgnSrc)
     {
         PREGION prgnDest = REGION_LockRgn(hrgnDest);
         if (prgnDest)
         {
             ret = IntGdiCombineRgn(prgnDest, prgnSrc, 0, RGN_COPY) == ERROR ? -1 : 1;
+            if ((ret == 1) && (iCode == SYSRGN))
+                IntGdiOffsetRgn(prgnDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
             REGION_UnlockRgn(prgnDest);
         }
         else
             ret = -1;
     }
 
-    if (iCode == SYSRGN)
-    {
-        ptlOrg = pdc->ptlDCOrig;
-        NtGdiOffsetRgn(hrgnDest, ptlOrg.x, ptlOrg.y );
-    }
-
     DC_UnlockDc(pdc);
 
     return ret;
index d20018e..38ad481 100644 (file)
@@ -51,23 +51,26 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
     pdcDst->dclevel.plfnt           = pdcSrc->dclevel.plfnt;
 
     /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
-    if (To) // Copy "To" SaveDC state.
+    if (!To)
     {
-        if (pdcSrc->rosdc.hClipRgn)
+        IntGdiExtSelectClipRgn(pdcDst, pdcSrc->dclevel.prgnClip, RGN_COPY);
+        if (pdcDst->dclevel.prgnMeta)
         {
-           pdcDst->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
-           NtGdiCombineRgn(pdcDst->rosdc.hClipRgn, pdcSrc->rosdc.hClipRgn, 0, RGN_COPY);
+            REGION_Delete(pdcDst->dclevel.prgnMeta);
+            pdcDst->dclevel.prgnMeta = NULL;
         }
-        // FIXME: Handle prgnMeta!
-    }
-    else // Copy "!To" RestoreDC state.
-    {  /* The VisRectRegion field needs to be set to a valid state */
-       GdiExtSelectClipRgn(pdcDst, pdcSrc->rosdc.hClipRgn, RGN_COPY);
+        if (pdcSrc->dclevel.prgnMeta)
+        {
+            pdcDst->dclevel.prgnMeta = IntSysCreateRectpRgn(0, 0, 0, 0);
+            IntGdiCombineRgn(pdcDst->dclevel.prgnMeta, pdcSrc->dclevel.prgnMeta, NULL, RGN_COPY);
+        }
+        pdcDst->fs |= DC_FLAG_DIRTY_RAO;
     }
 }
 
 
-BOOL FASTCALL
+BOOL
+FASTCALL
 IntGdiCleanDC(HDC hDC)
 {
     PDC dc;
@@ -87,6 +90,16 @@ IntGdiCleanDC(HDC hDC)
         DC_vUpdateTextBrush(dc);
     }
 
+    /* DC_vCopyState frees the Clip rgn and the Meta rgn. Take care of the other ones
+     * There is no need to clear prgnVis, as UserGetDC updates it immediately. */
+    if (dc->prgnRao)
+        REGION_Delete(dc->prgnRao);
+    if (dc->prgnAPI)
+        REGION_Delete(dc->prgnAPI);
+    dc->prgnRao = dc->prgnAPI = NULL;
+
+    dc->fs |= DC_FLAG_DIRTY_RAO;
+
     DC_UnlockDc(dc);
 
     return TRUE;
@@ -272,7 +285,7 @@ NtGdiSaveDC(
     GDIOBJ_vSetObjectOwner(&pdcSave->BaseObject, GDI_OBJ_HMGR_PUBLIC);
 
     /* Copy the current state */
-    DC_vCopyState(pdc, pdcSave, TRUE);
+    DC_vCopyState(pdc, pdcSave, FALSE);
 
     /* Only memory DC's change their surface */
     if (pdc->dctype == DCTYPE_MEMORY)
index 695d7e2..730713d 100644 (file)
@@ -367,7 +367,7 @@ IntGdiSetHookFlags(HDC hDC, WORD Flags)
     }
     else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
     {
-        dc->fs &= ~DC_FLAG_DIRTY_RAO;
+        //dc->fs &= ~DC_FLAG_DIRTY_RAO;
     }
 
     DC_UnlockDc(dc);
index 0320311..65fbdd9 100644 (file)
@@ -502,7 +502,7 @@ NtGdiSetDIBitsToDeviceInternal(
     }
 
     /* This is actually a blit */
-    DC_vPrepareDCsForBlit(pDC, rcDest, NULL, rcDest);
+    DC_vPrepareDCsForBlit(pDC, &rcDest, NULL, NULL);
     pSurf = pDC->dclevel.pSurface;
     if (!pSurf)
     {
@@ -1184,7 +1184,7 @@ NtGdiStretchDIBitsInternal(
     }
 
     /* Prepare DC for blit */
-    DC_vPrepareDCsForBlit(pdc, rcDst, NULL, rcSrc);
+    DC_vPrepareDCsForBlit(pdc, &rcDst, NULL, NULL);
 
     psurfDst = pdc->dclevel.pSurface;
 
index 77e22f7..1c3f374 100644 (file)
@@ -307,7 +307,7 @@ NtGdiEllipse(
         tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x;
         tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y;
 
-        DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);
+        DC_vPrepareDCsForBlit(dc, &RectBounds, NULL, NULL);
 
         ret = IntFillEllipse( dc,
                               CenterX - RadiusX,
@@ -480,8 +480,7 @@ NtGdiPolyPolyDraw( IN HDC hDC,
         return TRUE;
     }
 
-    DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
-                            NULL, dc->rosdc.CombinedClip->rclBounds);
+    DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
 
     if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
         DC_vUpdateFillBrush(dc);
@@ -567,7 +566,7 @@ IntRectangle(PDC dc,
         DestRect.bottom--;
     }
 
-    DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+    DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
 
     if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
         DC_vUpdateFillBrush(dc);
@@ -796,7 +795,7 @@ IntRoundRect(
     else
     {
 
-        DC_vPrepareDCsForBlit(dc, RectBounds, NULL, RectBounds);
+        DC_vPrepareDCsForBlit(dc, &RectBounds, NULL, NULL);
 
         RtlCopyMemory(&brushTemp, pbrFill, sizeof(brushTemp));
         brushTemp.ptOrigin.x += RectBounds.left - Left;
@@ -962,9 +961,9 @@ GreGradientFill(
 
     EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
 
-    ASSERT(pdc->rosdc.CombinedClip);
+    DC_vPrepareDCsForBlit(pdc, &rclExtent, NULL, NULL);
 
-    DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);
+    ASSERT(pdc->rosdc.CombinedClip);
 
     bRet = IntEngGradientFill(&psurf->SurfObj,
                              pdc->rosdc.CombinedClip,
@@ -1091,6 +1090,13 @@ NtGdiExtFloodFill(
         return TRUE;
     }
 
+    psurf = dc->dclevel.pSurface;
+    if (!psurf)
+    {
+        Ret = FALSE;
+        goto cleanup;
+    }
+
     pdcattr = dc->pdcattr;
 
     if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
@@ -1103,20 +1109,18 @@ NtGdiExtFloodFill(
     Pt.y = YStart;
     IntLPtoDP(dc, (LPPOINT)&Pt, 1);
 
-    Ret = NtGdiPtInRegion(dc->rosdc.hGCClipRgn, Pt.x, Pt.y);
-    if (Ret)
-        IntGdiGetRgnBox(dc->rosdc.hGCClipRgn,(LPRECT)&DestRect);
-    else
-        goto cleanup;
-
-    DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
-
-    psurf = dc->dclevel.pSurface;
-    if (!psurf)
+    if (dc->prgnRao)
     {
-        Ret = FALSE;
-        goto cleanup;
+        Ret = REGION_PtInRegion(dc->prgnRao, Pt.x, Pt.y);
+        if (Ret)
+            REGION_GetRgnBox(dc->prgnRao ,(LPRECT)&DestRect);
+        else
+            goto cleanup;
     }
+    else
+        RECTL_vSetRect(&DestRect, 0, psurf->SurfObj.sizlBitmap.cx, 0, psurf->SurfObj.sizlBitmap.cy);
+
+    DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
 
     EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);
 
@@ -1127,10 +1131,11 @@ NtGdiExtFloodFill(
     ConvColor = XLATEOBJ_iXlate(&exlo.xlo, Color);
     Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
 
+    DC_vFinishBlit(dc, NULL);
+
     EXLATEOBJ_vCleanup(&exlo);
 
 cleanup:
-    DC_vFinishBlit(dc, NULL);
     DC_UnlockDc(dc);
     return Ret;
 }
index 5ac3b60..560d12e 100644 (file)
@@ -3212,7 +3212,7 @@ GreExtTextOutW(
     LONGLONG TextLeft, RealXStart;
     ULONG TextTop, previous, BackgroundLeft;
     FT_Bool use_kerning;
-    RECTL DestRect, MaskRect, DummyRect = {0, 0, 0, 0};
+    RECTL DestRect, MaskRect;
     POINTL SourcePoint, BrushOrigin;
     HBITMAP HSourceGlyph;
     SURFOBJ *SourceGlyphSurf;
@@ -3308,7 +3308,7 @@ GreExtTextOutW(
         DestRect.right  += dc->ptlDCOrig.x;
         DestRect.bottom += dc->ptlDCOrig.y;
 
-        DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+        DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
 
         if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
             DC_vUpdateBackgroundBrush(dc);
@@ -3502,7 +3502,7 @@ GreExtTextOutW(
     BackgroundLeft = (RealXStart + 32) >> 6;
 
     /* Lock blit with a dummy rect */
-    DC_vPrepareDCsForBlit(dc, DummyRect, NULL, DummyRect);
+    DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
 
     psurf = dc->dclevel.pSurface ;
     if(!psurf) psurf = psurfDefaultBitmap;
index d4d5505..93c89be 100644 (file)
@@ -257,8 +257,7 @@ IntGdiPolyline(DC      *dc,
     if (PATH_IsPathOpen(dc->dclevel))
         return PATH_Polyline(dc, pt, Count);
 
-    DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
-                            NULL, dc->rosdc.CombinedClip->rclBounds);
+    DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
 
     if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
         DC_vUpdateFillBrush(dc);
@@ -411,7 +410,7 @@ NtGdiLineTo(HDC  hDC,
     rcLockRect.right += dc->ptlDCOrig.x;
     rcLockRect.bottom += dc->ptlDCOrig.y;
 
-    DC_vPrepareDCsForBlit(dc, rcLockRect, NULL, rcLockRect);
+    DC_vPrepareDCsForBlit(dc, &rcLockRect, NULL, NULL);
 
     if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
         DC_vUpdateLineBrush(dc);
index 434518a..1f4218b 100644 (file)
@@ -2511,8 +2511,7 @@ NtGdiFillPath(HDC  hDC)
         return FALSE;
     }
 
-    DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
-                          NULL, dc->rosdc.CombinedClip->rclBounds);
+    DC_vPrepareDCsForBlit(dc, NULL, NULL, NULL);
 
     pdcattr = dc->pdcattr;
 
@@ -2777,8 +2776,7 @@ NtGdiStrokeAndFillPath(HDC hDC)
         return FALSE;
     }
 
-    DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
-                          NULL, pDc->rosdc.CombinedClip->rclBounds);
+    DC_vPrepareDCsForBlit(pDc, NULL, NULL, NULL);
 
     pdcattr = pDc->pdcattr;
 
@@ -2822,8 +2820,7 @@ NtGdiStrokePath(HDC hDC)
         return FALSE;
     }
 
-    DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
-                          NULL, pDc->rosdc.CombinedClip->rclBounds);
+    DC_vPrepareDCsForBlit(pDc, NULL, NULL, NULL);
 
     pdcattr = pDc->pdcattr;
 
index ce79722..08a0cdd 100644 (file)
@@ -2300,11 +2300,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
@@ -2503,8 +2505,6 @@ IntGdiPaintRgn(
         return FALSE;
     }
 
-    NtGdiCombineRgn(tmpVisRgn, tmpVisRgn, dc->rosdc.hGCClipRgn, RGN_AND);
-
     visrgn = RGNOBJAPI_Lock(tmpVisRgn, NULL);
     if (visrgn == NULL)
     {
@@ -2512,6 +2512,9 @@ IntGdiPaintRgn(
         return FALSE;
     }
 
+    if (dc->prgnRao)
+        IntGdiCombineRgn(visrgn, visrgn, dc->prgnRao, RGN_AND);
+
     ClipRegion = IntEngCreateClipRegion(visrgn->rdh.nCount,
                                         visrgn->Buffer,
                                         &visrgn->rdh.rcBound );
@@ -2535,6 +2538,29 @@ IntGdiPaintRgn(
     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(
@@ -3861,27 +3887,19 @@ 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);
+    ret = REGION_PtInRegion(prgn, X, Y);
+
+    RGNOBJAPI_Unlock(prgn);
+    return ret;
+
+
+    RGNOBJAPI_Unlock(prgn);
     return FALSE;
 }
 
index b11f31d..8fb7ca2 100644 (file)
@@ -27,6 +27,7 @@ PROSRGNDATA FASTCALL REGION_AllocUserRgnWithHandle(INT n);
 VOID FASTCALL REGION_UnionRectWithRgn(ROSRGNDATA *rgn, const RECTL *rect);
 INT FASTCALL REGION_GetRgnBox(PROSRGNDATA Rgn, RECTL *pRect);
 BOOL FASTCALL REGION_RectInRegion(PROSRGNDATA Rgn, const RECTL *rc);
+BOOL FASTCALL REGION_PtInRegion(PREGION, INT, INT);
 BOOL FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off);
 VOID FASTCALL REGION_SetRectRgn(PROSRGNDATA pRgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect);
 VOID NTAPI REGION_vCleanup(PVOID ObjectBody);
index a4b0d3a..e730c58 100644 (file)
@@ -1287,7 +1287,7 @@ UserDrawIconEx(
         RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
 
         /* Prepare the underlying surface */
-        DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
+        DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
 
         /* Get the clip object */
         pdcClipObj = pdc->rosdc.CombinedClip;
@@ -1472,7 +1472,7 @@ done:
         RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
 
         /* Prepare the underlying surface */
-        DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
+        DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
 
         /* Get the clip object */
         pdcClipObj = pdc->rosdc.CombinedClip;
index bdd7fbb..98e4300 100644 (file)
@@ -1195,7 +1195,7 @@ UserDrawIconEx(
     RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
     
     /* Prepare the underlying surface */
-    DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
+    DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
 
     /* We now have our destination surface and rectangle */
     psurfDest = pdc->dclevel.pSurface;
index 9d56ffd..5c7e932 100644 (file)
@@ -51,3 +51,5 @@ void FASTCALL DceFreeClassDCE(HDC);
 HWND FASTCALL UserGethWnd(HDC,PWNDOBJ*);
 void FASTCALL DceFreeWindowDCE(PWND);
 void FASTCALL DceFreeThreadDCE(PTHREADINFO);
+VOID FASTCALL DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags);
+DCE* FASTCALL DceGetDceFromDC(HDC hdc);
index 4e697df..492e09e 100644 (file)
@@ -46,21 +46,47 @@ DceCreateDisplayDC(VOID)
   return IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
 }
 
+/* Returns the DCE pointer from the HDC handle */
+DCE*
+FASTCALL
+DceGetDceFromDC(HDC hdc)
+{
+    LIST_ENTRY* Entry = LEDce.Flink;
+    DCE* dce;
+
+    while (Entry != &LEDce)
+    {
+        dce = CONTAINING_RECORD(Entry, DCE, List);
+        if (dce->hDC == hdc)
+            return dce;
+        Entry = Entry->Flink;
+    }
+
+    return NULL;
+}
+
 static
-HRGN FASTCALL
+PREGION FASTCALL
 DceGetVisRgn(PWND Window, ULONG Flags, HWND hWndChild, ULONG CFlags)
 {
-  HRGN VisRgn;
+  PREGION RetRgn;
+  HRGN hVisRgn;
+  hVisRgn = VIS_ComputeVisibleRegion( Window,
+                                      0 == (Flags & DCX_WINDOW),
+                                      0 != (Flags & DCX_CLIPCHILDREN),
+                                      0 != (Flags & DCX_CLIPSIBLINGS));
 
-  VisRgn = VIS_ComputeVisibleRegion( Window,
-                                     0 == (Flags & DCX_WINDOW),
-                                     0 != (Flags & DCX_CLIPCHILDREN),
-                                     0 != (Flags & DCX_CLIPSIBLINGS));
+  RetRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
 
-  if (VisRgn == NULL)
-      VisRgn = IntSysCreateRectRgn(0, 0, 0, 0);
+  if (hVisRgn != NULL)
+  {
+      PREGION VisRgn = REGION_LockRgn(hVisRgn);
+      IntGdiCombineRgn(RetRgn, VisRgn, NULL, RGN_COPY);
+      REGION_UnlockRgn(VisRgn);
+      GreDeleteObject(hVisRgn);
+  }
 
-  return VisRgn;
+  return RetRgn;
 }
 
 PDCE FASTCALL
@@ -150,6 +176,7 @@ DceSetDrawable( PWND Window OPTIONAL,
          dc->ptlDCOrig.y = Window->rcClient.top;
       }
   }
+  dc->fs |= DC_FLAG_DIRTY_RAO;
   DC_UnlockDc(dc);
 }
 
@@ -175,10 +202,11 @@ DceDeleteClipRgn(DCE* Dce)
    IntGdiSetHookFlags(Dce->hDC, DCHF_INVALIDATEVISRGN);
 }
 
-static VOID FASTCALL
+VOID
+FASTCALL
 DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags)
 {
-   HANDLE hRgnVisible = NULL;
+   PREGION RgnVisible = NULL;
    ULONG DcxFlags;
    PWND DesktopWindow;
 
@@ -189,7 +217,7 @@ DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags)
       Parent = Window->spwndParent;
       if(!Parent)
       {
-         hRgnVisible = NULL;
+         RgnVisible = NULL;
          goto noparent;
       }
 
@@ -202,23 +230,23 @@ DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags)
       {
          DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
       }
-      hRgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags);
+      RgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags);
    }
    else if (Window == NULL)
    {
       DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
       if (NULL != DesktopWindow)
       {
-         hRgnVisible = IntSysCreateRectRgnIndirect(&DesktopWindow->rcWindow);
+         RgnVisible = IntSysCreateRectpRgnIndirect(&DesktopWindow->rcWindow);
       }
       else
       {
-         hRgnVisible = NULL;
+         RgnVisible = NULL;
       }
    }
    else
    {
-      hRgnVisible = DceGetVisRgn(Window, Flags, 0, 0);
+      RgnVisible = DceGetVisRgn(Window, Flags, 0, 0);
    }
 
 noparent:
@@ -226,33 +254,37 @@ noparent:
    {
       if(Dce->hrgnClip != NULL)
       {
-         NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_AND);
+         PREGION RgnClip = REGION_LockRgn(Dce->hrgnClip);
+         IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_AND);
+         REGION_UnlockRgn(RgnClip);
       }
       else
       {
-         if(hRgnVisible != NULL)
+         if(RgnVisible != NULL)
          {
-            GreDeleteObject(hRgnVisible);
+            REGION_Delete(RgnVisible);
          }
-         hRgnVisible = IntSysCreateRectRgn(0, 0, 0, 0);
+         RgnVisible = IntSysCreateRectpRgn(0, 0, 0, 0);
       }
    }
-   else if (Flags & DCX_EXCLUDERGN && Dce->hrgnClip != NULL)
+   else if ((Flags & DCX_EXCLUDERGN) && Dce->hrgnClip != NULL)
    {
-      NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_DIFF);
+       PREGION RgnClip = REGION_LockRgn(Dce->hrgnClip);
+       IntGdiCombineRgn(RgnVisible, RgnVisible, RgnClip, RGN_DIFF);
+       REGION_UnlockRgn(RgnClip);
    }
 
    Dce->DCXFlags &= ~DCX_DCEDIRTY;
-   GdiSelectVisRgn(Dce->hDC, hRgnVisible);
+   GdiSelectVisRgn(Dce->hDC, RgnVisible);
 
    if (VerifyWnd(Window)) // Window maybe dead by this time before finishing the DCE release.
    {
       IntEngWindowChanged(Window, WOC_RGN_CLIENT);
    }
 
-   if (hRgnVisible != NULL)
+   if (RgnVisible != NULL)
    {
-      GreDeleteObject(hRgnVisible);
+      REGION_Delete(RgnVisible);
    }
 }
 
@@ -889,10 +921,10 @@ DceResetActiveDCEs(PWND Window)
                dc->ptlDCOrig.y = CurrentWindow->rcClient.top;
             }
 
-            if (NULL != dc->rosdc.hClipRgn)
+            if (NULL != dc->dclevel.prgnClip)
             {
-               NtGdiOffsetRgn(dc->rosdc.hClipRgn, DeltaX, DeltaY);
-               CLIPPING_UpdateGCRegion(dc);
+               IntGdiOffsetRgn(dc->dclevel.prgnClip, DeltaX, DeltaY);
+               dc->fs |= DC_FLAG_DIRTY_RAO;
             }
             if (NULL != pDCE->hrgnClip)
             {