* Sync up to trunk head (r64921).
[reactos.git] / win32ss / user / ntuser / keyboard.c
index 80b29e4..705f4ff 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Keyboard functions
- * FILE:             subsystems/win32/win32k/ntuser/keyboard.c
+ * FILE:             win32ss/user/ntuser/keyboard.c
  * PROGRAMERS:       Casper S. Hornstrup (chorns@users.sourceforge.net)
  *                   Rafal Harabien (rafalh@reactos.org)
  */
@@ -14,6 +14,7 @@ BYTE gafAsyncKeyState[256 * 2 / 8]; // 2 bits per key
 static BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
 static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL;
 static KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0};
+KEYBOARD_ATTRIBUTES gKeyboardInfo;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -29,6 +30,10 @@ InitKeyboardImpl(VOID)
 {
     RtlZeroMemory(&gafAsyncKeyState, sizeof(gafAsyncKeyState));
     RtlZeroMemory(&gafAsyncKeyStateRecentDown, sizeof(gafAsyncKeyStateRecentDown));
+    // Clear and set default information.
+    RtlZeroMemory(&gKeyboardInfo, sizeof(gKeyboardInfo));
+    gKeyboardInfo.KeyboardIdentifier.Type = 4; /* AT-101 */
+    gKeyboardInfo.NumberOfFunctionKeys = 12; /* We're doing an 101 for now, so return 12 F-keys */
     return STATUS_SUCCESS;
 }
 
@@ -38,7 +43,7 @@ InitKeyboardImpl(VOID)
  * Asks the keyboard driver to send a small table that shows which
  * lights should connect with which scancodes
  */
-static
+//static
 NTSTATUS APIENTRY
 IntKeyboardGetIndicatorTrans(HANDLE hKeyboardDevice,
                              PKEYBOARD_INDICATOR_TRANSLATION *ppIndicatorTrans)
