Bug 855975 part.2 Wrap MapVirtualKeyEx() API for converting native key event to VK or Unichar with widget::NativeKey r=jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 29 May 2013 15:34:47 +0900
changeset 133239 6919e1b2926e053f88ce168bd2f7613c1f47ea33
parent 133238 90a6e3a943b659c15337c7edd5f4ef2dd5771552
child 133240 41e9211d9daad21d80cc70ced229cb28a4c5275a
push id24747
push useremorley@mozilla.com
push dateWed, 29 May 2013 14:24:37 +0000
treeherdermozilla-central@8d85de779506 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs855975
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 855975 part.2 Wrap MapVirtualKeyEx() API for converting native key event to VK or Unichar with widget::NativeKey r=jimm
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
widget/windows/nsWindow.cpp
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -383,16 +383,17 @@ VirtualKey::FillKbdState(PBYTE aKbdState
 
 NativeKey::NativeKey(nsWindow* aWindow,
                      const MSG& aKeyOrCharMessage,
                      const ModifierKeyState& aModKeyState) :
   mDOMKeyCode(0), mMessage(aKeyOrCharMessage.message),
   mVirtualKeyCode(0), mOriginalVirtualKeyCode(0)
 {
   KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
+  mKeyboardLayout = keyboardLayout->GetLayout();
   mScanCode = WinUtils::GetScanCode(aKeyOrCharMessage.lParam);
   mIsExtended = WinUtils::IsExtendedScanCode(aKeyOrCharMessage.lParam);
   // On WinXP and WinServer2003, we cannot compute the virtual keycode for
   // extended keys due to the API limitation.
   bool canComputeVirtualKeyCodeFromScanCode =
     (!mIsExtended || WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION);
   switch (mMessage) {
     case WM_KEYDOWN:
@@ -480,19 +481,17 @@ NativeKey::NativeKey(nsWindow* aWindow,
         }
         break;
       }
 
       NS_ASSERTION(!mVirtualKeyCode,
                    "mVirtualKeyCode has been computed already");
 
       // Otherwise, compute the virtual keycode with MapVirtualKeyEx().
-      mVirtualKeyCode = static_cast<uint8_t>(
-        ::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(),
-                          MAPVK_VSC_TO_VK_EX, keyboardLayout->GetLayout()));
+      mVirtualKeyCode = ComputeVirtualKeyCodeFromScanCodeEx();
 
       // The result might be unexpected value due to the scan code is
       // wrong.  For example, any key messages can be generated by
       // SendMessage() or PostMessage() from applications.  So, it's possible
       // failure.  Then, let's respect the extended flag even if it might be
       // set intentionally.
       switch (mOriginalVirtualKeyCode) {
         case VK_CONTROL:
@@ -522,19 +521,18 @@ NativeKey::NativeKey(nsWindow* aWindow,
     case WM_CHAR:
     case WM_UNICHAR:
     case WM_SYSCHAR:
       // We cannot compute the virtual key code from WM_CHAR message on WinXP
       // if it's caused by an extended key.
       if (!canComputeVirtualKeyCodeFromScanCode) {
         break;
       }
-      mVirtualKeyCode = mOriginalVirtualKeyCode = static_cast<uint8_t>(
-        ::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(),
-                          MAPVK_VSC_TO_VK_EX, keyboardLayout->GetLayout()));
+      mVirtualKeyCode = mOriginalVirtualKeyCode =
+        ComputeVirtualKeyCodeFromScanCodeEx();
       break;
     default:
       MOZ_NOT_REACHED("Unsupported message");
       break;
   }
 
   if (!mVirtualKeyCode) {
     mVirtualKeyCode = mOriginalVirtualKeyCode;
@@ -622,16 +620,44 @@ NativeKey::GetKeyLocation() const
     case VK_MENU:
       NS_WARNING("Failed to decide the key location?");
 
     default:
       return nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
   }
 }
 
