mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:53:06 +00:00
- 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
This commit is contained in:
parent
936dffea06
commit
9dacfa1b68
2 changed files with 89 additions and 259 deletions
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -34,183 +34,6 @@
|
||||||
#include <win32k/debug1.h>
|
#include <win32k/debug1.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#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
|
HRGN FASTCALL
|
||||||
VIS_ComputeVisibleRegion(
|
VIS_ComputeVisibleRegion(
|
||||||
PWINDOW_OBJECT Window,
|
PWINDOW_OBJECT Window,
|
||||||
|
@ -220,7 +43,7 @@ VIS_ComputeVisibleRegion(
|
||||||
{
|
{
|
||||||
HRGN VisRgn, ClipRgn;
|
HRGN VisRgn, ClipRgn;
|
||||||
INT LeftOffset, TopOffset;
|
INT LeftOffset, TopOffset;
|
||||||
PWINDOW_OBJECT CurrentWindow;
|
PWINDOW_OBJECT PreviousWindow, CurrentWindow, CurrentSibling;
|
||||||
|
|
||||||
if (!(Window->Style & WS_VISIBLE))
|
if (!(Window->Style & WS_VISIBLE))
|
||||||
{
|
{
|
||||||
|
@ -240,6 +63,13 @@ VIS_ComputeVisibleRegion(
|
||||||
TopOffset = Window->WindowRect.top;
|
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;
|
CurrentWindow = Window->Parent;
|
||||||
while (CurrentWindow)
|
while (CurrentWindow)
|
||||||
{
|
{
|
||||||
|
@ -251,6 +81,25 @@ VIS_ComputeVisibleRegion(
|
||||||
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->ClientRect);
|
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->ClientRect);
|
||||||
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
|
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
|
||||||
NtGdiDeleteObject(ClipRgn);
|
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;
|
CurrentWindow = CurrentWindow->Parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,28 +120,10 @@ VIS_ComputeVisibleRegion(
|
||||||
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
|
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);
|
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
|
||||||
|
|
||||||
return VisRgn;
|
return VisRgn;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
VIS_WindowLayoutChanged(
|
VIS_WindowLayoutChanged(
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -230,83 +230,82 @@ DceReleaseDC(DCE* dce)
|
||||||
STATIC VOID FASTCALL
|
STATIC VOID FASTCALL
|
||||||
DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
|
DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
|
||||||
{
|
{
|
||||||
HANDLE hRgnVisible = NULL;
|
HANDLE hRgnVisible = NULL;
|
||||||
ULONG DcxFlags;
|
ULONG DcxFlags;
|
||||||
PWINDOW_OBJECT DesktopWindow;
|
PWINDOW_OBJECT DesktopWindow;
|
||||||
|
|
||||||
if (Flags & DCX_PARENTCLIP)
|
if (Flags & DCX_PARENTCLIP)
|
||||||
{
|
{
|
||||||
PWINDOW_OBJECT Parent;
|
PWINDOW_OBJECT Parent;
|
||||||
|
|
||||||
Parent = Window->Parent;
|
Parent = Window->Parent;
|
||||||
|
if (Parent->Style & WS_CLIPSIBLINGS)
|
||||||
if (Window->Style & WS_VISIBLE)
|
{
|
||||||
{
|
DcxFlags = DCX_CLIPSIBLINGS |
|
||||||
if (Parent->Style & WS_CLIPSIBLINGS)
|
(Flags & ~(DCX_CLIPCHILDREN | DCX_WINDOW));
|
||||||
{
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hRgnVisible = NtGdiCreateRectRgn(0, 0, 0, 0);
|
DcxFlags = Flags & ~(DCX_CLIPSIBLINGS | DCX_CLIPCHILDREN | DCX_WINDOW);
|
||||||
}
|
}
|
||||||
}
|
hRgnVisible = DceGetVisRgn(Parent->Self, DcxFlags, Window->Self, Flags);
|
||||||
else if (NULL == Window)
|
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());
|
DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
|
||||||
if (NULL != DesktopWindow)
|
if (NULL != DesktopWindow)
|
||||||
{
|
{
|
||||||
hRgnVisible = UnsafeIntCreateRectRgnIndirect(&DesktopWindow->WindowRect);
|
hRgnVisible = UnsafeIntCreateRectRgnIndirect(&DesktopWindow->WindowRect);
|
||||||
IntReleaseWindowObject(DesktopWindow);
|
IntReleaseWindowObject(DesktopWindow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hRgnVisible = NULL;
|
hRgnVisible = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hRgnVisible = DceGetVisRgn(Window->Self, Flags, 0, 0);
|
hRgnVisible = DceGetVisRgn(Window->Self, Flags, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != (Flags & DCX_INTERSECTRGN))
|
if (Flags & DCX_INTERSECTRGN)
|
||||||
{
|
{
|
||||||
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND);
|
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_AND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != (Flags & DCX_EXCLUDERGN))
|
if (Flags & DCX_EXCLUDERGN)
|
||||||
{
|
{
|
||||||
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF);
|
NtGdiCombineRgn(hRgnVisible, hRgnVisible, Dce->hClipRgn, RGN_DIFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dce->DCXFlags &= ~DCX_DCEDIRTY;
|
Dce->DCXFlags &= ~DCX_DCEDIRTY;
|
||||||
NtGdiSelectVisRgn(Dce->hDC, hRgnVisible);
|
NtGdiSelectVisRgn(Dce->hDC, hRgnVisible);
|
||||||
|
|
||||||
if (hRgnVisible != NULL)
|
if (hRgnVisible != NULL)
|
||||||
{
|
{
|
||||||
NtGdiDeleteObject(hRgnVisible);
|
NtGdiDeleteObject(hRgnVisible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HDC STDCALL
|
HDC STDCALL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue