Don't return characters is key is up
[reactos.git] / reactos / subsys / win32k / ntuser / keyboard.c
index d94bdcb..835a5b8 100644 (file)
@@ -16,8 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: keyboard.c,v 1.29 2004/05/10 17:07:18 weiden Exp $
- *
+/*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Messages
@@ -82,35 +81,51 @@ static UINT DontDistinguishShifts( UINT ret ) {
 }
 
 static VOID STDCALL SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down) {
+  ASSERT(vk <= 0xff);
+
   /* Special handling for toggles like numpad and caps lock */
+  if (vk == VK_CAPITAL || vk == VK_NUMLOCK) {
+    if (down) QueueKeyStateTable[vk] ^= KS_LOCK_BIT;
+  } 
 
-  if (vk == VK_CAPITAL || vk == VK_NUMLOCK) 
-    {
-      if (down) QueueKeyStateTable[key] ^= 1;
-    } 
+  if (ext && vk == VK_LSHIFT)
+    vk = VK_RSHIFT;
+  if (ext && vk == VK_LCONTROL)
+    vk = VK_RCONTROL;
+  if (ext && vk == VK_LMENU)
+    vk = VK_RMENU;
 
-  if (vk == VK_LSHIFT && ext) {
-      SetKeyState(VK_RSHIFT, 0, 0, down);
-  } else if (vk == VK_LSHIFT || vk == VK_SHIFT) {
-      SetKeyState(VK_LSHIFT, 0, 0, down);
-  }
+  if (down)
+    QueueKeyStateTable[vk] |= KS_DOWN_BIT;
+  else
+    QueueKeyStateTable[vk] &= ~KS_DOWN_MASK;
 
