- Slap *a bit* of sense in the way we use region objects and handles, avoiding a massive orgy of handle allocations, locks, leaks and so on.
The motto here being "if you don't need a valid user-mode handle, then chances are that you don't need one at all."
CORE-8506 #resolve #comment Stale region handles should not be passed anymore to user-mode apps now.

svn path=/trunk/; revision=64177
This commit is contained in:
Jérôme Gardou 2014-09-17 09:54:27 +00:00
parent 726e4806e9
commit 215e0d90a1
18 changed files with 600 additions and 508 deletions

View file

@ -52,41 +52,31 @@ IntEngWndUpdateClipObj(
XCLIPOBJ* Clip, XCLIPOBJ* Clip,
PWND Window) PWND Window)
{ {
HRGN hVisRgn;
PROSRGNDATA visRgn; PROSRGNDATA visRgn;
TRACE("IntEngWndUpdateClipObj\n"); TRACE("IntEngWndUpdateClipObj\n");
hVisRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE); visRgn = VIS_ComputeVisibleRegion(Window, TRUE, TRUE, TRUE);
if (hVisRgn != NULL) if (visRgn != NULL)
{ {
visRgn = RGNOBJAPI_Lock(hVisRgn, NULL); if (visRgn->rdh.nCount > 0)
if (visRgn != NULL)
{ {
if (visRgn->rdh.nCount > 0) IntEngUpdateClipRegion(Clip, visRgn->rdh.nCount, visRgn->Buffer, &visRgn->rdh.rcBound);
TRACE("Created visible region with %lu rects\n", visRgn->rdh.nCount);
TRACE(" BoundingRect: %d, %d %d, %d\n",
visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,
visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);
{ {
IntEngUpdateClipRegion(Clip, visRgn->rdh.nCount, visRgn->Buffer, &visRgn->rdh.rcBound); ULONG i;
TRACE("Created visible region with %lu rects\n", visRgn->rdh.nCount); for (i = 0; i < visRgn->rdh.nCount; i++)
TRACE(" BoundingRect: %d, %d %d, %d\n",
visRgn->rdh.rcBound.left, visRgn->rdh.rcBound.top,
visRgn->rdh.rcBound.right, visRgn->rdh.rcBound.bottom);
{ {
ULONG i; TRACE(" Rect #%lu: %ld,%ld %ld,%ld\n", i+1,
for (i = 0; i < visRgn->rdh.nCount; i++) visRgn->Buffer[i].left, visRgn->Buffer[i].top,
{ visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);
TRACE(" Rect #%lu: %ld,%ld %ld,%ld\n", i+1,
visRgn->Buffer[i].left, visRgn->Buffer[i].top,
visRgn->Buffer[i].right, visRgn->Buffer[i].bottom);
}
} }
} }
RGNOBJAPI_Unlock(visRgn);
} }
else REGION_Delete(visRgn);
{
WARN("Couldn't lock visible region of window DC\n");
}
GreDeleteObject(hVisRgn);
} }
else else
{ {

View file

@ -477,7 +477,7 @@ NtGdiSelectClipPath(
HDC hDC, HDC hDC,
int Mode) int Mode)
{ {
HRGN hrgnPath; PREGION RgnPath;
PPATH pPath; PPATH pPath;
BOOL success = FALSE; BOOL success = FALSE;
PDC_ATTR pdcattr; PDC_ATTR pdcattr;
@ -507,21 +507,31 @@ NtGdiSelectClipPath(
} }
/* Construct a region from the path */ /* Construct a region from the path */
else if (PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgnPath)) RgnPath = IntSysCreateRectpRgn(0, 0, 0, 0);
if (!RgnPath)
{ {
PREGION prgnPath = REGION_LockRgn(hrgnPath); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
ASSERT(prgnPath); DC_UnlockDc(pdc);
success = IntGdiExtSelectClipRgn(pdc, prgnPath, Mode) != ERROR; return FALSE;
REGION_UnlockRgn(prgnPath);
GreDeleteObject( hrgnPath );
/* Empty the path */
if (success)
PATH_EmptyPath(pPath);
/* FIXME: Should this function delete the path even if it failed? */
} }
if (!PATH_PathToRegion(pPath, pdcattr->jFillMode, RgnPath))
{
EngSetLastError(ERROR_CAN_NOT_COMPLETE);
REGION_Delete(RgnPath);
DC_UnlockDc(pdc);
return FALSE;
}
success = IntGdiExtSelectClipRgn(pdc, RgnPath, Mode) != ERROR;
REGION_Delete(RgnPath);
/* Empty the path */
if (success)
PATH_EmptyPath(pPath);
/* FIXME: Should this function delete the path even if it failed? */
PATH_UnlockPath(pPath); PATH_UnlockPath(pPath);
DC_UnlockDc(pdc); DC_UnlockDc(pdc);

View file

@ -458,8 +458,24 @@ NtGdiPolyPolyDraw( IN HDC hDC,
/* Special handling for GdiPolyPolyRgn */ /* Special handling for GdiPolyPolyRgn */
if (iFunc == GdiPolyPolyRgn) if (iFunc == GdiPolyPolyRgn)
{ {
PREGION Rgn;
HRGN hRgn; HRGN hRgn;
hRgn = IntCreatePolyPolygonRgn(SafePoints, SafeCounts, Count, (INT_PTR)hDC);
Rgn = REGION_AllocUserRgnWithHandle(0);
if (!Rgn)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
ExFreePoolWithTag(pTemp, TAG_SHAPE);
return 0;
}
hRgn = Rgn->BaseObject.hHmgr;
if (!IntSetPolyPolygonRgn(SafePoints, SafeCounts, Count, hDC ? 1 : 2, Rgn))
{
/* EngSetLastError ? */
GreDeleteObject(hRgn);
hRgn = NULL;
}
RGNOBJAPI_Unlock(Rgn);
ExFreePoolWithTag(pTemp, TAG_SHAPE); ExFreePoolWithTag(pTemp, TAG_SHAPE);
return (ULONG_PTR)hRgn; return (ULONG_PTR)hRgn;
} }

View file

@ -98,7 +98,7 @@ PATH_FillPath(
//SIZE ptViewportExt, ptWindowExt; //SIZE ptViewportExt, ptWindowExt;
//POINTL ptViewportOrg, ptWindowOrg; //POINTL ptViewportOrg, ptWindowOrg;
XFORM xform; XFORM xform;
HRGN hrgn; PREGION Rgn;
PDC_ATTR pdcattr = dc->pdcattr; PDC_ATTR pdcattr = dc->pdcattr;
if (pPath->state != PATH_Closed) if (pPath->state != PATH_Closed)
@ -107,61 +107,72 @@ PATH_FillPath(
return FALSE; return FALSE;
} }
if (PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgn)) /* Allocate a temporary region */
Rgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (!Rgn)
{ {
/* Since PaintRgn interprets the region as being in logical coordinates EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
* but the points we store for the path are already in device return FALSE;
* coordinates, we have to set the mapping mode to MM_TEXT temporarily. }
* Using SaveDC to save information about the mapping mode / world
* transform would be easier but would require more overhead, especially
* now that SaveDC saves the current path.
*/
/* Save the information about the old mapping mode */ if (!PATH_PathToRegion(pPath, pdcattr->jFillMode, Rgn))
//mapMode = pdcattr->iMapMode; {
//ptViewportExt = pdcattr->szlViewportExt; /* EngSetLastError ? */
//ptViewportOrg = pdcattr->ptlViewportOrg; REGION_Delete(Rgn);
//ptWindowExt = pdcattr->szlWindowExt; return FALSE;
//ptWindowOrg = pdcattr->ptlWindowOrg; }
/* Save world transform /* Since PaintRgn interprets the region as being in logical coordinates
* NB: The Windows documentation on world transforms would lead one to * but the points we store for the path are already in device
* believe that this has to be done only in GM_ADVANCED; however, my * coordinates, we have to set the mapping mode to MM_TEXT temporarily.
* tests show that resetting the graphics mode to GM_COMPATIBLE does * Using SaveDC to save information about the mapping mode / world
* not reset the world transform. * transform would be easier but would require more overhead, especially
*/ * now that SaveDC saves the current path.
MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage); */
/* Set MM_TEXT */ /* Save the information about the old mapping mode */
//mapMode = pdcattr->iMapMode;
//ptViewportExt = pdcattr->szlViewportExt;
//ptViewportOrg = pdcattr->ptlViewportOrg;
//ptWindowExt = pdcattr->szlWindowExt;
//ptWindowOrg = pdcattr->ptlWindowOrg;
/* Save world transform
* NB: The Windows documentation on world transforms would lead one to
* believe that this has to be done only in GM_ADVANCED; however, my
* tests show that resetting the graphics mode to GM_COMPATIBLE does
* not reset the world transform.
*/
MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage);
/* Set MM_TEXT */
// IntGdiSetMapMode(dc, MM_TEXT); // IntGdiSetMapMode(dc, MM_TEXT);
// pdcattr->ptlViewportOrg.x = 0; // pdcattr->ptlViewportOrg.x = 0;
// pdcattr->ptlViewportOrg.y = 0; // pdcattr->ptlViewportOrg.y = 0;
// pdcattr->ptlWindowOrg.x = 0; // pdcattr->ptlWindowOrg.x = 0;
// pdcattr->ptlWindowOrg.y = 0; // pdcattr->ptlWindowOrg.y = 0;
// graphicsMode = pdcattr->iGraphicsMode; // graphicsMode = pdcattr->iGraphicsMode;
// pdcattr->iGraphicsMode = GM_ADVANCED; // pdcattr->iGraphicsMode = GM_ADVANCED;
// IntGdiModifyWorldTransform(dc, &xform, MWT_IDENTITY); // IntGdiModifyWorldTransform(dc, &xform, MWT_IDENTITY);
// pdcattr->iGraphicsMode = graphicsMode; // pdcattr->iGraphicsMode = graphicsMode;
/* Paint the region */ /* Paint the region */
IntGdiPaintRgn(dc, hrgn); IntGdiPaintRgn(dc, Rgn);
GreDeleteObject(hrgn); REGION_Delete(Rgn);
/* Restore the old mapping mode */ /* Restore the old mapping mode */
// IntGdiSetMapMode(dc, mapMode); // IntGdiSetMapMode(dc, mapMode);
// pdcattr->szlViewportExt = ptViewportExt; // pdcattr->szlViewportExt = ptViewportExt;
// pdcattr->ptlViewportOrg = ptViewportOrg; // pdcattr->ptlViewportOrg = ptViewportOrg;
// pdcattr->szlWindowExt = ptWindowExt; // pdcattr->szlWindowExt = ptWindowExt;
// pdcattr->ptlWindowOrg = ptWindowOrg; // pdcattr->ptlWindowOrg = ptWindowOrg;
/* Go to GM_ADVANCED temporarily to restore the world transform */ /* Go to GM_ADVANCED temporarily to restore the world transform */
//graphicsMode = pdcattr->iGraphicsMode; //graphicsMode = pdcattr->iGraphicsMode;
// pdcattr->iGraphicsMode = GM_ADVANCED; // pdcattr->iGraphicsMode = GM_ADVANCED;
// IntGdiModifyWorldTransform(dc, &xform, MWT_MAX+1); // IntGdiModifyWorldTransform(dc, &xform, MWT_MAX+1);
// pdcattr->iGraphicsMode = graphicsMode; // pdcattr->iGraphicsMode = graphicsMode;
return TRUE; return TRUE;
}
return FALSE;
} }
/* PATH_InitGdiPath /* PATH_InitGdiPath
@ -1221,14 +1232,14 @@ FASTCALL
PATH_PathToRegion( PATH_PathToRegion(
PPATH pPath, PPATH pPath,
INT nPolyFillMode, INT nPolyFillMode,
HRGN *pHrgn) PREGION Rgn)
{ {
int numStrokes, iStroke, i; int numStrokes, iStroke, i;
PULONG pNumPointsInStroke; PULONG pNumPointsInStroke;
HRGN hrgn = 0; BOOL Ret;
ASSERT(pPath != NULL); ASSERT(pPath != NULL);
ASSERT(pHrgn != NULL); ASSERT(Rgn != NULL);
PATH_FlattenPath(pPath); PATH_FlattenPath(pPath);
@ -1268,23 +1279,18 @@ PATH_PathToRegion(
pNumPointsInStroke[iStroke]++; pNumPointsInStroke[iStroke]++;
} }
/* Create a region from the strokes */ /* Fill the region with the strokes */
hrgn = IntCreatePolyPolygonRgn(pPath->pPoints, Ret = IntSetPolyPolygonRgn(pPath->pPoints,
pNumPointsInStroke, pNumPointsInStroke,
numStrokes, numStrokes,
nPolyFillMode); nPolyFillMode,
if (hrgn == (HRGN)0) Rgn);
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
/* Free memory for number-of-points-in-stroke array */ /* Free memory for number-of-points-in-stroke array */
ExFreePoolWithTag(pNumPointsInStroke, TAG_PATH); ExFreePoolWithTag(pNumPointsInStroke, TAG_PATH);
/* Success! */ /* Success! */
*pHrgn = hrgn; return Ret;
return TRUE;
} }
/* PATH_EmptyPath /* PATH_EmptyPath
@ -2675,6 +2681,7 @@ NtGdiPathToRegion(HDC hDC)
{ {
PPATH pPath; PPATH pPath;
HRGN hrgnRval = 0; HRGN hrgnRval = 0;
PREGION Rgn;
DC *pDc; DC *pDc;
PDC_ATTR pdcattr; PDC_ATTR pdcattr;
@ -2703,9 +2710,25 @@ NtGdiPathToRegion(HDC hDC)
} }
else else
{ {
/* Create the region and fill it with the path strokes */
Rgn = REGION_AllocUserRgnWithHandle(1);
if (!Rgn)
{
PATH_UnlockPath(pPath);
DC_UnlockDc(pDc);
}
hrgnRval = Rgn->BaseObject.hHmgr;
/* FIXME: Should we empty the path even if conversion failed? */ /* FIXME: Should we empty the path even if conversion failed? */
if (PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgnRval)) if (PATH_PathToRegion(pPath, pdcattr->jFillMode, Rgn))
{
PATH_EmptyPath(pPath); PATH_EmptyPath(pPath);
}
else
{
GreDeleteObject(hrgnRval);
hrgnRval = NULL;
}
RGNOBJAPI_Unlock(Rgn);
} }
PATH_UnlockPath(pPath); PATH_UnlockPath(pPath);

