diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 70 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.h | 9 |
2 files changed, 73 insertions, 6 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index da333ce4f08..fb419aef526 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -146,7 +146,6 @@ GHOST_SystemWin32::GHOST_SystemWin32() // Check if current keyboard layout uses AltGr this->keyboardAltGr(); - // Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32. OleInitialize(0); } @@ -334,6 +333,11 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons& buttons) const GHOST_TSuccess GHOST_SystemWin32::init() { GHOST_TSuccess success = GHOST_System::init(); + + for(int i = 0; i < 255; i++) { + m_prevKeyStatus[i] = false; + m_curKeyStatus[i] = false; + } /* Disable scaling on high DPI displays on Vista */ HMODULE user32 = ::LoadLibraryA("user32.dll"); @@ -375,25 +379,34 @@ GHOST_TSuccess GHOST_SystemWin32::init() if (::RegisterClass(&wc) == 0) { success = GHOST_kFailure; } + + // Add low-level keyboard hook for our process. + m_llKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, s_llKeyboardProc, wc.hInstance, 0); } + return success; } GHOST_TSuccess GHOST_SystemWin32::exit() { + // remove our low-level keyboard hook. + UnhookWindowsHookEx(m_llKeyboardHook); + return GHOST_System::exit(); } GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const { + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); bool isExtended = (lParam&(1<<24))?true:false; GHOST_TKey key; GHOST_ModifierKeys oldModifiers, newModifiers; - ((GHOST_SystemWin32*)getSystem())->retrieveModifierKeys(oldModifiers); - ((GHOST_SystemWin32*)getSystem())->getModifierKeys(newModifiers); + system->retrieveModifierKeys(oldModifiers); + system->getModifierKeys(newModifiers); + if ((wParam >= '0') && (wParam <= '9')) { // VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) @@ -463,7 +476,12 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, L if(lchanged) { key = GHOST_kKeyLeftShift; } else { - key = GHOST_kKeyRightShift; + bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightShift) != newModifiers.get(GHOST_kModifierKeyRightShift); + if(rchanged) { + key = GHOST_kKeyRightShift; + } else { + key = GHOST_kKeyUnknown; + } } } break; @@ -473,7 +491,12 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, L if(lchanged) { key = GHOST_kKeyLeftControl; } else { - key = GHOST_kKeyRightControl; + bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightControl) != newModifiers.get(GHOST_kModifierKeyRightControl); + if(rchanged) { + key = GHOST_kKeyRightControl; + } else { + key = GHOST_kKeyUnknown; + } } } break; @@ -493,7 +516,12 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, L if(lchanged) { key = GHOST_kKeyLeftAlt; } else { - key = GHOST_kKeyRightAlt; + bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightAlt) != newModifiers.get(GHOST_kModifierKeyRightAlt); + if(rchanged) { + key = GHOST_kKeyRightAlt; + } else { + key = GHOST_kKeyUnknown; + } } } break; @@ -635,6 +663,36 @@ void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO * minmax) minmax->ptMinTrackSize.y=240; } +/* Note that this function gets *all* key events from the entire system (all + * threads running in this desktop session. So when getting event here, don't assume + * it's for Blender. Thus we only do status bookkeeping, so we can check + * in s_wndProc and processKeyEvent what the real keyboard status is. + * This is needed for proper handling of shift+numpad keys for instance. + */ +LRESULT CALLBACK GHOST_SystemWin32::s_llKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem()); + KBDLLHOOKSTRUCT &keyb = *(PKBDLLHOOKSTRUCT)(lParam); + system->m_prevKeyStatus[keyb.vkCode] = system->m_curKeyStatus[keyb.vkCode]; + if(keyb.flags) { + if((keyb.flags & LLKHF_EXTENDED) == LLKHF_EXTENDED) { + } + if((keyb.flags & LLKHF_ALTDOWN) == LLKHF_ALTDOWN) { + } + if((keyb.flags & LLKHF_UP) == LLKHF_UP) { + system->m_curKeyStatus[keyb.vkCode] = false; + } else { + system->m_curKeyStatus[keyb.vkCode] = true; + } + if((keyb.flags & LLKHF_INJECTED)== LLKHF_INJECTED) { + } + } + else { + system->m_curKeyStatus[keyb.vkCode] = true; + } + + return CallNextHookEx(system->m_llKeyboardHook, nCode, wParam, lParam); +} LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index 3cd1deefda0..ab2f34cc27a 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -320,6 +320,11 @@ protected: * Windows call back routine for our window class. */ static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + + /** + * Low-level inspection of keyboard events + */ + static LRESULT CALLBACK s_llKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam); /** The current state of the modifier keys. */ GHOST_ModifierKeys m_modifierKeys; @@ -331,6 +336,10 @@ protected: __int64 m_start; /** AltGr on current keyboard layout. */ bool m_hasAltGr; + /** holding hook handle for low-level keyboard handling */ + HHOOK m_llKeyboardHook; + bool m_prevKeyStatus[255]; /* VK_* codes 0x01-0xFF, with 0xFF reserved */ + bool m_curKeyStatus[255]; /* VK_* codes 0x01-0xFF, with 0xFF reserved */ }; inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const |