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/painti…
==============================================================================
--- 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/painti…
==============================================================================
--- 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);