- More painting bugfixes.
authorFilip Navara <filip.navara@gmail.com>
Fri, 21 Nov 2003 17:01:16 +0000 (17:01 +0000)
committerFilip Navara <filip.navara@gmail.com>
Fri, 21 Nov 2003 17:01:16 +0000 (17:01 +0000)
svn path=/trunk/; revision=6737

reactos/subsys/win32k/include/painting.h
reactos/subsys/win32k/include/window.h
reactos/subsys/win32k/ntuser/message.c
reactos/subsys/win32k/ntuser/msgqueue.c
reactos/subsys/win32k/ntuser/painting.c
reactos/subsys/win32k/ntuser/vis.c
reactos/subsys/win32k/ntuser/window.c
reactos/subsys/win32k/ntuser/winpos.c

index 5caabcf..501ef19 100644 (file)
@@ -10,7 +10,7 @@
 BOOL FASTCALL
 IntRedrawWindow(PWINDOW_OBJECT Wnd, const RECT* UpdateRect, HRGN UpdateRgn, ULONG Flags);
 BOOL FASTCALL
-IntGetPaintMessage(PWINDOW_OBJECT Window, PW32THREAD Thread, MSG *Message);
+IntGetPaintMessage(PWINDOW_OBJECT Window, PW32THREAD Thread, MSG *Message, BOOL Remove);
 BOOL STDCALL
 NtUserValidateRgn(HWND hWnd, HRGN hRgn);
 
index bd15b5d..769b1b2 100644 (file)
@@ -88,7 +88,6 @@ typedef struct _WINDOW_OBJECT
 #define WINDOWOBJECT_NEED_ERASEBKGND      (0x00000002)
 #define WINDOWOBJECT_NEED_NCPAINT         (0x00000004)
 #define WINDOWOBJECT_NEED_INTERNALPAINT   (0x00000008)
-#define WINDOWOBJECT_MAPPING              (0x00000010)
 #define WINDOWOBJECT_RESTOREMAX           (0x00000020)
 
 inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT WindowObject);
index 247d3a5..ff3b579 100644 (file)
@@ -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: message.c,v 1.33 2003/11/19 13:19:40 weiden Exp $
+/* $Id: message.c,v 1.34 2003/11/21 17:01:16 navaraf Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -203,12 +203,9 @@ IntPeekMessage(LPMSG Msg,
     ;
 
   /* Check for paint messages. */
-  if (ThreadQueue->PaintPosted)
+  if (IntGetPaintMessage(Wnd, PsGetWin32Thread(), Msg, RemoveMessages))
     {
-      if (IntGetPaintMessage(Wnd, PsGetWin32Thread(), Msg))
-        {
-          return TRUE;
-        }
+      return TRUE;
     }
 
   return FALSE;
index d73daf3..8649f91 100644 (file)
@@ -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: msgqueue.c,v 1.32 2003/11/21 16:36:26 weiden Exp $
+/* $Id: msgqueue.c,v 1.33 2003/11/21 17:01:16 navaraf Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -819,6 +819,8 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
   KeInitializeEvent(&MessageQueue->NewMessages, SynchronizationEvent, FALSE);
   MessageQueue->QueueStatus = 0;
   MessageQueue->FocusWindow = NULL;
+  MessageQueue->PaintPosted = FALSE;
+  MessageQueue->PaintCount = 0;
 }
 
 VOID FASTCALL
index 276df74..ba23e94 100644 (file)
@@ -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.36 2003/11/20 21:21:29 navaraf Exp $
+ *  $Id: painting.c,v 1.37 2003/11/21 17:01:16 navaraf Exp $
  *
  *  COPYRIGHT:        See COPYING in the top level directory
  *  PROJECT:          ReactOS kernel
 
 /* PRIVATE FUNCTIONS **********************************************************/
 
