From 9dacfa1b682b37c7dc5d8f9f0c8a326af93b01dd Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sun, 22 Feb 2004 12:25:35 +0000 Subject: [PATCH] - Modifed DceUpdateVisRgn to correctly handle situations when DceGetVisRgn returns NULL. - Fixed the alternative version of VIS_ComputeVisibleRegion and made it the one and only, because it's smaller and faster than the original one. svn path=/trunk/; revision=8305 --- reactos/subsys/win32k/ntuser/vis.c | 225 ++++----------------------- reactos/subsys/win32k/ntuser/windc.c | 123 ++++++++------- 2 files changed, 89 insertions(+), 259 deletions(-) diff --git a/reactos/subsys/win32k/ntuser/vis.c b/reactos/subsys/win32k/ntuser/vis.c index 35c7a224a7c..c2aa65d3e46 100644 --- a/reactos/subsys/win32k/ntuser/vis.c +++ b/reactos/subsys/win32k/ntuser/vis.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: vis.c,v 1.17 2004/02/04 22:55:21 gvg Exp $ + * $Id: vis.c,v 1.18 2004/02/22 12:25:34 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -34,183 +34,6 @@ #include #include -#if 1 -BOOL STATIC FASTCALL -VIS_GetVisRect(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window, - BOOLEAN ClientArea, RECT* Rect) -{ - PWINDOW_OBJECT DesktopWindow; - - if (ClientArea) - { - *Rect = Window->ClientRect; - } - else - { - *Rect = Window->WindowRect; - } - - if (0 == (Window->Style & WS_VISIBLE)) - { - NtGdiSetEmptyRect(Rect); - - return FALSE; - } - - if (Window->Self == Desktop->DesktopWindow) - { - return TRUE; - } - - if (0 != (Window->Style & WS_CHILD)) - { - do - { - Window = Window->Parent; - if (WS_VISIBLE != (Window->Style & (WS_ICONIC | WS_VISIBLE))) - { - NtGdiSetEmptyRect(Rect); - return FALSE; - } - if (! NtGdiIntersectRect(Rect, Rect, &(Window->ClientRect))) - { - return FALSE; - } - } - while (0 != (Window->Style & WS_CHILD)); - } - - DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow); - if (NULL == DesktopWindow) - { - ASSERT(FALSE); - return FALSE; - } - - if (! NtGdiIntersectRect(Rect, Rect, &(DesktopWindow->ClientRect))) - { - IntReleaseWindowObject(DesktopWindow); - return FALSE; - } - IntReleaseWindowObject(DesktopWindow); - - return TRUE; -} - -STATIC BOOL FASTCALL -VIS_AddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, - HRGN ClipRgn, PRECT Rect) -{ - PWINDOW_OBJECT Child; - RECT Intersect; - - ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock); - Child = Parent->FirstChild; - while (Child) - { - if (Child == End) - { - ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); - return TRUE; - } - - if (Child->Style & WS_VISIBLE) - { - if (NtGdiIntersectRect(&Intersect, &Child->WindowRect, Rect)) - { - UnsafeIntUnionRectWithRgn(ClipRgn, &Child->WindowRect); - } - } - - Child = Child->NextSibling; - } - - ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); - - return FALSE; -} - -HRGN FASTCALL -VIS_ComputeVisibleRegion(PWINDOW_OBJECT Window, - BOOLEAN ClientArea, BOOLEAN ClipChildren, - BOOLEAN ClipSiblings) -{ - HRGN VisRgn; - RECT Rect; - HRGN ClipRgn; - PWINDOW_OBJECT DesktopWindow; - INT LeftOffset, TopOffset; - PDESKTOP_OBJECT Desktop = Window->OwnerThread->Win32Thread->Desktop; - - DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow); - if (NULL == DesktopWindow) - { - ASSERT(FALSE); - return NULL; - } - - if (VIS_GetVisRect(Desktop, Window, ClientArea, &Rect)) - { - VisRgn = UnsafeIntCreateRectRgnIndirect(&Rect); - if (NULL != VisRgn) - { - if (ClientArea) - { - LeftOffset = Window->ClientRect.left; - TopOffset = Window->ClientRect.top; - } - else - { - LeftOffset = Window->WindowRect.left; - TopOffset = Window->WindowRect.top; - } - - ClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0); - - if (ClipRgn != NULL) - { - if (ClipChildren && Window->FirstChild) - { - VIS_AddClipRects(Window, NULL, ClipRgn, &Rect); - } - - if (ClipSiblings && 0 != (Window->Style & WS_CHILD)) - { - VIS_AddClipRects(Window->Parent, Window, ClipRgn, &Rect); - } - - while (0 != (Window->Style & WS_CHILD)) - { - if (0 != (Window->Style & WS_CLIPSIBLINGS)) - { - VIS_AddClipRects(Window->Parent, Window, ClipRgn, &Rect); - } - Window = Window->Parent; - } - - VIS_AddClipRects(DesktopWindow, Window, ClipRgn, &Rect); - - NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); - NtGdiDeleteObject(ClipRgn); - NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset); - } - else - { - NtGdiDeleteObject(VisRgn); - VisRgn = NULL; - } - } - } - else - { - VisRgn = NtGdiCreateRectRgn(0, 0, 0, 0); - } - - IntReleaseWindowObject(DesktopWindow); - - return VisRgn; -} -#else HRGN FASTCALL VIS_ComputeVisibleRegion( PWINDOW_OBJECT Window, @@ -220,7 +43,7 @@ VIS_ComputeVisibleRegion( { HRGN VisRgn, ClipRgn; INT LeftOffset, TopOffset; - PWINDOW_OBJECT CurrentWindow; + PWINDOW_OBJECT PreviousWindow, CurrentWindow, CurrentSibling; if (!(Window->Style & WS_VISIBLE)) { @@ -240,6 +63,13 @@ VIS_ComputeVisibleRegion( TopOffset = Window->WindowRect.top; } + /* + * Walk through all perent windows and for each clip the visble region + * to the parent's client area and exclude all siblings that are over + * our window. + */ + + PreviousWindow = Window; CurrentWindow = Window->Parent; while (CurrentWindow) { @@ -251,6 +81,25 @@ VIS_ComputeVisibleRegion( ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->ClientRect); NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND); NtGdiDeleteObject(ClipRgn); + + if (ClipSiblings) + { + ExAcquireFastMutexUnsafe(&CurrentWindow->ChildrenListLock); + CurrentSibling = CurrentWindow->FirstChild; + while (CurrentSibling != PreviousWindow) + { + if (CurrentSibling->Style & WS_VISIBLE) + { + ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentSibling->WindowRect); + NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); + NtGdiDeleteObject(ClipRgn); + } + CurrentSibling = CurrentSibling->NextSibling; + } + ExReleaseFastMutexUnsafe(&CurrentWindow->ChildrenListLock); + } + + PreviousWindow = CurrentWindow; CurrentWindow = CurrentWindow->Parent; } @@ -271,28 +120,10 @@ VIS_ComputeVisibleRegion( ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); } - if (ClipSiblings && Window->Parent != NULL) - { - ExAcquireFastMutexUnsafe(&Window->Parent->ChildrenListLock); - CurrentWindow = Window->Parent->FirstChild; - while (CurrentWindow != Window) - { - if (CurrentWindow->Style & WS_VISIBLE) - { - ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->WindowRect); - NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); - NtGdiDeleteObject(ClipRgn); - } - CurrentWindow = CurrentWindow->NextSibling; - } - ExReleaseFastMutexUnsafe(&Window->Parent->ChildrenListLock); - } - NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset); return VisRgn; } -#endif VOID FASTCALL VIS_WindowLayoutChanged( diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index 3cbe02bfd43..3b37cc15765 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: windc.c,v 1.57 2004/02/21 13:13:27 navaraf Exp $ +/* $Id: windc.c,v 1.58 2004/02/22 12:25:35 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -230,83 +230,82 @@ DceReleaseDC(DCE* dce) STATIC VOID FASTCALL DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags) { - HANDLE hRgnVisible = NULL; - ULONG DcxFlags; - PWINDOW_OBJECT DesktopWindow; + HANDLE hRgnVisible = NULL; + ULONG DcxFlags; + PWINDOW_OBJECT DesktopWindow; - if (Flags & DCX_PARENTCLIP) - { + if (Flags & DCX_PARENTCLIP) + { PWINDOW_OBJECT Parent; Parent = Window->Parent; - - if (Window->Style & WS_VISIBLE) - { - 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->Self, DcxFlags, - Window->Self, Flags); - if (0 == (Flags & DCX_WINDOW)) - { - NtGdiOffsetRgn(hRgnVisible, - Parent->ClientRect.left - Window->ClientRect.left, - Parent->ClientRect.top - Window->ClientRect.top); - } - else - { - NtGdiOffsetRgn(hRgnVisible, - Parent->WindowRect.left - Window->WindowRect.left, - Parent->WindowRect.top - Window->WindowRect.top); - } - } + if (Parent->Style & WS_CLIPSIBLINGS) + { + DcxFlags = DCX_CLIPSIBLINGS | + (Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW)); + } else - { - hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0); - } - } - else if (NULL == Window) - { + { + DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW); + } + hRgnVisible = DceGetVisRgn(Parent->Self, DcxFlags, Window->Self, Flags); + if (hRgnVisible == NULL) + { + hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0); + } + else + { + if (0 == (Flags & DCX_WINDOW)) + { + NtGdiOffsetRgn( + hRgnVisible, + Parent->ClientRect.left - Window->ClientRect.left, + Parent->ClientRect.top - Window->ClientRect.top); + } + else + { + NtGdiOffsetRgn( + hRgnVisible, + Parent->WindowRect.left - Window->WindowRect.left, + Parent->WindowRect.top - Window->WindowRect.top); + } + } + } + else if (Window == NULL) + { DesktopWindow = IntGetWindowObject(IntGetDesktopWindow()); if (NULL != DesktopWindow) - { - hRgnVisible = UnsafeIntCreateRectRgnIndirect(&DesktopWindow->WindowRect); - IntReleaseWindowObject(DesktopWindow); - } + { + hRgnVisible = UnsafeIntCreateRectRgnIndirect(&DesktopWindow->WindowRect); + IntReleaseWindowObject(DesktopWindow); + } else - { - hRgnVisible = NULL; - } - } - else - { + { + hRgnVisible = NULL; + } + } + else + { hRgnVisible = DceGetVisRgn(Window->Self, Flags, 0, 0); - } + } - if (0 != (Flags & DCX_INTERSECTRGN)) - { + if (Flags & DCX_INTERSECTRGN) + { NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND); - } + } - if (0 != (Flags & DCX_EXCLUDERGN)) - { + if (Flags & DCX_EXCLUDERGN) + { NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF); - } + } - Dce->DCXFlags &= ~DCX_DCEDIRTY; - NtGdiSelectVisRgn(Dce->hDC, hRgnVisible); + Dce->DCXFlags &= ~DCX_DCEDIRTY; + NtGdiSelectVisRgn(Dce->hDC, hRgnVisible); - if (hRgnVisible != NULL) - { + if (hRgnVisible != NULL) + { NtGdiDeleteObject(hRgnVisible); - } + } } HDC STDCALL