Author: jimtabor Date: Thu Oct 4 20:00:28 2012 New Revision: 57483
URL: http://svn.reactos.org/svn/reactos?rev=57483&view=rev Log: [NtUser] - Fix all but one DCE scroll test. - Old patch at least two year old or more.
Modified: trunk/reactos/win32ss/user/ntuser/windc.c
Modified: trunk/reactos/win32ss/user/ntuser/windc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/windc.c... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/windc.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/windc.c [iso-8859-1] Thu Oct 4 20:00:28 2012 @@ -172,6 +172,88 @@
/* Make it dirty so that the vis rgn gets recomputed next time */ Dce->DCXFlags |= DCX_DCEDIRTY; + IntGdiSetHookFlags(Dce->hDC, DCHF_INVALIDATEVISRGN); +} + +static VOID FASTCALL +DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags) +{ + HANDLE hRgnVisible = NULL; + ULONG DcxFlags; + PWND DesktopWindow; + + if (Flags & DCX_PARENTCLIP) + { + PWND Parent; + + Parent = Window->spwndParent; + if(!Parent) + { + hRgnVisible = NULL; + goto noparent; + } + + if (Parent->style & WS_CLIPSIBLINGS) + { + DcxFlags = DCX_CLIPSIBLINGS | + (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW)); + } + else + { + DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW); + } + hRgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags); + } + else if (Window == NULL) + { + DesktopWindow = UserGetWindowObject(IntGetDesktopWindow()); + if (NULL != DesktopWindow) + { + hRgnVisible = IntSysCreateRectRgnIndirect(&DesktopWindow->rcWindow); + } + else + { + hRgnVisible = NULL; + } + } + else + { + hRgnVisible = DceGetVisRgn(Window, Flags, 0, 0); + } + +noparent: + if (Flags & DCX_INTERSECTRGN) + { + if(Dce->hrgnClip != NULL) + { + NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_AND); + } + else + { + if(hRgnVisible != NULL) + { + GreDeleteObject(hRgnVisible); + } + hRgnVisible = IntSysCreateRectRgn(0, 0, 0, 0); + } + } + else if (Flags & DCX_EXCLUDERGN && Dce->hrgnClip != NULL) + { + NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_DIFF); + } + + Dce->DCXFlags &= ~DCX_DCEDIRTY; + GdiSelectVisRgn(Dce->hDC, hRgnVisible); + + if (Window != NULL) + { + IntEngWindowChanged(Window, WOC_RGN_CLIENT); + } + + if (hRgnVisible != NULL) + { + GreDeleteObject(hRgnVisible); + } }
static INT FASTCALL @@ -183,6 +265,11 @@ }
/* Restore previous visible region */ + if (EndPaint) + { + DceUpdateVisRgn(dce, dce->pwndOrg, dce->DCXFlags); + } + if ((dce->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) && ((dce->DCXFlags & DCX_CACHE) || EndPaint)) { @@ -193,9 +280,6 @@ { if (!(dce->DCXFlags & DCX_NORESETATTRS)) { - /* Make the DC clean so that SetDCState doesn't try to update the vis rgn */ - IntGdiSetHookFlags(dce->hDC, DCHF_VALIDATEVISRGN); - // Clean the DC if (!IntGdiCleanDC(dce->hDC)) return 0;
@@ -205,6 +289,8 @@ * because SetDCState() disables hVisRgn updates * by removing dirty bit. */ dce->hwndCurrent = 0; + dce->pwndOrg = NULL; + dce->pwndClip = NULL; dce->DCXFlags &= DCX_CACHE; dce->DCXFlags |= DCX_DCEEMPTY; } @@ -237,86 +323,6 @@ return 1; // Released! }
-static VOID FASTCALL -DceUpdateVisRgn(DCE *Dce, PWND Window, ULONG Flags) -{ - HANDLE hRgnVisible = NULL; - ULONG DcxFlags; - PWND DesktopWindow; - - if (Flags & DCX_PARENTCLIP) - { - PWND Parent; - - Parent = Window->spwndParent; - if(!Parent) - { - hRgnVisible = NULL; - goto noparent; - } - - if (Parent->style & WS_CLIPSIBLINGS) - { - DcxFlags = DCX_CLIPSIBLINGS | - (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW)); - } - else - { - DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW); - } - hRgnVisible = DceGetVisRgn(Parent, DcxFlags, Window->head.h, Flags); - } - else if (Window == NULL) - { - DesktopWindow = UserGetWindowObject(IntGetDesktopWindow()); - if (NULL != DesktopWindow) - { - hRgnVisible = IntSysCreateRectRgnIndirect(&DesktopWindow->rcWindow); - } - else - { - hRgnVisible = NULL; - } - } - else - { - hRgnVisible = DceGetVisRgn(Window, Flags, 0, 0); - } - -noparent: - if (Flags & DCX_INTERSECTRGN) - { - if(Dce->hrgnClip != NULL) - { - NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_AND); - } - else - { - if(hRgnVisible != NULL) - { - GreDeleteObject(hRgnVisible); - } - hRgnVisible = IntSysCreateRectRgn(0, 0, 0, 0); - } - } - else if (Flags & DCX_EXCLUDERGN && Dce->hrgnClip != NULL) - { - NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hrgnClip, RGN_DIFF); - } - - Dce->DCXFlags &= ~DCX_DCEDIRTY; - GdiSelectVisRgn(Dce->hDC, hRgnVisible); - - if (Window != NULL) - { - IntEngWindowChanged(Window, WOC_RGN_CLIENT); - } - - if (hRgnVisible != NULL) - { - GreDeleteObject(hRgnVisible); - } -}
HDC FASTCALL UserGetDCEx(PWND Wnd OPTIONAL, HANDLE ClipRegion, ULONG Flags) @@ -325,6 +331,7 @@ ULONG DcxFlags; DCE* Dce = NULL; BOOL UpdateClipOrigin = FALSE; + BOOL bUpdateVisRgn = TRUE; HDC hDC = NULL; PPROCESSINFO ppi; PLIST_ENTRY pLE; @@ -360,12 +367,7 @@ TRACE("We have CLASS!!\n"); } } -/* else // For Testing! - { - ERR("We have POWNER!!\n"); - if (Window->Dce) ERR("We have POWNER with DCE!!\n"); - } -*/ + if (Wnd->style & WS_CLIPSIBLINGS) { Flags |= DCX_CLIPSIBLINGS; @@ -441,7 +443,7 @@ do { // The reason for this you may ask? -// Well, it seems ReactOS calls GetDC with out first creating a desktop DC window! +// Well, it seems ReactOS calls GetDC without first creating a desktop DC window! // Need to test for null here. Not sure if this is a bug or a feature. // First time use hax, need to use DceAllocDCE during window display init. if (!Dce) break; @@ -460,6 +462,7 @@ ((Dce->DCXFlags & DCX_CACHECOMPAREMASK) == DcxFlags)) { UpdateClipOrigin = TRUE; + //bUpdateVisRgn = FALSE; break; } } @@ -478,6 +481,7 @@ if (!Dce) return NULL;
Dce->hwndCurrent = (Wnd ? Wnd->head.h : NULL); + Dce->pwndOrg = Dce->pwndClip = Wnd; } else // If we are here, we are POWNED or having CLASS. { @@ -486,9 +490,12 @@ Dce = CONTAINING_RECORD(pLE, DCE, List); do { // Check for Window handle than HDC match for CLASS. - if ((Dce->hwndCurrent == Wnd->head.h) || - (Dce->hDC == hDC)) + if (Dce->hwndCurrent == Wnd->head.h) + { + bUpdateVisRgn = FALSE; break; + } + if (Dce->hDC == hDC) break; pLE = Dce->List.Flink; Dce = CONTAINING_RECORD(pLE, DCE, List); } @@ -535,6 +542,7 @@ Flags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN; Dce->DCXFlags |= DCX_INTERSECTRGN | DCX_KEEPCLIPRGN; ClipRegion = Wnd->hrgnUpdate; + bUpdateVisRgn = TRUE; }
if (ClipRegion == HRGN_WINDOW) @@ -548,6 +556,7 @@ Dce->hrgnClip = IntSysCreateRectRgnIndirect(&Wnd->rcWindow); } Dce->DCXFlags &= ~DCX_KEEPCLIPRGN; + bUpdateVisRgn = TRUE; } else if (ClipRegion != NULL) { @@ -558,11 +567,14 @@ Dce->hrgnClip = NULL; } Dce->hrgnClip = ClipRegion; - } + bUpdateVisRgn = TRUE; + } + + if (IntGdiSetHookFlags(Dce->hDC, DCHF_VALIDATEVISRGN)) bUpdateVisRgn = TRUE;
DceSetDrawable(Wnd, Dce->hDC, Flags, UpdateClipOrigin);
- DceUpdateVisRgn(Dce, Wnd, Flags); + if (bUpdateVisRgn) DceUpdateVisRgn(Dce, Wnd, Flags);
if (Dce->DCXFlags & DCX_CACHE) { @@ -697,6 +709,7 @@ DceUpdateVisRgn(pDCE, Window, pDCE->DCXFlags); pDCE->DCXFlags = DCX_DCEEMPTY|DCX_CACHE; pDCE->hwndCurrent = 0; + pDCE->pwndOrg = pDCE->pwndClip = NULL;
TRACE("POWNED DCE going Cheap!! DCX_CACHE!! hDC-> %x \n", pDCE->hDC); if (!GreSetDCOwner( pDCE->hDC, GDI_OBJ_HMGR_NONE)) @@ -734,6 +747,7 @@ } pDCE->DCXFlags |= DCX_DCEEMPTY; pDCE->hwndCurrent = 0; + pDCE->pwndOrg = pDCE->pwndClip = NULL; } } pLE = pDCE->List.Flink; @@ -872,6 +886,7 @@ dc->ptlDCOrig.x = CurrentWindow->rcClient.left; dc->ptlDCOrig.y = CurrentWindow->rcClient.top; } + if (NULL != dc->rosdc.hClipRgn) { NtGdiOffsetRgn(dc->rosdc.hClipRgn, DeltaX, DeltaY); @@ -885,6 +900,7 @@ DC_UnlockDc(dc);
DceUpdateVisRgn(pDCE, CurrentWindow, pDCE->DCXFlags); + IntGdiSetHookFlags(pDCE->hDC, DCHF_VALIDATEVISRGN);
if (Window->head.h != pDCE->hwndCurrent) {