- 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 * 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: 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -254,7 +254,6 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop)
} }
/* /*
<<<<<<< winsta.c
* NtUserCreateDesktop * NtUserCreateDesktop
* *
* Creates a new desktop. * Creates a new desktop.

View file

@ -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: 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * 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 * IntPaintWindows
* *
@ -158,11 +104,6 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
HDC hDC; HDC hDC;
HWND hWnd = Window->Self; HWND hWnd = Window->Self;
if (! (Window->Style & WS_VISIBLE))
{
return;
}
if (Flags & (RDW_ERASENOW | RDW_UPDATENOW)) if (Flags & (RDW_ERASENOW | RDW_UPDATENOW))
{ {
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
@ -239,7 +180,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
for (phWnd = List; *phWnd; ++phWnd) for (phWnd = List; *phWnd; ++phWnd)
{ {
Window = IntGetWindowObject(*phWnd); Window = IntGetWindowObject(*phWnd);
if (Window) if (Window && (Window->Style & WS_VISIBLE))
{ {
IntPaintWindows(Window, Flags); IntPaintWindows(Window, Flags);
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
@ -262,7 +203,6 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
INT RgnType; INT RgnType;
BOOL HadPaintMessage, HadNCPaintMessage; BOOL HadPaintMessage, HadNCPaintMessage;
BOOL HasPaintMessage, HasNCPaintMessage; BOOL HasPaintMessage, HasNCPaintMessage;
HRGN hRgnWindow;
/* /*
* Clip the given region with window rectangle (or region) * Clip the given region with window rectangle (or region)
@ -272,6 +212,8 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
if (!Window->WindowRegion) if (!Window->WindowRegion)
#endif #endif
{ {
HRGN hRgnWindow;
hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
NtGdiOffsetRgn(hRgnWindow, NtGdiOffsetRgn(hRgnWindow,
-Window->WindowRect.left, -Window->WindowRect.left,
@ -355,16 +297,44 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
* Split the nonclient update region. * Split the nonclient update region.
*/ */
if (Window->NCUpdateRegion == NULL)
{ {
Window->NCUpdateRegion = IntGetNCUpdateRegion(Window); HRGN hRgnWindow, hRgnNonClient;
}
else hRgnWindow = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
{ NtGdiOffsetRgn(hRgnWindow,
HRGN hRgnNonClient = IntGetNCUpdateRegion(Window); -Window->WindowRect.left,
NtGdiCombineRgn(Window->NCUpdateRegion, Window->NCUpdateRegion, -Window->WindowRect.top);
hRgnNonClient, RGN_OR);
NtGdiDeleteObject(hRgnNonClient); 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 * Fake post paint messages to window message queue if needed
*/ */
HasPaintMessage = Window->UpdateRegion != NULL || HasPaintMessage = Window->UpdateRegion != NULL ||
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT; Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
HasNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT; 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. * Repaint and erase windows if needed.
*/ */
if (Flags & (RDW_ERASENOW | RDW_UPDATENOW)) if ((Flags & (RDW_ERASENOW | RDW_UPDATENOW)) &&
IntIsWindowVisible(Window))
{ {
IntPaintWindows(Window, Flags); IntPaintWindows(Window, Flags);
} }
@ -552,6 +524,15 @@ IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
return TRUE; 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 HWND STDCALL
IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread) IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
{ {
@ -563,8 +544,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
if (Window == NULL) if (Window == NULL)
return NULL; return NULL;
if ((Window->UpdateRegion != NULL || if (IntIsWindowDirty(Window) &&
Window->Flags & (WINDOWOBJECT_NEED_INTERNALPAINT | WINDOWOBJECT_NEED_NCPAINT)) &&
IntWndBelongsToThread(Window, Thread)) IntWndBelongsToThread(Window, Thread))
{ {
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
@ -573,13 +553,10 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
ExAcquireFastMutex(&Window->ChildrenListLock); ExAcquireFastMutex(&Window->ChildrenListLock);
for (Child = Window->FirstChild; Child; Child = Child->NextSibling) for (Child = Window->LastChild; Child; Child = Child->PrevSibling)
{ {
if (Child->Style & WS_VISIBLE && if (IntIsWindowDirty(Child) &&
(Child->UpdateRegion != NULL || IntWndBelongsToThread(Child, Thread))
Child->Flags & WINDOWOBJECT_NEED_INTERNALPAINT ||
Child->Flags & WINDOWOBJECT_NEED_NCPAINT)
&& IntWndBelongsToThread(Child, Thread))
{ {
hFoundWnd = Child->Self; hFoundWnd = Child->Self;
break; break;
@ -588,7 +565,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
if (hFoundWnd == NULL) if (hFoundWnd == NULL)
{ {
for (Child = Window->FirstChild; Child; Child = Child->NextSibling) for (Child = Window->LastChild; Child; Child = Child->PrevSibling)
{ {
if (Child->Style & WS_VISIBLE) if (Child->Style & WS_VISIBLE)
{ {
@ -643,6 +620,7 @@ IntGetPaintMessage(HWND hWnd, PW32THREAD Thread, MSG *Message,
Message->lParam = 0; Message->lParam = 0;
if (Remove) if (Remove)
{ {
IntValidateParent(Window, Window->NCUpdateRegion);
Window->NCUpdateRegion = NULL; Window->NCUpdateRegion = NULL;
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
MsqDecPaintCountQueue(Window->MessageQueue); MsqDecPaintCountQueue(Window->MessageQueue);

View file

@ -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.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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -240,8 +240,7 @@ DceUpdateVisRgn(DCE *Dce, PWINDOW_OBJECT Window, ULONG Flags)
Parent = Window->Parent; Parent = Window->Parent;
if (Window->Style & WS_VISIBLE /*&& if (Window->Style & WS_VISIBLE)
!(Parent->Style & WS_MINIMIZE)*/)
{ {
if (Parent->Style & WS_CLIPSIBLINGS) if (Parent->Style & WS_CLIPSIBLINGS)
{ {
@ -381,18 +380,15 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
else if (Flags & DCX_PARENTCLIP) else if (Flags & DCX_PARENTCLIP)
{ {
Flags |= DCX_CACHE; Flags |= DCX_CACHE;
if (!(Flags & (DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS))) if ((Window->Style & WS_VISIBLE) &&
{ (Window->Parent->Style & WS_VISIBLE))
if ((Window->Style & WS_VISIBLE) && {
(Window->Parent->Style & WS_VISIBLE)) Flags &= ~DCX_CLIPCHILDREN;
{ if (Window->Parent->Style & WS_CLIPSIBLINGS)
Flags &= ~DCX_CLIPCHILDREN; {
if (Window->Parent->Style & WS_CLIPSIBLINGS) Flags |= DCX_CLIPSIBLINGS;
{ }
Flags |= DCX_CLIPSIBLINGS; }
}
}
}
} }
DcxFlags = Flags & DCX_CACHECOMPAREMASK; DcxFlags = Flags & DCX_CACHECOMPAREMASK;

View file

@ -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: 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -3309,29 +3309,6 @@ static BOOL IsStaticClass(PWINDOW_OBJECT Window)
return rc; 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) static BOOL IsDisabled(PWINDOW_OBJECT Window)
{ {
BOOL rc = FALSE; BOOL rc = FALSE;
@ -3365,7 +3342,7 @@ static PWINDOW_OBJECT RestrictiveSearchChildWindows(PWINDOW_OBJECT Window, POINT
*/ */
if (!IsStaticClass(ChildWindow) && if (!IsStaticClass(ChildWindow) &&
!IsDisabled(ChildWindow) && !IsDisabled(ChildWindow) &&
!IsHidden(ChildWindow) ) IntIsWindowVisible(ChildWindow))
{ {
/* /*
**Now find the deepest child window **Now find the deepest child window

View file

@ -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: 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -747,8 +747,8 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
if (Wnd == IntGetDesktopWindow() && if (Wnd == IntGetDesktopWindow() &&
Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess()) Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
{ {
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
return FALSE; return FALSE;
} }
WinPos.hwnd = Wnd; 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; OldWindowRect = Window->WindowRect;
OldClientRect = Window->ClientRect; OldClientRect = Window->ClientRect;