+VOID FASTCALL
+IntValidateParent(PWINDOW_OBJECT Child)
+{
+   HWND Parent;
+   PWINDOW_OBJECT ParentWindow;
+
+   Parent = NtUserGetAncestor(Child->Self, GA_PARENT);
+   while (Parent && Parent != IntGetDesktopWindow())
+   {
+      ParentWindow = IntGetWindowObject(Parent);
+      if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN))
+      {
+         if (ParentWindow->UpdateRegion != 0)
+         {
+            INT OffsetX, OffsetY;
+
+            /*
+             * We must offset the child region by the offset of the
+             * child rect in the parent.
+             */
+            OffsetX = Child->WindowRect.left - ParentWindow->WindowRect.left;
+            OffsetY = Child->WindowRect.top - ParentWindow->WindowRect.top;
+            NtGdiOffsetRgn(Child->UpdateRegion, OffsetX, OffsetY );
+            NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion,
+               Child->UpdateRegion, RGN_DIFF);
+            /* FIXME: If the resulting region is empty, remove fake posted paint message */
+            NtGdiOffsetRgn(Child->UpdateRegion, -OffsetX, -OffsetY);
+         }
+      }
+      IntReleaseWindowObject(ParentWindow);
+      Parent = NtUserGetAncestor(Parent, GA_PARENT);
+   }
+}
+
 /*
  * IntGetNCUpdateRegion
  *
  * Remarks
  *    This function also marks the nonclient update region of window
  *    as valid, clears the WINDOWOBJECT_NEED_NCPAINT flag and removes
- *    the fake paint message from message queue.
+ *    the fake paint message from message queue if the Remove is set
+ *    to TRUE.
  */
 
 HRGN FASTCALL
-IntGetNCUpdateRegion(PWINDOW_OBJECT Window)
+IntGetNCUpdateRegion(PWINDOW_OBJECT Window, BOOL Remove)
 {
    HRGN WindowRgn;
    HRGN NonclientRgn;
 
-   Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
-   MsqDecPaintCountQueue(Window->MessageQueue);
    WindowRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
    NtGdiOffsetRgn(WindowRgn, 
       -Window->WindowRect.left,
@@ -94,11 +127,16 @@ IntGetNCUpdateRegion(PWINDOW_OBJECT Window)
       NtGdiDeleteObject(NonclientRgn);
       NonclientRgn = NULL;
    }
-   if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
-       WindowRgn, RGN_AND) == NULLREGION)
+   if (Remove)
    {
-      NtGdiDeleteObject(Window->UpdateRegion);
-      Window->UpdateRegion = NULL;
+      if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
+          WindowRgn, RGN_AND) == NULLREGION)
+      {
+         NtGdiDeleteObject(Window->UpdateRegion);
+         Window->UpdateRegion = NULL;
+      }
+      Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
+      MsqDecPaintCountQueue(Window->MessageQueue);
    }
 
    return NonclientRgn;
@@ -165,7 +203,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
 
          if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
          {
-            NtUserSendMessage(hWnd, WM_NCPAINT, (WPARAM)IntGetNCUpdateRegion(Window), 0);
+            NtUserSendMessage(hWnd, WM_NCPAINT, (WPARAM)IntGetNCUpdateRegion(Window, TRUE), 0);
          }
 
          if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND)
@@ -244,12 +282,9 @@ VOID FASTCALL
 IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
 {
    INT RgnType;
+   BOOL HadPaintMessage, HadNCPaintMessage;
+   BOOL HasPaintMessage, HasNCPaintMessage;
 
-   if (!(Window->Style & WS_VISIBLE))
-   {
-      return;
-   }
-   
    /*
     * Clip the given region with window rectangle (or region)
     */
@@ -264,6 +299,7 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
          -Window->WindowRect.left,
          -Window->WindowRect.top);
       RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);        
+      NtGdiDeleteObject(hRgnWindow);
    }
 #ifdef TODO
    else
@@ -272,38 +308,19 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    }
 #endif
 
-   if (RgnType == NULLREGION)
-   {
-      return;
-   }
-
    /*
-    * Remove fake posted paint messages from window message queue
+    * Save current state of pending updates
     */
 
