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.…
==============================================================================
--- 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)
{