Commit in reactos/subsys/win32k on MAIN
include/winpos.h+1-11.13 -> 1.14
ntuser/msgqueue.c+134-1001.83 -> 1.84
      /window.c+2-21.216 -> 1.217
      /winpos.c+6-71.110 -> 1.111
+143-110
4 modified files
fixed major bugs in the message queue

reactos/subsys/win32k/include
winpos.h 1.13 -> 1.14
diff -u -r1.13 -r1.14
--- winpos.h	13 Apr 2004 23:12:29 -0000	1.13
+++ winpos.h	14 Apr 2004 17:19:38 -0000	1.14
@@ -29,7 +29,7 @@
 BOOLEAN FASTCALL
 WinPosShowWindow(HWND Wnd, INT Cmd);
 USHORT FASTCALL
-WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, BOOL SendHitTestMessage, POINT *WinPoint, 
+WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint, 
 		      PWINDOW_OBJECT* Window);
 VOID FASTCALL WinPosActivateOtherWindow(PWINDOW_OBJECT Window);
 

reactos/subsys/win32k/ntuser
msgqueue.c 1.83 -> 1.84
diff -u -r1.83 -r1.84
--- msgqueue.c	13 Apr 2004 13:50:31 -0000	1.83
+++ msgqueue.c	14 Apr 2004 17:19:38 -0000	1.84
@@ -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.83 2004/04/13 13:50:31 weiden Exp $
+/* $Id: msgqueue.c,v 1.84 2004/04/14 17:19:38 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -249,65 +249,73 @@
   PWINDOW_OBJECT Window = NULL;
   HWND CaptureWin;
   POINT Point;
-
+  
+  ThreadQueue = PsGetWin32Thread()->MessageQueue;
+  
   if (Msg == WM_LBUTTONDOWN || 
       Msg == WM_MBUTTONDOWN ||
       Msg == WM_RBUTTONDOWN ||
       Msg == WM_XBUTTONDOWN)
   {
-    *HitTest = WinPosWindowFromPoint(ScopeWin, !FromGlobalQueue, &Message->Msg.pt, &Window);
-    if(Window && FromGlobalQueue && (PsGetWin32Thread()->MessageQueue == Window->MessageQueue))
-    {
-      *HitTest = IntSendMessage(Window->Self, WM_NCHITTEST, 0, 
-                                MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y));
-    }
+    *HitTest = WinPosWindowFromPoint(ScopeWin, ThreadQueue, &Message->Msg.pt, &Window);
     /*
     **Make sure that we have a window that is not already in focus
     */
