Bug 757688 part.4 Remove GetShiftState() and move SetShiftState() to VirtualKey r=jimm
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 15 Jun 2012 18:52:50 +0900
changeset 99533 5d7af55c4536cc965a39a1de8f4dd8f0cb192839
parent 99532 3de03e1fb9ddf4c5af84d5ac33f2bdf1843269dd
child 99534 fd9de8d2e181c3ff95b756ee9967d5e7808eb664
push idunknown
push userunknown
push dateunknown
reviewersjimm
bugs757688
milestone16.0a1
Bug 757688 part.4 Remove GetShiftState() and move SetShiftState() to VirtualKey r=jimm
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
widget/windows/nsWindow.cpp
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -275,16 +275,54 @@ VirtualKey::GetNativeUniChars(ShiftState
        index < len && mShiftStates[aShiftState].Normal.Chars[index]; index++) {
     if (aUniChars) {
       aUniChars[index] = mShiftStates[aShiftState].Normal.Chars[index];
     }
   }
   return index;
 }
 
+// static
+void
+VirtualKey::FillKbdState(PBYTE aKbdState,
+                         const ShiftState aShiftState)
+{
+  NS_ASSERTION(aShiftState < 16, "aShiftState out of range");
+
+  if (aShiftState & STATE_SHIFT) {
+    aKbdState[VK_SHIFT] |= 0x80;
+  } else {
+    aKbdState[VK_SHIFT]  &= ~0x80;
+    aKbdState[VK_LSHIFT] &= ~0x80;
+    aKbdState[VK_RSHIFT] &= ~0x80;
+  }
+
+  if (aShiftState & STATE_CONTROL) {
+    aKbdState[VK_CONTROL] |= 0x80;
+  } else {
+    aKbdState[VK_CONTROL]  &= ~0x80;
+    aKbdState[VK_LCONTROL] &= ~0x80;
+    aKbdState[VK_RCONTROL] &= ~0x80;
+  }
+
+  if (aShiftState & STATE_ALT) {
+    aKbdState[VK_MENU] |= 0x80;
+  } else {
+    aKbdState[VK_MENU]  &= ~0x80;
+    aKbdState[VK_LMENU] &= ~0x80;
+    aKbdState[VK_RMENU] &= ~0x80;
+  }
+
+  if (aShiftState & STATE_CAPSLOCK) {
+    aKbdState[VK_CAPITAL] |= 0x01;
+  } else {
+    aKbdState[VK_CAPITAL] &= ~0x01;
+  }
+}
+
 /*****************************************************************************
  * mozilla::widget::NativeKey
  *****************************************************************************/
 
 NativeKey::NativeKey(const KeyboardLayout& aKeyboardLayout,
                      nsWindow* aWindow,
                      const MSG& aKeyOrCharMessage) :
   mDOMKeyCode(0), mVirtualKeyCode(0), mOriginalVirtualKeyCode(0)
@@ -461,33 +499,30 @@ static void FillModifiers(Modifiers* aDe
                           PRUint32 aCount)
 {
   for (PRUint32 i = 0; i < aCount; i++) {
     aDest[i] = aSrc;
   }
 }
 
 void
