forked from bartvdbraak/blender
Simplify GHOST modifier key handling on Windows.
This commit is contained in:
parent
99bd5f2f3b
commit
f631a8b5be
@ -136,9 +136,7 @@
|
||||
|
||||
|
||||
GHOST_SystemWin32::GHOST_SystemWin32()
|
||||
: m_hasPerformanceCounter(false), m_freq(0), m_start(0),
|
||||
m_separateLeftRight(false),
|
||||
m_separateLeftRightInitialized(false)
|
||||
: 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");
|
||||
@ -287,43 +285,24 @@ GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
|
||||
|
||||
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys& keys) const
|
||||
{
|
||||
if (m_separateLeftRight && m_separateLeftRightInitialized) {
|
||||
bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftShift, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightShift, down);
|
||||
down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightAlt, down);
|
||||
down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 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)
|
||||
keys.set(GHOST_kModifierKeyOS, true);
|
||||
else
|
||||
keys.set(GHOST_kModifierKeyOS, false);
|
||||
}
|
||||
else {
|
||||
bool down = HIBYTE(::GetKeyState(VK_SHIFT)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftShift, down);
|
||||
keys.set(GHOST_kModifierKeyRightShift, down);
|
||||
down = HIBYTE(::GetKeyState(VK_MENU)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, down);
|
||||
keys.set(GHOST_kModifierKeyRightAlt, down);
|
||||
down = HIBYTE(::GetKeyState(VK_CONTROL)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftControl, down);
|
||||
keys.set(GHOST_kModifierKeyRightControl, down);
|
||||
bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
|
||||
bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
|
||||
if(lwindown || rwindown)
|
||||
keys.set(GHOST_kModifierKeyOS, true);
|
||||
else
|
||||
keys.set(GHOST_kModifierKeyOS, false);
|
||||
}
|
||||
bool down = HIBYTE(::GetKeyState(VK_LSHIFT)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftShift, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RSHIFT)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightShift, down);
|
||||
down = HIBYTE(::GetKeyState(VK_LMENU)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RMENU)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightAlt, down);
|
||||
down = HIBYTE(::GetKeyState(VK_LCONTROL)) != 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)
|
||||
keys.set(GHOST_kModifierKeyOS, true);
|
||||
else
|
||||
keys.set(GHOST_kModifierKeyOS, false);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@ -405,6 +384,10 @@ GHOST_TSuccess GHOST_SystemWin32::exit()
|
||||
GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
|
||||
{
|
||||
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')) {
|
||||
@ -469,15 +452,43 @@ GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
|
||||
case VK_QUOTE: key = GHOST_kKeyQuote; break;
|
||||
case VK_GR_LESS: key = GHOST_kKeyGrLess; break;
|
||||
|
||||
// Process these keys separately because we need to distinguish right from left modifier keys
|
||||
case VK_SHIFT:
|
||||
{
|
||||
bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftShift) != newModifiers.get(GHOST_kModifierKeyLeftShift);
|
||||
if(lchanged) {
|
||||
key = GHOST_kKeyLeftShift;
|
||||
} else {
|
||||
key = GHOST_kKeyRightShift;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
{
|
||||
bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftControl) != newModifiers.get(GHOST_kModifierKeyLeftControl);
|
||||
if(lchanged) {
|
||||
key = GHOST_kKeyLeftControl;
|
||||
} else {
|
||||
key = GHOST_kKeyRightControl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VK_MENU:
|
||||
|
||||
// Ignore these keys
|
||||
case VK_NUMLOCK:
|
||||
case VK_SCROLL:
|
||||
case VK_CAPITAL:
|
||||
{
|
||||
bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftAlt) != newModifiers.get(GHOST_kModifierKeyLeftAlt);
|
||||
if(lchanged) {
|
||||
key = GHOST_kKeyLeftAlt;
|
||||
} else {
|
||||
key = GHOST_kKeyRightAlt;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VK_LWIN:
|
||||
case VK_RWIN:
|
||||
key = GHOST_kKeyOS;
|
||||
break;
|
||||
case VK_NUMLOCK: key = GHOST_kKeyNumLock; break;
|
||||
case VK_SCROLL: key = GHOST_kKeyScrollLock; break;
|
||||
case VK_CAPITAL: key = GHOST_kKeyCapsLock; break;
|
||||
default:
|
||||
key = GHOST_kKeyUnknown;
|
||||
break;
|
||||
@ -486,38 +497,6 @@ GHOST_TKey GHOST_SystemWin32::convertKey(WPARAM wParam, LPARAM lParam) const
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
void GHOST_SystemWin32::processModifierKeys(GHOST_IWindow *window)
|
||||
{
|
||||
GHOST_ModifierKeys oldModifiers, newModifiers;
|
||||
// Retrieve old state of the modifier keys
|
||||
((GHOST_SystemWin32*)getSystem())->retrieveModifierKeys(oldModifiers);
|
||||
// Retrieve current state of the modifier keys
|
||||
((GHOST_SystemWin32*)getSystem())->getModifierKeys(newModifiers);
|
||||
|
||||
// Compare the old and the new
|
||||
if (!newModifiers.equals(oldModifiers)) {
|
||||
// Create events for the masks that changed
|
||||
for (int i = 0; i < GHOST_kModifierKeyNumMasks; i++) {
|
||||
if (newModifiers.get((GHOST_TModifierKeyMask)i) != oldModifiers.get((GHOST_TModifierKeyMask)i)) {
|
||||
// Convert the mask to a key code
|
||||
GHOST_TKey key = GHOST_ModifierKeys::getModifierKeyCode((GHOST_TModifierKeyMask)i);
|
||||
bool keyDown = newModifiers.get((GHOST_TModifierKeyMask)i);
|
||||
GHOST_EventKey* event;
|
||||
if (key != GHOST_kKeyUnknown) {
|
||||
// Create an event
|
||||
event = new GHOST_EventKey(getSystem()->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key);
|
||||
pushEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store new modifier keys state
|
||||
((GHOST_SystemWin32*)getSystem())->storeModifierKeys(newModifiers);
|
||||
}
|
||||
|
||||
|
||||
GHOST_EventButton* GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask mask)
|
||||
{
|
||||
return new GHOST_EventButton (getSystem()->getMilliSeconds(), type, window, mask);
|
||||
@ -655,85 +634,22 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
// Keyboard events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case WM_KEYDOWN:
|
||||
/* The WM_KEYDOWN message is posted to the window with the keyboard focus when a
|
||||
* nonsystem key is pressed. A nonsystem key is a key that is pressed when the alt
|
||||
* key is not pressed.
|
||||
*/
|
||||
case WM_SYSKEYDOWN:
|
||||
/* The WM_SYSKEYDOWN message is posted to the window with the keyboard focus when
|
||||
* the user presses the F10 key (which activates the menu bar) or holds down the
|
||||
* alt key and then presses another key. It also occurs when no window currently
|
||||
* has the keyboard focus; in this case, the WM_SYSKEYDOWN message is sent to the
|
||||
* active window. The window that receives the message can distinguish between these
|
||||
* two contexts by checking the context code in the lKeyData parameter.
|
||||
*/
|
||||
switch (wParam) {
|
||||
case VK_SHIFT:
|
||||
case VK_CONTROL:
|
||||
case VK_MENU:
|
||||
case VK_LWIN:
|
||||
case VK_RWIN:
|
||||
if (!system->m_separateLeftRightInitialized) {
|
||||
// Check whether this system supports separate left and right keys
|
||||
switch (wParam) {
|
||||
case VK_SHIFT:
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LSHIFT)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RSHIFT)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LCONTROL)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RCONTROL)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_MENU:
|
||||
system->m_separateLeftRight =
|
||||
(HIBYTE(::GetKeyState(VK_LMENU)) != 0) ||
|
||||
(HIBYTE(::GetKeyState(VK_RMENU)) != 0) ?
|
||||
true : false;
|
||||
break;
|
||||
case VK_LWIN:
|
||||
case VK_RWIN:
|
||||
system->m_separateLeftRight = true;
|
||||
break;
|
||||
}
|
||||
system->m_separateLeftRightInitialized = true;
|
||||
}
|
||||
system->processModifierKeys(window);
|
||||
// Bypass call to DefWindowProc
|
||||
return 0;
|
||||
default:
|
||||
event = processKeyEvent(window, true, wParam, lParam);
|
||||
if (!event) {
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
|
||||
GHOST_PRINT(msg)
|
||||
GHOST_PRINT(" key ignored\n")
|
||||
}
|
||||
break;
|
||||
}
|
||||
event = processKeyEvent(window, true, wParam, lParam);
|
||||
if (!event) {
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
|
||||
GHOST_PRINT(msg)
|
||||
GHOST_PRINT(" key ignored\n")
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYUP:
|
||||
switch (wParam) {
|
||||
case VK_SHIFT:
|
||||
case VK_CONTROL:
|
||||
case VK_MENU:
|
||||
case VK_LWIN:
|
||||
case VK_RWIN:
|
||||
system->processModifierKeys(window);
|
||||
// Bypass call to DefWindowProc
|
||||
return 0;
|
||||
default:
|
||||
event = processKeyEvent(window, false, wParam, lParam);
|
||||
if (!event) {
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
|
||||
GHOST_PRINT(msg)
|
||||
GHOST_PRINT(" key ignored\n")
|
||||
}
|
||||
break;
|
||||
event = processKeyEvent(window, false, wParam, lParam);
|
||||
if (!event) {
|
||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
|
||||
GHOST_PRINT(msg)
|
||||
GHOST_PRINT(" key ignored\n")
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -248,7 +248,7 @@ protected:
|
||||
* events generated for both keys.
|
||||
* @param window The window receiving the event (the active window).
|
||||
*/
|
||||
void processModifierKeys(GHOST_IWindow *window);
|
||||
GHOST_EventKey* processModifierKeys(GHOST_IWindow *window);
|
||||
|
||||
/**
|
||||
* Creates mouse button event.
|
||||
@ -324,11 +324,6 @@ protected:
|
||||
__int64 m_freq;
|
||||
/** High frequency timer variable. */
|
||||
__int64 m_start;
|
||||
/** Stores the capability of this system to distinguish left and right modifier keys. */
|
||||
bool m_separateLeftRight;
|
||||
/** Stores the initialization state of the member m_leftRightDistinguishable. */
|
||||
bool m_separateLeftRightInitialized;
|
||||
|
||||
};
|
||||
|
||||
inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const
|
||||
|
Loading…
Reference in New Issue
Block a user