View file

@ -67,7 +67,7 @@ BOOL FASTCALL PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UI
BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines); BOOL FASTCALL PATH_PolyPolyline( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines);
BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2); BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2);
BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height); BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height);
BOOL FASTCALL PATH_PathToRegion (PPATH pPath, INT nPolyFillMode, HRGN *pHrgn); BOOL FASTCALL PATH_PathToRegion (PPATH pPath, INT nPolyFillMode, PREGION Rgn);
BOOL FASTCALL PATH_ExtTextOut(PDC dc,INT x,INT y,UINT flags,const RECTL *lprc,LPCWSTR str,UINT count,const INT *dx); BOOL FASTCALL PATH_ExtTextOut(PDC dc,INT x,INT y,UINT flags,const RECTL *lprc,LPCWSTR str,UINT count,const INT *dx);
BOOL FASTCALL PATH_AddEntry (PPATH pPath, const POINT *pPoint, BYTE flags); BOOL FASTCALL PATH_AddEntry (PPATH pPath, const POINT *pPoint, BYTE flags);

View file

@ -1956,46 +1956,35 @@ REGION_CreateFrameRgn(
} }
static
BOOL FASTCALL BOOL FASTCALL
REGION_LPTODP( REGION_LPTODP(
PDC dc, _In_ PDC dc,
HRGN hDest, _Inout_ PREGION RgnDest,
HRGN hSrc) _In_ PREGION RgnSrc)
{ {
RECTL *pCurRect, *pEndRect; RECTL *pCurRect, *pEndRect;
PROSRGNDATA srcObj = NULL;
PROSRGNDATA destObj = NULL;
RECTL tmpRect; RECTL tmpRect;
BOOL ret = FALSE;
PDC_ATTR pdcattr; PDC_ATTR pdcattr;
if (!dc) if (!dc)
return ret; return FALSE;
pdcattr = dc->pdcattr; pdcattr = dc->pdcattr;
if (pdcattr->iMapMode == MM_TEXT) // Requires only a translation if (pdcattr->iMapMode == MM_TEXT) // Requires only a translation
{ {
if (NtGdiCombineRgn(hDest, hSrc, 0, RGN_COPY) == ERROR) if (IntGdiCombineRgn(RgnDest, RgnSrc, 0, RGN_COPY) == ERROR)
goto done; return FALSE;
NtGdiOffsetRgn(hDest, pdcattr->ptlViewportOrg.x - pdcattr->ptlWindowOrg.x, IntGdiOffsetRgn(RgnDest, pdcattr->ptlViewportOrg.x - pdcattr->ptlWindowOrg.x,
pdcattr->ptlViewportOrg.y - pdcattr->ptlWindowOrg.y); pdcattr->ptlViewportOrg.y - pdcattr->ptlWindowOrg.y);
ret = TRUE; return TRUE;
goto done;
} }
if ( !(srcObj = RGNOBJAPI_Lock(hSrc, NULL)) ) EMPTY_REGION(RgnDest);
goto done;
if ( !(destObj = RGNOBJAPI_Lock(hDest, NULL)) )
{
RGNOBJAPI_Unlock(srcObj);
goto done;
}
EMPTY_REGION(destObj);
pEndRect = srcObj->Buffer + srcObj->rdh.nCount; pEndRect = RgnSrc->Buffer + RgnSrc->rdh.nCount;
for (pCurRect = srcObj->Buffer; pCurRect < pEndRect; pCurRect++) for (pCurRect = RgnSrc->Buffer; pCurRect < pEndRect; pCurRect++)
{ {
tmpRect = *pCurRect; tmpRect = *pCurRect;
tmpRect.left = XLPTODP(pdcattr, tmpRect.left); tmpRect.left = XLPTODP(pdcattr, tmpRect.left);
@ -2016,15 +2005,10 @@ REGION_LPTODP(
tmpRect.bottom = tmp; tmpRect.bottom = tmp;
} }
REGION_UnionRectWithRgn(destObj, &tmpRect); REGION_UnionRectWithRgn(RgnDest, &tmpRect);
} }
ret = TRUE;
RGNOBJAPI_Unlock(srcObj); return TRUE;
RGNOBJAPI_Unlock(destObj);
done:
return ret;
} }
PROSRGNDATA PROSRGNDATA
@ -2236,7 +2220,7 @@ IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
PREGION prgn; PREGION prgn;
/* Allocate a region, witout a handle */ /* Allocate a region, witout a handle */
prgn = (PREGION)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE, sizeof(REGION), 0); prgn = (PREGION)GDIOBJ_AllocateObject(GDIObjType_RGN_TYPE, sizeof(REGION), BASEFLAG_LOOKASIDE);
if (!prgn) if (!prgn)
{ {
return NULL; return NULL;
@ -2250,31 +2234,6 @@ IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
return prgn; return prgn;
} }
HRGN
FASTCALL
IntSysCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
{
PREGION prgn;
HRGN hrgn;
/* Allocate a region, witout a handle */
prgn = (PREGION)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_REGION, sizeof(REGION));
if (!prgn)
{
return NULL;
}
/* Initialize it */
prgn->Buffer = &prgn->rdh.rcBound;
REGION_SetRectRgn(prgn, LeftRect, TopRect, RightRect, BottomRect);
hrgn = prgn->BaseObject.hHmgr;
prgn->prgnattr = &prgn->rgnattr;
REGION_UnlockRgn(prgn);
return hrgn;
}
VOID NTAPI VOID NTAPI
REGION_vCleanup(PVOID ObjectBody) REGION_vCleanup(PVOID ObjectBody)
{ {
@ -2479,44 +2438,42 @@ BOOL
FASTCALL FASTCALL
IntGdiPaintRgn( IntGdiPaintRgn(
PDC dc, PDC dc,
HRGN hRgn PREGION Rgn
) )
{ {
HRGN tmpVisRgn; PROSRGNDATA VisRgn;
PROSRGNDATA visrgn;
XCLIPOBJ ClipRegion; XCLIPOBJ ClipRegion;
BOOL bRet = FALSE; BOOL bRet = FALSE;
POINTL BrushOrigin; POINTL BrushOrigin;
SURFACE *psurf; SURFACE *psurf;
PDC_ATTR pdcattr; PDC_ATTR pdcattr;
if (!dc) return FALSE; if (!dc || !Rgn)
return FALSE;
pdcattr = dc->pdcattr; pdcattr = dc->pdcattr;
ASSERT(!(pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))); ASSERT(!(pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)));
if (!(tmpVisRgn = IntSysCreateRectRgn(0, 0, 0, 0))) return FALSE; VisRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (!VisRgn)
// Transform region into device co-ords
if (!REGION_LPTODP(dc, tmpVisRgn, hRgn) ||
NtGdiOffsetRgn(tmpVisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
{ {
GreDeleteObject(tmpVisRgn);
return FALSE; return FALSE;
} }
visrgn = RGNOBJAPI_Lock(tmpVisRgn, NULL); // Transform region into device co-ords
if (visrgn == NULL) if (!REGION_LPTODP(dc, VisRgn, Rgn) ||
IntGdiOffsetRgn(VisRgn, dc->ptlDCOrig.x, dc->ptlDCOrig.y) == ERROR)
{ {
GreDeleteObject(tmpVisRgn); REGION_Delete(VisRgn);
return FALSE; return FALSE;
} }
if (dc->prgnRao) if (dc->prgnRao)
IntGdiCombineRgn(visrgn, visrgn, dc->prgnRao, RGN_AND); IntGdiCombineRgn(VisRgn, VisRgn, dc->prgnRao, RGN_AND);
IntEngInitClipObj(&ClipRegion); IntEngInitClipObj(&ClipRegion);
IntEngUpdateClipRegion(&ClipRegion, visrgn->rdh.nCount, visrgn->Buffer, &visrgn->rdh.rcBound ); IntEngUpdateClipRegion(&ClipRegion, VisRgn->rdh.nCount, VisRgn->Buffer, &VisRgn->rdh.rcBound );
BrushOrigin.x = pdcattr->ptlBrushOrigin.x; BrushOrigin.x = pdcattr->ptlBrushOrigin.x;
BrushOrigin.y = pdcattr->ptlBrushOrigin.y; BrushOrigin.y = pdcattr->ptlBrushOrigin.y;
@ -2529,8 +2486,7 @@ IntGdiPaintRgn(
&BrushOrigin, &BrushOrigin,
0xFFFF); // FIXME: Don't know what to put here 0xFFFF); // FIXME: Don't know what to put here
RGNOBJAPI_Unlock(visrgn); REGION_Delete(VisRgn);
GreDeleteObject(tmpVisRgn);
IntEngFreeClipResources(&ClipRegion); IntEngFreeClipResources(&ClipRegion);
// Fill the region // Fill the region
@ -3129,16 +3085,15 @@ REGION_CreateETandAET(
} }
} }
HRGN FASTCALL BOOL FASTCALL
IntCreatePolyPolygonRgn( IntSetPolyPolygonRgn(
POINT *Pts, POINT *Pts,
PULONG Count, PULONG Count,
INT nbpolygons, INT nbpolygons,
INT mode INT mode,
PREGION Rgn
) )
{ {
HRGN hrgn;
ROSRGNDATA *region;
EdgeTableEntry *pAET; /* Active Edge Table */ EdgeTableEntry *pAET; /* Active Edge Table */
INT y; /* Current scanline */ INT y; /* Current scanline */
int iPts = 0; /* Number of pts in buffer */ int iPts = 0; /* Number of pts in buffer */
@ -3158,10 +3113,6 @@ IntCreatePolyPolygonRgn(
if (mode == 0 || mode > 2) return 0; if (mode == 0 || mode > 2) return 0;
if (!(region = REGION_AllocUserRgnWithHandle(nbpolygons)))
return 0;
hrgn = region->BaseObject.hHmgr;
/* Special case a rectangle */ /* Special case a rectangle */
if (((nbpolygons == 1) && ((*Count == 4) || if (((nbpolygons == 1) && ((*Count == 4) ||
@ -3175,18 +3126,19 @@ IntCreatePolyPolygonRgn(
(Pts[2].x == Pts[3].x) && (Pts[2].x == Pts[3].x) &&
(Pts[3].y == Pts[0].y)))) (Pts[3].y == Pts[0].y))))
{ {
RGNOBJAPI_Unlock(region); REGION_SetRectRgn(Rgn,
NtGdiSetRectRgn(hrgn, min(Pts[0].x, Pts[2].x), min(Pts[0].y, Pts[2].y), min(Pts[0].x, Pts[2].x),
max(Pts[0].x, Pts[2].x), max(Pts[0].y, Pts[2].y)); min(Pts[0].y, Pts[2].y),
return hrgn; max(Pts[0].x, Pts[2].x),
max(Pts[0].y, Pts[2].y));
return TRUE;
} }
for (poly = total = 0; poly < nbpolygons; poly++) for (poly = total = 0; poly < nbpolygons; poly++)
total += Count[poly]; total += Count[poly];
if (! (pETEs = ExAllocatePoolWithTag(PagedPool, sizeof(EdgeTableEntry) * total, TAG_REGION)) ) if (! (pETEs = ExAllocatePoolWithTag(PagedPool, sizeof(EdgeTableEntry) * total, TAG_REGION)) )
{ {
GreDeleteObject(hrgn); return FALSE;
return 0;
} }
pts = FirstPtBlock.pts; pts = FirstPtBlock.pts;
REGION_CreateETandAET(Count, nbpolygons, Pts, &ET, &AET, pETEs, &SLLBlock); REGION_CreateETandAET(Count, nbpolygons, Pts, &ET, &AET, pETEs, &SLLBlock);
@ -3230,7 +3182,7 @@ IntCreatePolyPolygonRgn(
{ {
DPRINT1("Can't alloc tPB\n"); DPRINT1("Can't alloc tPB\n");
ExFreePoolWithTag(pETEs, TAG_REGION); ExFreePoolWithTag(pETEs, TAG_REGION);
return 0; return FALSE;
} }
curPtBlock->next = tmpPtBlock; curPtBlock->next = tmpPtBlock;
curPtBlock = tmpPtBlock; curPtBlock = tmpPtBlock;
@ -3289,8 +3241,7 @@ IntCreatePolyPolygonRgn(
{ {
DPRINT1("Can't alloc tPB\n"); DPRINT1("Can't alloc tPB\n");
ExFreePoolWithTag(pETEs, TAG_REGION); ExFreePoolWithTag(pETEs, TAG_REGION);
GreDeleteObject(hrgn); return FALSE;
return 0;
} }
curPtBlock->next = tmpPtBlock; curPtBlock->next = tmpPtBlock;
curPtBlock = tmpPtBlock; curPtBlock = tmpPtBlock;
@ -3315,7 +3266,7 @@ IntCreatePolyPolygonRgn(
} }
} }
REGION_FreeStorage(SLLBlock.next); REGION_FreeStorage(SLLBlock.next);
REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); REGION_PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, Rgn);
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;)
{ {
@ -3324,8 +3275,7 @@ IntCreatePolyPolygonRgn(
curPtBlock = tmpPtBlock; curPtBlock = tmpPtBlock;
} }
ExFreePoolWithTag(pETEs, TAG_REGION); ExFreePoolWithTag(pETEs, TAG_REGION);
RGNOBJAPI_Unlock(region); return TRUE;
return hrgn;
} }
BOOL BOOL
@ -3432,6 +3382,8 @@ NtGdiCreateRectRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect); REGION_SetRectRgn(pRgn, LeftRect, TopRect, RightRect, BottomRect);
RGNOBJAPI_Unlock(pRgn); RGNOBJAPI_Unlock(pRgn);
DPRINT1("Returning %p.\n", hRgn);
return hRgn; return hRgn;
} }
@ -3762,7 +3714,7 @@ NtGdiFrameRgn(
HRGN FrameRgn; HRGN FrameRgn;
BOOL Ret; BOOL Ret;
if (!(FrameRgn = IntSysCreateRectRgn(0, 0, 0, 0))) if (!(FrameRgn = NtGdiCreateRectRgn(0, 0, 0, 0)))
{ {
return FALSE; return FALSE;
} }

View file

@ -40,8 +40,8 @@ VOID FASTCALL IntGdiReleaseRaoRgn(PDC);
VOID FASTCALL IntGdiReleaseVisRgn(PDC); VOID FASTCALL IntGdiReleaseVisRgn(PDC);
INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*); INT APIENTRY IntGdiGetRgnBox(HRGN, RECTL*);
BOOL FASTCALL IntGdiPaintRgn(PDC, HRGN ); BOOL FASTCALL IntGdiPaintRgn(PDC, PREGION );
HRGN FASTCALL IntCreatePolyPolygonRgn(PPOINT, PULONG, INT, INT); BOOL FASTCALL IntSetPolyPolygonRgn(PPOINT, PULONG, INT, INT, PREGION);
INT FASTCALL IntGdiOffsetRgn(PROSRGNDATA,INT,INT); INT FASTCALL IntGdiOffsetRgn(PROSRGNDATA,INT,INT);
BOOL FASTCALL IntRectInRegion(HRGN,LPRECTL); BOOL FASTCALL IntRectInRegion(HRGN,LPRECTL);
@ -49,13 +49,9 @@ INT FASTCALL IntGdiCombineRgn(PROSRGNDATA, PROSRGNDATA, PROSRGNDATA, INT);
INT FASTCALL REGION_Complexity(PROSRGNDATA); INT FASTCALL REGION_Complexity(PROSRGNDATA);
PROSRGNDATA FASTCALL RGNOBJAPI_Lock(HRGN,PRGN_ATTR *); PROSRGNDATA FASTCALL RGNOBJAPI_Lock(HRGN,PRGN_ATTR *);
VOID FASTCALL RGNOBJAPI_Unlock(PROSRGNDATA); VOID FASTCALL RGNOBJAPI_Unlock(PROSRGNDATA);
HRGN FASTCALL IntSysCreateRectRgn(INT,INT,INT,INT);
PROSRGNDATA FASTCALL IntSysCreateRectpRgn(INT,INT,INT,INT); PROSRGNDATA FASTCALL IntSysCreateRectpRgn(INT,INT,INT,INT);
BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD); BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD);
#define IntSysCreateRectRgnIndirect(prc) \
IntSysCreateRectRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)
#define IntSysCreateRectpRgnIndirect(prc) \ #define IntSysCreateRectpRgnIndirect(prc) \
IntSysCreateRectpRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom) IntSysCreateRectpRgn((prc)->left, (prc)->top, (prc)->right, (prc)->bottom)

