[win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / msgqueue.c
index f79c193..1bba2a1 100644 (file)
@@ -12,9 +12,9 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 /*
  * COPYRIGHT:        See COPYING in the top level directory
@@ -28,7 +28,7 @@
 
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -71,15 +71,15 @@ IdlePing(VOID)
 {
   HWND hWnd;
   PWINDOW_OBJECT Window;
-  PW32PROCESS W32d = PsGetCurrentProcessWin32Process();
+  PPROCESSINFO W32d = PsGetCurrentProcessWin32Process();
 
   hWnd = UserGetForegroundWindow();
 
   Window = UserGetWindowObject(hWnd);
 
-  if (Window && Window->ti)
+  if (Window && Window->pti)
   {
-     if (Window->ti->Hooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE))
+     if (Window->pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE))
      {
         co_HOOK_CallHooks(WH_FOREGROUNDIDLE,HC_ACTION,0,0);
      }
@@ -118,6 +118,7 @@ IntMsqClearWakeMask(VOID)
       return FALSE;
 
    MessageQueue = Win32Thread->MessageQueue;
+// HACK!!!!!!! Newbies that wrote this should hold your head down in shame! (jt)
    MessageQueue->WakeMask = ~0;
 
    return TRUE;
@@ -170,11 +171,14 @@ MsqInitializeImpl(VOID)
 VOID FASTCALL
 MsqInsertSystemMessage(MSG* Msg)
 {
-   LARGE_INTEGER LargeTickCount;
    KIRQL OldIrql;
    ULONG Prev;
-   EVENTMSG Event;
 
+   /*
+    * If we got WM_MOUSEMOVE and there are already messages in the
+    * system message queue, check if the last message is mouse move
+    * and if it is then just overwrite it.
+    */
    IntLockSystemMessageQueue(OldIrql);
 
    /*
@@ -188,22 +192,6 @@ MsqInsertSystemMessage(MSG* Msg)
       return;
    }
 
-   KeQueryTickCount(&LargeTickCount);
-   Msg->time = MsqCalculateMessageTime(&LargeTickCount);
-
-   Event.message = Msg->message;
-   Event.time    = Msg->time;
-   Event.hwnd    = Msg->hwnd;
-   Event.paramL  = Msg->pt.x;
-   Event.paramH  = Msg->pt.y;
-   co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
-
-   /*
-    * If we got WM_MOUSEMOVE and there are already messages in the
-    * system message queue, check if the last message is mouse move
-    * and if it is then just overwrite it.
-    */
-
    if (Msg->message == WM_MOUSEMOVE && SystemMessageQueueCount)
    {
       if (SystemMessageQueueTail == 0)
@@ -231,26 +219,63 @@ MsqInsertSystemMessage(MSG* Msg)
    KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE);
 }
 
