[Win32k|Ggi32]
authorJames Tabor <james.tabor@reactos.org>
Mon, 25 Jan 2010 01:33:01 +0000 (01:33 +0000)
committerJames Tabor <james.tabor@reactos.org>
Mon, 25 Jan 2010 01:33:01 +0000 (01:33 +0000)
- Diagnostic commit used for troubleshooting leaking region handles.
- Updates to headers and experimental code added for regions.

svn path=/trunk/; revision=45242

reactos/dll/win32/gdi32/misc/misc.c
reactos/subsystems/win32/win32k/include/dc.h
reactos/subsystems/win32/win32k/include/engobjects.h
reactos/subsystems/win32/win32k/include/region.h
reactos/subsystems/win32/win32k/ntuser/windc.c
reactos/subsystems/win32/win32k/objects/cliprgn.c
reactos/subsystems/win32/win32k/objects/dclife.c
reactos/subsystems/win32/win32k/objects/dcstate.c
reactos/subsystems/win32/win32k/objects/gdiobj.c
reactos/subsystems/win32/win32k/objects/region.c

index b8a0906..cd7f124 100644 (file)
@@ -314,7 +314,7 @@ hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
          {
             if (pRgn_Attr->AttrFlags & ATTR_CACHED)
             {
-               DPRINT("Get Handle! Count %d\n", GdiHandleCache->ulNumHandles[Type]);
+               DPRINT1("Get Handle! Count %d PEB 0x%x\n", GdiHandleCache->ulNumHandles[Type], NtCurrentTeb()->ProcessEnvironmentBlock);
                pRgn_Attr->AttrFlags &= ~ATTR_CACHED;
                hPtr[Number - 1] = NULL;
                GdiHandleCache->ulNumHandles[Type]--;
index f8fec03..80d6620 100644 (file)
@@ -3,6 +3,7 @@
 
 typedef struct _DC *PDC;
 
+#include "engobjects.h"
 #include "brush.h"
 #include "bitmaps.h"
 #include "pdevobj.h"
@@ -31,23 +32,12 @@ typedef struct _ROS_DC_INFO
 
   BYTE   bitsPerPixel;
 
-  CLIPOBJ     *CombinedClip;
+  CLIPOBJ     *CombinedClip; /* Use XCLIPOBJ in DC. */
 
   UNICODE_STRING    DriverName;
 
 } ROS_DC_INFO;
 
-/* EXtended CLip and Window Region Object */
-typedef struct _XCLIPOBJ
-{
-  WNDOBJ  eClipWnd;
-  PVOID   pClipRgn;    /* prgnRao_ or (prgnVis_ if (prgnRao_ == z)) */
-  DWORD   Unknown1[16];
-  DWORD   nComplexity; /* count/mode based on # of rect in regions scan. */
-  PVOID   pUnknown;    /* UnK pointer to a large drawing structure. */
-                       /* We will use it for CombinedClip ptr. */
-} XCLIPOBJ, *PXCLIPOBJ;
-
 typedef struct _DCLEVEL
 {
   HPALETTE          hpal;
@@ -163,7 +153,7 @@ BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
 VOID FASTCALL DC_UpdateXforms(PDC  dc);
 BOOL FASTCALL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);
 VOID FASTCALL DC_vUpdateViewportExt(PDC pdc);
-VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst);
+VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL to);
 VOID FASTCALL DC_vUpdateFillBrush(PDC pdc);
 VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
 VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
index 854bb27..0da73d5 100644 (file)
 
 ---------------------------------------------------------------------------*/
 
