[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35437] trunk/blender: Apply [#26364] New Windows keyboard handling
Nathan Letwory
nathan at letworyinteractive.com
Wed Mar 9 23:10:52 CET 2011
Revision: 35437
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35437
Author: jesterking
Date: 2011-03-09 22:10:51 +0000 (Wed, 09 Mar 2011)
Log Message:
-----------
Apply [#26364] New Windows keyboard handling
Submitted by Alexander Kuznetsov
Fixes [#25279] Shift-Numpad Combinations fail to align view to selected
and addresses [#26328] Blender uses global keyboard message hook which hurts system responsiveness on Windows
A whole new way of handling keyboard input improves greatly both code readability and event handling. Thanks for the great patch, Alexander!
Modified Paths:
--------------
trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
trunk/blender/intern/ghost/intern/GHOST_SystemWin32.h
trunk/blender/source/blender/editors/space_view3d/view3d_ops.c
Modified: trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp 2011-03-09 21:19:15 UTC (rev 35436)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp 2011-03-09 22:10:51 UTC (rev 35437)
@@ -56,7 +56,7 @@
#ifdef WIN32
#ifndef GWL_USERDATA
#define GWL_USERDATA GWLP_USERDATA
-#define GWL_WNDPROC GWLP_WNDPROC
+#define GWL_WNDPROC GWLP_WNDPROC
#endif
#endif
@@ -154,14 +154,26 @@
#define VK_MEDIA_PLAY_PAUSE 0xB3
#endif // VK_MEDIA_PLAY_PAUSE
+/*
+ Initiates WM_INPUT messages from keyboard
+ That way GHOST can retrieve true keys
+*/
+GHOST_TInt32 GHOST_SystemWin32::initKeyboardRawInput(void)
+{
+ RAWINPUTDEVICE device = {0};
+ device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/
+ device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
+ return RegisterRawInputDevices(&device, 1, sizeof(device));
+};
+
GHOST_SystemWin32::GHOST_SystemWin32()
: 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");
m_displayManager->initialize();
-
+
// Check if current keyboard layout uses AltGr and save keylayout ID for
// specialized handling if keys like VK_OEM_*. I.e. french keylayout
// generates VK_OEM_8 for their exclamation key (key left of right shift)
@@ -357,20 +369,24 @@
{
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");
+ user32 = ::LoadLibraryA("user32.dll");
typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
(LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
if (SetProcessDPIAware)
SetProcessDPIAware();
- FreeLibrary(user32);
+ #ifdef NEED_RAW_PROC
+ pRegisterRawInputDevices = (LPFNDLLRRID)GetProcAddress(user32, "RegisterRawInputDevices");
+ pGetRawInputData = (LPFNDLLGRID)GetProcAddress(user32, "GetRawInputData");
+ #else
+ FreeLibrary(user32);
+ #endif
+ /* Initiates WM_INPUT messages from keyboard */
+ initKeyboardRawInput();
+
+
// Determine whether this system has a high frequency performance counter. */
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
if (m_hasPerformanceCounter) {
@@ -402,9 +418,6 @@
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;
@@ -413,170 +426,122 @@
GHOST_TSuccess GHOST_SystemWin32::exit()
{
- // remove our low-level keyboard hook.
- UnhookWindowsHookEx(m_llKeyboardHook);
-
+ #ifdef NEED_RAW_PROC
+ FreeLibrary(user32);
+ #endif
+
return GHOST_System::exit();
}
-void GHOST_SystemWin32::triggerKey(GHOST_IWindow *window, bool down, GHOST_TKey key)
+GHOST_TKey GHOST_SystemWin32::hardKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam, int * keyDown, char * vk)
{
- GHOST_Event *extra = new GHOST_EventKey(getSystem()->getMilliSeconds(), down ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, '\0');
- ((GHOST_SystemWin32*)getSystem())->pushEvent(extra);
+ unsigned int size = 0;
+ char * data;
+ GHOST_TKey key = GHOST_kKeyUnknown;
+
+
+ if(!keyDown)
+ return GHOST_kKeyUnknown;
+
+ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, 0, &size, sizeof(RAWINPUTHEADER));
+
+
+ if((data = (char*)malloc(size)) &&
+ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)))
+ {
+ RAWINPUT ri;
+ memcpy(&ri,data,sizeof(ri));
+
+ if (ri.header.dwType == RIM_TYPEKEYBOARD)
+ {
+ *keyDown = !(ri.data.keyboard.Flags & RI_KEY_BREAK);
+ key = this->convertKey(window, ri.data.keyboard.VKey, ri.data.keyboard.MakeCode, (ri.data.keyboard.Flags&(RI_KEY_E1|RI_KEY_E0)));
+ if(vk) *vk = ri.data.keyboard.VKey;
+ };
+
+ };
+ free(data);
+
+ return key;
}
-void GHOST_SystemWin32::handleModifierKeys(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam, GHOST_ModifierKeys &oldModifiers, GHOST_ModifierKeys &newModifiers) const
-{
- switch(wParam) {
- case VK_SHIFT:
- {
- bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftAlt) != newModifiers.get(GHOST_kModifierKeyLeftAlt);
- if(lchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftAlt), GHOST_kKeyLeftAlt);
- } else {
- bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightAlt) != newModifiers.get(GHOST_kModifierKeyRightAlt);
- if (rchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightAlt), GHOST_kKeyRightAlt);
- }
- }
- lchanged = oldModifiers.get(GHOST_kModifierKeyLeftControl) != newModifiers.get(GHOST_kModifierKeyLeftControl);
- if(lchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftControl), GHOST_kKeyLeftControl);
- } else {
- bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightControl) != newModifiers.get(GHOST_kModifierKeyRightControl);
- if (rchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightControl), GHOST_kKeyRightControl);
- }
- }
- }
- break;
- case VK_CONTROL:
- {
- bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftAlt) != newModifiers.get(GHOST_kModifierKeyLeftAlt);
- if(lchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftAlt), GHOST_kKeyLeftAlt);
- } else {
- bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightAlt) != newModifiers.get(GHOST_kModifierKeyRightAlt);
- if (rchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightAlt), GHOST_kKeyRightAlt);
- }
- }
- lchanged = oldModifiers.get(GHOST_kModifierKeyLeftShift) != newModifiers.get(GHOST_kModifierKeyLeftShift);
- if(lchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftShift), GHOST_kKeyLeftShift);
- } else {
- bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightShift) != newModifiers.get(GHOST_kModifierKeyRightShift);
- if (rchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightShift), GHOST_kKeyRightShift);
- }
- }
- }
- break;
- case VK_MENU:
- {
- bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftShift) != newModifiers.get(GHOST_kModifierKeyLeftShift);
- if(lchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftShift), GHOST_kKeyLeftShift);
- } else {
- bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightShift) != newModifiers.get(GHOST_kModifierKeyRightShift);
- if (rchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightShift), GHOST_kKeyRightShift);
- }
- }
- lchanged = oldModifiers.get(GHOST_kModifierKeyLeftControl) != newModifiers.get(GHOST_kModifierKeyLeftControl);
- if(lchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftControl), GHOST_kKeyLeftControl);
- } else {
- bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightControl) != newModifiers.get(GHOST_kModifierKeyRightControl);
- if (rchanged) {
- ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightControl), GHOST_kKeyRightControl);
- }
- }
- }
- break;
- default:
- break;
- }
-}
//! note: this function can be extended to include other exotic cases as they arise.
// This function was added in response to bug [#25715]
-GHOST_TKey GHOST_SystemWin32::processSpecialKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const
+GHOST_TKey GHOST_SystemWin32::processSpecialKey(GHOST_IWindow *window, short vKey, short scanCode) const
{
GHOST_TKey key = GHOST_kKeyUnknown;
switch(PRIMARYLANGID(m_langId)) {
case LANG_FRENCH:
- if(wParam==VK_OEM_8) key = GHOST_kKey1; // on 'normal' shift + 1 to create '!' we also get GHOST_kKey1. ASCII will be '!'.
+ if(vKey==VK_OEM_8) key = GHOST_kKeyF13; // oem key; used purely for shortcuts .
break;
}
return key;
}
-GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const
+GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, short vKey, short scanCode, short extend) const
{
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- bool isExtended = (lParam&(1<<24))?true:false;
-
GHOST_TKey key;
- GHOST_ModifierKeys oldModifiers, newModifiers;
- system->retrieveModifierKeys(oldModifiers);
- system->getModifierKeys(newModifiers);
- //std::cout << wParam << " " << system->m_curKeyStatus[wParam] << " shift pressed: " << system->shiftPressed() << std::endl;
-
- if ((wParam >= '0') && (wParam <= '9')) {
+ if ((vKey >= '0') && (vKey <= '9')) {
// VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39)
- key = (GHOST_TKey)(wParam - '0' + GHOST_kKey0);
+ key = (GHOST_TKey)(vKey - '0' + GHOST_kKey0);
}
- else if ((wParam >= 'A') && (wParam <= 'Z')) {
+ else if ((vKey >= 'A') && (vKey <= 'Z')) {
// VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A)
- key = (GHOST_TKey)(wParam - 'A' + GHOST_kKeyA);
+ key = (GHOST_TKey)(vKey - 'A' + GHOST_kKeyA);
}
- else if ((wParam >= VK_F1) && (wParam <= VK_F24)) {
- key = (GHOST_TKey)(wParam - VK_F1 + GHOST_kKeyF1);
+ else if ((vKey >= VK_F1) && (vKey <= VK_F24)) {
+ key = (GHOST_TKey)(vKey - VK_F1 + GHOST_kKeyF1);
}
else {
- switch (wParam) {
+ switch (vKey) {
case VK_RETURN:
- key = isExtended?GHOST_kKeyNumpadEnter:GHOST_kKeyEnter;
- break;
-
+ key = (extend)?GHOST_kKeyNumpadEnter : GHOST_kKeyEnter; break;
+
case VK_BACK: key = GHOST_kKeyBackSpace; break;
case VK_TAB: key = GHOST_kKeyTab; break;
case VK_ESCAPE: key = GHOST_kKeyEsc; break;
case VK_SPACE: key = GHOST_kKeySpace; break;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list