[ros-diffs] [jimtabor] 56662: [Win32k] - Fix the remaining wine Win test_NCRedraw test. Broken since r6737. - Miscellaneous fixes and changes.

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Mon May 28 03:34:16 UTC 2012


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/painting.c?rev=56662&r1=56661&r2=56662&view=diff
==============================================================================
--- 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/painting.h?rev=56662&r1=56661&r2=56662&view=diff
==============================================================================
--- 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);




More information about the Ros-diffs mailing list