+uint8_t
+NativeKey::ComputeVirtualKeyCodeFromScanCode() const
+{
+  return static_cast<uint8_t>(
+           ::MapVirtualKeyEx(mScanCode, MAPVK_VSC_TO_VK, mKeyboardLayout));
+}
+
+uint8_t
+NativeKey::ComputeVirtualKeyCodeFromScanCodeEx() const
+{
+  bool VistaOrLater =
+    (WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION);
+  // NOTE: WinXP doesn't support mapping scan code to virtual keycode of
+  //       extended keys.
+  NS_ENSURE_TRUE(!mIsExtended || VistaOrLater, 0);
+  return static_cast<uint8_t>(
+           ::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(), MAPVK_VSC_TO_VK_EX,
+                             mKeyboardLayout));
+}
+
+PRUnichar
+NativeKey::ComputeUnicharFromScanCode() const
+{
+  return static_cast<PRUnichar>(
+           ::MapVirtualKeyEx(ComputeVirtualKeyCodeFromScanCode(),
+                             MAPVK_VK_TO_CHAR, mKeyboardLayout));
+}
+
 /*****************************************************************************
  * mozilla::widget::KeyboardLayout
  *****************************************************************************/
 
 KeyboardLayout* KeyboardLayout::sInstance = nullptr;
 
 // static
 KeyboardLayout*
--- a/widget/windows/KeyboardLayout.h
+++ b/widget/windows/KeyboardLayout.h
@@ -294,17 +294,33 @@ public:
   bool IsKeyDownMessage() const
   {
     return (mMessage == WM_KEYDOWN || mMessage == WM_SYSKEYDOWN);
   }
   WORD GetScanCode() const { return mScanCode; }
   uint8_t GetVirtualKeyCode() const { return mVirtualKeyCode; }
   uint8_t GetOriginalVirtualKeyCode() const { return mOriginalVirtualKeyCode; }
 
+  /**
+   * Wraps MapVirtualKeyEx() with MAPVK_VSC_TO_VK.
+   */
+  uint8_t ComputeVirtualKeyCodeFromScanCode() const;
+
+  /**
+   * Wraps MapVirtualKeyEx() with MAPVK_VSC_TO_VK_EX.
+   */
+  uint8_t ComputeVirtualKeyCodeFromScanCodeEx() const;
+
+  /**
+   * Wraps MapVirtualKeyEx() with MAPVK_VSC_TO_VK and MAPVK_VK_TO_CHAR.
+   */
+  PRUnichar ComputeUnicharFromScanCode() const;
+
 private:
+  HKL mKeyboardLayout;
   uint32_t mDOMKeyCode;
   KeyNameIndex mKeyNameIndex;
 
   // The message which the instance was initialized with.
   UINT mMessage;
 
   // mVirtualKeyCode distinguishes left key or right key of modifier key.
   uint8_t mVirtualKeyCode;
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6887,24 +6887,20 @@ LRESULT nsWindow::OnChar(const MSG &aMsg
       uniChar = charCode;
     }
   }
 
   // Keep the characters unshifted for shortcuts and accesskeys and make sure
   // that numbers are always passed as such (among others: bugs 50255 and 351310)
   if (uniChar && (modKeyState.IsControl() || modKeyState.IsAlt())) {
     KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
-    UINT virtualKeyCode =
-      ::MapVirtualKeyEx(aNativeKey.GetScanCode(),
-                        MAPVK_VSC_TO_VK, keyboardLayout->GetLayout());
+    UINT virtualKeyCode = aNativeKey.ComputeVirtualKeyCodeFromScanCode();
     UINT unshiftedCharCode =
       virtualKeyCode >= '0' && virtualKeyCode <= '9' ? virtualKeyCode :
-        modKeyState.IsShift() ?
-          ::MapVirtualKeyEx(virtualKeyCode, MAPVK_VK_TO_CHAR,
-                            keyboardLayout->GetLayout()) : 0;
+        modKeyState.IsShift() ? aNativeKey.ComputeUnicharFromScanCode() : 0;
     // ignore diacritics (top bit set) and key mapping errors (char code 0)
     if ((INT)unshiftedCharCode > 0)
       uniChar = unshiftedCharCode;
   }
 
   // Fix for bug 285161 (and 295095) which was caused by the initial fix for bug 178110.
   // When pressing (alt|ctrl)+char, the char must be lowercase unless shift is
   // pressed too.