+/* EXtended CLip and Window Region Object */
+typedef struct _XCLIPOBJ
+{
+  WNDOBJ;
+  PVOID   pClipRgn;    /* prgnRao_ or (prgnVis_ if (prgnRao_ == z)) */
+  RECTL   rclClipRgn;
+  PVOID   pscanClipRgn; /* Ptr to regions rect buffer based on iDirection. */
+  DWORD   cScan;
+  DWORD   reserved;
+  ULONG   ulBSize;
+  LONG    lscnSize;
+  ULONG   ulObjSize;
+  ULONG   iDirection;
+  ULONG   ulClipType;
+  DWORD   reserved1;
+  LONG    lUpDown;
+  DWORD   reserved2;
+  BOOL    bShouldDoAll;
+  DWORD   nComplexity; /* count/mode based on # of rect in regions scan. */
+  PVOID   pDDA;        /* Pointer to a large drawing structure. */
+} XCLIPOBJ, *PXCLIPOBJ;
+/*
+  EngCreateClip allocates XCLIPOBJ and RGNOBJ, pco->co.pClipRgn = &pco->ro.
+  {
+    XCLIPOBJ co;
+    RGNOBJ   ro;
+  }
+ */
 typedef struct _CLIPGDI {
   CLIPOBJ ClipObj;
   ULONG EnumPos;
index f09ffb5..a7583fb 100644 (file)
@@ -27,6 +27,7 @@ typedef struct _ROSRGNDATA
 #define  REGION_UnlockRgn(pRgn) GDIOBJ_UnlockObjByPtr((POBJ)pRgn)
 
 PROSRGNDATA FASTCALL REGION_AllocRgnWithHandle(INT n);
+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);
@@ -44,15 +45,19 @@ VOID FASTCALL IntGdiReleaseVisRgn(PDC);
 INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*);
 BOOL FASTCALL IntGdiPaintRgn(PDC, HRGN );
 HRGN FASTCALL IntCreatePolyPolygonRgn(PPOINT, PULONG, INT, INT);
+INT FASTCALL IntGdiOffsetRgn(PROSRGNDATA,INT,INT);
 
 INT FASTCALL IntGdiCombineRgn(PROSRGNDATA, PROSRGNDATA, PROSRGNDATA, INT);
 INT FASTCALL REGION_Complexity(PROSRGNDATA);
-PROSRGNDATA FASTCALL IntGdiCreateRectRgn(INT, INT, INT, INT);
 PROSRGNDATA FASTCALL RGNOBJAPI_Lock(HRGN,PRGN_ATTR *);
 VOID FASTCALL RGNOBJAPI_Unlock(PROSRGNDATA);
 HRGN FASTCALL IntSysCreateRectRgn(INT,INT,INT,INT);
+PROSRGNDATA FASTCALL IntSysCreateRectpRgn(INT,INT,INT,INT);
 
 #define IntSysCreateRectRgnIndirect(prc) \
   IntSysCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
 
+#define IntSysCreateRectpRgnIndirect(prc) \
+  IntSysCreateRectpRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
+
 #endif /* not __WIN32K_REGION_H */
index 8be75da..fdf8f48 100644 (file)
@@ -49,7 +49,7 @@ DceCreateDisplayDC(VOID)
       defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
       RtlZeroMemory(defaultDCstate, sizeof(DC));
       defaultDCstate->pdcattr = &defaultDCstate->dcattr;
-      DC_vCopyState(dc, defaultDCstate);
+      DC_vCopyState(dc, defaultDCstate, TRUE);
       DC_UnlockDc( dc );
   }
   return hDC;
index be7e5e7..9b7416c 100644 (file)
@@ -27,9 +27,27 @@ CLIPPING_UpdateGCRegion(DC* Dc)
 {
    PROSRGNDATA CombinedRegion;
 
-   if (!Dc->rosdc.hVisRgn)
+   /* Experiment with API region based on wine.. */
+   if (Dc->rosdc.hClipRgn && Dc->dclevel.prgnMeta)
    {
-      DPRINT1("Warning, hVisRgn is NULL!\n");
+      PROSRGNDATA pClipRgn;
+
+      if ((pClipRgn = RGNOBJAPI_Lock(Dc->rosdc.hClipRgn, NULL)))
+      {
+         if (!Dc->prgnAPI) Dc->prgnAPI = IntSysCreateRectpRgn( 0, 0, 0, 0 );
+
+         IntGdiCombineRgn( Dc->prgnAPI,
+                           pClipRgn,
+                           Dc->dclevel.prgnMeta,
+                           RGN_AND );
+         RGNOBJAPI_Unlock(pClipRgn);
+      }
+   }
+   else
+   {
+      if (Dc->prgnAPI)
+         GreDeleteObject(((PROSRGNDATA)Dc->prgnAPI)->BaseObject.hHmgr);
+      Dc->prgnAPI = NULL;
    }
 
    if (Dc->rosdc.hGCClipRgn == NULL)
@@ -37,8 +55,9 @@ CLIPPING_UpdateGCRegion(DC* Dc)
 
    if (Dc->rosdc.hClipRgn == NULL)
       NtGdiCombineRgn(Dc->rosdc.hGCClipRgn, Dc->rosdc.hVisRgn, 0, RGN_COPY);
-   else // FYI: Vis == NULL! source of "IntGdiCombineRgn requires hSrc2 != NULL for combine mode 1!"
+   else
       NtGdiCombineRgn(Dc->rosdc.hGCClipRgn, Dc->rosdc.hClipRgn, Dc->rosdc.hVisRgn, RGN_AND);
+
    NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);
 
    if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