-#ifndef DESKTOP_IN_CSRSS
-   if (!IntIsDesktopWindow(Window))
-   {
-#endif
-      if (Window->UpdateRegion != NULL ||
-          Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
-      {
-         MsqDecPaintCountQueue(Window->MessageQueue);
-      }
-
-      if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
-      {
-         MsqDecPaintCountQueue(Window->MessageQueue);
-      }
-#ifndef DESKTOP_IN_CSRSS
-   }
-#endif
+   HadPaintMessage = Window->UpdateRegion != NULL ||
+      Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
+   HadNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT;
 
    /*
     * Update the region and flags
     */
 
-   if (Flags & RDW_INVALIDATE)
+   if (Flags & RDW_INVALIDATE && RgnType != NULLREGION)
    {
       if (Window->UpdateRegion == NULL)
       {
@@ -325,7 +342,7 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
       Flags |= RDW_FRAME;
    }
 
-   if (Flags & RDW_VALIDATE)
+   if (Flags & RDW_VALIDATE && RgnType != NULLREGION)
    {
       if (Window->UpdateRegion != NULL)
       {
@@ -337,6 +354,8 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
          }
       }
 
+      if (Window->UpdateRegion == NULL)
+         Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBKGND;
       if (Flags & RDW_NOFRAME)
          Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
       if (Flags & RDW_NOERASE)
@@ -354,22 +373,31 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    }
 
    /*
-    * Fake post paint messages to window message queue
+    * Fake post paint messages to window message queue if needed
     */
 
 #ifndef DESKTOP_IN_CSRSS
-   if (!IntIsDesktopWindow(Window))
-   {
+   if (Window->MessageQueue)
 #endif
-      if (Window->UpdateRegion != NULL ||
-          Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
+   {
+      HasPaintMessage = Window->UpdateRegion != NULL ||
+         Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
+      HasNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT;
+
+      if (HasPaintMessage != HadPaintMessage)
       {
-         MsqIncPaintCountQueue(Window->MessageQueue);
+         if (HadPaintMessage)
+            MsqDecPaintCountQueue(Window->MessageQueue);
+         else
+            MsqIncPaintCountQueue(Window->MessageQueue);
       }
 
-      if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
+      if (HasNCPaintMessage != HadNCPaintMessage)
       {
-         MsqIncPaintCountQueue(Window->MessageQueue);
+         if (HadNCPaintMessage)
+            MsqDecPaintCountQueue(Window->MessageQueue);
+         else
+            MsqIncPaintCountQueue(Window->MessageQueue);
       }
 #ifndef DESKTOP_IN_CSRSS
    }
@@ -389,14 +417,18 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
       {
          for (phWnd = List; *phWnd; ++phWnd)
          {
-            HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
             Child = IntGetWindowObject(*phWnd);
-            NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
-            NtGdiOffsetRgn(hRgnTemp,
-               Window->WindowRect.left - Child->WindowRect.left,
-               Window->WindowRect.top - Child->WindowRect.top);
-            IntInvalidateWindows(Child, hRgnTemp, Flags);
-            NtGdiDeleteObject(hRgnTemp);
+            if ((Child->Style & (WS_VISIBLE | WS_MINIMIZE)) == WS_VISIBLE)
+            {
+               HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
+               Child = IntGetWindowObject(*phWnd);
+               NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
+               NtGdiOffsetRgn(hRgnTemp,
+                  Window->WindowRect.left - Child->WindowRect.left,
+                  Window->WindowRect.top - Child->WindowRect.top);
+               IntInvalidateWindows(Child, hRgnTemp, Flags);
+               NtGdiDeleteObject(hRgnTemp);
+            }
             IntReleaseWindowObject(Child);
          }
          ExFreePool(List);
@@ -404,37 +436,24 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    }
 }
 
-VOID FASTCALL
-IntValidateParent(PWINDOW_OBJECT Child)
-{
-   HWND Parent;
-   PWINDOW_OBJECT ParentWindow;
+/*
+ * IntIsWindowDrawable
+ *
+ * Remarks
+ *    Window is drawable when it is visible, all parents are not
+ *    minimized, and it is itself not minimized.
+ */
 
-   Parent = NtUserGetAncestor(Child->Self, GA_PARENT);
-   while (Parent && Parent != IntGetDesktopWindow())
+BOOL FASTCALL
+IntIsWindowDrawable(PWINDOW_OBJECT Window)
+{
+   for (; Window; Window = Window->Parent)
    {
-      ParentWindow = IntGetWindowObject(Parent);
-      if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN))
-      {
-         if (ParentWindow->UpdateRegion != 0)
-         {
-            INT OffsetX, OffsetY;
-
-            /*
-             * We must offset the child region by the offset of the
-             * child rect in the parent.
-             */
-            OffsetX = Child->WindowRect.left - ParentWindow->WindowRect.left;
-            OffsetY = Child->WindowRect.top - ParentWindow->WindowRect.top;
-            NtGdiOffsetRgn(Child->UpdateRegion, OffsetX, OffsetY );
-            NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion,
-               Child->UpdateRegion, RGN_DIFF);
-            NtGdiOffsetRgn(Child->UpdateRegion, -OffsetX, -OffsetY);
-         }
-      }
-      IntReleaseWindowObject(ParentWindow);
-      Parent = NtUserGetAncestor(Parent, GA_PARENT);
+      if ((Window->Style & (WS_VISIBLE | WS_MINIMIZE)) != WS_VISIBLE)
+         return FALSE;
    }
+
+   return TRUE;
 }
 
 /*
@@ -455,7 +474,9 @@ IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
     * Validation of passed parameters.
     */
 
-   if ((Flags & (RDW_VALIDATE | RDW_INVALIDATE)) == (RDW_VALIDATE | RDW_INVALIDATE))
+   if (!IntIsWindowDrawable(Window) ||
+       (Flags & (RDW_VALIDATE | RDW_INVALIDATE)) ==
+       (RDW_VALIDATE | RDW_INVALIDATE))
    {
       return FALSE;
    }