-KeyboardLayout::OnKeyDown(PRUint8 aVirtualKey)
+KeyboardLayout::OnKeyDown(PRUint8 aVirtualKey,
+                          const ModifierKeyState& aModKeyState)
 {
   PRInt32 virtualKeyIndex = GetKeyIndex(aVirtualKey);
 
   if (virtualKeyIndex < 0) {
     // Does not produce any printable characters, but still preserves the
     // dead-key state.
     mNumOfChars = 0;
     return;
   }
 
-  BYTE kbdState[256];
-  if (!::GetKeyboardState(kbdState)) {
-    return;
-  }
-
-  PRUint8 shiftState = GetShiftState(kbdState);
+  PRUint8 shiftState =
+    VirtualKey::ModifiersToShiftState(aModKeyState.GetModifiers());
 
   if (mVirtualKeys[virtualKeyIndex].IsDeadKey(shiftState)) {
     if (mActiveDeadKey < 0) {
       // Dead-key state activated. No characters generated.
       mActiveDeadKey = aVirtualKey;
       mDeadKeyShiftState = shiftState;
       mNumOfChars = 0;
       return;
@@ -601,17 +636,17 @@ KeyboardLayout::LoadLayout(HKL aLayout)
   ReleaseDeadKeyTables();
 
   ::GetKeyboardState(originalKbdState);
 
   // For each shift state gather all printable characters that are produced
   // for normal case when no any dead-key is active.
 
   for (VirtualKey::ShiftState shiftState = 0; shiftState < 16; shiftState++) {
-    SetShiftState(kbdState, shiftState);
+    VirtualKey::FillKbdState(kbdState, shiftState);
     for (PRUint32 virtualKey = 0; virtualKey < 256; virtualKey++) {
       PRInt32 vki = GetKeyIndex(virtualKey);
       if (vki < 0) {
         continue;
       }
       NS_ASSERTION(PRUint32(vki) < ArrayLength(mVirtualKeys), "invalid index");
       PRUnichar uniChars[5];
       PRInt32 ret =
@@ -639,17 +674,17 @@ KeyboardLayout::LoadLayout(HKL aLayout)
 
   // Now process each dead-key to find all its base characters and resulting
   // composite characters.
   for (VirtualKey::ShiftState shiftState = 0; shiftState < 16; shiftState++) {
     if (!(shiftStatesWithDeadKeys & (1 << shiftState))) {
       continue;
     }
 
-    SetShiftState(kbdState, shiftState);
+    VirtualKey::FillKbdState(kbdState, shiftState);
 
     for (PRUint32 virtualKey = 0; virtualKey < 256; virtualKey++) {
       PRInt32 vki = GetKeyIndex(virtualKey);
       if (vki >= 0 && mVirtualKeys[vki].IsDeadKey(shiftState)) {
         DeadKeyEntry deadKeyArray[256];
         PRInt32 n = GetDeadKeyCombinations(virtualKey, kbdState,
                                            shiftStatesWithBaseChars,
                                            deadKeyArray,
@@ -662,66 +697,16 @@ KeyboardLayout::LoadLayout(HKL aLayout)
         mVirtualKeys[vki].AttachDeadKeyTable(shiftState, dkt);
       }
     }
   }
 
   ::SetKeyboardState(originalKbdState);
 }
 
-
-// static
-VirtualKey::ShiftState
-KeyboardLayout::GetShiftState(const PBYTE aKbdState)
-{
-  bool isShift = (aKbdState[VK_SHIFT] & 0x80) != 0;
-  bool isCtrl  = (aKbdState[VK_CONTROL] & 0x80) != 0;
-  bool isAlt   = (aKbdState[VK_MENU] & 0x80) != 0;
-  bool isCaps  = (aKbdState[VK_CAPITAL] & 0x01) != 0;
-
-  return ((isCaps << 3) | (isAlt << 2) | (isCtrl << 1) | isShift);
-}
-
-void
-KeyboardLayout::SetShiftState(PBYTE aKbdState,
-                              VirtualKey::ShiftState aShiftState)
-{
-  NS_ASSERTION(aShiftState < 16, "aShiftState out of range");
-
-  if (aShiftState & VirtualKey::STATE_SHIFT) {
-    aKbdState[VK_SHIFT] |= 0x80;
-  } else {
-    aKbdState[VK_SHIFT]  &= ~0x80;
-    aKbdState[VK_LSHIFT] &= ~0x80;
-    aKbdState[VK_RSHIFT] &= ~0x80;
-  }
-
-  if (aShiftState & VirtualKey::STATE_CONTROL) {
-    aKbdState[VK_CONTROL] |= 0x80;
-  } else {
-    aKbdState[VK_CONTROL]  &= ~0x80;
-    aKbdState[VK_LCONTROL] &= ~0x80;
-    aKbdState[VK_RCONTROL] &= ~0x80;
-  }
-
-  if (aShiftState & VirtualKey::STATE_ALT) {
-    aKbdState[VK_MENU] |= 0x80;
-  } else {
-    aKbdState[VK_MENU]  &= ~0x80;
-    aKbdState[VK_LMENU] &= ~0x80;
-    aKbdState[VK_RMENU] &= ~0x80;
-  }
-
-  if (aShiftState & VirtualKey::STATE_CAPSLOCK) {
-    aKbdState[VK_CAPITAL] |= 0x01;
-  } else {
-    aKbdState[VK_CAPITAL] &= ~0x01;
-  }
-}
-
 inline PRInt32
 KeyboardLayout::GetKeyIndex(PRUint8 aVirtualKey)
 {
 // Currently these 54 (NS_NUM_OF_KEYS) virtual keys are assumed
 // to produce visible representation:
 // 0x20 - VK_SPACE          ' '
 // 0x30..0x39               '0'..'9'
 // 0x41..0x5A               'A'..'Z'
@@ -839,17 +824,17 @@ KeyboardLayout::DeactivateDeadKeyState()
 {
   if (mActiveDeadKey < 0) {
     return;
   }
 
   BYTE kbdState[256];
   memset(kbdState, 0, sizeof(kbdState));
 
-  SetShiftState(kbdState, mDeadKeyShiftState);
+  VirtualKey::FillKbdState(kbdState, mDeadKeyShiftState);
 
   EnsureDeadKeyActive(false, mActiveDeadKey, kbdState);
   mActiveDeadKey = -1;
 }
 
 bool
 KeyboardLayout::AddDeadKeyEntry(PRUnichar aBaseChar,
                                 PRUnichar aCompositeChar,
@@ -880,17 +865,17 @@ KeyboardLayout::GetDeadKeyCombinations(P
   BYTE kbdState[256];
   memset(kbdState, 0, sizeof(kbdState));
 
   for (PRUint32 shiftState = 0; shiftState < 16; shiftState++) {
     if (!(aShiftStatesWithBaseChars & (1 << shiftState))) {
       continue;
     }
 
-    SetShiftState(kbdState, shiftState);
+    VirtualKey::FillKbdState(kbdState, shiftState);
 
     for (PRUint32 virtualKey = 0; virtualKey < 256; virtualKey++) {
       PRInt32 vki = GetKeyIndex(virtualKey);
       // Dead-key can pair only with such key that produces exactly one base
       // character.
       if (vki >= 0 && mVirtualKeys[vki].GetNativeUniChars(shiftState) == 1) {
         // Ensure dead-key is in active state, when it swallows entered
         // character and waits for the next pressed key.
--- a/widget/windows/KeyboardLayout.h
+++ b/widget/windows/KeyboardLayout.h
@@ -204,16 +204,18 @@ private:
     if (aIsDeadKey) {
       mIsDeadKey |= 1 << aShiftState;
     } else {
       mIsDeadKey &= ~(1 << aShiftState);
     }
   }
 
 public:
+  static void FillKbdState(PBYTE aKbdState, const ShiftState aShiftState);
+
   bool IsDeadKey(ShiftState aShiftState) const
   {
     return (mIsDeadKey & (1 << aShiftState)) != 0;
   }
 
   void AttachDeadKeyTable(ShiftState aShiftState,
                           const DeadKeyTable* aDeadKeyTable)
   {
@@ -280,19 +282,16 @@ class KeyboardLayout
   VirtualKey mVirtualKeys[NS_NUM_OF_KEYS];
   DeadKeyTableListEntry* mDeadKeyTableListHead;
   PRInt32 mActiveDeadKey;                 // -1 = no active dead-key
   VirtualKey::ShiftState mDeadKeyShiftState;
   PRUnichar mChars[5];                    // Dead-key + up to 4 characters
   Modifiers mModifiersOfChars[5];
   PRUint8 mNumOfChars;
 
-  static VirtualKey::ShiftState GetShiftState(const PBYTE aKbdState);
-  static void SetShiftState(PBYTE aKbdState,
-                            VirtualKey::ShiftState aShiftState);
   static inline PRInt32 GetKeyIndex(PRUint8 aVirtualKey);
   static int CompareDeadKeyEntries(const void* aArg1, const void* aArg2,
                                    void* aData);
   static bool AddDeadKeyEntry(PRUnichar aBaseChar, PRUnichar aCompositeChar,
                                 DeadKeyEntry* aDeadKeyArray, PRUint32 aEntries);
   bool EnsureDeadKeyActive(bool aIsActive, PRUint8 aDeadKey,
                              const PBYTE aDeadKeyKbdState);
   PRUint32 GetDeadKeyCombinations(PRUint8 aDeadKey,
@@ -313,18 +312,26 @@ public:
   static bool IsNumpadKey(PRUint8 aVirtualKey);
 
   /**
    * IsDeadKey() returns true if aVirtualKey is a dead key with aModKeyState.
    */
   bool IsDeadKey(PRUint8 aVirtualKey,
                  const ModifierKeyState& aModKeyState) const;
 
+  /**
+   * OnKeyDown() must be called when actually widget receives WM_KEYDOWN
+   * message.  This method is stateful.  This saves current dead key state
+   * and computes current inputted character(s).
+   */
+  void OnKeyDown(PRUint8 aVirtualKey,
+                 const ModifierKeyState& aModKeyState);
+
   void LoadLayout(HKL aLayout);
-  void OnKeyDown(PRUint8 aVirtualKey);
+
   PRUint32 GetUniChars(PRUnichar* aUniChars, Modifiers* aModifiersOfUniChars,
                        PRUint32 aMaxChars) const;
   PRUint32 GetUniCharsWithShiftState(PRUint8 aVirtualKey, Modifiers aModifiers,
                                      PRUnichar* aUniChars,
                                      PRUint32 aMaxChars) const;
   PRUint32 ConvertNativeKeyCodeToDOMKeyCode(UINT aNativeKeyCode) const;
 
   HKL GetLayout() const { return mKeyboardLayout; }
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -6225,17 +6225,17 @@ bool nsWindow::IsRedirectedKeyDownMessag
  */
 LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
                             const ModifierKeyState &aModKeyState,
                             bool *aEventDispatched,
                             nsFakeCharMessage* aFakeCharMessage)
 {
   NativeKey nativeKey(gKbdLayout, this, aMsg);
   UINT virtualKeyCode = nativeKey.GetOriginalVirtualKeyCode();
-  gKbdLayout.OnKeyDown(virtualKeyCode);
+  gKbdLayout.OnKeyDown(virtualKeyCode, aModKeyState);
 
   // Use only DOMKeyCode for XP processing.
   // Use virtualKeyCode for gKbdLayout and native processing.
   PRUint32 DOMKeyCode = nativeKey.GetDOMKeyCode();
 
 #ifdef DEBUG
   //PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("In OnKeyDown virt: %d\n", DOMKeyCode));
 #endif