-  if (vk == VK_LCONTROL && ext) {
-      SetKeyState(VK_RCONTROL, 0, 0, down);
-  } else if (vk == VK_LCONTROL || vk == VK_CONTROL) {
-      SetKeyState(VK_LCONTROL, 0, 0, down);
+  if (vk == VK_LSHIFT || vk == VK_RSHIFT) {
+    if ((QueueKeyStateTable[VK_LSHIFT] & KS_DOWN_BIT) ||
+        (QueueKeyStateTable[VK_RSHIFT] & KS_DOWN_BIT)) {
+      QueueKeyStateTable[VK_SHIFT] |= KS_DOWN_BIT;
+    } else {
+      QueueKeyStateTable[VK_SHIFT] &= ~KS_DOWN_MASK;
+    }
   }
 
-  if (vk == VK_LMENU && ext) {
-      SetKeyState(VK_RMENU, 0, 0, down);
-  } else if (vk == VK_LMENU || vk == VK_MENU) {
-      SetKeyState(VK_LMENU, 0, 0, down);
+  if (vk == VK_LCONTROL || vk == VK_RCONTROL) {
+    if ((QueueKeyStateTable[VK_LCONTROL] & KS_DOWN_BIT) ||
+        (QueueKeyStateTable[VK_RCONTROL] & KS_DOWN_BIT)) {
+      QueueKeyStateTable[VK_CONTROL] |= KS_DOWN_BIT;
+    } else {
+      QueueKeyStateTable[VK_CONTROL] &= ~KS_DOWN_MASK;
+    }
   }
 
-  if (down)
-    QueueKeyStateTable[key] |= KS_DOWN_BIT;
-  else
-    QueueKeyStateTable[key] &= ~KS_DOWN_MASK;
+  if (vk == VK_LMENU || vk == VK_RMENU) {
+    if ((QueueKeyStateTable[VK_LMENU] & KS_DOWN_BIT) ||
+        (QueueKeyStateTable[VK_RMENU] & KS_DOWN_BIT)) {
+      QueueKeyStateTable[VK_MENU] |= KS_DOWN_BIT;
+    } else {
+      QueueKeyStateTable[VK_MENU] &= ~KS_DOWN_MASK;
+    }
+  }
 }
 
 VOID DumpKeyState( PBYTE KeyState ) {
@@ -326,16 +341,23 @@ int STDCALL ToUnicodeEx( UINT wVirtKey,
                         HKL dwhkl ) {
   int ToUnicodeResult = 0;
 
-  IntLockQueueState;
-  ToUnicodeResult = ToUnicodeInner( wVirtKey,
-                                   wScanCode,
-                                   lpKeyState,
-                                   pwszBuff,
-                                   cchBuff,
-                                   wFlags,
-                                   PsGetWin32Thread() ? 
-                                   PsGetWin32Thread()->KeyboardLayout : 0 );
-  IntUnLockQueueState;
+  if (0 == (lpKeyState[wVirtKey] & KS_DOWN_BIT))
+    {
+      ToUnicodeResult = 0;
+    }
+  else
+    {
+      IntLockQueueState;
+      ToUnicodeResult = ToUnicodeInner( wVirtKey,
+                                       wScanCode,
+                                       lpKeyState,
+                                       pwszBuff,
+                                       cchBuff,
+                                       wFlags,
+                                       PsGetWin32Thread() ? 
+                                       PsGetWin32Thread()->KeyboardLayout : 0 );
+      IntUnLockQueueState;
+    }
 
   return ToUnicodeResult;
 }
@@ -470,14 +492,15 @@ NTSTATUS STDCALL LdrGetProcedureAddress(PVOID module,
                                        DWORD flags,
                                        PVOID *func_addr);
 
-void InitKbdLayout( PVOID *pkKeyboardLayout ) {
-  UNICODE_STRING KeyName;
-  UNICODE_STRING ValueName;
+void InitKbdLayout( PVOID *pkKeyboardLayout )
+{
+  WCHAR LocaleBuffer[16];
   UNICODE_STRING LayoutKeyName;
   UNICODE_STRING LayoutValueName;
   UNICODE_STRING DefaultLocale;
   UNICODE_STRING LayoutFile;
   UNICODE_STRING FullLayoutPath;
+  LCID LocaleId;
   PWCHAR KeyboardLayoutWSTR;
   HMODULE kbModule = 0;
   NTSTATUS Status;
@@ -487,20 +510,17 @@ void InitKbdLayout( PVOID *pkKeyboardLayout ) {
   #define XX_STATUS(x) if (!NT_SUCCESS(Status = (x))) continue;
 
   do {
-    RtlInitUnicodeString(&KeyName,
-                        L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet"
-                        L"\\Control\\Nls\\Locale");
-    RtlInitUnicodeString(&ValueName,
-                        L"(Default)");
-       
-    DPRINT("KeyName = %wZ, ValueName = %wZ\n", &KeyName, &ValueName);
-
-    Status = ReadRegistryValue(&KeyName,&ValueName,&DefaultLocale);
-    
-    if( !NT_SUCCESS(Status) ) {
-      DPRINT1( "Could not get default locale (%08x).\n", Status );
-    } else {
-      DPRINT( "DefaultLocale = %wZ\n", &DefaultLocale );
+    Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
+    if (!NT_SUCCESS(Status))
+    {
+      DPRINT1("Could not get default locale (%08lx).\n", Status);
+    }
+    else
+    {
+      DPRINT("DefaultLocale = %lx\n", LocaleId);
+      swprintf(LocaleBuffer, L"%08lx", LocaleId);
+      DPRINT("DefaultLocale = %S\n", LocaleBuffer);
+      RtlInitUnicodeString(&DefaultLocale, LocaleBuffer);
 
       RtlInitUnicodeString(&LayoutKeyName,
                           L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet"
@@ -508,7 +528,6 @@ void InitKbdLayout( PVOID *pkKeyboardLayout ) {
 
       AppendUnicodeString(&LayoutKeyName,&DefaultLocale,FALSE);
 
-      RtlFreeUnicodeString(&DefaultLocale);
       RtlInitUnicodeString(&LayoutValueName,L"Layout File");
 
       Status = ReadRegistryValue(&LayoutKeyName,&LayoutValueName,&LayoutFile);
@@ -647,14 +666,14 @@ IntTranslateKbdMessage(LPMSG lpMsg,
          NewMsg.wParam = dead_char;
          NewMsg.lParam = lpMsg->lParam;
          dead_char = 0;
-         MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE);
+         MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
        }
       
       NewMsg.hwnd = lpMsg->hwnd;
       NewMsg.wParam = wp[0];
       NewMsg.lParam = lpMsg->lParam;
       DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
-      MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE);
+      MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
       Result = TRUE;
     }
   else if (UState == -1)
@@ -665,7 +684,7 @@ IntTranslateKbdMessage(LPMSG lpMsg,
       NewMsg.wParam = wp[0];
       NewMsg.lParam = lpMsg->lParam;
       dead_char = wp[0];
-      MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE);
+      MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
       Result = TRUE;
     }
 
@@ -965,7 +984,10 @@ VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyboardLayout) {
   ScanCode = (Msg->lParam >> 16) & 0xff;
   BaseMapping = Msg->wParam = 
     IntMapVirtualKeyEx( ScanCode, 1, KeyboardLayout );
-  RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
+  if( ScanCode >= KeyboardLayout->bMaxVSCtoVK )
+    RawVk = 0;
+  else
+    RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
 
   if ((ModifierBits & NUMLOCK_BIT) && 
       !(ModifierBits & GetShiftBit(KeyboardLayout, VK_SHIFT)) &&