[Win32k]
authorJames Tabor <james.tabor@reactos.org>
Wed, 4 May 2011 23:37:35 +0000 (23:37 +0000)
committerJames Tabor <james.tabor@reactos.org>
Wed, 4 May 2011 23:37:35 +0000 (23:37 +0000)
- Move hook call close to the keyboard message post. This allows the registering of Aly keys before the hook call. This fixes all but one GetKeyState Api Test.
- Fix GetAsync/KeyState error codes and the return for GetAsyncKeyState. See http://appdb.winehq.org/objectManager.php?sClass=version&iId=8516&iTestingId=13644
- Fix TranslateMessage, check for window and use the window pti for re-posting to message queue.
- Peeking hardware queue should be the same as other Peek queue.

svn path=/trunk/; revision=51583

reactos/subsystems/win32/win32k/ntuser/input.c
reactos/subsystems/win32/win32k/ntuser/keyboard.c
reactos/subsystems/win32/win32k/ntuser/msgqueue.c

index 5c7637f..8e5d5f3 100644 (file)
@@ -1333,6 +1333,27 @@ IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected)
       Msg.lParam = MAKELPARAM(1 /* repeat count */, ki->wScan);
    }
 
+   if (!(ki->dwFlags & KEYEVENTF_UNICODE))
+   {
+      if (ki->dwFlags & KEYEVENTF_KEYUP)
+      {
+         gQueueKeyStateTable[wVk] &= ~0x80;
+         gQueueKeyStateTable[wVkStripped] = gQueueKeyStateTable[wVkL] | gQueueKeyStateTable[wVkR];
+      }
+      else
+      {
+         if (!(gQueueKeyStateTable[wVk] & 0x80)) gQueueKeyStateTable[wVk] ^= 0x01;
+         gQueueKeyStateTable[wVk] |= 0xc0;
+         gQueueKeyStateTable[wVkStripped] = gQueueKeyStateTable[wVkL] | gQueueKeyStateTable[wVkR];
+      }
+
+      if (gQueueKeyStateTable[VK_MENU] & 0x80) flags |= KF_ALTDOWN;
+
+      if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
+
+      Msg.lParam = MAKELPARAM(1 /* repeat count */, flags);
+   }
+
    FocusMessageQueue = IntGetFocusMessageQueue();
 
    Msg.hwnd = 0;
@@ -1365,27 +1386,6 @@ IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected)
       return FALSE;
    }
 
