Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp70
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h9
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