+BOOL FASTCALL
+MsqIsClkLck(LPMSG Msg, BOOL Remove)
+{
+   PTHREADINFO pti;
+   PSYSTEM_CURSORINFO CurInfo;
+   BOOL Res = FALSE;
+
+   pti = PsGetCurrentThreadWin32Thread();
+   if (pti->rpdesk == NULL)
+   {
+      return FALSE;
+   }
+
+   CurInfo = IntGetSysCursorInfo();
+
+   switch (Msg->message)
+   {
+     case WM_LBUTTONUP:
+       Res = ((Msg->time - CurInfo->ClickLockTime) >= gspv.dwMouseClickLockTime);
+       if (Res && (!CurInfo->ClickLockActive))
+       {
+         CurInfo->ClickLockActive = TRUE;
+       }
+       break;
+     case WM_LBUTTONDOWN:
+       if (CurInfo->ClickLockActive)
+       {
+         Res = TRUE;
+         CurInfo->ClickLockActive = FALSE;
+         CurInfo->ClickLockTime = 0;
+       }
+       else
+       {
+         CurInfo->ClickLockTime = Msg->time;
+       }
+       break;
+   }
+   return Res;
+}
+
 BOOL FASTCALL
 MsqIsDblClk(LPMSG Msg, BOOL Remove)
 {
    PTHREADINFO pti;
-   PWINSTATION_OBJECT WinStaObject;
    PSYSTEM_CURSORINFO CurInfo;
    LONG dX, dY;
    BOOL Res;
 
    pti = PsGetCurrentThreadWin32Thread();
-   if (pti->Desktop == NULL)
+   if (pti->rpdesk == NULL)
    {
       return FALSE;
    }
 
-   WinStaObject = pti->Desktop->WindowStation;
-
-   CurInfo = IntGetSysCursorInfo(WinStaObject);
+   CurInfo = IntGetSysCursorInfo();
    Res = (Msg->hwnd == (HWND)CurInfo->LastClkWnd) &&
-         ((Msg->time - CurInfo->LastBtnDown) < CurInfo->DblClickSpeed);
+         ((Msg->time - CurInfo->LastBtnDown) < gspv.iDblClickTime);
    if(Res)
    {
 
@@ -261,8 +286,8 @@ MsqIsDblClk(LPMSG Msg, BOOL Remove)
       if(dY < 0)
          dY = -dY;
 
-      Res = (dX <= CurInfo->DblClickWidth) &&
-            (dY <= CurInfo->DblClickHeight);
+      Res = (dX <= gspv.iDblClickWidth) &&
+            (dY <= gspv.iDblClickHeight);
 
       if(Res)
       {
@@ -273,34 +298,31 @@ MsqIsDblClk(LPMSG Msg, BOOL Remove)
 
    if(Remove)
    {
+      CurInfo->LastBtnDownX = Msg->pt.x;
+      CurInfo->LastBtnDownY = Msg->pt.y;
+      CurInfo->ButtonsDown = Msg->message;
       if (Res)
       {
          CurInfo->LastBtnDown = 0;
-         CurInfo->LastBtnDownX = Msg->pt.x;
-         CurInfo->LastBtnDownY = Msg->pt.y;
          CurInfo->LastClkWnd = NULL;
-                CurInfo->ButtonsDown = Msg->message;
       }
       else
       {
-         CurInfo->LastBtnDownX = Msg->pt.x;
-         CurInfo->LastBtnDownY = Msg->pt.y;
          CurInfo->LastClkWnd = (HANDLE)Msg->hwnd;
          CurInfo->LastBtnDown = Msg->time;
-                CurInfo->ButtonsDown = Msg->message;
       }
    }
 
    return Res;
 }
 
-BOOL static STDCALL
-co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT FilterLow, UINT FilterHigh,
+static BOOL APIENTRY
+co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Window, UINT FilterLow, UINT FilterHigh,
                             PUSER_MESSAGE Message, BOOL Remove, PBOOL Freed,
                             PWINDOW_OBJECT ScopeWin, PPOINT ScreenPoint, BOOL FromGlobalQueue, PLIST_ENTRY *Next)
 {
    USHORT Msg = Message->Msg.message;
-   PWINDOW_OBJECT Window = NULL;
+   PWINDOW_OBJECT CaptureWindow = NULL;
    HWND hCaptureWin;
 
    ASSERT_REFS_CO(ScopeWin);
@@ -314,18 +336,18 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
    hCaptureWin = IntGetCaptureWindow();
    if (hCaptureWin == NULL)
    {
-      if(Msg == WM_MOUSEWHEEL)
+      if (Msg == WM_MOUSEWHEEL)
       {
-         Window = UserGetWindowObject(IntGetFocusWindow());
-         if (Window) UserReferenceObject(Window);
+         CaptureWindow = UserGetWindowObject(IntGetFocusWindow());
+         if (CaptureWindow) UserReferenceObject(CaptureWindow);
       }
       else
       {
-         co_WinPosWindowFromPoint(ScopeWin, NULL, &Message->Msg.pt, &Window);
-         if(Window == NULL)
+         co_WinPosWindowFromPoint(ScopeWin, NULL, &Message->Msg.pt, &CaptureWindow);
+         if(CaptureWindow == NULL)
          {
-            Window = ScopeWin;
-            if (Window) UserReferenceObject(Window);
+            CaptureWindow = ScopeWin;
+            if (CaptureWindow) UserReferenceObject(CaptureWindow);
          }
          else
          {
@@ -338,13 +360,13 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
    {
       /* FIXME - window messages should go to the right window if no buttons are
                  pressed */
-      Window = UserGetWindowObject(hCaptureWin);
-      if (Window) UserReferenceObject(Window);
+      CaptureWindow = UserGetWindowObject(hCaptureWin);
+      if (CaptureWindow) UserReferenceObject(CaptureWindow);
    }
 
 
 
-   if (Window == NULL)
+   if (CaptureWindow == NULL)
    {
       if(!FromGlobalQueue)
       {
@@ -360,7 +382,7 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
       return(FALSE);
    }
 
-   if (Window->MessageQueue != MessageQueue)
+   if (CaptureWindow->pti->MessageQueue != MessageQueue)
    {
       if (! FromGlobalQueue)
       {
@@ -383,37 +405,37 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
 
       /* 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);
-      InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
+      IntLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+      InsertTailList(&CaptureWindow->pti->MessageQueue->HardwareMessagesListHead,
                      &Message->ListEntry);
       if(Message->Msg.message == WM_MOUSEMOVE)
       {
-         if(Window->MessageQueue->MouseMoveMsg)
+         if(CaptureWindow->pti->MessageQueue->MouseMoveMsg)
          {
             /* remove the old WM_MOUSEMOVE message, we're processing a more recent
                one */
-            RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
-            ExFreePool(Window->MessageQueue->MouseMoveMsg);
+            RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
+            ExFreePool(CaptureWindow->pti->MessageQueue->MouseMoveMsg);
          }
          /* save the pointer to the WM_MOUSEMOVE message in the new queue */
-         Window->MessageQueue->MouseMoveMsg = Message;
+         CaptureWindow->pti->MessageQueue->MouseMoveMsg = Message;
 
-         Window->MessageQueue->QueueBits |= QS_MOUSEMOVE;
-         Window->MessageQueue->ChangedBits |= QS_MOUSEMOVE;
-         if (Window->MessageQueue->WakeMask & QS_MOUSEMOVE)
-            KeSetEvent(Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+         CaptureWindow->pti->MessageQueue->QueueBits |= QS_MOUSEMOVE;
+         CaptureWindow->pti->MessageQueue->ChangedBits |= QS_MOUSEMOVE;
+         if (CaptureWindow->pti->MessageQueue->WakeMask & QS_MOUSEMOVE)
+            KeSetEvent(CaptureWindow->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
       }
       else
       {
-         Window->MessageQueue->QueueBits |= QS_MOUSEBUTTON;
-         Window->MessageQueue->ChangedBits |= QS_MOUSEBUTTON;
-         if (Window->MessageQueue->WakeMask & QS_MOUSEBUTTON)
-            KeSetEvent(Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
+         CaptureWindow->pti->MessageQueue->QueueBits |= QS_MOUSEBUTTON;
+         CaptureWindow->pti->MessageQueue->ChangedBits |= QS_MOUSEBUTTON;
+         if (CaptureWindow->pti->MessageQueue->WakeMask & QS_MOUSEBUTTON)
+            KeSetEvent(CaptureWindow->pti->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
       }
-      IntUnLockHardwareMessageQueue(Window->MessageQueue);
+      IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
 
       *Freed = FALSE;
-      UserDereferenceObject(Window);
+      UserDereferenceObject(CaptureWindow);
       return(FALSE);
    }
 
@@ -421,7 +443,7 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
 
    *ScreenPoint = Message->Msg.pt;
 
-   if((hWnd != NULL && Window->hSelf != hWnd) ||
+   if((Window != NULL && PtrToInt(Window) != 1 && CaptureWindow->hSelf != Window->hSelf) ||
          ((FilterLow != 0 || FilterHigh != 0) && (Msg < FilterLow || Msg > FilterHigh)))
    {
       /* Reject the message because it doesn't match the filter */
@@ -431,21 +453,21 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
          /* 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);
+         IntLockHardwareMessageQueue(CaptureWindow->pti->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,
+         InsertTailList(&CaptureWindow->pti->MessageQueue->HardwareMessagesListHead,
                         &Message->ListEntry);
       }
 
       if (Message->Msg.message == WM_MOUSEMOVE)
       {
-         if(Window->MessageQueue->MouseMoveMsg &&
-               (Window->MessageQueue->MouseMoveMsg != Message))
+         if(CaptureWindow->pti->MessageQueue->MouseMoveMsg &&
+               (CaptureWindow->pti->MessageQueue->MouseMoveMsg != Message))
          {
             /* delete the old message */
-            RemoveEntryList(&Window->MessageQueue->MouseMoveMsg->ListEntry);
-            ExFreePool(Window->MessageQueue->MouseMoveMsg);
+            RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
+            ExFreePool(CaptureWindow->pti->MessageQueue->MouseMoveMsg);
             if (!FromGlobalQueue)
             {
                // We might have deleted the next one in our queue, so fix next
@@ -454,20 +476,20 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
          }
          /* 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;
+         CaptureWindow->pti->MessageQueue->MouseMoveMsg = Message;
       }
       if(FromGlobalQueue)
       {
-         IntUnLockHardwareMessageQueue(Window->MessageQueue);
+         IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
       }
 
-      UserDereferenceObject(Window);
+      UserDereferenceObject(CaptureWindow);
       *Freed = FALSE;
       return(FALSE);
    }
 
    /* FIXME - only assign if removing? */
-   Message->Msg.hwnd = Window->hSelf;
+   Message->Msg.hwnd = CaptureWindow->hSelf;
    Message->Msg.message = Msg;
    Message->Msg.lParam = MAKELONG(Message->Msg.pt.x, Message->Msg.pt.y);
 
@@ -481,32 +503,32 @@ co_MsqTranslateMouseMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, UINT Fi
          /* 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)
+         IntLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
+         if(CaptureWindow->pti->MessageQueue->MouseMoveMsg)
          {
             /* delete the WM_(NC)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);
+            RemoveEntryList(&CaptureWindow->pti->MessageQueue->MouseMoveMsg->ListEntry);
+            ExFreePool(CaptureWindow->pti->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;
+            CaptureWindow->pti->MessageQueue->MouseMoveMsg = NULL;
          }
-         IntUnLockHardwareMessageQueue(Window->MessageQueue);
+         IntUnLockHardwareMessageQueue(CaptureWindow->pti->MessageQueue);
       }
-      else if(Window->MessageQueue->MouseMoveMsg == Message)
+      else if (CaptureWindow->pti->MessageQueue->MouseMoveMsg == Message)
       {
-         Window->MessageQueue->MouseMoveMsg = NULL;
+         CaptureWindow->pti->MessageQueue->MouseMoveMsg = NULL;
       }
    }
 
-   UserDereferenceObject(Window);
+   UserDereferenceObject(CaptureWindow);
    *Freed = FALSE;
    return(TRUE);
 }
 
-BOOL STDCALL
-co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
+BOOL APIENTRY
+co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT Window,
                           UINT FilterLow, UINT FilterHigh, BOOL Remove,
                           PUSER_MESSAGE* Message)
 {
@@ -533,11 +555,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
                                             UserMode, FALSE, NULL, NULL);
 
       UserEnterCo();
-
-      while (co_MsqDispatchOneSentMessage(MessageQueue))
-      {
-         ;
-      }
    }
    while (NT_SUCCESS(WaitStatus) && STATUS_WAIT_0 != WaitStatus);
 
@@ -546,7 +563,7 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
    if (DesktopWindow)
    {
        UserRefObjectCo(DesktopWindow, &Ref);//can DesktopWindow be NULL?
-       Desk = DesktopWindow->ti->Desktop;
+       Desk = DesktopWindow->pti->pDeskInfo;
    }
 
    /* Process messages in the message queue itself. */
@@ -562,7 +579,7 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
       {
 
 
-         Accept = co_MsqTranslateMouseMessage(MessageQueue, hWnd, FilterLow, FilterHigh,
+         Accept = co_MsqTranslateMouseMessage(MessageQueue, Window, FilterLow, FilterHigh,
                                               Current, Remove, &Freed,
                                               DesktopWindow, &ScreenPoint, FALSE, &CurrentEntry);
          if (Accept)
@@ -593,7 +610,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
    {
       PUSER_MESSAGE UserMsg;
       MSG Msg;
-      BOOL ProcessMessage;
 
       ASSERT(SystemMessageQueueHead < SYSTEM_MESSAGE_QUEUE_SIZE);
       Msg = SystemMessageQueue[SystemMessageQueueHead];
@@ -601,48 +617,14 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
          (SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
       SystemMessageQueueCount--;
       IntUnLockSystemMessageQueue(OldIrql);
-      if (WM_MOUSEFIRST <= Msg.message && Msg.message <= WM_MOUSELAST)
-      {
-         MSLLHOOKSTRUCT MouseHookData;
 
-         MouseHookData.pt.x = LOWORD(Msg.lParam);
-         MouseHookData.pt.y = HIWORD(Msg.lParam);
-         switch(Msg.message)
-         {
-            case WM_MOUSEWHEEL:
-               MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg.wParam));
-               break;
-            case WM_XBUTTONDOWN:
-            case WM_XBUTTONUP:
-            case WM_XBUTTONDBLCLK:
-            case WM_NCXBUTTONDOWN:
-            case WM_NCXBUTTONUP:
-            case WM_NCXBUTTONDBLCLK:
-               MouseHookData.mouseData = MAKELONG(0, HIWORD(Msg.wParam));
-               break;
-            default:
-               MouseHookData.mouseData = 0;
-               break;
-         }
-         MouseHookData.flags = 0;
-         MouseHookData.time = Msg.time;
-         MouseHookData.dwExtraInfo = 0;
-         ProcessMessage = (0 == co_HOOK_CallHooks(WH_MOUSE_LL, HC_ACTION,
-                           Msg.message, (LPARAM) &MouseHookData));
-      }
-      else
-      {
-         ProcessMessage = TRUE;
-      }
-      if (ProcessMessage)
-      {
-         UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
-         /* What to do if out of memory? For now we just panic a bit in debug */
-         ASSERT(UserMsg);
-         UserMsg->FreeLParam = FALSE;
-         UserMsg->Msg = Msg;
-         InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
-      }
+      UserMsg = ExAllocateFromPagedLookasideList(&MessageLookasideList);
+      /* What to do if out of memory? For now we just panic a bit in debug */
+      ASSERT(UserMsg);
+      UserMsg->FreeLParam = FALSE;
+      UserMsg->Msg = Msg;
+      InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
+
       IntLockSystemMessageQueue(OldIrql);
    }
    HardwareMessageQueueStamp++;
@@ -662,7 +644,7 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
       {
          const ULONG ActiveStamp = HardwareMessageQueueStamp;
          /* Translate the message. */
-         Accept = co_MsqTranslateMouseMessage(MessageQueue, hWnd, FilterLow, FilterHigh,
+         Accept = co_MsqTranslateMouseMessage(MessageQueue, Window, FilterLow, FilterHigh,
                                               Current, Remove, &Freed,
                                               DesktopWindow, &ScreenPoint, TRUE, NULL);
          if (Accept)
@@ -737,13 +719,18 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    MSG Msg;
    LARGE_INTEGER LargeTickCount;
    KBDLLHOOKSTRUCT KbdHookData;
-   EVENTMSG Event;
+   BOOLEAN Entered = FALSE;
 
    DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
           uMsg, wParam, lParam);
 
    // Condition may arise when calling MsqPostMessage and waiting for an event.
-   if (!UserIsEntered()) UserEnterExclusive(); // Fixme: Not sure ATM if this thread is locked.
+   if (!UserIsEntered())
+   {
+         // Fixme: Not sure ATM if this thread is locked.
+         UserEnterExclusive();
+         Entered = TRUE;
+   }
 
    FocusMessageQueue = IntGetFocusMessageQueue();
 
@@ -759,14 +746,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    KeQueryTickCount(&LargeTickCount);
    Msg.time = MsqCalculateMessageTime(&LargeTickCount);
 
-   Event.message = Msg.message;
-   Event.hwnd    = Msg.hwnd;
-   Event.time    = Msg.time;
-   Event.paramL  = (Msg.wParam & 0xFF) | (HIWORD(Msg.lParam) << 8);
-   Event.paramH  = Msg.lParam & 0x7FFF;
-   if (HIWORD(Msg.lParam) & 0x0100) Event.paramH |= 0x8000;
-   co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
-
    /* We can't get the Msg.pt point here since we don't know thread
       (and thus the window station) the message will end up in yet. */
 
@@ -781,12 +760,14 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
       DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
              Msg.message, Msg.wParam, Msg.lParam);
+      if (Entered) UserLeave();
       return;
    }
 
    if (FocusMessageQueue == NULL)
    {
          DPRINT("No focus message queue\n");
+         if (Entered) UserLeave();
          return;
    }
 
@@ -795,17 +776,18 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
          Msg.hwnd = FocusMessageQueue->FocusWindow;
          DPRINT("Msg.hwnd = %x\n", Msg.hwnd);
 
-         FocusMessageQueue->Desktop->DesktopInfo->LastInputWasKbd = TRUE;
+         FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
 
-         IntGetCursorLocation(FocusMessageQueue->Desktop->WindowStation,
-                              &Msg.pt);
+         Msg.pt = gpsi->ptCursor;
          MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY);
    }
    else
    {
          DPRINT("Invalid focus window handle\n");
    }
-   if (UserIsEntered()) UserLeave();
+
+   if (Entered) UserLeave();
+   return;
 }
 
 VOID FASTCALL
@@ -813,7 +795,6 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
 {
    PWINDOW_OBJECT Window;
    PTHREADINFO Win32Thread;
-   PWINSTATION_OBJECT WinSta;
    MSG Mesg;
    LARGE_INTEGER LargeTickCount;
    NTSTATUS Status;
@@ -832,7 +813,6 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
       return;
    }
 
-   WinSta = Win32Thread->Desktop->WindowStation;
    Window = IntGetWindowObject(hWnd);
    if (!Window)
    {
@@ -846,8 +826,8 @@ MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
    Mesg.lParam = lParam;
    KeQueryTickCount(&LargeTickCount);
    Mesg.time = MsqCalculateMessageTime(&LargeTickCount);
-   IntGetCursorLocation(WinSta, &Mesg.pt);
-   MsqPostMessage(Window->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
+   Mesg.pt = gpsi->ptCursor;
+   MsqPostMessage(Window->pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
    UserDereferenceObject(Window);
    ObDereferenceObject (Thread);
 
@@ -914,7 +894,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
    PLIST_ENTRY Entry;
    LRESULT Result;
    BOOL SenderReturned;
-   PUSER_SENT_MESSAGE_NOTIFY NotifyMessage;
 
    if (IsListEmpty(&MessageQueue->SentMessagesListHead))
    {
@@ -957,12 +936,15 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
       to be cleaned up on thread termination anymore */
    RemoveEntryList(&Message->ListEntry);
 
-   /* remove the message from the dispatching list, so lock the sender's message queue */
-   SenderReturned = (Message->DispatchingListEntry.Flink == NULL);
-   if(!SenderReturned)
+   /* remove the message from the dispatching list if needed, so lock the sender's message queue */
+   if (!(Message->HookMessage & MSQ_SENTNOWAIT))
    {
-      /* only remove it from the dispatching list if not already removed by a timeout */
-      RemoveEntryList(&Message->DispatchingListEntry);
+      SenderReturned = (Message->DispatchingListEntry.Flink == NULL);
+      if (!SenderReturned)
+      {
+         /* only remove it from the dispatching list if not already removed by a timeout */
+         RemoveEntryList(&Message->DispatchingListEntry);
+      }
    }
    /* still keep the sender's message queue locked, so the sender can't exit the
       MsqSendMessage() function (if timed out) */
@@ -973,43 +955,41 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
       *Message->Result = Result;
    }
 
+   if (Message->HasPackedLParam == TRUE)
+   {
+      if (Message->Msg.lParam)
+         ExFreePool((PVOID)Message->Msg.lParam);
+   }
+
    /* Notify the sender. */
    if (Message->CompletionEvent != NULL)
    {
       KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
    }
 
-   /* Notify the sender if they specified a callback. */
+   /* Call the callback if the message was sent with SendMessageCallback */
    if (!SenderReturned && Message->CompletionCallback != NULL)
    {
-      if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool,
-                           sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG)))
-      {
-         DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n");
-         goto Notified;
-      }
-      NotifyMessage->CompletionCallback =
-         Message->CompletionCallback;
-      NotifyMessage->CompletionCallbackContext =
-         Message->CompletionCallbackContext;
-      NotifyMessage->Result = Result;
-      NotifyMessage->hWnd = Message->Msg.hwnd;
-      NotifyMessage->Msg = Message->Msg.message;
-      MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage);
+      co_IntCallSentMessageCallback(Message->CompletionCallback,
+                                    Message->Msg.hwnd,
+                                    Message->Msg.message,
+                                    Message->CompletionCallbackContext,
+                                    Result);
    }
 
-Notified:
-
-   /* dereference both sender and our queue */
-   IntDereferenceMessageQueue(MessageQueue);
-   IntDereferenceMessageQueue(Message->SenderQueue);
+   /* Only if it is not a no wait message */
+   if (!(Message->HookMessage & MSQ_SENTNOWAIT))
+   {
+      IntDereferenceMessageQueue(Message->SenderQueue);
+      IntDereferenceMessageQueue(MessageQueue);
+   }
 
    /* free the message */
-   ExFreePool(Message);
+   ExFreePoolWithTag(Message, TAG_USRMSG);
    return(TRUE);
 }
 
-VOID STDCALL
+VOID APIENTRY
 MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
 {
    PUSER_SENT_MESSAGE SentMessage;
@@ -1020,7 +1000,7 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
 
    ASSERT(Window);
 
-   MessageQueue = Window->MessageQueue;
+   MessageQueue = Window->pti->MessageQueue;
    ASSERT(MessageQueue);
 
    /* remove the posted messages for this window */
@@ -1053,10 +1033,11 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
       {
          DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
 
-        RemoveEntryList(&SentMessage->ListEntry);
+         RemoveEntryList(&SentMessage->ListEntry);
 
-         /* remove the message from the dispatching list */
-         if(SentMessage->DispatchingListEntry.Flink != NULL)
+         /* remove the message from the dispatching list if neede */
+         if ((!(SentMessage->HookMessage & MSQ_SENTNOWAIT))
+            && (SentMessage->DispatchingListEntry.Flink != NULL))
          {
             RemoveEntryList(&SentMessage->DispatchingListEntry);
          }
@@ -1067,12 +1048,22 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow)
             KeSetEvent(SentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
          }
 
-         /* dereference our and the sender's message queue */
-         IntDereferenceMessageQueue(MessageQueue);
-         IntDereferenceMessageQueue(SentMessage->SenderQueue);
+         if (SentMessage->HasPackedLParam == TRUE)
+         {
+            if (SentMessage->Msg.lParam)
+               ExFreePool((PVOID)SentMessage->Msg.lParam);
+         }
+
+         /* Only if it is not a no wait message */
+         if (!(SentMessage->HookMessage & MSQ_SENTNOWAIT))
+         {
+            /* dereference our and the sender's message queue */
+            IntDereferenceMessageQueue(MessageQueue);
+            IntDereferenceMessageQueue(SentMessage->SenderQueue);
+         }
 
          /* free the message */
-         ExFreePool(SentMessage);
+         ExFreePoolWithTag(SentMessage, TAG_USRMSG);
 
          CurrentEntry = MessageQueue->SentMessagesListHead.Flink;
       }
@@ -1137,6 +1128,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
    IntReferenceMessageQueue(ThreadQueue);
    Message->CompletionCallback = NULL;
    Message->HookMessage = HookMessage;
+   Message->HasPackedLParam = FALSE;
 
    IntReferenceMessageQueue(MessageQueue);
 
@@ -1311,11 +1303,11 @@ MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode)
       KeSetEvent(MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
 }
 
-BOOLEAN STDCALL
+BOOLEAN APIENTRY
 co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
                   IN BOOLEAN Hardware,
                   IN BOOLEAN Remove,
-                  IN HWND Wnd,
+                  IN PWINDOW_OBJECT Window,
                   IN UINT MsgFilterLow,
                   IN UINT MsgFilterHigh,
                   OUT PUSER_MESSAGE* Message)
@@ -1326,9 +1318,12 @@ co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
 
    if (Hardware)
    {
-      return(co_MsqPeekHardwareMessage(MessageQueue, Wnd,
-                                       MsgFilterLow, MsgFilterHigh,
-                                       Remove, Message));
+      return(co_MsqPeekHardwareMessage( MessageQueue,
+                                        Window,
+                                        MsgFilterLow,
+                                        MsgFilterHigh,
+                                        Remove,
+                                        Message));
    }
 
    CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
@@ -1337,10 +1332,12 @@ co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
    {
       CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
                                          ListEntry);
-      if ((Wnd == 0 || Wnd == CurrentMessage->Msg.hwnd) &&
-            ((MsgFilterLow == 0 && MsgFilterHigh == 0) ||
-             (MsgFilterLow <= CurrentMessage->Msg.message &&
-              MsgFilterHigh >= CurrentMessage->Msg.message)))
+      if ( ( !Window ||
+            PtrToInt(Window) == 1 ||
+            Window->hSelf == CurrentMessage->Msg.hwnd ) &&
+            ( (MsgFilterLow == 0 && MsgFilterHigh == 0) ||
+              ( MsgFilterLow <= CurrentMessage->Msg.message &&
+                MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
       {
          if (Remove)
          {
@@ -1357,23 +1354,12 @@ co_MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
 }
 
 NTSTATUS FASTCALL
-co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, HWND WndFilter,
+co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWINDOW_OBJECT WndFilter,
                          UINT MsgFilterMin, UINT MsgFilterMax)
 {
    PVOID WaitObjects[2] = {MessageQueue->NewMessages, &HardwareMessageEvent};
-   LARGE_INTEGER TimerExpiry;
-   PLARGE_INTEGER Timeout;
    NTSTATUS ret;
 
-   if (MsqGetFirstTimerExpiry(MessageQueue, WndFilter, MsgFilterMin, MsgFilterMax, &TimerExpiry))
-   {
-      Timeout = &TimerExpiry;
-   }
-   else
-   {
-      Timeout = NULL;
-   }
-
    IdlePing(); // Going to wait so send Idle ping.
 
    UserLeaveCo();
@@ -1384,11 +1370,9 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, HWND WndFilter,
                                   Executive,
                                   UserMode,
                                   FALSE,
-                                  Timeout,
+                                  NULL,
                                   NULL);
-
    UserEnterCo();
-
    return ret;
 }
 
@@ -1422,6 +1406,7 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
    MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
    MessageQueue->FocusWindow = NULL;
    MessageQueue->PaintCount = 0;
+// HACK!!!!!!! Newbies that wrote this should hold your head down in shame! (jt)
    MessageQueue->WakeMask = ~0;
    MessageQueue->NewMessagesHandle = NULL;
 
@@ -1471,8 +1456,9 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
 
       DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n");
 
-      /* remove the message from the dispatching list */
-      if(CurrentSentMessage->DispatchingListEntry.Flink != NULL)
+      /* remove the message from the dispatching list if needed */
+      if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) 
+         && (CurrentSentMessage->DispatchingListEntry.Flink != NULL))
       {
          RemoveEntryList(&CurrentSentMessage->DispatchingListEntry);
       }
@@ -1483,9 +1469,19 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
          KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
       }
 
-      /* dereference our and the sender's message queue */
-      IntDereferenceMessageQueue(MessageQueue);
-      IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      if (CurrentSentMessage->HasPackedLParam == TRUE)
+      {
+         if (CurrentSentMessage->Msg.lParam)
+            ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
+      }
+
+      /* Only if it is not a no wait message */
+      if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+      {
+         /* dereference our and the sender's message queue */
+         IntDereferenceMessageQueue(MessageQueue);
+         IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      }
 
       /* free the message */
       ExFreePool(CurrentSentMessage);
@@ -1521,9 +1517,19 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
          KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
       }
 
-      /* dereference our and the sender's message queue */
-      IntDereferenceMessageQueue(MessageQueue);
-      IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      if (CurrentSentMessage->HasPackedLParam == TRUE)
+      {
+         if (CurrentSentMessage->Msg.lParam)
+            ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
+      }
+
+      /* Only if it is not a no wait message */
+      if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT))
+      {
+         /* dereference our and the sender's message queue */
+         IntDereferenceMessageQueue(MessageQueue);
+         IntDereferenceMessageQueue(CurrentSentMessage->SenderQueue);
+      }
 
       /* free the message */
       ExFreePool(CurrentSentMessage);