-   if (!(ki->dwFlags & KEYEVENTF_UNICODE))
-   {
-      if (ki->dwFlags & KEYEVENTF_KEYUP)
-      {
-         gQueueKeyStateTable[wVk] &= ~0x80;
-         gQueueKeyStateTable[wVkStripped] = gQueueKeyStateTable[wVkL] | gQueueKeyStateTable[wVkR];
-      }
-      else
-      {
-         if (!(gQueueKeyStateTable[wVk] & 0x80)) gQueueKeyStateTable[wVk] ^= 0x01;
-         gQueueKeyStateTable[wVk] |= 0xc0;
-         gQueueKeyStateTable[wVkStripped] = gQueueKeyStateTable[wVkL] | gQueueKeyStateTable[wVkR];
-      }
-
-      if (gQueueKeyStateTable[VK_MENU] & 0x80) flags |= KF_ALTDOWN;
-
-      if (wVkStripped == VK_SHIFT) flags &= ~KF_EXTENDED;
-
-      Msg.lParam = MAKELPARAM(1 /* repeat count */, flags);
-   }
-
    if (FocusMessageQueue == NULL)
    {
          DPRINT("No focus message queue\n");
@@ -1400,7 +1400,6 @@ IntKeyboardInput(KEYBDINPUT *ki, BOOL Injected)
 
          FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
 
-         Msg.pt = gpsi->ptCursor;
       // Post to hardware queue, based on the first part of wine "some GetMessage tests"
       // in test_PeekMessage()
          MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
index 0583b0c..93e2d2f 100644 (file)
@@ -341,8 +341,13 @@ DWORD FASTCALL UserGetAsyncKeyState(DWORD key)
    {
       ret = ((DWORD)(gQueueKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
             (gQueueKeyStateTable[key] & KS_LOCK_BIT);
+      if ( ret & 0x8000 )
+         ret |= 0xFFFF0000; // If down, windows returns 0xFFFF8000.
+   }
+   else
+   {
+      EngSetLastError(ERROR_INVALID_PARAMETER);
    }
-
    return ret;
 }
 
@@ -355,19 +360,19 @@ WORD FASTCALL get_key_state(void)
 
     if (gpsi->aiSysMet[SM_SWAPBUTTON])
     {
-        if (UserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON;
-        if (UserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON;
+        if (gQueueKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_LBUTTON;
+        if (gQueueKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_RBUTTON;
     }
     else
     {
-        if (UserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON;
-        if (UserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON;
+        if (gQueueKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_LBUTTON;
+        if (gQueueKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_RBUTTON;
     }
-    if (UserGetAsyncKeyState(VK_MBUTTON) & 0x80)  ret |= MK_MBUTTON;
-    if (UserGetAsyncKeyState(VK_SHIFT) & 0x80)    ret |= MK_SHIFT;
-    if (UserGetAsyncKeyState(VK_CONTROL) & 0x80)  ret |= MK_CONTROL;
-    if (UserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1;
-    if (UserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2;
+    if (gQueueKeyStateTable[VK_MBUTTON]  & 0x80) ret |= MK_MBUTTON;
+    if (gQueueKeyStateTable[VK_SHIFT]    & 0x80) ret |= MK_SHIFT;
+    if (gQueueKeyStateTable[VK_CONTROL]  & 0x80) ret |= MK_CONTROL;
+    if (gQueueKeyStateTable[VK_XBUTTON1] & 0x80) ret |= MK_XBUTTON1;
+    if (gQueueKeyStateTable[VK_XBUTTON2] & 0x80) ret |= MK_XBUTTON2;
     return ret;
 }
 
@@ -401,9 +406,17 @@ IntTranslateKbdMessage(LPMSG lpMsg,
    WCHAR wp[2] = { 0 };
    MSG NewMsg = { 0 };
    PKBDTABLES keyLayout;
+   PWND pWndMsg;
    BOOL Result = FALSE;
 
-   pti = PsGetCurrentThreadWin32Thread();
+   pWndMsg = UserGetWindowObject(lpMsg->hwnd);
+   if (!pWndMsg) // Must have a window!
+   {
+      DPRINT1("No Window for Translate.\n");
+      return FALSE;
+   }
+
+   pti = pWndMsg->head.pti;
    keyLayout = pti->KeyboardLayout->KBTables;
    if( !keyLayout )
       return FALSE;
@@ -416,6 +429,8 @@ IntTranslateKbdMessage(LPMSG lpMsg,
    /* All messages have to contain the cursor point. */
    NewMsg.pt = gpsi->ptCursor;
 
+   DPRINT("IntTranslateKbdMessage %s\n", lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN");
+
     switch (lpMsg->wParam)
     {
     case VK_PACKET:
@@ -427,9 +442,13 @@ IntTranslateKbdMessage(LPMSG lpMsg,
         return TRUE;
     }
 
-   UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff,
-                           gQueueKeyStateTable, wp, 2, 0,
-                           keyLayout );
+   UState = ToUnicodeInner( lpMsg->wParam,
+                            HIWORD(lpMsg->lParam) & 0xff,
+                            gQueueKeyStateTable,
+                            wp,
+                            2,
+                            0,
+                            keyLayout );
 
    if (UState == 1)
    {
@@ -482,7 +501,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
       MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
       Result = TRUE;
    }
-
+   DPRINT("IntTranslateKbdMessage E %s\n", NewMsg.message == WM_CHAR ? "WM_CHAR" : "WM_SYSCHAR");
    return Result;
 }
 
@@ -839,6 +858,8 @@ W32kKeyProcessMessage(LPMSG Msg,
     *
     * Shift and the LP_EXT_BIT cancel. */
    ScanCode = (Msg->lParam >> 16) & 0xff;
+   DPRINT("ScanCode %04x\n",ScanCode);
+
    BaseMapping = Msg->wParam =
                     IntMapVirtualKeyEx( ScanCode, 1, KeyboardLayout );
    if( Prefix == 0 )
index b14cd96..7856102 100644 (file)
@@ -56,7 +56,10 @@ DWORD FASTCALL UserGetKeyState(DWORD key)
        if (MessageQueue->KeyState[key] & KS_DOWN_BIT)
           ret |= 0xFF00; // If down, windows returns 0xFF80. 
    }
-
+   else
+   {
+      EngSetLastError(ERROR_INVALID_PARAMETER);
+   }
    return ret;
 }
 
@@ -1457,9 +1460,17 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
         if (IsListEmpty(CurrentEntry)) break;
         if (!CurrentMessage) break;
         CurrentEntry = CurrentMessage->ListEntry.Flink;
-
-        if ( (( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && (CurrentMessage->QS_Flags & QSflags)) ||
-             ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) )
+/*
+ MSDN:
+ 1: any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL.
+ 2: retrieves only messages on the current thread's message queue whose hwnd value is NULL.
+ 3: handle to the window whose messages are to be retrieved.
+ */
+      if ( ( !Window || // 1
+            ( Window == HWND_BOTTOM && CurrentMessage->Msg.hwnd == NULL ) || // 2
+            ( Window != HWND_BOTTOM && Window->head.h == CurrentMessage->Msg.hwnd ) ) && // 3
+            ( ( ( MsgFilterLow == 0 && MsgFilterHigh == 0 ) && CurrentMessage->QS_Flags & QSflags ) ||
+              ( MsgFilterLow <= CurrentMessage->Msg.message && MsgFilterHigh >= CurrentMessage->Msg.message ) ) )
         {
            msg = CurrentMessage->Msg;