Author: jimtabor Date: Mon May 28 03:34:04 2012 New Revision: 56662
URL: http://svn.reactos.org/svn/reactos?rev=56662&view=rev Log: [Win32k] - Fix the remaining wine Win test_NCRedraw test. Broken since r6737. - Miscellaneous fixes and changes.
Modified: trunk/reactos/win32ss/user/ntuser/painting.c trunk/reactos/win32ss/user/ntuser/painting.h
Modified: trunk/reactos/win32ss/user/ntuser/painting.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/paintin... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/painting.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/painting.c [iso-8859-1] Mon May 28 03:34:04 2012 @@ -223,6 +223,7 @@ if (Wnd->hrgnUpdate != NULL || Wnd->state & WNDS_INTERNALPAINT) { + Wnd->state2 |= WNDS2_WMPAINTSENT; co_IntSendMessage(hWnd, WM_PAINT, 0, 0); } } @@ -232,9 +233,7 @@ { TempRegion = IntGetNCUpdateRgn(Wnd, TRUE); Wnd->state &= ~WNDS_SENDNCPAINT; - MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue); co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)TempRegion, 0); - }
if (Wnd->state & WNDS_SENDERASEBACKGROUND) @@ -303,10 +302,10 @@ IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags) { INT RgnType; - BOOL HadPaintMessage, HadNCPaintMessage; - BOOL HasPaintMessage, HasNCPaintMessage; + BOOL HadPaintMessage;
TRACE("IntInvalidateWindows start\n"); + /* * If the nonclient is not to be redrawn, clip the region to the client * rect @@ -347,67 +346,79 @@ * Save current state of pending updates */
- HadPaintMessage = Wnd->hrgnUpdate != NULL || - Wnd->state & WNDS_INTERNALPAINT; - HadNCPaintMessage = Wnd->state & WNDS_SENDNCPAINT; + HadPaintMessage = IntIsWindowDirty(Wnd);
/* * Update the region and flags */
- if (Flags & RDW_INVALIDATE && RgnType != NULLREGION) - { - if (Wnd->hrgnUpdate == NULL) - { - Wnd->hrgnUpdate = IntSysCreateRectRgn(0, 0, 0, 0); - IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC); - } - - if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate, - hRgn, RGN_OR) == NULLREGION) - { - IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(Wnd->hrgnUpdate); - Wnd->hrgnUpdate = NULL; - } - - if (Flags & RDW_FRAME) - Wnd->state |= WNDS_SENDNCPAINT; - if (Flags & RDW_ERASE) - Wnd->state |= WNDS_SENDERASEBACKGROUND; - - Flags |= RDW_FRAME; - } - - if (Flags & RDW_VALIDATE && RgnType != NULLREGION) - { - if (Wnd->hrgnUpdate != NULL) - { + // The following flags are used to invalidate the window. + if (Flags & (RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_ERASE|RDW_FRAME)) + { + if (Flags & RDW_INTERNALPAINT) + { + Wnd->state |= WNDS_INTERNALPAINT; + } + + if (Flags & RDW_INVALIDATE && RgnType != NULLREGION) + { + /* If not the same thread set it dirty. */ + if (Wnd->head.pti != PsGetCurrentThreadWin32Thread()) + { + Wnd->state |= WNDS_UPDATEDIRTY; + } + + if (Flags & RDW_FRAME) + Wnd->state |= WNDS_SENDNCPAINT; + if (Flags & RDW_ERASE) + Wnd->state |= WNDS_SENDERASEBACKGROUND; + + if (Wnd->hrgnUpdate == NULL) + { + Wnd->hrgnUpdate = IntSysCreateRectRgn(0, 0, 0, 0); + IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC); + } + if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate, - hRgn, RGN_DIFF) == NULLREGION) + hRgn, RGN_OR) == NULLREGION) { IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED); GreDeleteObject(Wnd->hrgnUpdate); Wnd->hrgnUpdate = NULL; } - } - - if (Wnd->hrgnUpdate == NULL) - Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND); - if (Flags & RDW_NOFRAME) - Wnd->state &= ~WNDS_SENDNCPAINT; - if (Flags & RDW_NOERASE) - Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND); - } - - if (Flags & RDW_INTERNALPAINT) - { - Wnd->state |= WNDS_INTERNALPAINT; - } - - if (Flags & RDW_NOINTERNALPAINT) - { - Wnd->state &= ~WNDS_INTERNALPAINT; + Flags |= RDW_FRAME; // For children. + } + } // The following flags are used to validate the window. + else if (Flags & (RDW_VALIDATE|RDW_NOINTERNALPAINT|RDW_NOERASE|RDW_NOFRAME)) + { + /* FIXME: Handle WNDS_UPDATEDIRTY */ + + if (Flags & RDW_NOINTERNALPAINT) + { + Wnd->state &= ~WNDS_INTERNALPAINT; + } + + if (Flags & RDW_VALIDATE && RgnType != NULLREGION) + { + if (Flags & RDW_NOFRAME) + Wnd->state &= ~WNDS_SENDNCPAINT; + if (Flags & RDW_NOERASE) + Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND); + + if (Wnd->hrgnUpdate != NULL) + { + if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate, + hRgn, RGN_DIFF) == NULLREGION) + { + IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED); + GreDeleteObject(Wnd->hrgnUpdate); + Wnd->hrgnUpdate = NULL; + } + } + + if (Wnd->hrgnUpdate == NULL) + Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND); + } }
/* @@ -431,7 +442,6 @@ IntInvalidateWindows(Child, hRgnTemp, Flags); GreDeleteObject(hRgnTemp); } - } }
@@ -439,21 +449,9 @@ * Fake post paint messages to window message queue if needed */
- HasPaintMessage = Wnd->hrgnUpdate != NULL || - Wnd->state & WNDS_INTERNALPAINT; - HasNCPaintMessage = Wnd->state & WNDS_SENDNCPAINT; - - if (HasPaintMessage != HadPaintMessage) + if (HadPaintMessage != IntIsWindowDirty(Wnd)) { if (HadPaintMessage) - MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue); - else - MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue); - } - - if (HasNCPaintMessage != HadNCPaintMessage) - { - if (HadNCPaintMessage) MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue); else MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue); @@ -594,16 +592,16 @@ BOOL FASTCALL IntIsWindowDirty(PWND Wnd) { - return (Wnd->style & WS_VISIBLE) && - ((Wnd->hrgnUpdate != NULL) || - (Wnd->state & WNDS_INTERNALPAINT) || - (Wnd->state & WNDS_SENDNCPAINT)); -} - -HWND FASTCALL + return ( Wnd->style & WS_VISIBLE && + ( Wnd->hrgnUpdate != NULL || + Wnd->state & WNDS_INTERNALPAINT || + Wnd->state & WNDS_SENDNCPAINT ) ); +} + +PWND FASTCALL IntFindWindowToRepaint(PWND Window, PTHREADINFO Thread) { - HWND hChild; + PWND hChild; PWND TempWindow;
for (; Window != NULL; Window = Window->spwndNext) @@ -621,12 +619,12 @@ IntWndBelongsToThread(TempWindow, Thread) && IntIsWindowDirty(TempWindow)) { - return TempWindow->head.h; + return TempWindow; } } }
- return Window->head.h; + return Window; }
if (Window->spwndChild) @@ -636,8 +634,7 @@ return hChild; } } - - return NULL; + return Window; }
BOOL FASTCALL @@ -649,14 +646,20 @@ MSG *Message, BOOL Remove) { - if (!Thread->cPaintsReady) - return FALSE; + PWND PaintWnd;
if ((MsgFilterMin != 0 || MsgFilterMax != 0) && (MsgFilterMin > WM_PAINT || MsgFilterMax < WM_PAINT)) return FALSE;
- Message->hwnd = IntFindWindowToRepaint(UserGetDesktopWindow(), PsGetCurrentThreadWin32Thread()); + if (Thread->TIF_flags & TIF_SYSTEMTHREAD ) + { + ERR("WM_PAINT is in a System Thread!\n"); + } + + PaintWnd = IntFindWindowToRepaint(UserGetDesktopWindow(), Thread); + + Message->hwnd = PaintWnd ? UserHMGetHandle(PaintWnd) : NULL;
if (Message->hwnd == NULL) { @@ -666,12 +669,19 @@ return FALSE; }
- if (Window != NULL && Message->hwnd != Window->head.h) + if (Window != NULL && PaintWnd != Window) return FALSE;
+ if (PaintWnd->state & WNDS_INTERNALPAINT) + { + PaintWnd->state &= ~WNDS_INTERNALPAINT; + if (!PaintWnd->hrgnUpdate) + MsqDecPaintCountQueue(Thread->MessageQueue); + } + PaintWnd->state2 &= ~WNDS2_WMPAINTSENT; + PaintWnd->state &= ~WNDS_UPDATEDIRTY; + Message->wParam = Message->lParam = 0; Message->message = WM_PAINT; - Message->wParam = Message->lParam = 0; - return TRUE; }
@@ -831,19 +841,26 @@
co_UserHideCaret(Window);
+ Window->state2 |= WNDS2_STARTPAINT; + Window->state &= ~WNDS_PAINTNOTPROCESSED; + if (Window->state & WNDS_SENDNCPAINT) { HRGN hRgn;
+ Window->state &= ~WNDS_UPDATEDIRTY; hRgn = IntGetNCUpdateRgn(Window, FALSE); Window->state &= ~WNDS_SENDNCPAINT; - MsqDecPaintCountQueue(Window->head.pti->MessageQueue); co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0); if (hRgn != HRGN_WINDOW && hRgn != NULL && GreIsHandleValid(hRgn)) { /* NOTE: The region can already by deleted! */ GreDeleteObject(hRgn); } + } + else + { + Window->state &= ~WNDS_UPDATEDIRTY; }
RtlZeroMemory(&Ps, sizeof(PAINTSTRUCT)); @@ -894,6 +911,7 @@ PWND Child; for (Child = Window->spwndChild; Child; Child = Child->spwndNext) { + if (Child->hrgnUpdate == NULL && Child->state & WNDS_SENDNCPAINT) // Helped fixing test_redrawnow. IntInvalidateWindows(Child, Window->hrgnUpdate, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN); } } @@ -958,6 +976,8 @@
UserReleaseDC(Window, hdc, TRUE);
+ Window->state2 &= ~(WNDS2_WMPAINTSENT|WNDS2_STARTPAINT); + UserRefObjectCo(Window, &Ref); co_UserShowCaret(Window); UserDerefObjectCo(Window); @@ -1019,6 +1039,8 @@ RECTL Rect;
ASSERT_REFS_CO(Window); + + Window->state &= ~WNDS_UPDATEDIRTY;
if (Window->hrgnUpdate == NULL) { @@ -1100,6 +1122,8 @@ { RETURN(FALSE); } + + Window->state &= ~WNDS_UPDATEDIRTY;
if (Window->hrgnUpdate == NULL) { @@ -1974,8 +1998,13 @@
if (hwnd) { - Window = UserGetWindowObject(hwnd); - // TODO: Add Desktop and MessageBox check via FNID's. + if (!(Window = UserGetWindowObject(hwnd)) || // FIXME: + Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP + Window == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND + { + goto Exit; + } + if ( Window ) { /* Validate flags and check it as a mask for 0 or 1. */ @@ -1985,7 +2014,7 @@ EngSetLastError(ERROR_INVALID_PARAMETER); } } - +Exit: UserLeave(); return Ret; }
Modified: trunk/reactos/win32ss/user/ntuser/painting.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/paintin... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/painting.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/painting.h [iso-8859-1] Mon May 28 03:34:04 2012 @@ -7,3 +7,4 @@ INT FASTCALL co_UserGetUpdateRgn(PWND, HRGN, BOOL); VOID FASTCALL co_IntPaintWindows(PWND Window, ULONG Flags, BOOL Recurse); BOOL FASTCALL IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse); +BOOL FASTCALL IntIsWindowDirty(PWND);