@@ -1549,7 +1555,7 @@ MsqCreateMessageQueue(struct _ETHREAD *Thread)
 {
    PUSER_MESSAGE_QUEUE MessageQueue;
 
-   MessageQueue = (PUSER_MESSAGE_QUEUE)ExAllocatePoolWithTag(PagedPool,
+   MessageQueue = (PUSER_MESSAGE_QUEUE)ExAllocatePoolWithTag(NonPagedPool,
                   sizeof(USER_MESSAGE_QUEUE) + sizeof(THRDCARETINFO),
                   TAG_MSGQ);
 
@@ -1821,7 +1827,7 @@ MsqKillTimer(PUSER_MESSAGE_QUEUE MessageQueue, HWND Wnd,
 
 BOOLEAN FASTCALL
 MsqGetTimerMessage(PUSER_MESSAGE_QUEUE MessageQueue,
-                   HWND WndFilter, UINT MsgFilterMin, UINT MsgFilterMax,
+                   PWINDOW_OBJECT WindowFilter, UINT MsgFilterMin, UINT MsgFilterMax,
                    MSG *Msg, BOOLEAN Restart)
 {
    PTIMER_ENTRY Timer;
@@ -1829,7 +1835,6 @@ MsqGetTimerMessage(PUSER_MESSAGE_QUEUE MessageQueue,
    LARGE_INTEGER LargeTickCount;
    PLIST_ENTRY EnumEntry;
    BOOLEAN GotMessage;
-   PTHREADINFO pti;
 
    DPRINT("MsqGetTimerMessage queue %p msg %p restart %s\n",
           MessageQueue, Msg, Restart ? "TRUE" : "FALSE");
@@ -1845,7 +1850,7 @@ MsqGetTimerMessage(PUSER_MESSAGE_QUEUE MessageQueue,
       DPRINT("Checking timer %p wnd %x expiry %I64d\n", Timer, Timer->Wnd,
              Timer->ExpiryTime.QuadPart);
       EnumEntry = EnumEntry->Flink;
-      if ((NULL == WndFilter || Timer->Wnd == WndFilter) &&
+      if ((NULL == WindowFilter || Timer->Wnd == WindowFilter->hSelf) &&
             ((MsgFilterMin == 0 && MsgFilterMax == 0) ||
              (MsgFilterMin <= Timer->Msg &&
               Timer->Msg <= MsgFilterMax)))
@@ -1865,7 +1870,7 @@ MsqGetTimerMessage(PUSER_MESSAGE_QUEUE MessageQueue,
       else
       {
          DPRINT("timer %p (wnd %x msg %d) failed filter wnd %x msgmin %d msgmax %d\n",
-                Timer, Timer->Wnd, Timer->Msg, WndFilter, MsgFilterMin, MsgFilterMax);
+                Timer, Timer->Wnd, Timer->Msg, WindowFilter->hSelf, MsgFilterMin, MsgFilterMax);
       }
    }
 
@@ -1881,9 +1886,7 @@ MsqGetTimerMessage(PUSER_MESSAGE_QUEUE MessageQueue,
    Msg->lParam = (LPARAM) Timer->TimerFunc;
    KeQueryTickCount(&LargeTickCount);
    Msg->time = MsqCalculateMessageTime(&LargeTickCount);
-   pti = PsGetCurrentThreadWin32Thread();
-   IntGetCursorLocation(pti->Desktop->WindowStation,
-                        &Msg->pt);
+   Msg->pt = gpsi->ptCursor;
 
    if (Restart)
    {
@@ -1935,7 +1938,7 @@ MsqRemoveTimersWindow(PUSER_MESSAGE_QUEUE MessageQueue, HWND Wnd)
 
 BOOLEAN FASTCALL
 MsqGetFirstTimerExpiry(PUSER_MESSAGE_QUEUE MessageQueue,
-                       HWND WndFilter, UINT MsgFilterMin, UINT MsgFilterMax,
+                       PWINDOW_OBJECT WndFilter, UINT MsgFilterMin, UINT MsgFilterMax,
                        PLARGE_INTEGER FirstTimerExpiry)
 {
    PTIMER_ENTRY Timer;
@@ -1950,7 +1953,7 @@ MsqGetFirstTimerExpiry(PUSER_MESSAGE_QUEUE MessageQueue,
       Timer = CONTAINING_RECORD(MessageQueue->TimerListHead.Flink,
                                 TIMER_ENTRY, ListEntry);
       EnumEntry = EnumEntry->Flink;
-      if ((NULL == WndFilter || Timer->Wnd == WndFilter) &&
+      if ((NULL == WndFilter || PtrToInt(WndFilter) == 1 || Timer->Wnd == WndFilter->hSelf) &&
             ((MsgFilterMin == 0 && MsgFilterMax == 0) ||
              (MsgFilterMin <= Timer->Msg &&
               Timer->Msg <= MsgFilterMax)))