diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp index 77e970d14357..cd41803b0ef1 100644 --- a/widget/windows/KeyboardLayout.cpp +++ b/widget/windows/KeyboardLayout.cpp @@ -388,6 +388,7 @@ NativeKey::NativeKey(nsWindow* aWindow, 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 @@ -485,9 +486,7 @@ NativeKey::NativeKey(nsWindow* aWindow, "mVirtualKeyCode has been computed already"); // Otherwise, compute the virtual keycode with MapVirtualKeyEx(). - mVirtualKeyCode = static_cast( - ::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 @@ -527,9 +526,8 @@ NativeKey::NativeKey(nsWindow* aWindow, if (!canComputeVirtualKeyCodeFromScanCode) { break; } - mVirtualKeyCode = mOriginalVirtualKeyCode = static_cast( - ::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(), - MAPVK_VSC_TO_VK_EX, keyboardLayout->GetLayout())); + mVirtualKeyCode = mOriginalVirtualKeyCode = + ComputeVirtualKeyCodeFromScanCodeEx(); break; default: MOZ_NOT_REACHED("Unsupported message"); @@ -627,6 +625,34 @@ NativeKey::GetKeyLocation() const } } +uint8_t +NativeKey::ComputeVirtualKeyCodeFromScanCode() const +{ + return static_cast( + ::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( + ::MapVirtualKeyEx(GetScanCodeWithExtendedFlag(), MAPVK_VSC_TO_VK_EX, + mKeyboardLayout)); +} + +PRUnichar +NativeKey::ComputeUnicharFromScanCode() const +{ + return static_cast( + ::MapVirtualKeyEx(ComputeVirtualKeyCodeFromScanCode(), + MAPVK_VK_TO_CHAR, mKeyboardLayout)); +} + /***************************************************************************** * mozilla::widget::KeyboardLayout *****************************************************************************/ diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h index fc641d364659..850485b0ddcd 100644 --- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -299,7 +299,23 @@ public: 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; diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index fb6703a72506..b1b3d74540e0 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -6892,14 +6892,10 @@ LRESULT nsWindow::OnChar(const MSG &aMsg, // 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;