From 409eab1805cc1e19636c340604c97cc995a898dd Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sat, 21 Feb 2004 13:13:27 +0000 Subject: [PATCH] - 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 --- reactos/subsys/win32k/ntuser/desktop.c | 3 +- reactos/subsys/win32k/ntuser/painting.c | 142 ++++++++++-------------- reactos/subsys/win32k/ntuser/windc.c | 26 ++--- reactos/subsys/win32k/ntuser/window.c | 27 +---- reactos/subsys/win32k/ntuser/winpos.c | 8 +- 5 files changed, 77 insertions(+), 129 deletions(-) diff --git a/reactos/subsys/win32k/ntuser/desktop.c b/reactos/subsys/win32k/ntuser/desktop.c index a4bbac36970..558c09f4006 100644 --- a/reactos/subsys/win32k/ntuser/desktop.c +++ b/reactos/subsys/win32k/ntuser/desktop.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: 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. diff --git a/reactos/subsys/win32k/ntuser/painting.c b/reactos/subsys/win32k/ntuser/painting.c index 03c4e0bf74e..c3aabd0a82f 100644 --- a/reactos/subsys/win32k/ntuser/painting.c +++ b/reactos/subsys/win32k/ntuser/painting.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: 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); diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index f724e343ea8..3cbe02bfd43 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.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; diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 0a7b6d000d8..9a0cd6dd21d 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.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: 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 diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index f0b7c198a62..f5224e26f0d 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.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: 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;