@@ -94,6 +113,7 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn)
     NtGdiOffsetRgn(dc->rosdc.hVisRgn, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
     CLIPPING_UpdateGCRegion(dc);
   }
+
   DC_UnlockDc(dc);
 
   return retval;
@@ -146,7 +166,6 @@ int FASTCALL GdiExtSelectClipRgn(PDC dc,
     else
       NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode);
   }
-
   return CLIPPING_UpdateGCRegion(dc);
 }
 
@@ -176,13 +195,47 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
    PROSRGNDATA Rgn;
    INT retval;
    PDC dc;
+   HRGN hRgnNew, hRgn = NULL;
 
    if (!(dc = DC_LockDc(hDC)))
    {
       return ERROR;
    }
 
-   if (!(Rgn = RGNOBJAPI_Lock(dc->rosdc.hGCClipRgn, NULL)))
+   if (dc->prgnAPI) // APIRGN
+   {
+      hRgn = ((PROSRGNDATA)dc->prgnAPI)->BaseObject.hHmgr;
+   }
+   else if (dc->dclevel.prgnMeta) // METARGN
+   {
+      hRgn = ((PROSRGNDATA)dc->dclevel.prgnMeta)->BaseObject.hHmgr;
+   }
+   else
+   {
+      hRgn = dc->rosdc.hClipRgn; // CLIPRGN
+   }
+
+   if (hRgn)
+   {
+      hRgnNew = IntSysCreateRectRgn( 0, 0, 0, 0 );
+
+      NtGdiCombineRgn(hRgnNew, dc->rosdc.hVisRgn, hRgn, RGN_AND);
+
+      if (!(Rgn = RGNOBJAPI_Lock(hRgnNew, NULL)))
+      {
+         DC_UnlockDc(dc);
+         return ERROR;
+      }
+
+      retval = REGION_GetRgnBox(Rgn, rc);
+
+      REGION_FreeRgnByHandle(hRgnNew);
+      RGNOBJAPI_Unlock(Rgn);
+      DC_UnlockDc(dc);
+      return retval;
+   }
+
+   if (!(Rgn = RGNOBJAPI_Lock(dc->rosdc.hVisRgn, NULL)))
    {
       DC_UnlockDc(dc);
       return ERROR;
@@ -435,7 +488,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,
@@ -479,7 +532,6 @@ IntGdiSetMetaRgn(PDC pDC)
   return Ret;
 }
 
-
 int APIENTRY NtGdiSetMetaRgn(HDC  hDC)
 {
   INT Ret;
@@ -501,56 +553,74 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC)
 {
   CLIPOBJ * co;
 
-  if (!pDC->prgnVis) return 0;
+  /* Must have VisRgn set to a valid state! */
+  if (!pDC->prgnVis) return ERROR;
 
   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);
+
+  if (pDC->rosdc.CombinedClip != NULL)
+     IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
+
+  // 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,
-                                 &pDC->erclClip);
+                               ((PROSRGNDATA)pDC->prgnRao)->Buffer,
+                               &pDC->erclClip);
+
+  pDC->rosdc.CombinedClip = co;
 
-  return REGION_Complexity(pDC->prgnRao);
+  return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
 }
 
 /* EOF */
index be3ad34..3837b78 100644 (file)
@@ -468,7 +468,7 @@ IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
         defaultDCstate->pdcattr = &defaultDCstate->dcattr;
         hsurf = (HSURF)PrimarySurface.pSurface; // HAX²
         defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
-        DC_vCopyState(dc, defaultDCstate);
+        DC_vCopyState(dc, defaultDCstate, TRUE);
         DC_UnlockDc(dc);
     }
     return hDC;
@@ -539,6 +539,14 @@ IntGdiDeleteDC(HDC hDC, BOOL Force)
     {
         GreDeleteObject(DCToDelete->rosdc.hGCClipRgn);
     }
+    if (DCToDelete->dclevel.prgnMeta)
+    {
+       GreDeleteObject(((PROSRGNDATA)DCToDelete->dclevel.prgnMeta)->BaseObject.hHmgr);
+    }
+    if (DCToDelete->prgnAPI)
+    {
+       GreDeleteObject(((PROSRGNDATA)DCToDelete->prgnAPI)->BaseObject.hHmgr);
+    }
     PATH_Delete(DCToDelete->dclevel.hPath);
 
     DC_UnlockDc(DCToDelete);
index 44e690d..9e491a4 100644 (file)
 
 VOID
 FASTCALL
-DC_vCopyState(PDC pdcSrc, PDC pdcDst)
+DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
 {
     /* Copy full DC attribute */
     *pdcDst->pdcattr = *pdcSrc->pdcattr;
-
-    /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
-    /* The VisRectRegion field needs to be set to a valid state */
-
+    
     /* Mark some fields as dirty */
-    pdcDst->pdcattr->ulDirty_ |= 0x0012001f;
+    pdcDst->pdcattr->ulDirty_ |= 0x0012001f; // Note: Use if, To is FALSE....
 
     /* Copy DC level */
     pdcDst->dclevel.pColorSpace     = pdcSrc->dclevel.pColorSpace;
@@ -53,8 +50,20 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst)
         pdcDst->rosdc.bitsPerPixel = pdcSrc->rosdc.bitsPerPixel;
     }
 
-    GdiExtSelectClipRgn(pdcDst, pdcSrc->rosdc.hClipRgn, RGN_COPY);
-
+    /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
+    if (To) // Copy "To" SaveDC state.
+    {
+        if (pdcSrc->rosdc.hClipRgn)
+        {
+           pdcDst->rosdc.hClipRgn = IntSysCreateRectRgn(0, 0, 0, 0);
+           NtGdiCombineRgn(pdcDst->rosdc.hClipRgn, pdcSrc->rosdc.hClipRgn, 0, RGN_COPY);
+        }
+        // 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);
+    }
 }
 
 
@@ -66,7 +75,7 @@ IntGdiCleanDC(HDC hDC)
     dc = DC_LockDc(hDC);
     if (!dc) return FALSE;
     // Clean the DC
