diff --git a/reactos/dll/win32/gdi32/misc/misc.c b/reactos/dll/win32/gdi32/misc/misc.c index b8a0906e929..cd7f124ce15 100644 --- a/reactos/dll/win32/gdi32/misc/misc.c +++ b/reactos/dll/win32/gdi32/misc/misc.c @@ -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]--; diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index f8fec039b33..80d66209e36 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -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); diff --git a/reactos/subsystems/win32/win32k/include/engobjects.h b/reactos/subsystems/win32/win32k/include/engobjects.h index 854bb277a56..0da73d561ad 100644 --- a/reactos/subsystems/win32/win32k/include/engobjects.h +++ b/reactos/subsystems/win32/win32k/include/engobjects.h @@ -42,6 +42,34 @@ ---------------------------------------------------------------------------*/ +/* 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; diff --git a/reactos/subsystems/win32/win32k/include/region.h b/reactos/subsystems/win32/win32k/include/region.h index f09ffb56ef4..a7583fbf36b 100644 --- a/reactos/subsystems/win32/win32k/include/region.h +++ b/reactos/subsystems/win32/win32k/include/region.h @@ -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 */ diff --git a/reactos/subsystems/win32/win32k/ntuser/windc.c b/reactos/subsystems/win32/win32k/ntuser/windc.c index 8be75da50c0..fdf8f488e94 100644 --- a/reactos/subsystems/win32/win32k/ntuser/windc.c +++ b/reactos/subsystems/win32/win32k/ntuser/windc.c @@ -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; diff --git a/reactos/subsystems/win32/win32k/objects/cliprgn.c b/reactos/subsystems/win32/win32k/objects/cliprgn.c index be7e5e72cd4..9b7416c6dea 100644 --- a/reactos/subsystems/win32/win32k/objects/cliprgn.c +++ b/reactos/subsystems/win32/win32k/objects/cliprgn.c @@ -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); - - co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount, - ((PROSRGNDATA)pDC->prgnRao)->Buffer, - &pDC->erclClip); + IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y); - return REGION_Complexity(pDC->prgnRao); + 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); + + pDC->rosdc.CombinedClip = co; + + return IntGdiOffsetRgn(pDC->prgnRao, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y); } /* EOF */ diff --git a/reactos/subsystems/win32/win32k/objects/dclife.c b/reactos/subsystems/win32/win32k/objects/dclife.c index be3ad345476..3837b78567d 100644 --- a/reactos/subsystems/win32/win32k/objects/dclife.c +++ b/reactos/subsystems/win32/win32k/objects/dclife.c @@ -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); diff --git a/reactos/subsystems/win32/win32k/objects/dcstate.c b/reactos/subsystems/win32/win32k/objects/dcstate.c index 44e690d2390..9e491a4f0b1 100644 --- a/reactos/subsystems/win32/win32k/objects/dcstate.c +++ b/reactos/subsystems/win32/win32k/objects/dcstate.c @@ -13,16 +13,13 @@ 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; diff --git a/reactos/subsystems/win32/win32k/objects/gdiobj.c b/reactos/subsystems/win32/win32k/objects/gdiobj.c index 244c41ea766..62b7111b1eb 100644 --- a/reactos/subsystems/win32/win32k/objects/gdiobj.c +++ b/reactos/subsystems/win32/win32k/objects/gdiobj.c @@ -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; } } diff --git a/reactos/subsystems/win32/win32k/objects/region.c b/reactos/subsystems/win32/win32k/objects/region.c index ff76b6a1c00..083f6bd345c 100644 --- a/reactos/subsystems/win32/win32k/objects/region.c +++ b/reactos/subsystems/win32/win32k/objects/region.c @@ -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; }