diff --git a/src/lib/platform/MSWindowsHook.cpp b/src/lib/platform/MSWindowsHook.cpp index 202f9e58..b10d5c63 100644 --- a/src/lib/platform/MSWindowsHook.cpp +++ b/src/lib/platform/MSWindowsHook.cpp @@ -143,9 +143,9 @@ keyboardGetState(BYTE keys[256], DWORD vkCode, bool kf_up) static WPARAM -makeKeyMsg(UINT virtKey, char c, bool noAltGr) +makeKeyMsg(UINT virtKey, WCHAR wc, bool noAltGr) { - return MAKEWPARAM(MAKEWORD(virtKey & 0xff, (BYTE)c), noAltGr ? 1 : 0); + return MAKEWPARAM((WORD)wc, MAKEWORD(virtKey & 0xff, noAltGr ? 1 : 0)); } static @@ -192,7 +192,7 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) (lParam & 0x80000000u) != 0) { g_deadRelease = 0; PostThreadMessage(g_threadID, BARRIER_MSG_DEBUG, - wParam | 0x04000000, lParam); + wParam | 0x40000000, lParam); return false; } @@ -244,19 +244,19 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) } } - WORD c = 0; + WCHAR wc[2] = { 0, 0 }; // map the key event to a character. we have to put the dead // key back first and this has the side effect of removing it. if (g_deadVirtKey != 0) { - if (ToAscii((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, - g_deadKeyState, &c, flags) == 2) { - // If ToAscii returned 2, it means that we accidentally removed + if (ToUnicode((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, + g_deadKeyState, wc, 2, flags) == 2) { + // If ToUnicode returned 2, it means that we accidentally removed // a double dead key instead of restoring it. Thus, we call - // ToAscii again with the same parameters to restore the + // ToUnicode again with the same parameters to restore the // internal dead key state. - ToAscii((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, - g_deadKeyState, &c, flags); + ToUnicode((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, + g_deadKeyState, wc, 2, flags); // We need to keep track of this because g_deadVirtKey will be // cleared later on; this would cause the dead key release to @@ -266,7 +266,7 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) } UINT scanCode = ((lParam & 0x10ff0000u) >> 16); - int n = ToAscii((UINT)wParam, scanCode, keys, &c, flags); + int n = ToUnicode((UINT)wParam, scanCode, keys, wc, 2, flags); // if mapping failed and ctrl and alt are pressed then try again // with both not pressed. this handles the case where ctrl and @@ -278,12 +278,12 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) if (n == 0 && (control & 0x80) != 0 && (menu & 0x80) != 0) { noAltGr = true; PostThreadMessage(g_threadID, BARRIER_MSG_DEBUG, - wParam | 0x05000000, lParam); + wParam | 0x50000000, lParam); if (g_deadVirtKey != 0) { - if (ToAscii((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, - g_deadKeyState, &c, flags) == 2) { - ToAscii((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, - g_deadKeyState, &c, flags); + if (ToUnicode((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, + g_deadKeyState, wc, 2, flags) == 2) { + ToUnicode((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, + g_deadKeyState, wc, 2, flags); g_deadRelease = g_deadVirtKey; } } @@ -297,12 +297,12 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) keys2[VK_LMENU] = 0; keys2[VK_RMENU] = 0; keys2[VK_MENU] = 0; - n = ToAscii((UINT)wParam, scanCode, keys2, &c, flags); + n = ToUnicode((UINT)wParam, scanCode, keys2, wc, 2, flags); } PostThreadMessage(g_threadID, BARRIER_MSG_DEBUG, - wParam | ((c & 0xff) << 8) | - ((n & 0xff) << 16) | 0x06000000, + (wc[0] & 0xffff) | ((wParam & 0xff) << 16) | + ((n & 0xf) << 24) | 0x60000000, lParam); WPARAM charAndVirtKey = 0; bool clearDeadKey = false; @@ -328,12 +328,12 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) case 0: // key doesn't map to a character. this can happen if // non-character keys are pressed after a dead key. - charAndVirtKey = makeKeyMsg((UINT)wParam, (char)0, noAltGr); + charAndVirtKey = makeKeyMsg((UINT)wParam, (WCHAR)0, noAltGr); break; case 1: // key maps to a character composed with dead key - charAndVirtKey = makeKeyMsg((UINT)wParam, (char)LOBYTE(c), noAltGr); + charAndVirtKey = makeKeyMsg((UINT)wParam, wc[0], noAltGr); clearDeadKey = true; break; @@ -341,14 +341,14 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) // previous dead key not composed. send a fake key press // and release for the dead key to our window. WPARAM deadCharAndVirtKey = - makeKeyMsg((UINT)g_deadVirtKey, (char)LOBYTE(c), noAltGr); + makeKeyMsg((UINT)g_deadVirtKey, wc[0], noAltGr); PostThreadMessage(g_threadID, BARRIER_MSG_KEY, deadCharAndVirtKey, g_deadLParam & 0x7fffffffu); PostThreadMessage(g_threadID, BARRIER_MSG_KEY, deadCharAndVirtKey, g_deadLParam | 0x80000000u); // use uncomposed character - charAndVirtKey = makeKeyMsg((UINT)wParam, (char)HIBYTE(c), noAltGr); + charAndVirtKey = makeKeyMsg((UINT)wParam, wc[1], noAltGr); clearDeadKey = true; break; } @@ -356,8 +356,8 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) // put back the dead key, if any, for the application to use if (g_deadVirtKey != 0) { - ToAscii((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, - g_deadKeyState, &c, flags); + ToUnicode((UINT)g_deadVirtKey, (g_deadLParam & 0x10ff0000u) >> 16, + g_deadKeyState, wc, 2, flags); } // clear out old dead key state @@ -374,7 +374,7 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam) // forwarding. if (charAndVirtKey != 0) { PostThreadMessage(g_threadID, BARRIER_MSG_DEBUG, - charAndVirtKey | 0x07000000, lParam); + charAndVirtKey | 0x70000000, lParam); PostThreadMessage(g_threadID, BARRIER_MSG_KEY, charAndVirtKey, lParam); } diff --git a/src/lib/platform/MSWindowsKeyState.cpp b/src/lib/platform/MSWindowsKeyState.cpp index f2a0463c..5afa9e8f 100644 --- a/src/lib/platform/MSWindowsKeyState.cpp +++ b/src/lib/platform/MSWindowsKeyState.cpp @@ -688,34 +688,17 @@ MSWindowsKeyState::mapKeyFromEvent(WPARAM charAndVirtKey, KeyModifierControl | KeyModifierAlt; // extract character, virtual key, and if we didn't use AltGr - char c = (char)((charAndVirtKey & 0xff00u) >> 8); - UINT vkCode = (charAndVirtKey & 0xffu); - bool noAltGr = ((charAndVirtKey & 0xff0000u) != 0); + WCHAR wc = (WCHAR)(charAndVirtKey & 0xffffu); + UINT vkCode = ((charAndVirtKey >> 16) & 0xffu); + bool noAltGr = ((charAndVirtKey & 0xff000000u) != 0); // handle some keys via table lookup KeyID id = getKeyID(vkCode, (KeyButton)((info >> 16) & 0x1ffu)); // check if not in table; map character to key id - if (id == kKeyNone && c != 0) { - if ((c & 0x80u) == 0) { - // ASCII - id = static_cast(c) & 0xffu; - } - else { - // character is not really ASCII. instead it's some - // character in the current ANSI code page. try to - // convert that to a Unicode character. if we fail - // then use the single byte character as is. - char src = c; - wchar_t unicode; - if (MultiByteToWideChar(CP_THREAD_ACP, MB_PRECOMPOSED, - &src, 1, &unicode, 1) > 0) { - id = static_cast(unicode); - } - else { - id = static_cast(c) & 0xffu; - } - } + if (id == kKeyNone && wc != 0) { + // UTF16 + id = static_cast(wc) & 0xffffu; } // set modifier mask diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index 352368ac..739a1e25 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -1104,7 +1104,7 @@ MSWindowsScreen::onKey(WPARAM wParam, LPARAM lParam) static const KeyModifierMask s_ctrlAlt = KeyModifierControl | KeyModifierAlt; - LOG((CLOG_DEBUG1 "event: Key char=%d, vk=0x%02x, nagr=%d, lParam=0x%08x", (wParam & 0xff00u) >> 8, wParam & 0xffu, (wParam & 0x10000u) ? 1 : 0, lParam)); + LOG((CLOG_DEBUG1 "event: Key char=%d, vk=0x%02x, nagr=%d, lParam=0x%08x", wParam & 0xffffu, (wParam >> 16) & 0xffu, (wParam & 0x1000000u) ? 1 : 0, lParam)); // get event info KeyButton button = (KeyButton)((lParam & 0x01ff0000) >> 16); @@ -1122,7 +1122,7 @@ MSWindowsScreen::onKey(WPARAM wParam, LPARAM lParam) // that maps mouse buttons to keys is known to do this. // alternatively, we could just throw these events out. if (button == 0) { - button = m_keyState->virtualKeyToButton(wParam & 0xffu); + button = m_keyState->virtualKeyToButton((wParam >> 16) & 0xffu); if (button == 0) { return true; } @@ -1188,7 +1188,7 @@ MSWindowsScreen::onKey(WPARAM wParam, LPARAM lParam) if (!ignore()) { // check for ctrl+alt+del. we do not want to pass that to the // client. the user can use ctrl+alt+pause to emulate it. - UINT virtKey = (wParam & 0xffu); + UINT virtKey = (wParam >> 16) & 0xffu; if (virtKey == VK_DELETE && (state & s_ctrlAlt) == s_ctrlAlt) { LOG((CLOG_DEBUG "discard ctrl+alt+del")); return true; @@ -1202,9 +1202,9 @@ MSWindowsScreen::onKey(WPARAM wParam, LPARAM lParam) // pressed or released. when mapping the key we require that // we not use AltGr (the 0x10000 flag in wParam) and we not // use the keypad delete key (the 0x01000000 flag in lParam). - wParam = VK_DELETE | 0x00010000u; + wParam = (VK_DELETE << 16) | 0x01000000u; lParam &= 0xfe000000; - lParam |= m_keyState->virtualKeyToButton(wParam & 0xffu) << 16; + lParam |= m_keyState->virtualKeyToButton(VK_DELETE) << 16; lParam |= 0x01000001; } @@ -1232,7 +1232,7 @@ MSWindowsScreen::onHotKey(WPARAM wParam, LPARAM lParam) { // get the key info KeyModifierMask state = getActiveModifiers(); - UINT virtKey = (wParam & 0xffu); + UINT virtKey = (wParam >> 16) & 0xffu; UINT modifiers = 0; if ((state & KeyModifierShift) != 0) { modifiers |= MOD_SHIFT; @@ -1939,7 +1939,7 @@ MSWindowsScreen::isModifierRepeat(KeyModifierMask oldState, KeyModifierMask stat bool result = false; if (oldState == state && state != 0) { - UINT virtKey = (wParam & 0xffu); + UINT virtKey = (wParam >> 16) & 0xffu; if ((state & KeyModifierShift) != 0 && (virtKey == VK_LSHIFT || virtKey == VK_RSHIFT)) { result = true;