-    if (defaultDCstate) DC_vCopyState(defaultDCstate, dc);
+    if (defaultDCstate) DC_vCopyState(defaultDCstate, dc, FALSE);
 
     if (dc->dctype != DC_TYPE_MEMORY)
     {
@@ -101,7 +110,6 @@ NtGdiRestoreDC(
 {
     PDC pdc, pdcSave;
     HDC hdcSave;
-    PEPROCESS pepCurrentProcess;
 
     DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel);
 
@@ -129,16 +137,13 @@ NtGdiRestoreDC(
         return FALSE;
     }
 
-    /* Get current process */
-    pepCurrentProcess = PsGetCurrentProcess();
-
     /* Loop the save levels */
     while (pdc->dclevel.lSaveDepth > iSaveLevel)
     {
         hdcSave = pdc->dclevel.hdcSave;
 
         /* Set us as the owner */
-        if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
+        if (!IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_POWNED, FALSE ))
         {
             /* Could not get ownership. That's bad! */
             DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n",
@@ -167,7 +172,7 @@ NtGdiRestoreDC(
         if (pdc->dclevel.lSaveDepth == iSaveLevel)
         {
             /* Copy the state back */
-            DC_vCopyState(pdcSave, pdc);
+            DC_vCopyState(pdcSave, pdc, FALSE);
 
             // Restore Path by removing it, if the Save flag is set.
             // BeginPath will takecare of the rest.
@@ -177,6 +182,13 @@ NtGdiRestoreDC(
                 pdc->dclevel.hPath = 0;
                 pdc->dclevel.flPath &= ~DCPATH_SAVE;
             }
+            // Attempt to plug the leak!
+            if (pdcSave->rosdc.hClipRgn)
+            {
+               DPRINT("Have hClipRgn!\n");
+               REGION_FreeRgnByHandle(pdcSave->rosdc.hClipRgn);
+            }
+            // FIXME! Handle prgnMeta!
         }
 
         /* Delete the saved dc */
@@ -220,12 +232,12 @@ NtGdiSaveDC(
     }
     hdcSave = pdcSave->BaseObject.hHmgr;
 
+    /* Copy the current state */
+    DC_vCopyState(pdc, pdcSave, TRUE);
+
     /* Make it a kernel handle
        (FIXME: windows handles this different, see wiki)*/
-    GDIOBJ_SetOwnership(hdcSave, NULL);
-
-    /* Copy the current state */
-    DC_vCopyState(pdc, pdcSave);
+    IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_NONE, FALSE);
 
     /* Copy path. FIXME: why this way? */
     pdcSave->dclevel.hPath = pdc->dclevel.hPath;
index 244c41e..62b7111 100644 (file)
@@ -84,6 +84,59 @@ static LARGE_INTEGER ShortDelay;
 
 /** INTERNAL FUNCTIONS ********************************************************/
 
+// Audit Functions
+int tDC = 0;
+int tBRUSH = 0;
+int tBITMAP = 0;
+int tFONT = 0;
+int tRGN = 0;
+
+VOID
+AllocTypeDataDump(INT TypeInfo)
+{
+    switch( TypeInfo & GDI_HANDLE_TYPE_MASK )
+    {
+       case GDILoObjType_LO_BRUSH_TYPE:
+          tBRUSH++;
+          break;
+       case GDILoObjType_LO_DC_TYPE:
+          tDC++;
+          break;
+       case GDILoObjType_LO_BITMAP_TYPE:
+          tBITMAP++;
+          break;
+       case GDILoObjType_LO_FONT_TYPE:
+          tFONT++;
+          break;
+       case GDILoObjType_LO_REGION_TYPE:
+          tRGN++;
+          break;
+    }
+}
+
+VOID
+DeAllocTypeDataDump(INT TypeInfo)
+{
+    switch( TypeInfo & GDI_HANDLE_TYPE_MASK )
+    {
+       case GDILoObjType_LO_BRUSH_TYPE:
+          tBRUSH--;
+          break;
+       case GDILoObjType_LO_DC_TYPE:
+          tDC--;
+          break;
+       case GDILoObjType_LO_BITMAP_TYPE:
+          tBITMAP--;
+          break;
+       case GDILoObjType_LO_FONT_TYPE:
+          tFONT--;
+          break;
+       case GDILoObjType_LO_REGION_TYPE:
+          tRGN--;
+          break;
+    }
+}
+
 /*
  * Dummy GDI Cleanup Callback
  */
@@ -361,6 +414,7 @@ GDIOBJ_AllocObjWithHandle(ULONG ObjectType)
     if (W32Process && W32Process->GDIHandleCount >= 0x2710)
     {
         DPRINT1("Too many objects for process!!!\n");
+        DPRINT1("DC %d BRUSH %d BITMAP %d FONT %d RGN %d\n",tDC,tBRUSH,tBITMAP,tFONT,tRGN);
         GDIDBG_DUMPHANDLETABLE();
         return NULL;
     }
@@ -418,6 +472,8 @@ LockHandle:
             newObject->cExclusiveLock = 1;
             newObject->Tid = Thread;
 
+            AllocTypeDataDump(TypeInfo);
+
             /* unlock the entry */
             (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, CurrentProcessId);
 
@@ -565,6 +621,8 @@ LockHandle:
                 TypeIndex = GDI_OBJECT_GET_TYPE_INDEX(HandleType);
                 Ret = ObjTypeInfo[TypeIndex].CleanupProc(Object);
 
+                DeAllocTypeDataDump(HandleType);
+
                 /* Now it's time to free the memory */
                 GDIOBJ_FreeObj(Object, TypeIndex);
 
@@ -702,7 +760,7 @@ bPEBCacheHandle(HGDIOBJ Handle, int oType, PVOID pAttr)
            ((PRGN_ATTR)pAttr)->AttrFlags |= ATTR_CACHED;
            hPtr[Number] = Handle;
            GdiHandleCache->ulNumHandles[oType]++;
-           DPRINT("Put Handle Count %d\n", GdiHandleCache->ulNumHandles[oType]);
+           DPRINT1("Put Handle Count %d PEB 0x%x\n", GdiHandleCache->ulNumHandles[oType], NtCurrentTeb()->ProcessEnvironmentBlock);
            Ret = TRUE;
         }
      }
index ff76b6a..083f6bd 100644 (file)
@@ -2035,8 +2035,6 @@ REGION_AllocRgnWithHandle(INT nReg)
 {
     HRGN hReg;
     PROSRGNDATA pReg;
-    INT Index;
-    PGDI_TABLE_ENTRY Entry;
     
     pReg = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
     if(!pReg)
@@ -2063,10 +2061,6 @@ REGION_AllocRgnWithHandle(INT nReg)
         }
     }
 
