- Fixed some nonsense code in NtGdiGetDCEx.

- Fixed few race conditions in painting code.
- Removed function IntGetNCUpdateRegion and inlined it's code into IntInvalidateWindows.
- Removed function IsHidden and replaced it's usage by IntIsWindowVisible.

svn path=/trunk/; revision=8285
This commit is contained in:
Filip Navara 2004-02-21 13:13:27 +00:00
parent 5b5028fcb9
commit 409eab1805
5 changed files with 77 additions and 129 deletions

View file

@ -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: desktop.c,v 1.8 2003/12/26 00:58:33 weiden Exp $
* $Id: desktop.c,v 1.9 2004/02/21 13:13:26 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -254,7 +254,6 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop)
}
/*
<<<<<<< winsta.c
* NtUserCreateDesktop
*
* Creates a new desktop.

View file

@ -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: painting.c,v 1.67 2004/02/04 23:01:07 gvg Exp $
* $Id: painting.c,v 1.68 2004/02/21 13:13:26 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -92,60 +92,6 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
}
}
/*
* IntGetNCUpdateRegion
*
* Get nonclient part of window update region.
*
* Return Value
* Handle to region that represents invalid nonclient window area. The
* caller is responsible for deleting it.
*
* Remarks
* This function also marks the nonclient update region of window
* as valid, clears the WINDOWOBJECT_NEED_NCPAINT flag.
*/
STATIC HRGN FASTCALL
IntGetNCUpdateRegion(PWINDOW_OBJECT Window)
{
HRGN WindowRgn;
HRGN NonclientRgn;
ASSERT(! ExTryToAcquireFastMutex(&Window->UpdateLock));
/*
* Generate the update region.
*/
WindowRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
NtGdiOffsetRgn(WindowRgn,
-Window->WindowRect.left,
-Window->WindowRect.top);
NonclientRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
if (NtGdiCombineRgn(NonclientRgn, Window->UpdateRegion,
WindowRgn, RGN_DIFF) == NULLREGION)
{
NtGdiDeleteObject(NonclientRgn);
NonclientRgn = NULL;
}
/*
* Remove the nonclient region from the standard update region.
*/
if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
WindowRgn, RGN_AND) == NULLREGION)
{
NtGdiDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL;
}
NtGdiDeleteObject(WindowRgn);
return NonclientRgn;
}
/*
* IntPaintWindows
*
@ -158,11 +104,6 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
HDC hDC;
HWND hWnd = Window->Self;
if (! (Window->Style & WS_VISIBLE))
{
return;
}
if (Flags & (RDW_ERASENOW | RDW_UPDATENOW))
{
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
@ -239,7 +180,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
for (phWnd = List; *phWnd; ++phWnd)
{
Window = IntGetWindowObject(*phWnd);
if (Window)
if (Window && (Window->Style & WS_VISIBLE))
{
IntPaintWindows(Window, Flags);
IntReleaseWindowObject(Window);
@ -262,7 +203,6 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
INT RgnType;
BOOL HadPaintMessage, HadNCPaintMessage;
BOOL HasPaintMessage, HasNCPaintMessage;
HRGN hRgnWindow;
/*
* Clip the given region with window rectangle (or region)
@ -272,11 +212,13 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
if (!Window->WindowRegion)
#endif
{
HRGN hRgnWindow;
hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
NtGdiOffsetRgn(hRgnWindow,
-Window->WindowRect.left,
-Window->WindowRect.top);
RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);
RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);
NtGdiDeleteObject(hRgnWindow);
}
#ifdef TODO
@ -355,16 +297,44 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
* Split the nonclient update region.
*/
if (Window->NCUpdateRegion == NULL)
{
Window->NCUpdateRegion = IntGetNCUpdateRegion(Window);
}
else
{
HRGN hRgnNonClient = IntGetNCUpdateRegion(Window);
NtGdiCombineRgn(Window->NCUpdateRegion, Window->NCUpdateRegion,
hRgnNonClient, RGN_OR);
NtGdiDeleteObject(hRgnNonClient);
HRGN hRgnWindow, hRgnNonClient;
hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
NtGdiOffsetRgn(hRgnWindow,
-Window->WindowRect.left,
-Window->WindowRect.top);
hRgnNonClient = NtGdiCreateRectRgn(0, 0, 0, 0);
if (NtGdiCombineRgn(hRgnNonClient, Window->UpdateRegion,
hRgnWindow, RGN_DIFF) == NULLREGION)
{
NtGdiDeleteObject(hRgnNonClient);
hRgnNonClient = NULL;
}
/*
* Remove the nonclient region from the standard update region.
*/
if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
hRgnWindow, RGN_AND) == NULLREGION)
{
NtGdiDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL;
}
if (Window->NCUpdateRegion == NULL)
{
Window->NCUpdateRegion = hRgnNonClient;
}
else
{
NtGdiCombineRgn(Window->NCUpdateRegion, Window->NCUpdateRegion,
hRgnNonClient, RGN_OR);
}
NtGdiDeleteObject(hRgnWindow);
}
/*
@ -408,6 +378,7 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
/*
* Fake post paint messages to window message queue if needed
*/
HasPaintMessage = Window->UpdateRegion != NULL ||
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
HasNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT;
@ -534,7 +505,8 @@ IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
* Repaint and erase windows if needed.
*/
if (Flags & (RDW_ERASENOW | RDW_UPDATENOW))
if ((Flags & (RDW_ERASENOW | RDW_UPDATENOW)) &&
IntIsWindowVisible(Window))
{
IntPaintWindows(Window, Flags);
}
@ -552,6 +524,15 @@ IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
return TRUE;
}
BOOL FASTCALL
IntIsWindowDirty(PWINDOW_OBJECT Window)
{
return (Window->Style & WS_VISIBLE) &&
((Window->UpdateRegion != NULL) ||
(Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) ||
(Window->Flags & WINDOWOBJECT_NEED_NCPAINT));
}
HWND STDCALL
IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
{
@ -563,8 +544,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
if (Window == NULL)
return NULL;
if ((Window->UpdateRegion != NULL ||
Window->Flags & (WINDOWOBJECT_NEED_INTERNALPAINT | WINDOWOBJECT_NEED_NCPAINT)) &&
if (IntIsWindowDirty(Window) &&
IntWndBelongsToThread(Window, Thread))
{
IntReleaseWindowObject(Window);
@ -573,13 +553,10 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
ExAcquireFastMutex(&Window->ChildrenListLock);
for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
for (Child = Window->LastChild; Child; Child = Child->PrevSibling)
{
if (Child->Style & WS_VISIBLE &&
(Child->UpdateRegion != NULL ||
Child->Flags & WINDOWOBJECT_NEED_INTERNALPAINT ||
Child->Flags & WINDOWOBJECT_NEED_NCPAINT)
&& IntWndBelongsToThread(Child, Thread))
if (IntIsWindowDirty(Child) &&
IntWndBelongsToThread(Child, Thread))
{
hFoundWnd = Child->Self;
break;
@ -588,7 +565,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
if (hFoundWnd == NULL)
{
for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
for (Child = Window->LastChild; Child; Child = Child->PrevSibling)
{
if (Child->Style & WS_VISIBLE)
{
@ -643,6 +620,7 @@ IntGetPaintMessage(HWND hWnd, PW32THREAD Thread, MSG *Message,
Message->lParam = 0;
if (Remove)
{
IntValidateParent(Window, Window->NCUpdateRegion);
Window->NCUpdateRegion = NULL;
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
MsqDecPaintCountQueue(Window->MessageQueue);

View file

@ -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.56 2004/02/08 22:02:40 gvg Exp $
/* $Id: windc.c,v 1.57 2004/02/21 13:13:27 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -240,8 +240,7 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
Parent = Window->Parent;
if (Window->Style & WS_VISIBLE /*&&
!(Parent->Style & WS_MINIMIZE)*/)
if (Window->Style & WS_VISIBLE)
{
if (Parent->Style & WS_CLIPSIBLINGS)
{
@ -381,18 +380,15 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
else if (Flags & DCX_PARENTCLIP)
{
Flags |= DCX_CACHE;
if (!(Flags & (DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS)))
{
if ((Window->Style & WS_VISIBLE) &&
(Window->Parent->Style & WS_VISIBLE))
{
Flags &= ~DCX_CLIPCHILDREN;
if (Window->Parent->Style & WS_CLIPSIBLINGS)
{
Flags |= DCX_CLIPSIBLINGS;
}
}
}
if ((Window->Style & WS_VISIBLE) &&
(Window->Parent->Style & WS_VISIBLE))
{
Flags &= ~DCX_CLIPCHILDREN;
if (Window->Parent->Style & WS_CLIPSIBLINGS)
{
Flags |= DCX_CLIPSIBLINGS;
}
}
}
DcxFlags = Flags & DCX_CACHECOMPAREMASK;

View file

@ -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: window.c,v 1.185 2004/02/19 21:12:09 weiden Exp $
/* $Id: window.c,v 1.186 2004/02/21 13:13:27 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -3309,29 +3309,6 @@ static BOOL IsStaticClass(PWINDOW_OBJECT Window)
return rc;
}
static BOOL IsHidden(PWINDOW_OBJECT Window)
{
BOOL rc = FALSE;
ASSERT(0 != Window);
PWINDOW_OBJECT wnd = Window;
while (0 != wnd && wnd->Style & WS_CHILD)
{
if (!(wnd->Style & WS_VISIBLE))
{
rc = TRUE;
break;
}
wnd = wnd->Parent;
}
if (0 != wnd)
{
rc = !(wnd->Style & WS_VISIBLE);
}
return rc;
}
static BOOL IsDisabled(PWINDOW_OBJECT Window)
{
BOOL rc = FALSE;
@ -3365,7 +3342,7 @@ static PWINDOW_OBJECT RestrictiveSearchChildWindows(PWINDOW_OBJECT Window, POINT
*/
if (!IsStaticClass(ChildWindow) &&
!IsDisabled(ChildWindow) &&
!IsHidden(ChildWindow) )
IntIsWindowVisible(ChildWindow))
{
/*
**Now find the deepest child window

View file

@ -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: winpos.c,v 1.92 2004/02/19 21:12:09 weiden Exp $
/* $Id: winpos.c,v 1.93 2004/02/21 13:13:27 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -747,8 +747,8 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
if (Wnd == IntGetDesktopWindow() &&
Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
{
IntReleaseWindowObject(Window);
return FALSE;
IntReleaseWindowObject(Window);
return FALSE;
}
WinPos.hwnd = Wnd;
@ -831,8 +831,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
}
}
/* FIXME: Reset active DCEs */
OldWindowRect = Window->WindowRect;
OldClientRect = Window->ClientRect;