-    if (Window)
+    if (Window && (Window->Self != IntGetFocusWindow()))
     {
-      if(Window->Self != IntGetFocusWindow())
+      if(ThreadQueue == Window->MessageQueue)
       {
+        /* only get a more detailed hit-test if the window is in the same thread! */
+        *HitTest = IntSendMessage(Window->Self, WM_NCHITTEST, 0, 
+                                  MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y));
+      }
+      if(*HitTest != (USHORT)HTTRANSPARENT)
+      {
+        LRESULT Result;
         
-        if(*HitTest != (USHORT)HTTRANSPARENT)
-        {
-          LRESULT Result;
+        /* Sending a message to another thread might lock up our own when it's 
+           hung, so just send messages to our own thread */
+        if(Window->MessageQueue == ThreadQueue)
           Result = IntSendMessage(Window->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(Window->Self), (LPARAM)MAKELONG(*HitTest, Msg));
-          
-          switch (Result)
-          {
-              case MA_NOACTIVATEANDEAT:
-                  *Freed = FALSE;
-                  IntReleaseWindowObject(Window);
-                  return TRUE;
-              case MA_NOACTIVATE:
-                  break;
-              case MA_ACTIVATEANDEAT:
-                  IntMouseActivateWindow(Window);
-                  IntReleaseWindowObject(Window);
-                  *Freed = FALSE;
-                  return TRUE;
-/*              case MA_ACTIVATE:
-              case 0:*/
-              default:
-                  IntMouseActivateWindow(Window);
-                  break;
-          }
-        }
         else
         {
-          IntReleaseWindowObject(Window);
-          if(RemoveWhenFreed)
-          {
-            RemoveEntryList(&Message->ListEntry);
-          }
-          ExFreePool(Message);
-          *Freed = TRUE;
-          return(FALSE);
+          /* just post WM_MOUSEACTIVATE to the other thread */
+          NtUserPostMessage(Window->Self, WM_MOUSEACTIVATE, (WPARAM)NtUserGetParent(Window->Self), (LPARAM)MAKELONG(*HitTest, Msg));
+          /* and assume that windows of other threads should always be activated. */
+          Result = MA_ACTIVATE;
+        }
+        
+        switch (Result)
+        {
+          case MA_NOACTIVATEANDEAT:
+            *Freed = FALSE;
+            IntReleaseWindowObject(Window);
+            return TRUE;
+          case MA_NOACTIVATE:
+            break;
+          case MA_ACTIVATEANDEAT:
+            IntMouseActivateWindow(Window);
+            IntReleaseWindowObject(Window);
+            *Freed = FALSE;
+            return TRUE;
+          default:
+            /* MA_ACTIVATE */
+            IntMouseActivateWindow(Window);
+            break;
         }
       }
+      else
+      {
+        IntReleaseWindowObject(Window);
+        if(RemoveWhenFreed)
+        {
+          RemoveEntryList(&Message->ListEntry);
+        }
+        ExFreePool(Message);
+        *Freed = TRUE;
+        return(FALSE);
+      }
     }
-
   }
   
   CaptureWin = IntGetCaptureWindow();
@@ -325,8 +333,8 @@
     {
       if(!Window)
       {
-        *HitTest = WinPosWindowFromPoint(ScopeWin, !FromGlobalQueue, &Message->Msg.pt, &Window);
-        if(Window && FromGlobalQueue && (PsGetWin32Thread()->MessageQueue == Window->MessageQueue))
+        *HitTest = WinPosWindowFromPoint(ScopeWin, ThreadQueue, &Message->Msg.pt, &Window);
+        if(Window && (ThreadQueue == Window->MessageQueue))
         {
           *HitTest = IntSendMessage(Window->Self, WM_NCHITTEST, 0, 
                                     MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y));
@@ -358,7 +366,6 @@
     return(FALSE);
   }
   
-  ThreadQueue = PsGetWin32Thread()->MessageQueue;
   if (Window->MessageQueue != ThreadQueue)
   {
     if (! FromGlobalQueue)
@@ -379,70 +386,33 @@
         ThreadQueue->MouseMoveMsg = NULL;
       }
     }
+    
+    /* lock the destination message queue, so we don't get in trouble with other
+       threads, messing with it at the same time */
     IntLockHardwareMessageQueue(Window->MessageQueue);
-    if((Message->Msg.message == WM_MOUSEMOVE) && Window->MessageQueue->MouseMoveMsg)
-    {
-      /* we do not hold more than one WM_MOUSEMOVE message in the queue */
-      Window->MessageQueue->MouseMoveMsg->Msg = Message->Msg;
-      if(RemoveWhenFreed && FromGlobalQueue)
-      {
-        RemoveEntryList(&Message->ListEntry);
-      }
-      *Freed = TRUE;
-    }
-    else
+    InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
+                   &Message->ListEntry);
+    if(Message->Msg.message == WM_MOUSEMOVE)
     {
-      InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
-                     &Message->ListEntry);
-      if(Message->Msg.message == WM_MOUSEMOVE)
+      if(Window->MessageQueue->MouseMoveMsg)
       {
-        Window->MessageQueue->MouseMoveMsg = Message;
+        /* remove the old WM_MOUSEMOVE message, we're processing a more recent
+           one */
+        RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
+        ExFreePool(Window->MessageQueue->MouseMoveMsg);
       }
