Simplify GHOST modifier key handling on Windows.
authorNathan Letwory <nathan@letworyinteractive.com>
Fri, 15 Oct 2010 14:52:47 +0000 (14:52 +0000)
committerNathan Letwory <nathan@letworyinteractive.com>
Fri, 15 Oct 2010 14:52:47 +0000 (14:52 +0000)
intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_SystemWin32.h

index 6255995319564b56b572e420434f17a7a07551e0..d63ac70083156a661b56d4275416e97efd1aaac4 100644 (file)
 
 
 GHOST_SystemWin32::GHOST_SystemWin32()
-: m_hasPerformanceCounter(false), m_freq(0), m_start(0),
-  m_separateLeftRight(false),
-  m_separateLeftRightInitialized(false)
+: m_hasPerformanceCounter(false), m_freq(0), m_start(0)
 {
        m_displayManager = new GHOST_DisplayManagerWin32 ();
        GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
@@ -287,43 +285,24 @@ GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
 
 GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys& keys) const
 {
-       if (m_separateLeftRight && m_separateLeftRightInitialized) {
-               bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
-               keys.set(GHOST_kModifierKeyLeftShift, down);
-               down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
-               keys.set(GHOST_kModifierKeyRightShift, down);
-               down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
-               keys.set(GHOST_kModifierKeyLeftAlt, down);
-               down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
-               keys.set(GHOST_kModifierKeyRightAlt, down);
-               down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
-               keys.set(GHOST_kModifierKeyLeftControl, down);
-               down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
-               keys.set(GHOST_kModifierKeyRightControl, down);
-               bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
-               bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
-               if(lwindown || rwindown)
-                       keys.set(GHOST_kModifierKeyOS, true);
-               else
-                       keys.set(GHOST_kModifierKeyOS, false);
-       }
-       else {
-               bool down = HIBYTE(::GetKeyState(VK_SHIFT)) != 0;
-               keys.set(GHOST_kModifierKeyLeftShift, down);
-               keys.set(GHOST_kModifierKeyRightShift, down);
-               down = HIBYTE(::GetKeyState(VK_MENU)) != 0;
-               keys.set(GHOST_kModifierKeyLeftAlt, down);
-               keys.set(GHOST_kModifierKeyRightAlt, down);
-               down = HIBYTE(::GetKeyState(VK_CONTROL)) != 0;
-               keys.set(GHOST_kModifierKeyLeftControl, down);
-               keys.set(GHOST_kModifierKeyRightControl, down);
-               bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
-               bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
-               if(lwindown || rwindown)
-                       keys.set(GHOST_kModifierKeyOS, true);
-               else
-                       keys.set(GHOST_kModifierKeyOS, false);
-       }
+       bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
+       keys.set(GHOST_kModifierKeyLeftShift, down);
+       down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
+       keys.set(GHOST_kModifierKeyRightShift, down);
+       down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
+       keys.set(GHOST_kModifierKeyLeftAlt, down);
+       down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
+       keys.set(GHOST_kModifierKeyRightAlt, down);
+       down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
+       keys.set(GHOST_kModifierKeyLeftControl, down);
+       down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
+       keys.set(GHOST_kModifierKeyRightControl, down);
+       bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
+       bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
+       if(lwindown || rwindown)
+               keys.set(GHOST_kModifierKeyOS, true);
+       else
+               keys.set(GHOST_kModifierKeyOS, false);
        return GHOST_kSuccess;
 }
 
