From f949c567b95ea03aa95bc283c73ae4818fbe4881 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Mon, 24 Jan 2011 14:37:10 +0000 Subject: Fix [#25715] [!] key doesn't work on french keyboard with Windows XP/7.\nSubmitted by Eric Le Pape\n\nThe key sent VK_OEM_8, which wasn't handled at all. Added code to detect primary language and handle VK_OEM_8 specifically for certain layouts. --- intern/ghost/intern/GHOST_SystemWin32.cpp | 26 +++++++++++++++++++++++--- intern/ghost/intern/GHOST_SystemWin32.h | 19 +++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) (limited to 'intern') diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index df968d30cb1..91e497bf631 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -144,8 +144,10 @@ GHOST_SystemWin32::GHOST_SystemWin32() GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n"); m_displayManager->initialize(); - // Check if current keyboard layout uses AltGr - this->keyboardAltGr(); + // 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) + this->handleKeyboardChange(); // Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32. OleInitialize(0); } @@ -478,6 +480,20 @@ void GHOST_SystemWin32::handleModifierKeys(GHOST_IWindow *window, WPARAM wParam, } } +//! 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 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 '!'. + break; + } + + return key; +} + GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const { GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); @@ -621,6 +637,9 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, L case VK_NUMLOCK: key = GHOST_kKeyNumLock; break; case VK_SCROLL: key = GHOST_kKeyScrollLock; break; case VK_CAPITAL: key = GHOST_kKeyCapsLock; break; + case VK_OEM_8: + key = ((GHOST_SystemWin32*)getSystem())->processSpecialKey(window, wParam, lParam); + break; default: key = GHOST_kKeyUnknown; break; @@ -719,6 +738,7 @@ GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, bool k } event = new GHOST_EventKey(getSystem()->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii); + std::cout << ascii << std::endl; } else { event = 0; @@ -812,7 +832,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, switch (msg) { // we need to check if new key layout has AltGr case WM_INPUTLANGCHANGE: - system->keyboardAltGr(); + system->handleKeyboardChange(); break; //////////////////////////////////////////////////////////////////////// // Keyboard events, processed diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index 29f4e64efa0..90431494992 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -282,6 +282,15 @@ protected: */ static GHOST_EventKey* processKeyEvent(GHOST_IWindow *window, bool keyDown, WPARAM wParam, LPARAM lParam); + /** + * Process special keys (VK_OEM_*), to see if current key layout + * gives us anything special, like ! on french AZERTY. + * @param window The window receiving the event (the active window). + * @param wParam The wParam from the wndproc + * @param lParam The lParam from the wndproc + */ + virtual GHOST_TKey processSpecialKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const; + /** * Creates a window event. * @param type The type of event to create. @@ -311,7 +320,7 @@ protected: /** * Check current key layout for AltGr */ - inline virtual void keyboardAltGr(void); + inline virtual void handleKeyboardChange(void); /** * Windows call back routine for our window class. @@ -338,6 +347,8 @@ protected: __int64 m_start; /** AltGr on current keyboard layout. */ bool m_hasAltGr; + /** language identifier. */ + WORD m_langId; /** holding hook handle for low-level keyboard handling */ HHOOK m_llKeyboardHook; bool m_prevKeyStatus[255]; /* VK_* codes 0x01-0xFF, with 0xFF reserved */ @@ -354,11 +365,15 @@ inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys& keys) m_modifierKeys = keys; } -inline void GHOST_SystemWin32::keyboardAltGr(void) +inline void GHOST_SystemWin32::handleKeyboardChange(void) { HKL keylayout = GetKeyboardLayout(0); // get keylayout for current thread int i; SHORT s; + + // save the language identifier. + m_langId = LOWORD(keylayout); + for(m_hasAltGr = false, i = 32; i < 256; ++i) { s = VkKeyScanEx((char)i, keylayout); // s == -1 means no key that translates passed char code -- cgit v1.2.3