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
path: root/intern
diff options
context:
space:
mode:
authorNathan Letwory <nathan@letworyinteractive.com>2010-10-16 19:21:55 +0400
committerNathan Letwory <nathan@letworyinteractive.com>2010-10-16 19:21:55 +0400
commitc52e7c13706e96816f5f8893349d602803948ae2 (patch)
treebb1f65ec8f2526d477d183487d8e3e0eb337732f /intern
parent7122b534fa6879c7f321705213a71ffdc091dcfd (diff)
Fix AltGr problem on Windows
It was impossible for keyboard layouts that use AltGr to create certain characters to insert them in Text and Console. The keyboard driver in Windows sends left control events when AltGr is pressed. This meant that Blender thought control was being held, which is a PASS_THROUGH condition for the insert operator in both editors. Add testing of keyboard layout for AltGr, both on initialization and WM_INPUTLANGCHANGE. To remedy AltGr problem, we send now a left control key up event to Blender before further processing the AltGr key.
Diffstat (limited to 'intern')
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp42
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h26
2 files changed, 56 insertions, 12 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index d63ac700831..1f1fc65adc4 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -34,6 +34,8 @@
* @date May 7, 2001
*/
+#include <iostream>
+
#include "GHOST_SystemWin32.h"
#include "GHOST_EventDragnDrop.h"
@@ -142,6 +144,8 @@ GHOST_SystemWin32::GHOST_SystemWin32()
GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
m_displayManager->initialize();
+ this->keyboardAltGr();
+
// Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
OleInitialize(0);
}
@@ -285,18 +289,18 @@ GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys& keys) const
{
- bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
+ bool down = HIBYTE(::GetKeyState(VK_SHIFT)) != 0;
keys.set(GHOST_kModifierKeyLeftShift, down);
- down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
keys.set(GHOST_kModifierKeyRightShift, down);
- down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
+
+ down = HIBYTE(::GetKeyState(VK_MENU)) != 0;
keys.set(GHOST_kModifierKeyLeftAlt, down);
- down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
keys.set(GHOST_kModifierKeyRightAlt, down);
- down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 0;
+
+ down = HIBYTE(::GetKeyState(VK_CONTROL)) != 0;
keys.set(GHOST_kModifierKeyLeftControl, down);
- down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
keys.set(GHOST_kModifierKeyRightControl, down);
+
bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
if(lwindown || rwindown)
@@ -365,7 +369,7 @@ GHOST_TSuccess GHOST_SystemWin32::init()
wc.hbrBackground= (HBRUSH)::GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName= GHOST_WindowWin32::getWindowClassName();
-
+
// Use RegisterClassEx for setting small icon
if (::RegisterClass(&wc) == 0) {
success = GHOST_kFailure;
@@ -381,14 +385,14 @@ GHOST_TSuccess GHOST_SystemWin32::exit()
}
-GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
+GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const
{
+ bool isExtended = (lParam&(1<<24))?true:false;
+
GHOST_TKey key;
GHOST_ModifierKeys oldModifiers, newModifiers;
((GHOST_SystemWin32*)getSystem())->retrieveModifierKeys(oldModifiers);
((GHOST_SystemWin32*)getSystem())->getModifierKeys(newModifiers);
-
- bool isExtended = (lParam&(1<<24))?true:false;
if ((wParam >= '0') && (wParam <= '9')) {
// VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39)
@@ -474,6 +478,16 @@ GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
break;
case VK_MENU:
{
+ if(m_hasAltGr && isExtended) {
+ // We have here an extended RAlt, which is AltGr. The keyboard driver on Windows sends before this a LControl, so
+ // to be able to input characters created with AltGr (normal on German, French, Finnish and other keyboards) we
+ // push an extra LControl up event. This ensures we don't have a 'hanging' ctrl event in Blender windowmanager
+ // when typing in Text editor or Console.
+ GHOST_Event *extra = new GHOST_EventKey(getSystem()->getMilliSeconds(), GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl, '\0');
+ ((GHOST_SystemWin32*)getSystem())->pushEvent(extra);
+ newModifiers.set(GHOST_kModifierKeyRightControl, false);
+ newModifiers.set(GHOST_kModifierKeyLeftControl, false);
+ }
bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftAlt) != newModifiers.get(GHOST_kModifierKeyLeftAlt);
if(lchanged) {
key = GHOST_kKeyLeftAlt;
@@ -494,6 +508,7 @@ GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
break;
}
}
+ ((GHOST_SystemWin32*)getSystem())->storeModifierKeys(newModifiers);
return key;
}
@@ -573,7 +588,7 @@ GHOST_EventWheel* GHOST_SystemWin32::processWheelEvent(GHOST_IWindow *window, WP
GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, bool keyDown, WPARAM wParam, LPARAM lParam)
{
- GHOST_TKey key = ((GHOST_SystemWin32*)getSystem())->convertKey(wParam, lParam);
+ GHOST_TKey key = ((GHOST_SystemWin32*)getSystem())->convertKey(window, wParam, lParam);
GHOST_EventKey* event;
if (key != GHOST_kKeyUnknown) {
MSG keyMsg;
@@ -582,6 +597,7 @@ GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, bool k
/* Eat any character related messages */
if (::PeekMessage(&keyMsg, NULL, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE)) {
ascii = (char) keyMsg.wParam;
+
}
event = new GHOST_EventKey(getSystem()->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii);
@@ -630,6 +646,10 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
GHOST_WindowWin32* window = (GHOST_WindowWin32*)::GetWindowLong(hwnd, GWL_USERDATA);
if (window) {
switch (msg) {
+ // we need to check if new key layout has altgr
+ case WM_INPUTLANGCHANGE:
+ system->keyboardAltGr();
+ break;
////////////////////////////////////////////////////////////////////////
// Keyboard events, processed
////////////////////////////////////////////////////////////////////////
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 03f5349a606..3cd1deefda0 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -239,7 +239,7 @@ protected:
* @param lParam The lParam from the wndproc
* @return The GHOST key (GHOST_kKeyUnknown if no match).
*/
- virtual GHOST_TKey convertKey(WPARAM wParam, LPARAM lParam) const;
+ virtual GHOST_TKey convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const;
/**
* Creates modifier key event(s) and updates the key data stored locally (m_modifierKeys).
@@ -310,6 +310,11 @@ protected:
* @param keys The new state of the modifier keys.
*/
inline virtual void storeModifierKeys(const GHOST_ModifierKeys& keys);
+
+ /**
+ * Check current key layout for AltGr
+ */
+ inline virtual void keyboardAltGr();
/**
* Windows call back routine for our window class.
@@ -324,6 +329,8 @@ protected:
__int64 m_freq;
/** High frequency timer variable. */
__int64 m_start;
+ /** AltGr on current keyboard layout. */
+ bool m_hasAltGr;
};
inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const
@@ -336,5 +343,22 @@ inline void GHOST_SystemWin32::storeModifierKeys(const GHOST_ModifierKeys& keys)
m_modifierKeys = keys;
}
+inline void GHOST_SystemWin32::keyboardAltGr()
+{
+ HKL keylayout = GetKeyboardLayout(0); // get keylayout for current thread
+ int i;
+ SHORT s;
+ for(m_hasAltGr = false, i = 32; i < 256; ++i) {
+ s = VkKeyScanEx((char)i, keylayout);
+ // s == -1 means no key that translates passed char code
+ // high byte contains shift state. bit 2 ctrl pressed, bit 4 alt pressed
+ // if both are pressed, we have AltGr keycombo on keylayout
+ if(s!=-1 && (s & 0x600) == 0x600) {
+ m_hasAltGr = true;
+ break;
+ }
+ }
+}
+
#endif // _GHOST_SYSTEM_WIN32_H_