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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to