View file

@ -1010,16 +1010,20 @@ IntDefWindowProc(
case WM_SYNCPAINT: case WM_SYNCPAINT:
{ {
HRGN hRgn; PREGION Rgn;
Wnd->state &= ~WNDS_SYNCPAINTPENDING; Wnd->state &= ~WNDS_SYNCPAINTPENDING;
ERR("WM_SYNCPAINT\n"); ERR("WM_SYNCPAINT\n");
hRgn = IntSysCreateRectRgn(0, 0, 0, 0); Rgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION) if (Rgn)
{ {
if (!wParam) wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN); if (co_UserGetUpdateRgn(Wnd, Rgn, FALSE) != NULLREGION)
co_UserRedrawWindow(Wnd, NULL, hRgn, wParam); {
if (!wParam)
wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
co_UserRedrawWindow(Wnd, NULL, Rgn, wParam);
}
REGION_Delete(Rgn);
} }
GreDeleteObject(hRgn);
return 0; return 0;
} }

View file

@ -752,19 +752,19 @@ VOID APIENTRY
UserRedrawDesktop() UserRedrawDesktop()
{ {
PWND Window = NULL; PWND Window = NULL;
HRGN hRgn; PREGION Rgn;
Window = UserGetDesktopWindow(); Window = UserGetDesktopWindow();
hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow); Rgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
IntInvalidateWindows( Window, IntInvalidateWindows( Window,
hRgn, Rgn,
RDW_FRAME | RDW_FRAME |
RDW_ERASE | RDW_ERASE |
RDW_INVALIDATE | RDW_INVALIDATE |
RDW_ALLCHILDREN); RDW_ALLCHILDREN);
GreDeleteObject(hRgn); REGION_Delete(Rgn);
} }

View file

@ -652,7 +652,6 @@ IntDispatchMessage(PMSG pMsg)
LRESULT retval = 0; LRESULT retval = 0;
PTHREADINFO pti; PTHREADINFO pti;
PWND Window = NULL; PWND Window = NULL;
HRGN hrgn;
BOOL DoCallBack = TRUE; BOOL DoCallBack = TRUE;
if (pMsg->hwnd) if (pMsg->hwnd)
@ -743,11 +742,12 @@ IntDispatchMessage(PMSG pMsg)
if (pMsg->message == WM_PAINT) if (pMsg->message == WM_PAINT)
{ {
PREGION Rgn;
Window->state2 &= ~WNDS2_WMPAINTSENT; Window->state2 &= ~WNDS2_WMPAINTSENT;
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */ /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 ); Rgn = IntSysCreateRectpRgn( 0, 0, 0, 0 );
co_UserGetUpdateRgn( Window, hrgn, TRUE ); co_UserGetUpdateRgn( Window, Rgn, TRUE );
GreDeleteObject(hrgn); REGION_Delete(Rgn);
} }
return retval; return retval;

View file