@@ -405,6 +384,10 @@ GHOST_TSuccess GHOST_SystemWin32::exit()
 GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
 {
        GHOST_TKey key;
+       GHOST_ModifierKeys oldModifiers, newModifiers;
+       ((GHOST_SystemWin32*)getSystem())->retrieveModifierKeys(oldModifiers);
+       ((GHOST_SystemWin32*)getSystem())->getModifierKeys(newModifiers);
+       
        bool isExtended = (lParam&(1<<24))?true:false;
 
        if ((wParam >= '0') && (wParam <= '9')) {
@@ -469,15 +452,43 @@ GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
                case VK_QUOTE:                  key = GHOST_kKeyQuote;                  break;
                case VK_GR_LESS:                key = GHOST_kKeyGrLess;                 break;
 
-               // Process these keys separately because we need to distinguish right from left modifier keys
                case VK_SHIFT:
+                       {
+                               bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftShift) != newModifiers.get(GHOST_kModifierKeyLeftShift);
+                               if(lchanged) {
+                                       key = GHOST_kKeyLeftShift;
+                               } else {
+                                       key = GHOST_kKeyRightShift;
+                               }
+                       }
+                       break;
                case VK_CONTROL:
+                       {
+                               bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftControl) != newModifiers.get(GHOST_kModifierKeyLeftControl);
+                               if(lchanged) {
+                                       key = GHOST_kKeyLeftControl;
+                               } else {
+                                       key = GHOST_kKeyRightControl;
+                               }
+                       }
+                       break;
                case VK_MENU:
-
-               // Ignore these keys
-               case VK_NUMLOCK:
-               case VK_SCROLL:
-               case VK_CAPITAL:
+                       {
+                               bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftAlt) != newModifiers.get(GHOST_kModifierKeyLeftAlt);
+                               if(lchanged) {
+                                       key = GHOST_kKeyLeftAlt;
+                               } else {
+                                       key = GHOST_kKeyRightAlt;
+                               }
+                       }
+                       break;
+               case VK_LWIN:
+               case VK_RWIN:
+                       key = GHOST_kKeyOS;
+                       break;
+               case VK_NUMLOCK: key = GHOST_kKeyNumLock; break;
+               case VK_SCROLL: key = GHOST_kKeyScrollLock; break;
+               case VK_CAPITAL: key = GHOST_kKeyCapsLock; break;
                default:
                        key = GHOST_kKeyUnknown;
                        break;
@@ -486,38 +497,6 @@ GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
        return key;
 }
 