@@ -56,7 +61,7 @@ IntKeyboardGetIndicatorTrans(HANDLE hKeyboardDevice,
 
     while (pRet)
     {
-        Status = NtDeviceIoControlFile(hKeyboardDevice,
+        Status = ZwDeviceIoControlFile(hKeyboardDevice,
                                        NULL,
                                        NULL,
                                        NULL,
@@ -99,8 +104,7 @@ static
 NTSTATUS APIENTRY
 IntKeyboardUpdateLeds(HANDLE hKeyboardDevice,
                       WORD wVk,
-                      WORD wScanCode,
-                      BOOL bEnabled)
+                      WORD wScanCode)
 {
     NTSTATUS Status;
     UINT i;
@@ -128,13 +132,10 @@ IntKeyboardUpdateLeds(HANDLE hKeyboardDevice,
 
     if (LedFlag)
     {
-        if (bEnabled)
-            gIndicators.LedFlags |= LedFlag;
-        else
-            gIndicators.LedFlags = ~LedFlag;
+        gIndicators.LedFlags ^= LedFlag;
 
         /* Update the lights on the hardware */
-        Status = NtDeviceIoControlFile(hKeyboardDevice,
+        Status = ZwDeviceIoControlFile(hKeyboardDevice,
                                        NULL,
                                        NULL,
                                        NULL,
@@ -162,7 +163,7 @@ UserInitKeyboard(HANDLE hKeyboardDevice)
 
     IntKeyboardGetIndicatorTrans(hKeyboardDevice, &gpKeyboardIndicatorTrans);
 
-    Status = NtDeviceIoControlFile(hKeyboardDevice,
+    Status = ZwDeviceIoControlFile(hKeyboardDevice,
                                    NULL,
                                    NULL,
                                    NULL,
@@ -175,13 +176,31 @@ UserInitKeyboard(HANDLE hKeyboardDevice)
     {
         WARN("NtDeviceIoControlFile() failed, ignored\n");
     }
-
     SET_KEY_LOCKED(gafAsyncKeyState, VK_CAPITAL,
                    gIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON);
     SET_KEY_LOCKED(gafAsyncKeyState, VK_NUMLOCK,
                    gIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON);
     SET_KEY_LOCKED(gafAsyncKeyState, VK_SCROLL,
                    gIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON);
+
+    // FIXME: Need device driver to work! HID support more than one!!!!
+    Status = ZwDeviceIoControlFile(hKeyboardDevice,
+                                   NULL,
+                                   NULL,
+                                   NULL,
+                                   &Block,
+                                   IOCTL_KEYBOARD_QUERY_ATTRIBUTES,
+                                   NULL, 0,
+                                   &gKeyboardInfo, sizeof(gKeyboardInfo));
+
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("NtDeviceIoControlFile() failed, ignored\n");
+    }
+    ERR("Keyboard type %d, subtype %d and number of func keys %d\n",
+             gKeyboardInfo.KeyboardIdentifier.Type,
+             gKeyboardInfo.KeyboardIdentifier.Subtype,
+             gKeyboardInfo.NumberOfFunctionKeys);
 }
 
 /*
@@ -361,7 +380,7 @@ IntTranslateChar(WORD wVirtKey,
                 *pbLigature = (wch == WCH_LGTR);
                 *pwcTranslatedChar = wch;
 
-                TRACE("%d %04x: dwModNumber %08x Char %04x\n",
+                TRACE("%lu %04x: dwModNumber %08x Char %04x\n",
                       i, wVirtKey, dwModNumber, wch);
 
                 if (*pbDead)
@@ -614,7 +633,7 @@ NtUserGetAsyncKeyState(INT Key)
 
     UserLeave();
 
-    TRACE("Leave NtUserGetAsyncKeyState, ret=%i\n", wRet);
+    TRACE("Leave NtUserGetAsyncKeyState, ret=%u\n", wRet);
     return wRet;
 }
 
@@ -763,6 +782,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
 {
     WORD wSimpleVk = 0, wFixedVk, wVk2;
     PUSER_MESSAGE_QUEUE pFocusQueue;
+    PTHREADINFO pti;
     BOOL bExt = (dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
     BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
     BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
@@ -784,8 +804,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
         /* Update keyboard LEDs */
         IntKeyboardUpdateLeds(ghKeyboardDevice,
                               wSimpleVk,
-                              wScanCode,
-                              IS_KEY_LOCKED(gafAsyncKeyState, wSimpleVk));
+                              wScanCode);
     }
 
     /* Call WH_KEYBOARD_LL hook */
@@ -797,8 +816,11 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
 
     /* Check if this is a hotkey */
     if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
+    {
+        TRACE("HotKey Processed\n");
         bPostMsg = FALSE;
-
+    }
     wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
     if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
         bExt = FALSE;
@@ -866,20 +888,36 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
     }
     else if (pFocusQueue && bPostMsg)
     {
-        PWND Wnd = pFocusQueue->spwndFocus;
-        if (!Wnd)
+        PWND Wnd = pFocusQueue->spwndFocus; // SysInit.....
+
+        pti = pFocusQueue->ptiKeyboard;
+
+        if (!Wnd && pFocusQueue->spwndActive) // SysInit.....
         {
-           // Focus can be null so going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
+           // Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
            Wnd = pFocusQueue->spwndActive;
         }
+        if (Wnd) pti = Wnd->head.pti;
 
         /* Init message */
-        Msg.hwnd = UserHMGetHandle(Wnd);
+        Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
         Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
         Msg.lParam = MAKELPARAM(1, wScanCode);
         Msg.time = dwTime;
         Msg.pt = gpsi->ptCursor;
 
+        if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN )
+        {
+           if ( (Msg.wParam == VK_SHIFT ||
+                 Msg.wParam == VK_CONTROL ||
+                 Msg.wParam == VK_MENU ) &&
+               !IS_KEY_DOWN(gafAsyncKeyState, Msg.wParam))
+           {
+              ERR("Set last input\n");
+              //ptiLastInput = pti;
+           }
+        }
+
         /* If it is VK_PACKET, high word of wParam is used for wchar */
         if (!bPacket)
         {
@@ -900,7 +938,8 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
 
         /* Post a keyboard message */
         TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
-        MsqPostMessage(pFocusQueue, &Msg, TRUE, QS_KEY, 0);
+        if (!Wnd) {ERR("Window is NULL\n");}
+        MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0);
     }
 
     return TRUE;
@@ -913,7 +952,6 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
     PKL pKl = NULL;
     PKBDTABLES pKbdTbl;
     PUSER_MESSAGE_QUEUE pFocusQueue;
-    struct _ETHREAD *pFocusThread;
     LARGE_INTEGER LargeTickCount;
     DWORD dwTime;
     BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
@@ -923,11 +961,9 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
     /* Find the target thread whose locale is in effect */
     pFocusQueue = IntGetFocusMessageQueue();
 
-    if (pFocusQueue)
+    if (pFocusQueue && pFocusQueue->ptiKeyboard)
     {
-        pFocusThread = pFocusQueue->Thread;
-        if (pFocusThread && pFocusThread->Tcb.Win32Thread)
-            pKl = ((PTHREADINFO)pFocusThread->Tcb.Win32Thread)->KeyboardLayout;
+        pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
     }
 
     if (!pKl)
@@ -997,7 +1033,6 @@ UserProcessKeyboardInput(
     PKL pKl = NULL;
     PKBDTABLES pKbdTbl;
     PUSER_MESSAGE_QUEUE pFocusQueue;
-    struct _ETHREAD *pFocusThread;
 
     /* Calculate scan code with prefix */
     wScanCode = pKbdInputData->MakeCode & 0x7F;
@@ -1009,11 +1044,9 @@ UserProcessKeyboardInput(
     /* Find the target thread whose locale is in effect */
     pFocusQueue = IntGetFocusMessageQueue();
 
-    if (pFocusQueue)
+    if (pFocusQueue && pFocusQueue->ptiKeyboard)
     {
-        pFocusThread = pFocusQueue->Thread;
-        if (pFocusThread && pFocusThread->Tcb.Win32Thread)
-            pKl = ((PTHREADINFO)pFocusThread->Tcb.Win32Thread)->KeyboardLayout;
+        pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
     }
 
     if (!pKl)
@@ -1121,7 +1154,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
         NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
         NewMsg.wParam = HIWORD(lpMsg->lParam);
         NewMsg.lParam = LOWORD(lpMsg->lParam);
-        MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0);
+        MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0);
         return TRUE;
     }
 
@@ -1150,7 +1183,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
         {
             TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
             NewMsg.wParam = wch[i];
-            MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY, 0);
+            MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0);
         }
         bResult = TRUE;
     }