@ -258,7 +258,11 @@ UserUpdateMonitorSize(IN HDEV hDev)
} }
/* ...and create new one */ /* ...and create new one */
pMonitor->hrgnMonitor = IntSysCreateRectRgnIndirect(&pMonitor->rcMonitor); pMonitor->hrgnMonitor = NtGdiCreateRectRgn(
pMonitor->rcMonitor.left,
pMonitor->rcMonitor.top,
pMonitor->rcMonitor.right,
pMonitor->rcMonitor.bottom);
if (pMonitor->hrgnMonitor) if (pMonitor->hrgnMonitor)
IntGdiSetRegionOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC); IntGdiSetRegionOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_PUBLIC);

View file

@ -56,7 +56,7 @@ IntIntersectWithParents(PWND Child, RECTL *WindowRect)
} }
BOOL FASTCALL BOOL FASTCALL
IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse) IntValidateParent(PWND Child, PREGION ValidateRgn, BOOL Recurse)
{ {
PWND ParentWnd = Child; PWND ParentWnd = Child;
@ -81,7 +81,7 @@ IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse)
return FALSE; return FALSE;
IntInvalidateWindows( ParentWnd, IntInvalidateWindows( ParentWnd,
hValidateRgn, ValidateRgn,
RDW_VALIDATE | RDW_NOCHILDREN); RDW_VALIDATE | RDW_NOCHILDREN);
} }
@ -177,9 +177,21 @@ IntCalcWindowRgn(PWND Wnd, BOOL Client)
HRGN hRgnWindow; HRGN hRgnWindow;
if (Client) if (Client)
hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcClient); {
hRgnWindow = NtGdiCreateRectRgn(
Wnd->rcClient.left,
Wnd->rcClient.top,
Wnd->rcClient.right,
Wnd->rcClient.bottom);
}
else else
hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow); {
hRgnWindow = NtGdiCreateRectRgn(
Wnd->rcWindow.left,
Wnd->rcWindow.top,
Wnd->rcWindow.right,
Wnd->rcWindow.bottom);
}
if (Wnd->hrgnClip != NULL && !(Wnd->style & WS_MINIMIZE)) if (Wnd->hrgnClip != NULL && !(Wnd->style & WS_MINIMIZE))
{ {
@ -302,8 +314,16 @@ co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
{ {
if (Wnd->hrgnUpdate) if (Wnd->hrgnUpdate)
{ {
if (!IntValidateParent(Wnd, Wnd->hrgnUpdate, Recurse)) PREGION RgnUpdate = RGNOBJAPI_Lock(Wnd->hrgnUpdate, NULL);
return; if (RgnUpdate)
{
if (!IntValidateParent(Wnd, RgnUpdate, Recurse))
{
RGNOBJAPI_Unlock(RgnUpdate);
return;
}
RGNOBJAPI_Unlock(RgnUpdate);
}
} }
if (Flags & RDW_UPDATENOW) if (Flags & RDW_UPDATENOW)
@ -397,7 +417,7 @@ co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
* co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow. * co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow.
*/ */
VOID FASTCALL VOID FASTCALL
IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags) IntInvalidateWindows(PWND Wnd, PREGION Rgn, ULONG Flags)
{ {
INT RgnType; INT RgnType;
BOOL HadPaintMessage; BOOL HadPaintMessage;
@ -412,11 +432,14 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
*/ */
if (0 != (Flags & RDW_INVALIDATE) && 0 == (Flags & RDW_FRAME)) if (0 != (Flags & RDW_INVALIDATE) && 0 == (Flags & RDW_FRAME))
{ {
HRGN hRgnClient; PREGION RgnClient;
hRgnClient = IntSysCreateRectRgnIndirect(&Wnd->rcClient); RgnClient = IntSysCreateRectpRgnIndirect(&Wnd->rcClient);
RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnClient, RGN_AND); if (RgnClient)
GreDeleteObject(hRgnClient); {
RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnClient, RGN_AND);
REGION_Delete(RgnClient);
}
} }
/* /*
@ -425,21 +448,27 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
if (!Wnd->hrgnClip || (Wnd->style & WS_MINIMIZE)) if (!Wnd->hrgnClip || (Wnd->style & WS_MINIMIZE))
{ {
HRGN hRgnWindow; PREGION RgnWindow = IntSysCreateRectpRgnIndirect(&Wnd->rcWindow);
if (RgnWindow)
hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow); {
RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND); RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnWindow, RGN_AND);
GreDeleteObject(hRgnWindow); REGION_Delete(RgnWindow);
}
} }
else else
{ {
NtGdiOffsetRgn( hRgn, PREGION RgnClip = RGNOBJAPI_Lock(Wnd->hrgnClip, NULL);
-Wnd->rcWindow.left, if (RgnClip)
-Wnd->rcWindow.top); {
RgnType = NtGdiCombineRgn(hRgn, hRgn, Wnd->hrgnClip, RGN_AND); IntGdiOffsetRgn( Rgn,
NtGdiOffsetRgn( hRgn, -Wnd->rcWindow.left,
Wnd->rcWindow.left, -Wnd->rcWindow.top);
Wnd->rcWindow.top); RgnType = IntGdiCombineRgn(Rgn, Rgn, RgnClip, RGN_AND);
IntGdiOffsetRgn( Rgn,
Wnd->rcWindow.left,
Wnd->rcWindow.top);
RGNOBJAPI_Unlock(RgnClip);
}
} }
/* /*
@ -462,6 +491,8 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
if (Flags & RDW_INVALIDATE && RgnType != NULLREGION) if (Flags & RDW_INVALIDATE && RgnType != NULLREGION)
{ {
PREGION RgnUpdate;
Wnd->state &= ~WNDS_NONCPAINT; Wnd->state &= ~WNDS_NONCPAINT;
/* If not the same thread set it dirty. */ /* If not the same thread set it dirty. */
@ -479,16 +510,21 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
if (Wnd->hrgnUpdate == NULL) if (Wnd->hrgnUpdate == NULL)
{ {
Wnd->hrgnUpdate = IntSysCreateRectRgn(0, 0, 0, 0); Wnd->hrgnUpdate = NtGdiCreateRectRgn(0, 0, 0, 0);
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC); IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC);
} }
if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate, RgnUpdate = RGNOBJAPI_Lock(Wnd->hrgnUpdate, NULL);
hRgn, RGN_OR) == NULLREGION) if (RgnUpdate)
{ {
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED); RgnType = IntGdiCombineRgn(RgnUpdate, RgnUpdate, Rgn, RGN_OR);
GreDeleteObject(Wnd->hrgnUpdate); RGNOBJAPI_Unlock(RgnUpdate);
Wnd->hrgnUpdate = NULL; if (RgnType == NULLREGION)
{
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Wnd->hrgnUpdate);
Wnd->hrgnUpdate = NULL;
}
} }
Flags |= RDW_FRAME; // For children. Flags |= RDW_FRAME; // For children.
} }
@ -511,13 +547,20 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
if (Wnd->hrgnUpdate != NULL) if (Wnd->hrgnUpdate != NULL)
{ {
if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate, PREGION RgnUpdate = RGNOBJAPI_Lock(Wnd->hrgnUpdate, NULL);
hRgn, RGN_DIFF) == NULLREGION)
{ if (RgnUpdate)
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED); {
GreDeleteObject(Wnd->hrgnUpdate); RgnType = IntGdiCombineRgn(RgnUpdate, RgnUpdate, Rgn, RGN_DIFF);
Wnd->hrgnUpdate = NULL; RGNOBJAPI_Unlock(RgnUpdate);
}
if(RgnType == NULLREGION)
{
IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(Wnd->hrgnUpdate);
Wnd->hrgnUpdate = NULL;
}
}
} }
if (Wnd->hrgnUpdate == NULL) if (Wnd->hrgnUpdate == NULL)
@ -541,10 +584,13 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
/* /*
* Recursive call to update children hrgnUpdate * Recursive call to update children hrgnUpdate
*/ */
HRGN hRgnTemp = IntSysCreateRectRgn(0, 0, 0, 0); PREGION RgnTemp = IntSysCreateRectpRgn(0, 0, 0, 0);
NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY); if (RgnTemp)
IntInvalidateWindows(Child, hRgnTemp, Flags); {
GreDeleteObject(hRgnTemp); IntGdiCombineRgn(RgnTemp, Rgn, 0, RGN_COPY);
IntInvalidateWindows(Child, RgnTemp, Flags);
REGION_Delete(RgnTemp);
}
} }
} }
} }
@ -602,10 +648,10 @@ BOOL FASTCALL
co_UserRedrawWindow( co_UserRedrawWindow(
PWND Window, PWND Window,
const RECTL* UpdateRect, const RECTL* UpdateRect,
HRGN UpdateRgn, PREGION UpdateRgn,
ULONG Flags) ULONG Flags)
{ {
HRGN hRgn = NULL; PREGION TmpRgn = NULL;
TRACE("co_UserRedrawWindow start\n"); TRACE("co_UserRedrawWindow start\n");
/* /*
@ -626,35 +672,37 @@ co_UserRedrawWindow(
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) // Both are OKAY! if (Flags & (RDW_INVALIDATE | RDW_VALIDATE)) // Both are OKAY!
{ {
if (UpdateRgn != NULL) if (UpdateRgn)
{ {
hRgn = IntSysCreateRectRgn(0, 0, 0, 0); TmpRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION) if (IntGdiCombineRgn(TmpRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION)
{ {
GreDeleteObject(hRgn); REGION_Delete(TmpRgn);
hRgn = NULL; TmpRgn = NULL;
} }
else else
NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top); {
IntGdiOffsetRgn(TmpRgn, Window->rcClient.left, Window->rcClient.top);
}
} }
else if (UpdateRect != NULL) else if (UpdateRect != NULL)
{ {
if (!RECTL_bIsEmptyRect(UpdateRect)) if (!RECTL_bIsEmptyRect(UpdateRect))
{ {
hRgn = IntSysCreateRectRgnIndirect((RECTL *)UpdateRect); TmpRgn = IntSysCreateRectpRgnIndirect(UpdateRect);
NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top); IntGdiOffsetRgn(TmpRgn, Window->rcClient.left, Window->rcClient.top);
} }
} }
else if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) || else if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) ||
(Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME)) (Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME))
{ {
if (!RECTL_bIsEmptyRect(&Window->rcWindow)) if (!RECTL_bIsEmptyRect(&Window->rcWindow))
hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow); TmpRgn = IntSysCreateRectpRgnIndirect(&Window->rcWindow);
} }
else else
{ {
if (!RECTL_bIsEmptyRect(&Window->rcClient)) if (!RECTL_bIsEmptyRect(&Window->rcClient))
hRgn = IntSysCreateRectRgnIndirect(&Window->rcClient); TmpRgn = IntSysCreateRectpRgnIndirect(&Window->rcClient);
} }
} }
@ -664,9 +712,9 @@ co_UserRedrawWindow(
*/ */
if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT) && if (Flags & (RDW_INVALIDATE | RDW_VALIDATE | RDW_INTERNALPAINT | RDW_NOINTERNALPAINT) &&
hRgn != NULL) TmpRgn != NULL)
{ {
IntInvalidateWindows(Window, hRgn, Flags); IntInvalidateWindows(Window, TmpRgn, Flags);
} }
/* /*
@ -685,9 +733,9 @@ co_UserRedrawWindow(
* Cleanup ;-) * Cleanup ;-)
*/ */
if (hRgn != NULL) if (TmpRgn != NULL)
{ {
GreDeleteObject(hRgn); REGION_Delete(TmpRgn);
} }
TRACE("co_UserRedrawWindow exit\n"); TRACE("co_UserRedrawWindow exit\n");
@ -991,7 +1039,7 @@ IntBeginPaint(PWND Window, PPAINTSTRUCT Ps)
for (Child = Window->spwndChild; Child; Child = Child->spwndNext) for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
{ {
if (Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT) // Helped fixing test_redrawnow. if (Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT) // Helped fixing test_redrawnow.
IntInvalidateWindows(Child, Window->hrgnUpdate, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN); IntInvalidateWindows(Child, NULL, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
} }
} }
} }
@ -1157,33 +1205,39 @@ Exit:
} }
INT FASTCALL INT FASTCALL
co_UserGetUpdateRgn(PWND Window, HRGN hRgn, BOOL bErase) co_UserGetUpdateRgn(PWND Window, PREGION Rgn, BOOL bErase)
{ {
int RegionType; int RegionType;
RECTL Rect; RECTL Rect;
PREGION UpdateRgn;
ASSERT_REFS_CO(Window); ASSERT_REFS_CO(Window);
Window->state &= ~WNDS_UPDATEDIRTY; Window->state &= ~WNDS_UPDATEDIRTY;
if (Window->hrgnUpdate == NULL) if (Window->hrgnUpdate == NULL)
{ {
RegionType = (NtGdiSetRectRgn(hRgn, 0, 0, 0, 0) ? NULLREGION : ERROR); REGION_SetRectRgn(Rgn, 0, 0, 0, 0);
} return NULLREGION;
else }
{
Rect = Window->rcClient; UpdateRgn = RGNOBJAPI_Lock(Window->hrgnUpdate, NULL);
IntIntersectWithParents(Window, &Rect); if (!UpdateRgn)
NtGdiSetRectRgn(hRgn, Rect.left, Rect.top, Rect.right, Rect.bottom); return ERROR;
RegionType = NtGdiCombineRgn(hRgn, hRgn, Window->hrgnUpdate, RGN_AND);
NtGdiOffsetRgn(hRgn, -Window->rcClient.left, -Window->rcClient.top); Rect = Window->rcClient;
} IntIntersectWithParents(Window, &Rect);
REGION_SetRectRgn(Rgn, Rect.left, Rect.top, Rect.right, Rect.bottom);
RegionType = IntGdiCombineRgn(Rgn, Rgn, UpdateRgn, RGN_AND);
IntGdiOffsetRgn(Rgn, -Window->rcClient.left, -Window->rcClient.top);
if (bErase && RegionType != NULLREGION && RegionType != ERROR) if (bErase && RegionType != NULLREGION && RegionType != ERROR)
{ {
co_UserRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN); co_UserRedrawWindow(Window, NULL, NULL, RDW_ERASENOW | RDW_NOCHILDREN);
} }
RGNOBJAPI_Unlock(UpdateRgn);
return RegionType; return RegionType;
} }
@ -1201,6 +1255,7 @@ NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
PWND Window; PWND Window;
INT ret; INT ret;
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
PREGION Rgn = NULL;
TRACE("Enter NtUserGetUpdateRgn\n"); TRACE("Enter NtUserGetUpdateRgn\n");
UserEnterExclusive(); UserEnterExclusive();
@ -1210,13 +1265,19 @@ NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
RETURN(ERROR); RETURN(ERROR);
} }
Rgn = RGNOBJAPI_Lock(hRgn, NULL);
if (!Rgn)
RETURN(ERROR);
UserRefObjectCo(Window, &Ref); UserRefObjectCo(Window, &Ref);
ret = co_UserGetUpdateRgn(Window, hRgn, bErase); ret = co_UserGetUpdateRgn(Window, Rgn, bErase);
UserDerefObjectCo(Window); UserDerefObjectCo(Window);
RETURN(ret); RETURN(ret);
CLEANUP: CLEANUP:
if (Rgn)
RGNOBJAPI_Unlock(Rgn);
TRACE("Leave NtUserGetUpdateRgn, ret=%i\n",_ret_); TRACE("Leave NtUserGetUpdateRgn, ret=%i\n",_ret_);
UserLeave(); UserLeave();
END_CLEANUP; END_CLEANUP;
@ -1327,6 +1388,7 @@ NtUserRedrawWindow(
BOOL Ret; BOOL Ret;
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PREGION RgnUpdate = NULL;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
TRACE("Enter NtUserRedrawWindow\n"); TRACE("Enter NtUserRedrawWindow\n");
@ -1365,11 +1427,21 @@ NtUserRedrawWindow(
RETURN( FALSE); RETURN( FALSE);
} }
if (hrgnUpdate)
{
RgnUpdate = RGNOBJAPI_Lock(hrgnUpdate, NULL);
if (!RgnUpdate)
{
EngSetLastError(ERROR_INVALID_HANDLE);
RETURN(FALSE);
}
}
UserRefObjectCo(Wnd, &Ref); UserRefObjectCo(Wnd, &Ref);
Ret = co_UserRedrawWindow( Wnd, Ret = co_UserRedrawWindow( Wnd,
lprcUpdate ? &SafeUpdateRect : NULL, lprcUpdate ? &SafeUpdateRect : NULL,
hrgnUpdate, RgnUpdate,
flags); flags);
UserDerefObjectCo(Wnd); UserDerefObjectCo(Wnd);
@ -1377,6 +1449,8 @@ NtUserRedrawWindow(
RETURN( Ret); RETURN( Ret);
CLEANUP: CLEANUP:
if (RgnUpdate)
RGNOBJAPI_Unlock(RgnUpdate);
TRACE("Leave NtUserRedrawWindow, ret=%i\n",_ret_); TRACE("Leave NtUserRedrawWindow, ret=%i\n",_ret_);
UserLeave(); UserLeave();
END_CLEANUP; END_CLEANUP;
@ -1390,7 +1464,7 @@ UserScrollDC(
INT dy, INT dy,
const RECTL *prcScroll, const RECTL *prcScroll,
const RECTL *prcClip, const RECTL *prcClip,
HRGN hrgnUpdate, PREGION RgnUpdate,
RECTL *prcUpdate) RECTL *prcUpdate)
{ {
PDC pDC; PDC pDC;
@ -1435,10 +1509,9 @@ UserScrollDC(
/* Calculate the region that was invalidated by moving or /* Calculate the region that was invalidated by moving or
could not be copied, because it was not visible */ could not be copied, because it was not visible */
if (hrgnUpdate || prcUpdate) if (RgnUpdate || prcUpdate)
{ {
HRGN hrgnOwn, hrgnTmp; PREGION RgnOwn, RgnTmp;
PREGION prgnTmp;
pDC = DC_LockDc(hDC); pDC = DC_LockDc(hDC);
if (!pDC) if (!pDC)
@ -1450,44 +1523,38 @@ UserScrollDC(
rcDst = rcScroll; rcDst = rcScroll;
RECTL_vOffsetRect(&rcDst, dx, dy); RECTL_vOffsetRect(&rcDst, dx, dy);
RECTL_bIntersectRect(&rcDst, &rcDst, &rcClip); RECTL_bIntersectRect(&rcDst, &rcDst, &rcClip);
if (hrgnUpdate) if (RgnUpdate)
{ {
hrgnOwn = hrgnUpdate; RgnOwn = RgnUpdate;
if (!NtGdiSetRectRgn(hrgnOwn, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom)) REGION_SetRectRgn(RgnOwn, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom);
{
DC_UnlockDc(pDC);
return ERROR;
}
} }
else else
{ {
hrgnOwn = IntSysCreateRectRgnIndirect(&rcDst); RgnOwn = IntSysCreateRectpRgnIndirect(&rcDst);
} }
/* Add the source rect */ /* Add the source rect */
hrgnTmp = IntSysCreateRectRgnIndirect(&rcSrc); RgnTmp = IntSysCreateRectpRgnIndirect(&rcSrc);
NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_OR); IntGdiCombineRgn(RgnOwn, RgnOwn, RgnTmp, RGN_OR);
/* Substract the part of the dest that was visible in source */ /* Substract the part of the dest that was visible in source */
prgnTmp = RGNOBJAPI_Lock(hrgnTmp, NULL); IntGdiCombineRgn(RgnTmp, RgnTmp, pDC->prgnVis, RGN_AND);
IntGdiCombineRgn(prgnTmp, prgnTmp, pDC->prgnVis, RGN_AND); IntGdiOffsetRgn(RgnTmp, dx, dy);
RGNOBJAPI_Unlock(prgnTmp); Result = IntGdiCombineRgn(RgnOwn, RgnOwn, RgnTmp, RGN_DIFF);
NtGdiOffsetRgn(hrgnTmp, dx, dy);
Result = NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
/* DO NOT Unlock DC while messing with prgnVis! */ /* DO NOT Unlock DC while messing with prgnVis! */
DC_UnlockDc(pDC); DC_UnlockDc(pDC);
GreDeleteObject(hrgnTmp); REGION_Delete(RgnTmp);
if (prcUpdate) if (prcUpdate)
{ {
IntGdiGetRgnBox(hrgnOwn, prcUpdate); REGION_GetRgnBox(RgnOwn, prcUpdate);
} }
if (!hrgnUpdate) if (!RgnUpdate)
{ {
GreDeleteObject(hrgnOwn); REGION_Delete(RgnOwn);
} }
} }
else else
@ -1516,6 +1583,7 @@ NtUserScrollDC(
RECTL rcScroll, rcClip, rcUpdate; RECTL rcScroll, rcClip, rcUpdate;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DWORD Result; DWORD Result;
PREGION RgnUpdate = NULL;
TRACE("Enter NtUserScrollDC\n"); TRACE("Enter NtUserScrollDC\n");
UserEnterExclusive(); UserEnterExclusive();
@ -1548,12 +1616,19 @@ NtUserScrollDC(
RETURN(FALSE); RETURN(FALSE);
} }
if (hrgnUpdate)
{
RgnUpdate = RGNOBJAPI_Lock(hrgnUpdate, NULL);
if (!RgnUpdate)
RETURN(FALSE);
}
Result = UserScrollDC( hDC, Result = UserScrollDC( hDC,
dx, dx,
dy, dy,
prcUnsafeScroll? &rcScroll : 0, prcUnsafeScroll? &rcScroll : 0,
prcUnsafeClip? &rcClip : 0, prcUnsafeClip? &rcClip : 0,
hrgnUpdate, RgnUpdate,
prcUnsafeUpdate? &rcUpdate : NULL); prcUnsafeUpdate? &rcUpdate : NULL);
if(Result == ERROR) if(Result == ERROR)
{ {
@ -1583,6 +1658,8 @@ NtUserScrollDC(
RETURN(TRUE); RETURN(TRUE);
CLEANUP: CLEANUP:
if (RgnUpdate)
RGNOBJAPI_Unlock(RgnUpdate);
TRACE("Leave NtUserScrollDC, ret=%lu\n",_ret_); TRACE("Leave NtUserScrollDC, ret=%lu\n",_ret_);
UserLeave(); UserLeave();
END_CLEANUP; END_CLEANUP;
@ -1610,7 +1687,7 @@ NtUserScrollWindowEx(
INT Result; INT Result;
PWND Window = NULL, CaretWnd; PWND Window = NULL, CaretWnd;
HDC hDC; HDC hDC;
HRGN hrgnOwn = NULL, hrgnTemp, hrgnWinupd = NULL; PREGION RgnOwn = NULL, RgnTemp, RgnWinupd = NULL;
HWND hwndCaret; HWND hwndCaret;
DWORD dcxflags = 0; DWORD dcxflags = 0;
int rdw_flags; int rdw_flags;
@ -1668,11 +1745,15 @@ NtUserScrollWindowEx(
if (hrgnUpdate) if (hrgnUpdate)
{ {
hrgnOwn = hrgnUpdate; RgnOwn = RGNOBJAPI_Lock(hrgnUpdate, NULL);
if (!RgnOwn)
{
RETURN(ERROR);
}
bOwnRgn = FALSE; bOwnRgn = FALSE;
} }
else else
hrgnOwn = IntSysCreateRectRgn(0, 0, 0, 0); RgnOwn = IntSysCreateRectpRgn(0, 0, 0, 0);
/* ScrollWindow uses the window DC, ScrollWindowEx doesn't */ /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
if (flags & SW_SCROLLWNDDCE) if (flags & SW_SCROLLWNDDCE)
@ -1709,7 +1790,7 @@ NtUserScrollWindowEx(
dy, dy,
&rcScroll, &rcScroll,
&rcClip, &rcClip,
hrgnOwn, RgnOwn,
prcUnsafeUpdate? &rcUpdate : NULL); prcUnsafeUpdate? &rcUpdate : NULL);
UserReleaseDC(Window, hDC, FALSE); UserReleaseDC(Window, hDC, FALSE);
@ -1719,22 +1800,29 @@ NtUserScrollWindowEx(
* the scroll. Keep a copy in hrgnWinupd to be added to hrngUpdate at the end. * the scroll. Keep a copy in hrgnWinupd to be added to hrngUpdate at the end.
*/ */
hrgnTemp = IntSysCreateRectRgn(0, 0, 0, 0); RgnTemp = IntSysCreateRectpRgn(0, 0, 0, 0);
if (co_UserGetUpdateRgn(Window, hrgnTemp, FALSE) != NULLREGION) if (RgnTemp)
{ {
HRGN hrgnClip = IntSysCreateRectRgnIndirect(&rcClip); if (co_UserGetUpdateRgn(Window, RgnTemp, FALSE) != NULLREGION)
if (!bOwnRgn) {
{ PREGION RgnClip = IntSysCreateRectpRgnIndirect(&rcClip);
hrgnWinupd = IntSysCreateRectRgn( 0, 0, 0, 0); if (RgnClip)
NtGdiCombineRgn( hrgnWinupd, hrgnTemp, 0, RGN_COPY); {
} if (!bOwnRgn)
NtGdiOffsetRgn(hrgnTemp, dx, dy); {
NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnClip, RGN_AND); RgnWinupd = IntSysCreateRectpRgn( 0, 0, 0, 0);
if (!bOwnRgn) NtGdiCombineRgn( hrgnWinupd, hrgnWinupd, hrgnTemp, RGN_OR ); IntGdiCombineRgn( RgnWinupd, RgnTemp, 0, RGN_COPY);
co_UserRedrawWindow(Window, NULL, hrgnTemp, rdw_flags ); }
GreDeleteObject(hrgnClip); IntGdiOffsetRgn(RgnTemp, dx, dy);
IntGdiCombineRgn(RgnTemp, RgnTemp, RgnClip, RGN_AND);
if (!bOwnRgn)
IntGdiCombineRgn( RgnWinupd, RgnWinupd, RgnTemp, RGN_OR );
co_UserRedrawWindow(Window, NULL, RgnTemp, rdw_flags );
REGION_Delete(RgnClip);
}
}
REGION_Delete(RgnTemp);
} }
GreDeleteObject(hrgnTemp);
if (flags & SW_SCROLLCHILDREN) if (flags & SW_SCROLLCHILDREN)
{ {
@ -1766,7 +1854,7 @@ NtUserScrollWindowEx(
if (flags & (SW_INVALIDATE | SW_ERASE)) if (flags & (SW_INVALIDATE | SW_ERASE))
{ {
co_UserRedrawWindow(Window, NULL, hrgnOwn, rdw_flags | co_UserRedrawWindow(Window, NULL, RgnOwn, rdw_flags |
((flags & SW_ERASE) ? RDW_ERASENOW : 0) | ((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0)); ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0));
} }
@ -1805,15 +1893,19 @@ NtUserScrollWindowEx(
RETURN(Result); RETURN(Result);
CLEANUP: CLEANUP:
if (hrgnWinupd && !bOwnRgn) if (RgnWinupd && !bOwnRgn)
{ {
NtGdiCombineRgn( hrgnOwn, hrgnOwn, hrgnWinupd, RGN_OR); IntGdiCombineRgn( RgnOwn, RgnOwn, RgnWinupd, RGN_OR);
GreDeleteObject(hrgnWinupd); REGION_Delete(RgnWinupd);
} }
if (hrgnOwn && !hrgnUpdate) if (RgnOwn && !hrgnUpdate)
{ {
GreDeleteObject(hrgnOwn); REGION_Delete(RgnOwn);
}
else if (RgnOwn)
{
RGNOBJAPI_Unlock(RgnOwn);
} }
if (Window) if (Window)

View file

@ -1,12 +1,12 @@
#pragma once #pragma once
BOOL FASTCALL co_UserRedrawWindow(PWND Wnd, const RECTL* UpdateRect, HRGN UpdateRgn, ULONG Flags); BOOL FASTCALL co_UserRedrawWindow(PWND Wnd, const RECTL* UpdateRect, PREGION UpdateRgn, ULONG Flags);
VOID FASTCALL IntInvalidateWindows(PWND Window, HRGN hRgn, ULONG Flags); VOID FASTCALL IntInvalidateWindows(PWND Window, PREGION Rgn, ULONG Flags);
BOOL FASTCALL IntGetPaintMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove); BOOL FASTCALL IntGetPaintMessage(PWND Window, UINT MsgFilterMin, UINT MsgFilterMax, PTHREADINFO Thread, MSG *Message, BOOL Remove);
INT FASTCALL UserRealizePalette(HDC); INT FASTCALL UserRealizePalette(HDC);
INT FASTCALL co_UserGetUpdateRgn(PWND, HRGN, BOOL); INT FASTCALL co_UserGetUpdateRgn(PWND, PREGION, BOOL);
VOID FASTCALL co_IntPaintWindows(PWND Window, ULONG Flags, BOOL Recurse); VOID FASTCALL co_IntPaintWindows(PWND Window, ULONG Flags, BOOL Recurse);
BOOL FASTCALL IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse); BOOL FASTCALL IntValidateParent(PWND Child, PREGION ValidateRgn, BOOL Recurse);
BOOL FASTCALL IntIsWindowDirty(PWND); BOOL FASTCALL IntIsWindowDirty(PWND);
BOOL FASTCALL IntEndPaint(PWND,PPAINTSTRUCT); BOOL FASTCALL IntEndPaint(PWND,PPAINTSTRUCT);
HDC FASTCALL IntBeginPaint(PWND,PPAINTSTRUCT); HDC FASTCALL IntBeginPaint(PWND,PPAINTSTRUCT);

View file

@ -793,8 +793,15 @@ NtUserCallHwndParamLock(
switch (Routine) switch (Routine)
{ {
case TWOPARAM_ROUTINE_VALIDATERGN: case TWOPARAM_ROUTINE_VALIDATERGN:
Ret = (DWORD)co_UserRedrawWindow( Window, NULL, (HRGN)Param, RDW_VALIDATE); {
break; PREGION Rgn = RGNOBJAPI_Lock((HRGN)Param, NULL);
if (Rgn)
{
Ret = (DWORD)co_UserRedrawWindow( Window, NULL, Rgn, RDW_VALIDATE);
RGNOBJAPI_Unlock(Rgn);
}
break;
}
} }
UserDerefObjectCo(Window); UserDerefObjectCo(Window);

View file

@ -9,14 +9,14 @@
#include <win32k.h> #include <win32k.h>
DBG_DEFAULT_CHANNEL(UserWinpos); DBG_DEFAULT_CHANNEL(UserWinpos);
HRGN FASTCALL PREGION FASTCALL
VIS_ComputeVisibleRegion( VIS_ComputeVisibleRegion(
PWND Wnd, PWND Wnd,
BOOLEAN ClientArea, BOOLEAN ClientArea,
BOOLEAN ClipChildren, BOOLEAN ClipChildren,
BOOLEAN ClipSiblings) BOOLEAN ClipSiblings)
{ {
HRGN VisRgn, ClipRgn; PREGION VisRgn, ClipRgn;
PWND PreviousWindow, CurrentWindow, CurrentSibling; PWND PreviousWindow, CurrentWindow, CurrentSibling;
if (!Wnd || !(Wnd->style & WS_VISIBLE)) if (!Wnd || !(Wnd->style & WS_VISIBLE))
@ -28,11 +28,11 @@ VIS_ComputeVisibleRegion(
if (ClientArea) if (ClientArea)
{ {
VisRgn = IntSysCreateRectRgnIndirect(&Wnd->rcClient); VisRgn = IntSysCreateRectpRgnIndirect(&Wnd->rcClient);
} }
else else
{ {
VisRgn = IntSysCreateRectRgnIndirect(&Wnd->rcWindow); VisRgn = IntSysCreateRectpRgnIndirect(&Wnd->rcWindow);
} }
/* /*
@ -48,19 +48,21 @@ VIS_ComputeVisibleRegion(
if (!VerifyWnd(CurrentWindow)) if (!VerifyWnd(CurrentWindow))
{ {
ERR("ATM the Current Window or Parent is dead! %p\n",CurrentWindow); ERR("ATM the Current Window or Parent is dead! %p\n",CurrentWindow);
if (VisRgn) GreDeleteObject(VisRgn); if (VisRgn)
REGION_Delete(VisRgn);
return NULL; return NULL;
} }
if (!(CurrentWindow->style & WS_VISIBLE)) if (!(CurrentWindow->style & WS_VISIBLE))
{ {
if (VisRgn) GreDeleteObject(VisRgn); if (VisRgn)
REGION_Delete(VisRgn);
return NULL; return NULL;
} }
ClipRgn = IntSysCreateRectRgnIndirect(&CurrentWindow->rcClient); ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentWindow->rcClient);
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND); IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
GreDeleteObject(ClipRgn); REGION_Delete(ClipRgn);
if ((PreviousWindow->style & WS_CLIPSIBLINGS) || if ((PreviousWindow->style & WS_CLIPSIBLINGS) ||
(PreviousWindow == Wnd && ClipSiblings)) (PreviousWindow == Wnd && ClipSiblings))
@ -72,16 +74,21 @@ VIS_ComputeVisibleRegion(
if ((CurrentSibling->style & WS_VISIBLE) && if ((CurrentSibling->style & WS_VISIBLE) &&
!(CurrentSibling->ExStyle & WS_EX_TRANSPARENT)) !(CurrentSibling->ExStyle & WS_EX_TRANSPARENT))
{ {
ClipRgn = IntSysCreateRectRgnIndirect(&CurrentSibling->rcWindow); ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentSibling->rcWindow);
/* Combine it with the window region if available */ /* Combine it with the window region if available */
if (CurrentSibling->hrgnClip && !(CurrentSibling->style & WS_MINIMIZE)) if (CurrentSibling->hrgnClip && !(CurrentSibling->style & WS_MINIMIZE))
{ {
NtGdiOffsetRgn(ClipRgn, -CurrentSibling->rcWindow.left, -CurrentSibling->rcWindow.top); PREGION SiblingClipRgn = RGNOBJAPI_Lock(CurrentSibling->hrgnClip, NULL);
NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentSibling->hrgnClip, RGN_AND); if (SiblingClipRgn)
NtGdiOffsetRgn(ClipRgn, CurrentSibling->rcWindow.left, CurrentSibling->rcWindow.top); {
IntGdiOffsetRgn(ClipRgn, -CurrentSibling->rcWindow.left, -CurrentSibling->rcWindow.top);
IntGdiCombineRgn(ClipRgn, ClipRgn, SiblingClipRgn, RGN_AND);
IntGdiOffsetRgn(ClipRgn, CurrentSibling->rcWindow.left, CurrentSibling->rcWindow.top);
RGNOBJAPI_Unlock(SiblingClipRgn);
}
} }
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
GreDeleteObject(ClipRgn); REGION_Delete(ClipRgn);
} }
CurrentSibling = CurrentSibling->spwndNext; CurrentSibling = CurrentSibling->spwndNext;
} }
@ -99,16 +106,20 @@ VIS_ComputeVisibleRegion(
if ((CurrentWindow->style & WS_VISIBLE) && if ((CurrentWindow->style & WS_VISIBLE) &&
!(CurrentWindow->ExStyle & WS_EX_TRANSPARENT)) !(CurrentWindow->ExStyle & WS_EX_TRANSPARENT))
{ {
ClipRgn = IntSysCreateRectRgnIndirect(&CurrentWindow->rcWindow); ClipRgn = IntSysCreateRectpRgnIndirect(&CurrentWindow->rcWindow);
/* Combine it with the window region if available */ /* Combine it with the window region if available */
if (CurrentWindow->hrgnClip && !(CurrentWindow->style & WS_MINIMIZE)) if (CurrentWindow->hrgnClip && !(CurrentWindow->style & WS_MINIMIZE))
{ {
NtGdiOffsetRgn(ClipRgn, -CurrentWindow->rcWindow.left, -CurrentWindow->rcWindow.top); PREGION CurrentRgnClip = RGNOBJAPI_Lock(CurrentWindow->hrgnClip, NULL);
NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentWindow->hrgnClip, RGN_AND); if (CurrentRgnClip)
NtGdiOffsetRgn(ClipRgn, CurrentWindow->rcWindow.left, CurrentWindow->rcWindow.top); {
IntGdiOffsetRgn(ClipRgn, -CurrentWindow->rcWindow.left, -CurrentWindow->rcWindow.top);
IntGdiCombineRgn(ClipRgn, ClipRgn, CurrentRgnClip, RGN_AND);
IntGdiOffsetRgn(ClipRgn, CurrentWindow->rcWindow.left, CurrentWindow->rcWindow.top);
}
} }
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); IntGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
GreDeleteObject(ClipRgn); REGION_Delete(ClipRgn);
} }
CurrentWindow = CurrentWindow->spwndNext; CurrentWindow = CurrentWindow->spwndNext;
} }
@ -116,9 +127,14 @@ VIS_ComputeVisibleRegion(
if (Wnd->hrgnClip && !(Wnd->style & WS_MINIMIZE)) if (Wnd->hrgnClip && !(Wnd->style & WS_MINIMIZE))
{ {
NtGdiOffsetRgn(VisRgn, -Wnd->rcWindow.left, -Wnd->rcWindow.top); PREGION WndRgnClip = RGNOBJAPI_Lock(Wnd->hrgnClip, NULL);
NtGdiCombineRgn(VisRgn, VisRgn, Wnd->hrgnClip, RGN_AND); if (WndRgnClip)
NtGdiOffsetRgn(VisRgn, Wnd->rcWindow.left, Wnd->rcWindow.top); {
IntGdiOffsetRgn(VisRgn, -Wnd->rcWindow.left, -Wnd->rcWindow.top);
IntGdiCombineRgn(VisRgn, VisRgn, WndRgnClip, RGN_AND);
IntGdiOffsetRgn(VisRgn, Wnd->rcWindow.left, Wnd->rcWindow.top);
RGNOBJAPI_Unlock(WndRgnClip);
}
} }
return VisRgn; return VisRgn;
@ -127,9 +143,8 @@ VIS_ComputeVisibleRegion(
VOID FASTCALL VOID FASTCALL
co_VIS_WindowLayoutChanged( co_VIS_WindowLayoutChanged(
PWND Wnd, PWND Wnd,
HRGN NewlyExposed) PREGION NewlyExposed)
{ {
HRGN Temp;
PWND Parent; PWND Parent;
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
@ -138,20 +153,23 @@ co_VIS_WindowLayoutChanged(
Parent = Wnd->spwndParent; Parent = Wnd->spwndParent;
if(Parent) if(Parent)
{ {
Temp = IntSysCreateRectRgn(0, 0, 0, 0); PREGION TempRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
NtGdiCombineRgn(Temp, NewlyExposed, NULL, RGN_COPY); if (!TempRgn)
NtGdiOffsetRgn(Temp, return;
Wnd->rcWindow.left - Parent->rcClient.left,
Wnd->rcWindow.top - Parent->rcClient.top);
UserRefObjectCo(Parent, &Ref); IntGdiCombineRgn(TempRgn, NewlyExposed, NULL, RGN_COPY);
co_UserRedrawWindow(Parent, NULL, Temp, IntGdiOffsetRgn(TempRgn,
RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | Wnd->rcWindow.left - Parent->rcClient.left,
RDW_ALLCHILDREN); Wnd->rcWindow.top - Parent->rcClient.top);
UserDerefObjectCo(Parent);
GreDeleteObject(Temp); UserRefObjectCo(Parent, &Ref);
co_UserRedrawWindow(Parent, NULL, TempRgn,
RDW_FRAME | RDW_ERASE | RDW_INVALIDATE |
RDW_ALLCHILDREN);
UserDerefObjectCo(Parent);
REGION_Delete(TempRgn);
} }
} }

View file

@ -9,7 +9,7 @@
#pragma once #pragma once
HRGN FASTCALL VIS_ComputeVisibleRegion(PWND Window, BOOLEAN ClientArea, BOOLEAN ClipChildren, BOOLEAN ClipSiblings); PREGION FASTCALL VIS_ComputeVisibleRegion(PWND Window, BOOLEAN ClientArea, BOOLEAN ClipChildren, BOOLEAN ClipSiblings);
VOID FASTCALL co_VIS_WindowLayoutChanged(PWND Window, HRGN UncoveredRgn); VOID FASTCALL co_VIS_WindowLayoutChanged(PWND Window, PREGION UncoveredRgn);
/* EOF */ /* EOF */

View file

@ -69,24 +69,10 @@ static
PREGION FASTCALL PREGION FASTCALL
DceGetVisRgn(PWND Window, ULONG Flags, HWND hWndChild, ULONG CFlags) DceGetVisRgn(PWND Window, ULONG Flags, HWND hWndChild, ULONG CFlags)
{ {
PREGION RetRgn; return VIS_ComputeVisibleRegion( Window,
HRGN hVisRgn; 0 == (Flags & DCX_WINDOW),
hVisRgn = VIS_ComputeVisibleRegion( Window, 0 != (Flags & DCX_CLIPCHILDREN),
0 == (Flags & DCX_WINDOW), 0 != (Flags & DCX_CLIPSIBLINGS));
0 != (Flags & DCX_CLIPCHILDREN),
0 != (Flags & DCX_CLIPSIBLINGS));
RetRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (hVisRgn != NULL)
{
PREGION VisRgn = REGION_LockRgn(hVisRgn);
IntGdiCombineRgn(RetRgn, VisRgn, NULL, RGN_COPY);
REGION_UnlockRgn(VisRgn);
GreDeleteObject(hVisRgn);
}
return RetRgn;
} }
PDCE FASTCALL PDCE FASTCALL
@ -582,11 +568,19 @@ UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
{ {
if (!(Flags & DCX_WINDOW)) if (!(Flags & DCX_WINDOW))
{ {
Dce->hrgnClip = IntSysCreateRectRgnIndirect(&Wnd->rcClient); Dce->hrgnClip = NtGdiCreateRectRgn(
Wnd->rcClient.left,
Wnd->rcClient.top,
Wnd->rcClient.right,
Wnd->rcClient.bottom);
} }
else else
{ {
Dce->hrgnClip = IntSysCreateRectRgnIndirect(&Wnd->rcWindow); Dce->hrgnClip = NtGdiCreateRectRgn(
Wnd->rcWindow.left,
Wnd->rcWindow.top,
Wnd->rcWindow.right,
Wnd->rcWindow.bottom);
} }
Dce->DCXFlags &= ~DCX_KEEPCLIPRGN; Dce->DCXFlags &= ~DCX_KEEPCLIPRGN;
bUpdateVisRgn = TRUE; bUpdateVisRgn = TRUE;

View file

@ -1652,13 +1652,10 @@ co_WinPosSetWindowPos(
RECTL NewWindowRect; RECTL NewWindowRect;
RECTL NewClientRect; RECTL NewClientRect;
RECTL valid_rects[2]; RECTL valid_rects[2];
PROSRGNDATA VisRgn; PREGION VisBefore = NULL;
HRGN VisBefore = NULL; PREGION VisBeforeJustClient = NULL;
HRGN VisBeforeJustClient = NULL; PREGION VisAfter = NULL;
HRGN VisAfter = NULL; PREGION CopyRgn = NULL;
HRGN DirtyRgn = NULL;
HRGN ExposedRgn = NULL;
HRGN CopyRgn = NULL;
ULONG WvrFlags = 0; ULONG WvrFlags = 0;
RECTL OldWindowRect, OldClientRect; RECTL OldWindowRect, OldClientRect;
int RgnType; int RgnType;
@ -1736,20 +1733,16 @@ co_WinPosSetWindowPos(
{ {
VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE,
(Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE); (Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE);
VisRgn = NULL;
if ( VisBefore != NULL && if ( VisBefore != NULL &&
(VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisBefore, NULL)) && REGION_Complexity(VisBefore) == NULLREGION )
REGION_Complexity(VisRgn) == NULLREGION )
{ {
RGNOBJAPI_Unlock(VisRgn); REGION_Delete(VisBefore);
GreDeleteObject(VisBefore);
VisBefore = NULL; VisBefore = NULL;
} }
else if(VisRgn) else if(VisBefore)
{ {
RGNOBJAPI_Unlock(VisRgn); IntGdiOffsetRgn(VisBefore, -Window->rcWindow.left, -Window->rcWindow.top);
NtGdiOffsetRgn(VisBefore, -Window->rcWindow.left, -Window->rcWindow.top);
} }
/* Calculate the non client area for resizes, as this is used in the copy region */ /* Calculate the non client area for resizes, as this is used in the copy region */
@ -1757,20 +1750,16 @@ co_WinPosSetWindowPos(
{ {
VisBeforeJustClient = VIS_ComputeVisibleRegion(Window, TRUE, FALSE, VisBeforeJustClient = VIS_ComputeVisibleRegion(Window, TRUE, FALSE,
(Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE); (Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE);
VisRgn = NULL;
if ( VisBeforeJustClient != NULL && if ( VisBeforeJustClient != NULL &&
(VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisBeforeJustClient, NULL)) && REGION_Complexity(VisBeforeJustClient) == NULLREGION )
REGION_Complexity(VisRgn) == NULLREGION )
{ {
RGNOBJAPI_Unlock(VisRgn); REGION_Delete(VisBeforeJustClient);
GreDeleteObject(VisBeforeJustClient);
VisBeforeJustClient = NULL; VisBeforeJustClient = NULL;
} }
else if(VisRgn) else if(VisBeforeJustClient)
{ {
RGNOBJAPI_Unlock(VisRgn); IntGdiOffsetRgn(VisBeforeJustClient, -Window->rcWindow.left, -Window->rcWindow.top);
NtGdiOffsetRgn(VisBeforeJustClient, -Window->rcWindow.left, -Window->rcWindow.top);
} }
} }
} }
@ -1843,20 +1832,16 @@ co_WinPosSetWindowPos(
/* Determine the new visible region */ /* Determine the new visible region */
VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE,
(Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE); (Window->style & WS_CLIPSIBLINGS) ? TRUE : FALSE);
VisRgn = NULL;
if ( VisAfter != NULL && if ( VisAfter != NULL &&
(VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisAfter, NULL)) && REGION_Complexity(VisAfter) == NULLREGION )
REGION_Complexity(VisRgn) == NULLREGION )
{ {
RGNOBJAPI_Unlock(VisRgn); REGION_Delete(VisAfter);
GreDeleteObject(VisAfter);
VisAfter = NULL; VisAfter = NULL;
} }
else if(VisRgn) else if(VisAfter)
{ {
RGNOBJAPI_Unlock(VisRgn); IntGdiOffsetRgn(VisAfter, -Window->rcWindow.left, -Window->rcWindow.top);
NtGdiOffsetRgn(VisAfter, -Window->rcWindow.left, -Window->rcWindow.top);
} }
/* /*
@ -1882,21 +1867,26 @@ co_WinPosSetWindowPos(
* region...) * region...)
*/ */
CopyRgn = IntSysCreateRectRgn(0, 0, 0, 0); CopyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (WinPos.flags & SWP_NOSIZE) if (WinPos.flags & SWP_NOSIZE)
RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND); RgnType = IntGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
else if (VisBeforeJustClient != NULL) else if (VisBeforeJustClient != NULL)
{ {
RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBeforeJustClient, RGN_AND); RgnType = IntGdiCombineRgn(CopyRgn, VisAfter, VisBeforeJustClient, RGN_AND);
GreDeleteObject(VisBeforeJustClient); REGION_Delete(VisBeforeJustClient);
} }
/* No use in copying bits which are in the update region. */ /* No use in copying bits which are in the update region. */
if (Window->hrgnUpdate != NULL) if (Window->hrgnUpdate != NULL)
{ {
NtGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top); PREGION RgnUpdate = RGNOBJAPI_Lock(Window->hrgnUpdate, NULL);
NtGdiCombineRgn(CopyRgn, CopyRgn, Window->hrgnUpdate, RGN_DIFF); if (RgnUpdate)
NtGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top); {
IntGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
IntGdiCombineRgn(CopyRgn, CopyRgn, RgnUpdate, RGN_DIFF);
IntGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
RGNOBJAPI_Unlock(RgnUpdate);
}
} }
/* /*
@ -1904,21 +1894,17 @@ co_WinPosSetWindowPos(
* there's nothing to copy. Also, it's no use copying bits onto * there's nothing to copy. Also, it's no use copying bits onto
* themselves. * themselves.
*/ */
if ( (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(CopyRgn, NULL)) && if (REGION_GetRgnBox(CopyRgn, &CopyRect) == NULLREGION)
REGION_GetRgnBox(VisRgn, &CopyRect) == NULLREGION)
{ {
/* Nothing to copy, clean up */ /* Nothing to copy, clean up */
RGNOBJAPI_Unlock(VisRgn); REGION_Delete(CopyRgn);
GreDeleteObject(CopyRgn);
CopyRgn = NULL; CopyRgn = NULL;
} }
else if (OldWindowRect.left != NewWindowRect.left || else if (OldWindowRect.left != NewWindowRect.left ||
OldWindowRect.top != NewWindowRect.top) OldWindowRect.top != NewWindowRect.top)
{ {
if(VisRgn) HRGN DcRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
{ PREGION DcRgnObj = RGNOBJAPI_Lock(DcRgn, NULL);
RGNOBJAPI_Unlock(VisRgn);
}
/* /*
* Small trick here: there is no function to bitblt a region. So * Small trick here: there is no function to bitblt a region. So
@ -1929,9 +1915,11 @@ co_WinPosSetWindowPos(
* Since NtUserGetDCEx takes ownership of the clip region, we need * Since NtUserGetDCEx takes ownership of the clip region, we need
* to create a copy of CopyRgn and pass that. We need CopyRgn later * to create a copy of CopyRgn and pass that. We need CopyRgn later
*/ */
NtGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top); IntGdiCombineRgn(DcRgnObj, CopyRgn, NULL, RGN_COPY);
IntGdiOffsetRgn(DcRgnObj, NewWindowRect.left, NewWindowRect.top);
RGNOBJAPI_Unlock(DcRgnObj);
Dc = UserGetDCEx( Window, Dc = UserGetDCEx( Window,
CopyRgn, DcRgn,
DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_CLIPSIBLINGS|DCX_KEEPCLIPRGN); DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_CLIPSIBLINGS|DCX_KEEPCLIPRGN);
NtGdiBitBlt( Dc, NtGdiBitBlt( Dc,
CopyRect.left, CopyRect.top, CopyRect.left, CopyRect.top,
@ -1946,11 +1934,7 @@ co_WinPosSetWindowPos(
UserReleaseDC(Window, Dc, FALSE); UserReleaseDC(Window, Dc, FALSE);
IntValidateParent(Window, CopyRgn, FALSE); IntValidateParent(Window, CopyRgn, FALSE);
NtGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top); GreDeleteObject(DcRgn);
}
else if(VisRgn)
{
RGNOBJAPI_Unlock(VisRgn);
} }
} }
else else
@ -1961,78 +1945,84 @@ co_WinPosSetWindowPos(
/* We need to redraw what wasn't visible before */ /* We need to redraw what wasn't visible before */
if (VisAfter != NULL) if (VisAfter != NULL)
{ {
DirtyRgn = IntSysCreateRectRgn(0, 0, 0, 0); PREGION DirtyRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
if (CopyRgn != NULL) if (DirtyRgn)
{ {
RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF); if (CopyRgn != NULL)
} {
else RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
{ }
RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY); else
} {
if (RgnType != ERROR && RgnType != NULLREGION) RgnType = IntGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
{ }
/* old code if (RgnType != ERROR && RgnType != NULLREGION)
NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left, Window->rcWindow.top); {
IntInvalidateWindows( Window, /* old code
DirtyRgn, NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
GreDeleteObject(DirtyRgn);
*/
PWND Parent = Window->spwndParent;
NtGdiOffsetRgn( DirtyRgn,
Window->rcWindow.left,
Window->rcWindow.top);
if ( (Window->style & WS_CHILD) &&
(Parent) &&
!(Parent->style & WS_CLIPCHILDREN))
{
IntInvalidateWindows( Parent,
DirtyRgn,
RDW_ERASE | RDW_INVALIDATE);
co_IntPaintWindows(Parent, RDW_ERASENOW, FALSE);
}
else
{
IntInvalidateWindows( Window, IntInvalidateWindows( Window,
DirtyRgn, DirtyRgn,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
} }
GreDeleteObject(DirtyRgn);
*/
PWND Parent = Window->spwndParent;
IntGdiOffsetRgn( DirtyRgn,
Window->rcWindow.left,
Window->rcWindow.top);
if ( (Window->style & WS_CHILD) &&
(Parent) &&
!(Parent->style & WS_CLIPCHILDREN))
{
IntInvalidateWindows( Parent,
DirtyRgn,
RDW_ERASE | RDW_INVALIDATE);
co_IntPaintWindows(Parent, RDW_ERASENOW, FALSE);
}
else
{
IntInvalidateWindows( Window,
DirtyRgn,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
REGION_Delete(DirtyRgn);
} }
GreDeleteObject(DirtyRgn);
} }
if (CopyRgn != NULL) if (CopyRgn != NULL)
{ {
GreDeleteObject(CopyRgn); REGION_Delete(CopyRgn);
} }
/* Expose what was covered before but not covered anymore */ /* Expose what was covered before but not covered anymore */
if (VisBefore != NULL) if (VisBefore != NULL)
{ {
ExposedRgn = IntSysCreateRectRgn(0, 0, 0, 0); PREGION ExposedRgn = IntSysCreateRectpRgn(0, 0, 0, 0);
RgnType = NtGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY); if (ExposedRgn)
NtGdiOffsetRgn( ExposedRgn,
OldWindowRect.left - NewWindowRect.left,
OldWindowRect.top - NewWindowRect.top);
if (VisAfter != NULL)
RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
if (RgnType != ERROR && RgnType != NULLREGION)
{ {
co_VIS_WindowLayoutChanged(Window, ExposedRgn); RgnType = IntGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
IntGdiOffsetRgn( ExposedRgn,
OldWindowRect.left - NewWindowRect.left,
OldWindowRect.top - NewWindowRect.top);
if (VisAfter != NULL)
RgnType = IntGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
if (RgnType != ERROR && RgnType != NULLREGION)
{
co_VIS_WindowLayoutChanged(Window, ExposedRgn);
}
REGION_Delete(ExposedRgn);
} }
GreDeleteObject(ExposedRgn); REGION_Delete(VisBefore);
GreDeleteObject(VisBefore);
} }
if (VisAfter != NULL) if (VisAfter != NULL)
{ {
GreDeleteObject(VisAfter); REGION_Delete(VisAfter);
} }
} }
@ -3112,7 +3102,7 @@ NtUserSetWindowRgn(
HRGN hRgn, HRGN hRgn,
BOOL bRedraw) BOOL bRedraw)
{ {
HRGN hrgnCopy; HRGN hrgnCopy = NULL;
PWND Window; PWND Window;
INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE); INT flags = (SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE);
BOOLEAN Ret = FALSE; BOOLEAN Ret = FALSE;
@ -3132,7 +3122,7 @@ NtUserSetWindowRgn(
{ {
if (GreIsHandleValid(hRgn)) if (GreIsHandleValid(hRgn))
{ {
hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0); hrgnCopy = NtGdiCreateRectRgn(0, 0, 0, 0);
/* The coordinates of a window's window region are relative to the /* The coordinates of a window's window region are relative to the
upper-left corner of the window, not the client area of the window. */ upper-left corner of the window, not the client area of the window. */
NtGdiCombineRgn( hrgnCopy, hRgn, 0, RGN_COPY); NtGdiCombineRgn( hrgnCopy, hRgn, 0, RGN_COPY);
@ -3140,10 +3130,6 @@ NtUserSetWindowRgn(
else else
RETURN( 0); RETURN( 0);
} }
else
{
hrgnCopy = NULL;
}
if (Window->hrgnClip) if (Window->hrgnClip)
{ {