-
-void GHOST_SystemWin32::processModifierKeys(GHOST_IWindow *window)
-{
-       GHOST_ModifierKeys oldModifiers, newModifiers;
-       // Retrieve old state of the modifier keys
-       ((GHOST_SystemWin32*)getSystem())->retrieveModifierKeys(oldModifiers);
-       // Retrieve current state of the modifier keys
-       ((GHOST_SystemWin32*)getSystem())->getModifierKeys(newModifiers);
-
-       // Compare the old and the new
-       if (!newModifiers.equals(oldModifiers)) {
-               // Create events for the masks that changed
-               for (int i = 0; i < GHOST_kModifierKeyNumMasks; i++) {
-                       if (newModifiers.get((GHOST_TModifierKeyMask)i) != oldModifiers.get((GHOST_TModifierKeyMask)i)) {
-                               // Convert the mask to a key code
-                               GHOST_TKey key = GHOST_ModifierKeys::getModifierKeyCode((GHOST_TModifierKeyMask)i);
-                               bool keyDown = newModifiers.get((GHOST_TModifierKeyMask)i);
-                               GHOST_EventKey* event;
-                               if (key != GHOST_kKeyUnknown) {
-                                       // Create an event
-                                       event = new GHOST_EventKey(getSystem()->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key);
-                                       pushEvent(event);
-                               }
-                       }
-               }
-       }
-
-       // Store new modifier keys state
-       ((GHOST_SystemWin32*)getSystem())->storeModifierKeys(newModifiers);
-}
-
-
 GHOST_EventButton* GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask mask)
 {
        return new GHOST_EventButton (getSystem()->getMilliSeconds(), type, window, mask);
@@ -655,85 +634,22 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                // Keyboard events, processed
                                ////////////////////////////////////////////////////////////////////////
                                case WM_KEYDOWN:
-                                       /* The WM_KEYDOWN message is posted to the window with the keyboard focus when a 
-                                        * nonsystem key is pressed. A nonsystem key is a key that is pressed when the alt
-                                        * key is not pressed. 
-                                        */
                                case WM_SYSKEYDOWN:
-                                       /* The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when 
-                                        * the user presses the F10 key (which activates the menu bar) or holds down the 
-                                        * alt key and then presses another key. It also occurs when no window currently 
-                                        * has the keyboard focus; in this case, the WM_SYSKEYDOWN message is sent to the 
-                                        * active window. The window that receives the message can distinguish between these 
-                                        * two contexts by checking the context code in the lKeyData parameter. 
-                                        */
-                                       switch (wParam) {
-                                               case VK_SHIFT:
-                                               case VK_CONTROL:
-                                               case VK_MENU:
-                                               case VK_LWIN:
-                                               case VK_RWIN:
-                                                       if (!system->m_separateLeftRightInitialized) {
-                                                               // Check whether this system supports separate left and right keys
-                                                               switch (wParam) {
-                                                                       case VK_SHIFT:
-                                                                               system->m_separateLeftRight = 
-                                                                                       (HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
-                                                                                       (HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
-                                                                                       true : false;
-                                                                               break;
-                                                                       case VK_CONTROL:
-                                                                               system->m_separateLeftRight = 
-                                                                                       (HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
-                                                                                       (HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
-                                                                                       true : false;
-                                                                               break;
-                                                                       case VK_MENU:
-                                                                               system->m_separateLeftRight = 
-                                                                                       (HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
-                                                                                       (HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
-                                                                                       true : false;
-                                                                               break;
-                                                                       case VK_LWIN:
-                                                                       case VK_RWIN:
-                                                                               system->m_separateLeftRight = true;
-                                                                               break;
-                                                               }
-                                                               system->m_separateLeftRightInitialized = true;
-                                                       }
-                                                       system->processModifierKeys(window);
-                                                       // Bypass call to DefWindowProc
-                                                       return 0;
-                                               default:
-                                                       event = processKeyEvent(window, true, wParam, lParam);
-                                                       if (!event) {
-                                                               GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
-                                                               GHOST_PRINT(msg)
-                                                               GHOST_PRINT(" key ignored\n")
-                                                       }
-                                                       break;
-                                               }
+                                       event = processKeyEvent(window, true, wParam, lParam);
+                                       if (!event) {
+                                               GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
+                                               GHOST_PRINT(msg)
+                                               GHOST_PRINT(" key ignored\n")
+                                       }
                                        break;
 
                                case WM_KEYUP:
                                case WM_SYSKEYUP:
-                                       switch (wParam) {
-                                               case VK_SHIFT:
-                                               case VK_CONTROL:
-                                               case VK_MENU:
-                                               case VK_LWIN:
-                                               case VK_RWIN:
-                                                       system->processModifierKeys(window);
-                                                       // Bypass call to DefWindowProc
-                                                       return 0;
-                                               default:
-                                                       event = processKeyEvent(window, false, wParam, lParam);
-                                                       if (!event) {
-                                                               GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
-                                                               GHOST_PRINT(msg)
-                                                               GHOST_PRINT(" key ignored\n")
-                                                       }
-                                                       break;
+                                       event = processKeyEvent(window, false, wParam, lParam);
+                                       if (!event) {
+                                               GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
+                                               GHOST_PRINT(msg)
+                                               GHOST_PRINT(" key ignored\n")
                                        }
                                        break;
 
index 35b8debf6b4ca923652d78ba9829c6702da0f0b8..03f5349a606cdc95d37687050454cdecceaa82d1 100644 (file)
@@ -248,7 +248,7 @@ protected:
         * events generated for both keys.
         * @param window        The window receiving the event (the active window).
         */
-       void processModifierKeys(GHOST_IWindow *window);
+       GHOST_EventKey* processModifierKeys(GHOST_IWindow *window);
 
        /**
         * Creates mouse button event.
@@ -324,11 +324,6 @@ protected:
        __int64 m_freq;
        /** High frequency timer variable. */
        __int64 m_start;
-       /** Stores the capability of this system to distinguish left and right modifier keys. */
-       bool m_separateLeftRight;
-       /** Stores the initialization state of the member m_leftRightDistinguishable. */
-       bool m_separateLeftRightInitialized;
-       
 };
 
 inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const