@@ -1254,7 +1287,7 @@ NtUserMapVirtualKeyEx(UINT uCode, UINT uType, DWORD keyboardId, HKL dwhkl)
         ret = IntMapVirtualKeyEx(uCode, uType, pKbdTbl);
 
     UserLeave();
-    TRACE("Leave NtUserMapVirtualKeyEx, ret=%i\n", ret);
+    TRACE("Leave NtUserMapVirtualKeyEx, ret=%u\n", ret);
     return ret;
 }
 
@@ -1312,7 +1345,7 @@ NtUserToUnicodeEx(
     pwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
     if (!pwszBuff)
     {
-        ERR("ExAllocatePoolWithTag(%d) failed\n", sizeof(WCHAR) * cchBuff);
+        ERR("ExAllocatePoolWithTag(%u) failed\n", sizeof(WCHAR) * cchBuff);
         return 0;
     }
     RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
@@ -1440,7 +1473,7 @@ NtUserGetKeyNameText(LONG lParam, LPWSTR lpString, int cchSize)
 
 cleanup:
     UserLeave();
-    TRACE("Leave NtUserGetKeyNameText, ret=%i\n", dwRet);
+    TRACE("Leave NtUserGetKeyNameText, ret=%lu\n", dwRet);
     return dwRet;
 }
 
@@ -1456,11 +1489,11 @@ UserGetKeyboardType(
     switch (dwTypeFlag)
     {
         case 0:        /* Keyboard type */
-            return 4;    /* AT-101 */
+            return (DWORD)gKeyboardInfo.KeyboardIdentifier.Type;
         case 1:        /* Keyboard Subtype */
-            return 0;    /* There are no defined subtypes */
+            return (DWORD)gKeyboardInfo.KeyboardIdentifier.Subtype;
         case 2:        /* Number of F-keys */
-            return 12;   /* We're doing an 101 for now, so return 12 F-keys */
+            return (DWORD)gKeyboardInfo.NumberOfFunctionKeys;
         default:
             ERR("Unknown type!\n");
             return 0;    /* Note: we don't have to set last error here */
@@ -1486,7 +1519,7 @@ NtUserVkKeyScanEx(
     PKL pKl = NULL;
     DWORD i, dwModBits = 0, dwModNumber = 0, Ret = (DWORD)-1;
 
-    TRACE("NtUserVkKeyScanEx() wch %d, KbdLayout 0x%p\n", wch, dwhkl);
+    TRACE("NtUserVkKeyScanEx() wch %u, KbdLayout 0x%p\n", wch, dwhkl);
     UserEnterShared();
 
     if (bUsehKL)
@@ -1520,7 +1553,7 @@ NtUserVkKeyScanEx(
                 if (pVkToWch->wch[dwModNumber] == wch)
                 {
                     dwModBits = pKbdTbl->pCharModifiers->ModNumber[dwModNumber];
-                    TRACE("i %d wC %04x: dwModBits %08x dwModNumber %08x MaxModBits %08x\n",
+                    TRACE("i %lu wC %04x: dwModBits %08x dwModNumber %08x MaxModBits %08x\n",
                           i, wch, dwModBits, dwModNumber, pKbdTbl->pCharModifiers->wMaxModBits);
                     Ret = (dwModBits << 8) | (pVkToWch->VirtualKey & 0xFF);
                     goto Exit;