@@ -514,7 +535,7 @@ IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
     * Validate parent covered by region.
     */
 
-   if (Window->UpdateRegion != NULL && Flags & RDW_UPDATENOW)
+   if (Window->UpdateRegion != NULL && Flags & (RDW_ERASENOW | RDW_VALIDATE))
    {
       IntValidateParent(Window);
    }
@@ -557,6 +578,10 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
            CurrentEntry = CurrentEntry->Flink)
       {
          Window = CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, ThreadListEntry);
+         if (Window->Parent != NULL && !IntIsDesktopWindow(Window->Parent))
+         {
+            continue;
+         }
          if (Window->Style & WS_VISIBLE)
          {
             hFoundWnd = IntFindWindowToRepaint(Window->Self, Thread);
@@ -586,7 +611,6 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
 
       ExAcquireFastMutex(&Window->ChildrenListLock);
 
-#if 0
       for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
       {
          if (Child->Style & WS_VISIBLE &&
@@ -601,7 +625,6 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
 
       if (hFoundWnd == NULL)
       {
-#endif
          for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
          {
             if (Child->Style & WS_VISIBLE)
@@ -611,9 +634,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
                   break;
             }
          }
-#if 0
       }
-#endif
 
       ExReleaseFastMutex(&Window->ChildrenListLock);
       IntReleaseWindowObject(Window);
@@ -623,9 +644,14 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
 }
 
 BOOL FASTCALL
-IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message)
+IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message,
+   BOOL Remove)
 {
    PWINDOW_OBJECT Window;
+   PUSER_MESSAGE_QUEUE MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
+
+   if (!MessageQueue->PaintPosted)
+      return FALSE;
 
    if (Wnd)
       Message->hwnd = IntFindWindowToRepaint(Wnd->Self, PsGetWin32Thread());
@@ -634,15 +660,7 @@ IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message)
 
    if (Message->hwnd == NULL)
    {
-      PUSER_MESSAGE_QUEUE MessageQueue;
-
       DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
-      MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
-      ExAcquireFastMutex(&MessageQueue->Lock);
-      DPRINT1("Current paint count: %d\n", MessageQueue->PaintCount);
-      MessageQueue->PaintCount = 0;
-      MessageQueue->PaintPosted = FALSE;
-      ExReleaseFastMutex(&MessageQueue->Lock);
       return FALSE;
    }
 