-      *Freed = FALSE;
+      /* save the pointer to the WM_MOUSEMOVE message in the new queue */
+      Window->MessageQueue->MouseMoveMsg = Message;
     }
     IntUnLockHardwareMessageQueue(Window->MessageQueue);
-    if(*Freed)
-    {
-      ExFreePool(Message);
-    }
+    
     KeSetEvent(&Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+    *Freed = FALSE;
     IntReleaseWindowObject(Window);
     return(FALSE);
   }
   
-  if (hWnd != NULL && Window->Self != hWnd &&
-      !IntIsChildWindow(hWnd, Window->Self))
-  {
-    IntLockHardwareMessageQueue(Window->MessageQueue);
-    if((Message->Msg.message == WM_MOUSEMOVE) && Window->MessageQueue->MouseMoveMsg)
-    {
-      /* we do not hold more than one WM_MOUSEMOVE message in the queue */
-      Window->MessageQueue->MouseMoveMsg->Msg = Message->Msg;
-      if(RemoveWhenFreed)
-      {
-        RemoveEntryList(&Message->ListEntry);
-      }
-      *Freed = TRUE;
-    }
-    else
-    {
-      InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
-                     &Message->ListEntry);
-      if(Message->Msg.message == WM_MOUSEMOVE)
-      {
-        Window->MessageQueue->MouseMoveMsg = Message;
-      }
-      *Freed = FALSE;
-    }
-    IntUnLockHardwareMessageQueue(Window->MessageQueue);
-    if(*Freed)
-    {
-      ExFreePool(Message);
-    }
-    KeSetEvent(&Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
-    IntReleaseWindowObject(Window);
-    return(FALSE);
-  }
+  /* From here on, we're in the same message queue as the caller! */
   
   switch (Msg)
   {
@@ -487,7 +457,43 @@
     }
   }
   
-  /* FIXME: Check message filter. */
+  if(hWnd != NULL && Window->Self != hWnd)
+  {
+    /* Reject the message because it doesn't match the filter */
+    
+    if(FromGlobalQueue)
+    {
+      /* Lock the message queue so no other thread can mess with it.
+         Our own message queue is not locked while fetching from the global
+         queue, so we have to make sure nothing interferes! */
+      IntLockHardwareMessageQueue(Window->MessageQueue);
+      /* if we're from the global queue, we need to add our message to our
+         private queue so we don't loose it! */
+      InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
+                     &Message->ListEntry);
+    }
+    
+    if (Message->Msg.message == WM_MOUSEMOVE)
+    {
+      if(Window->MessageQueue->MouseMoveMsg)
+      {
+        /* delete the old message */
+        RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
+        ExFreePool(Window->MessageQueue->MouseMoveMsg);
+      }
+      /* always save a pointer to this WM_MOUSEMOVE message here because we're
+         sure that the message is in the private queue */
+      Window->MessageQueue->MouseMoveMsg = Message;
+    }
+    if(FromGlobalQueue)
+    {
+      IntUnLockHardwareMessageQueue(Window->MessageQueue);
+    }
+    
+    IntReleaseWindowObject(Window);
+    *Freed = FALSE;
+    return(FALSE);
+  }
 
   if (Remove)
     {
@@ -496,6 +502,34 @@
       Message->Msg.lParam = MAKELONG(Point.x, Point.y);
     }
   
