[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35437] trunk/blender: Apply [#26364] New Windows keyboard handling

Dalai Felinto dfelinto at gmail.com
Thu Mar 10 04:22:58 CET 2011


Hi Nathan,

>Fixes [#25279] Shift-Numpad Combinations fail to align view to selected

I thought Alt+Numpad was the combination supposed to align view to
selected. Ton even fixed this in rev. 34975

Cheers,
Dalai

2011/3/9 Nathan Letwory <nathan at letworyinteractive.com>:
> 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
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>


More information about the Bf-committers mailing list