-    Index = GDI_HANDLE_GET_INDEX(hReg);
-    Entry = &GdiHandleTable->Entries[Index];
-    Entry->UserData = AllocateObjectAttr();
-
     EMPTY_REGION(pReg);
     pReg->rdh.dwSize = sizeof(RGNDATAHEADER);
     pReg->rdh.nCount = nReg;
@@ -2075,6 +2069,27 @@ REGION_AllocRgnWithHandle(INT nReg)
     return pReg;
 }
 
+//
+// Allocate User Space Region Handle.
+//
+PROSRGNDATA
+FASTCALL
+REGION_AllocUserRgnWithHandle(INT nRgn)
+{
+    PROSRGNDATA pRgn;
+    INT Index;
+    PGDI_TABLE_ENTRY Entry;
+
+    pRgn = REGION_AllocRgnWithHandle(nRgn);
+    if (pRgn)
+    {
+       Index = GDI_HANDLE_GET_INDEX(pRgn->BaseObject.hHmgr);
+       Entry = &GdiHandleTable->Entries[Index];
+       Entry->UserData = AllocateObjectAttr();
+    }
+    return pRgn;
+}
+
 PROSRGNDATA
 FASTCALL
 RGNOBJAPI_Lock(HRGN hRgn, PRGN_ATTR *ppRgn_Attr)
@@ -2183,23 +2198,29 @@ RGNOBJAPI_Unlock(PROSRGNDATA pRgn)
 //
 // System Region Functions
 //
-HRGN
+PROSRGNDATA
 FASTCALL
-IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
+IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
 {
   PROSRGNDATA pRgn;
-  HRGN hRgn;
 
   pRgn = (PROSRGNDATA)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION);
   if (!pRgn)
   {
      return NULL;
   }
-  hRgn = pRgn->BaseObject.hHmgr;
   pRgn->Buffer = &pRgn->rdh.rcBound;
   REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
   REGION_UnlockRgn(pRgn);
-  return hRgn;
+  return pRgn;
+}
+
+HRGN
+FASTCALL
+IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
+{
+  PROSRGNDATA pRgn = IntSysCreateRectpRgn(LeftRect,TopRect,RightRect,BottomRect);
+  return (pRgn ? pRgn->BaseObject.hHmgr : NULL);
 }
 
 BOOL INTERNAL_CALL
@@ -2337,22 +2358,6 @@ IntGdiCombineRgn(PROSRGNDATA destRgn,
   return result;
 }
 
-PROSRGNDATA
-FASTCALL
-IntGdiCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
-{
-  PROSRGNDATA pRgn;
-
-  if (!(pRgn = REGION_AllocRgnWithHandle(1))) return NULL;
-
-  REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
-  RGNOBJAPI_Unlock(pRgn);
-  // Return pointer with Share locks.
-  pRgn = GDIOBJ_ShareLockObj(pRgn->BaseObject.hHmgr, GDI_OBJECT_TYPE_REGION);
-
-  return pRgn;
-}
-
 INT FASTCALL
 REGION_GetRgnBox(
     PROSRGNDATA Rgn,
@@ -2547,6 +2552,40 @@ REGION_SetRectRgn(
     }
 }
 