@@ -652,13 +670,13 @@ IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message)
       if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
       {
          Message->message = WM_NCPAINT;
-         Message->wParam = (WPARAM)IntGetNCUpdateRegion(Window);
+         Message->wParam = (WPARAM)IntGetNCUpdateRegion(Window, Remove);
          Message->lParam = 0;
       } else
       {
          Message->message = WM_PAINT;
          Message->wParam = Message->lParam = 0;
-         if (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
+         if (Remove && Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
          {
             Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
             if (Window->UpdateRegion == NULL)
@@ -715,9 +733,11 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs)
       return NULL;
    }
 
+/*   IntRedrawWindow(Window, NULL, 0, RDW_NOINTERNALPAINT | RDW_VALIDATE | RDW_NOCHILDREN);*/
    if (Window->UpdateRegion != NULL)
    {
       MsqDecPaintCountQueue(Window->MessageQueue);
+      IntValidateParent(Window);
       NtGdiDeleteObject(Window->UpdateRegion);
       Window->UpdateRegion = NULL;
    }
@@ -892,7 +912,7 @@ NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
    NTSTATUS Status;
    PWINDOW_OBJECT Wnd;
 
-   if (!(Wnd = IntGetWindowObject(hWnd)))
+   if (!(Wnd = IntGetWindowObject(hWnd ? hWnd : IntGetDesktopWindow())))
    {
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
index 8fa3d88..9b7a686 100644 (file)
@@ -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: vis.c,v 1.10 2003/11/20 09:18:49 navaraf Exp $
+ * $Id: vis.c,v 1.11 2003/11/21 17:01:16 navaraf Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -301,7 +301,9 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
          RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND);
          if (NULLREGION != RgnType && ERROR != RgnType)
            {
-              NtGdiOffsetRgn(DirtyRgn, -Sibling->ClientRect.left, -Sibling->ClientRect.top);
+              NtGdiOffsetRgn(DirtyRgn,
+                Sibling->WindowRect.left - Sibling->ClientRect.left,
+                Sibling->WindowRect.top - Sibling->ClientRect.top);
              IntRedrawWindow(Sibling, NULL, DirtyRgn,
                              RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
                              RDW_ALLCHILDREN);
@@ -328,8 +330,9 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
       RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND);
       if (NULLREGION != RgnType && ERROR != RgnType)
        {
-          NtGdiOffsetRgn(DirtyRgn, -Parent->ClientRect.left,
-            -Parent->ClientRect.top);
+          NtGdiOffsetRgn(DirtyRgn,
+            Parent->WindowRect.left - Parent->ClientRect.left,
+            Parent->WindowRect.top - Parent->ClientRect.top);
          IntRedrawWindow(Parent, NULL, DirtyRgn,
                          RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
                          RDW_NOCHILDREN);
index c1c1f48..a7c0715 100644 (file)
@@ -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.140 2003/11/20 21:21:29 navaraf Exp $
+/* $Id: window.c,v 1.141 2003/11/21 17:01:16 navaraf Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -1809,7 +1809,7 @@ NtUserDestroyWindow(HWND Wnd)
     }
 
   /* Recursively destroy owned windows */
-#if 1 /* FIXME */
+#if 0 /* FIXME */
   if (! isChild)
     {
       for (;;)
index a4d645f..4de3af9 100644 (file)
@@ -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.44 2003/11/20 21:21:29 navaraf Exp $
+/* $Id: winpos.c,v 1.45 2003/11/21 17:01:16 navaraf Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -745,14 +745,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
       return FALSE;
    }
 
-   if (Window->Flags & WINDOWOBJECT_MAPPING)
-   {
-      /* FIXME: SetLastWin32Error */
-      return FALSE;
-   }
-
-   Window->Flags |= WINDOWOBJECT_MAPPING;
-   
    WinPos.hwnd = Wnd;
    WinPos.hwndInsertAfter = WndInsertAfter;
    WinPos.x = x;
@@ -869,7 +861,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
                       RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
       Window->Style &= ~WS_VISIBLE;
    }
-   else
+   else if (WinPos.flags & SWP_SHOWWINDOW)
    {
       Window->Style |= WS_VISIBLE;
    }
@@ -987,7 +979,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
       }
       else
       {
-         IntRedrawWindow(Window, NULL, NULL,
+         IntRedrawWindow(Window, NULL, 0,
             RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
       }
    }
@@ -1025,15 +1017,12 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
 
    if (!(WinPos.flags & SWP_NOREDRAW))
    {
-      /* FIXME: Call IntRedrawWindow to erase *all* touched windows. */
       IntRedrawWindow(Window, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW);
    }
 
    /* FIXME: Check some conditions before doing this. */
    IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
 
-   Window->Flags &= ~WINDOWOBJECT_MAPPING;
-
    IntReleaseWindowObject(Window);
 
    return TRUE;
@@ -1055,7 +1044,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
   UINT Swp = 0;
   RECT NewPos;
   BOOLEAN ShowFlag;
-  HRGN VisibleRgn;
+//  HRGN VisibleRgn;
 
   Status = 
     ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
@@ -1153,6 +1142,44 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
        */
     }
 
+#if 1
+  /* We can't activate a child window */
+  if ((Window->Style & WS_CHILD) &&
+      !(Window->ExStyle & WS_EX_MDICHILD))
+    {
+      Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
+    }
+
+  WinPosSetWindowPos(Window->Self, HWND_TOP, NewPos.left, NewPos.top,
+    NewPos.right, NewPos.bottom, LOWORD(Swp));
+
+  if (Cmd == SW_HIDE)
+    {
+      /* FIXME: This will cause the window to be activated irrespective
+       * of whether it is owned by the same thread. Has to be done
+       * asynchronously.
+       */
+
+      if (Window->Self == IntGetActiveWindow())
+        {
+          WinPosActivateOtherWindow(Window);
+        }
+
+      /* Revert focus to parent */
+      if (Wnd == IntGetFocusWindow() ||
+          IntIsChildWindow(Wnd, IntGetFocusWindow()))
+        {
+          IntSetFocusWindow(Window->Parent->Self);
+        }
+    }
+
+  /* FIXME: Check for window destruction. */
+  /* Show title for minimized windows. */
+  if (Window->Style & WS_MINIMIZE)
+    {
+      WinPosShowIconTitle(Window, TRUE);
+    }
+#else
   if (Window->Style & WS_CHILD &&
       !IntIsWindowVisible(Window->Parent->Self) &&
       (Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE))
@@ -1203,6 +1230,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
          WinPosShowIconTitle(Window, TRUE);
        }
     }
+#endif
 
   if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
     {