+  /* remove the reference to the current WM_MOUSEMOVE message, if this message
+     is it */
+  if (Message->Msg.message == WM_MOUSEMOVE)
+  {
+    if(FromGlobalQueue)
+    {
+      /* Lock the message queue so no other thread can mess with it.
+         Our own message queue is not locked while fetching from the global
+         queue, so we have to make sure nothing interferes! */
+      IntLockHardwareMessageQueue(Window->MessageQueue);
+      if(Window->MessageQueue->MouseMoveMsg)
+      {
+        /* delete the WM_MOUSEMOVE message in the private queue, we're dealing
+           with one that's been sent later */
+        RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
+        ExFreePool(Window->MessageQueue->MouseMoveMsg);
+        /* our message is not in the private queue so we can remove the pointer
+           instead of setting it to the current message we're processing */
+        Window->MessageQueue->MouseMoveMsg = NULL;
+      }
+      IntUnLockHardwareMessageQueue(Window->MessageQueue);
+    }
+    else if(Window->MessageQueue->MouseMoveMsg == Message)
+    {
+      Window->MessageQueue->MouseMoveMsg = NULL;
+    }
+  }
+  
   IntReleaseWindowObject(Window);
   *Freed = FALSE;
   return(TRUE);

reactos/subsys/win32k/ntuser
window.c 1.216 -> 1.217
diff -u -r1.216 -r1.217
--- window.c	13 Apr 2004 23:25:54 -0000	1.216
+++ window.c	14 Apr 2004 17:19:38 -0000	1.217
@@ -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.216 2004/04/13 23:25:54 weiden Exp $
+/* $Id: window.c,v 1.217 2004/04/14 17:19:38 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -3715,7 +3715,7 @@
       pt.x = X;
       pt.y = Y;
       
-      Hit = WinPosWindowFromPoint(DesktopWindow, TRUE, &pt, &Window);
+      Hit = WinPosWindowFromPoint(DesktopWindow, PsGetWin32Thread()->MessageQueue, &pt, &Window);
       
       if(Window)
       {

reactos/subsys/win32k/ntuser
winpos.c 1.110 -> 1.111
diff -u -r1.110 -r1.111
--- winpos.c	13 Apr 2004 23:12:30 -0000	1.110
+++ winpos.c	14 Apr 2004 17:19:38 -0000	1.111
@@ -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.110 2004/04/13 23:12:30 weiden Exp $
+/* $Id: winpos.c,v 1.111 2004/04/14 17:19:38 weiden Exp $
  *
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
@@ -1368,7 +1368,7 @@
 }
 
 VOID STATIC FASTCALL
-WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, BOOL SendHitTestMessage, POINT *Point,
+WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *Point,
 		     PWINDOW_OBJECT* Window, USHORT *HitTest)
 {
   PWINDOW_OBJECT Current;
@@ -1400,8 +1400,7 @@
           return;
         }
         
-        if(SendHitTestMessage &&
-           (Current->MessageQueue == PsGetWin32Thread()->MessageQueue))
+        if(OnlyHitTests && (Current->MessageQueue == OnlyHitTests))
         {
           *HitTest = IntSendMessage(Current->Self, WM_NCHITTEST, 0,
                                     MAKELONG(Point->x, Point->y));
@@ -1420,7 +1419,7 @@
            Point->y >= Current->ClientRect.top &&
            Point->y < Current->ClientRect.bottom)
         {
-          WinPosSearchChildren(Current, SendHitTestMessage, Point, Window, HitTest);
+          WinPosSearchChildren(Current, OnlyHitTests, Point, Window, HitTest);
           ExFreePool(List);
           return;
         }
@@ -1435,7 +1434,7 @@
 }
 
 USHORT FASTCALL
-WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, BOOL SendHitTestMessage, POINT *WinPoint, 
+WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint, 
 		      PWINDOW_OBJECT* Window)
 {
   HWND DesktopWindowHandle;
@@ -1468,7 +1467,7 @@
   
   HitTest = HTNOWHERE;
   
-  WinPosSearchChildren(ScopeWin, SendHitTestMessage, &Point, Window, &HitTest);
+  WinPosSearchChildren(ScopeWin, OnlyHitTests, &Point, Window, &HitTest);
 
   return ((*Window) ? HitTest : HTNOWHERE);
 }
CVSspam 0.2.8