+INT  
+FASTCALL
+IntGdiOffsetRgn(
+    PROSRGNDATA rgn,
+    INT XOffset,
+    INT YOffset )
+{            
+    if (XOffset || YOffset)
+    {
+        int nbox = rgn->rdh.nCount;
+        PRECTL pbox = rgn->Buffer;
+
+        if (nbox && pbox)
+        {
+            while (nbox--)
+            {
+                pbox->left += XOffset;
+                pbox->right += XOffset;
+                pbox->top += YOffset;
+                pbox->bottom += YOffset;
+                pbox++;
+            }
+            if (rgn->Buffer != &rgn->rdh.rcBound)
+            {
+                rgn->rdh.rcBound.left += XOffset;
+                rgn->rdh.rcBound.right += XOffset;
+                rgn->rdh.rcBound.top += YOffset;
+                rgn->rdh.rcBound.bottom += YOffset;
+            }
+        }
+    }
+    return REGION_Complexity(rgn);
+}
+
 /***********************************************************************
  *     REGION_InsertEdgeInET
  *
@@ -3011,7 +3050,7 @@ IntCreatePolyPolygonRgn(
 
     if (mode == 0 || mode > 2) return 0;
 
-    if (!(region = REGION_AllocRgnWithHandle(nbpolygons)))
+    if (!(region = REGION_AllocUserRgnWithHandle(nbpolygons)))
         return 0;
     hrgn = region->BaseObject.hHmgr;
 
@@ -3248,7 +3287,7 @@ NtGdiCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
     HRGN hRgn;
 
     /* Allocate region data structure with space for 1 RECTL */
-    if (!(pRgn = REGION_AllocRgnWithHandle(1)))
+    if (!(pRgn = REGION_AllocUserRgnWithHandle(1)))
     {
         SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
         return NULL;
@@ -3308,7 +3347,7 @@ NtGdiCreateRoundRectRgn(
     /* Create region */
 
     d = (ellipse_height < 128) ? ((3 * ellipse_height) >> 2) : 64;
-    if (!(obj = REGION_AllocRgnWithHandle(d))) return 0;
+    if (!(obj = REGION_AllocUserRgnWithHandle(d))) return 0;
     hrgn = obj->BaseObject.hHmgr;
 
     /* Ellipse algorithm, based on an article by K. Porter */
@@ -3473,7 +3512,7 @@ NtGdiExtCreateRegion(
         return NULL;
     }
 
-    Region = REGION_AllocRgnWithHandle(nCount);
+    Region = REGION_AllocUserRgnWithHandle(nCount);
 
     if (Region == NULL)
     {
@@ -3640,10 +3679,10 @@ NtGdiGetRandomRgn(
         if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr;
         break;
     case APIRGN:
-        hSrc = pDC->rosdc.hClipRgn;
-//        if (pDC->prgnAPI) hSrc = ((PROSRGNDATA)pDC->prgnAPI)->BaseObject.hHmgr;
+        if (pDC->prgnAPI) hSrc = ((PROSRGNDATA)pDC->prgnAPI)->BaseObject.hHmgr;
 //        else if (pDC->dclevel.prgnClip) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnClip)->BaseObject.hHmgr;
-//        else if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr;
+        else if (pDC->rosdc.hClipRgn) hSrc = pDC->rosdc.hClipRgn;
+        else if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr;
         break;
     case SYSRGN:
         hSrc = pDC->rosdc.hVisRgn;
@@ -3767,31 +3806,8 @@ NtGdiOffsetRgn(
         return ERROR;
     }
 
-    if (XOffset || YOffset)
-    {
-        int nbox = rgn->rdh.nCount;
-        PRECTL pbox = rgn->Buffer;
+    ret = IntGdiOffsetRgn(rgn, XOffset, YOffset);
 
-        if (nbox && pbox)
-        {
-            while (nbox--)
-            {
-                pbox->left += XOffset;
-                pbox->right += XOffset;
-                pbox->top += YOffset;
-                pbox->bottom += YOffset;
-                pbox++;
-            }
-            if (rgn->Buffer != &rgn->rdh.rcBound)
-            {
-                rgn->rdh.rcBound.left += XOffset;
-                rgn->rdh.rcBound.right += XOffset;
-                rgn->rdh.rcBound.top += YOffset;
-                rgn->rdh.rcBound.bottom += YOffset;
-            }
-        }
-    }
-    ret = REGION_Complexity(rgn);
     RGNOBJAPI_Unlock(rgn);
     return ret;
 }