From 9015f6a3283ca80236cf37c042822ff693da9d12 Mon Sep 17 00:00:00 2001 From: Jamie Newbon Date: Sat, 11 Jan 2020 01:07:39 +0000 Subject: [PATCH] WIP printscreen fixes for Windows # Conflicts: # src/lib/platform/MSWindowsDesks.cpp # src/lib/platform/MSWindowsDesks.h --- src/lib/platform/MSWindowsDesks.cpp | 65 +++++++++++---- src/lib/platform/MSWindowsDesks.h | 4 +- src/lib/platform/MSWindowsKeyState.cpp | 105 ++++++++++++++----------- 3 files changed, 108 insertions(+), 66 deletions(-) diff --git a/src/lib/platform/MSWindowsDesks.cpp b/src/lib/platform/MSWindowsDesks.cpp index 418028915d..d9542aeab5 100644 --- a/src/lib/platform/MSWindowsDesks.cpp +++ b/src/lib/platform/MSWindowsDesks.cpp @@ -88,6 +88,34 @@ // enable; #define SYNERGY_MSG_FAKE_INPUT SYNERGY_HOOK_LAST_MSG + 12 + +static void +send_keyboard_input(WORD wVk, WORD wScan, DWORD dwFlags) +{ + INPUT inp; + inp.type = INPUT_KEYBOARD; + inp.ki.wVk = (dwFlags & KEYEVENTF_UNICODE) ? 0 : wVk; // 1..254 inclusive otherwise + inp.ki.wScan = wScan; + inp.ki.dwFlags = dwFlags & 0xF; + inp.ki.time = 0; + inp.ki.dwExtraInfo = 0; + SendInput(1, &inp, sizeof(inp)); +} + +static void +send_mouse_input(DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData) +{ + INPUT inp; + inp.type = INPUT_MOUSE; + inp.mi.dwFlags = dwFlags; + inp.mi.dx = dx; + inp.mi.dy = dy; + inp.mi.mouseData = dwData; + inp.mi.time = 0; + inp.mi.dwExtraInfo = 0; + SendInput(1, &inp, sizeof(inp)); +} + // // MSWindowsDesks // @@ -245,10 +273,9 @@ MSWindowsDesks::getCursorPos(SInt32& x, SInt32& y) const } void -MSWindowsDesks::fakeKeyEvent( - KeyButton button, UINT virtualKey, - bool press, bool /*isAutoRepeat*/) const +MSWindowsDesks::fakeKeyEvent(WORD virtualKey, WORD scanCode, DWORD flags, bool /*isAutoRepeat*/) const { +#if 0 // synthesize event DWORD flags = 0; if (((button & 0x100u) != 0)) { @@ -257,9 +284,8 @@ MSWindowsDesks::fakeKeyEvent( if (!press) { flags |= KEYEVENTF_KEYUP; } - sendMessage(SYNERGY_MSG_FAKE_KEY, flags, - MAKEWORD(static_cast(button & 0xffu), - static_cast(virtualKey & 0xffu))); +#endif + sendMessage(SYNERGY_MSG_FAKE_KEY, flags, MAKELPARAM(scanCode, virtualKey)); } void @@ -468,10 +494,10 @@ MSWindowsDesks::deskMouseMove(SInt32 x, SInt32 y) const // the primary screen. SInt32 w = GetSystemMetrics(SM_CXSCREEN); SInt32 h = GetSystemMetrics(SM_CYSCREEN); - mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + send_mouse_input(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, (DWORD)((65535.0f * x) / (w - 1) + 0.5f), (DWORD)((65535.0f * y) / (h - 1) + 0.5f), - 0, 0); + 0); } void @@ -501,7 +527,7 @@ MSWindowsDesks::deskMouseRelativeMove(SInt32 dx, SInt32 dy) const } // move relative to mouse position - mouse_event(MOUSEEVENTF_MOVE, dx, dy, 0, 0); + send_mouse_input(MOUSEEVENTF_MOVE, dx, dy, 0); // restore mouse speed & acceleration if (accelChanged) { @@ -699,12 +725,16 @@ MSWindowsDesks::deskThread(void* vdesk) break; case SYNERGY_MSG_FAKE_KEY: - keybd_event(HIBYTE(msg.lParam), LOBYTE(msg.lParam), (DWORD)msg.wParam, 0); + // Note, this is intended to be HI/LOWORD and not HI/LOBYTE + send_keyboard_input( + HIWORD(msg.lParam), + LOWORD(msg.lParam), + (DWORD)msg.wParam); break; case SYNERGY_MSG_FAKE_BUTTON: - if (msg.wParam != 0) { - mouse_event((DWORD)msg.wParam, 0, 0, (DWORD)msg.lParam, 0); + if (msg.wParam != 0) { + send_mouse_input((DWORD)msg.wParam, 0, 0, (DWORD)msg.lParam); } break; @@ -721,7 +751,7 @@ MSWindowsDesks::deskThread(void* vdesk) case SYNERGY_MSG_FAKE_WHEEL: // XXX -- add support for x-axis scrolling if (msg.lParam != 0) { - mouse_event(MOUSEEVENTF_WHEEL, 0, 0, (DWORD)msg.lParam, 0); + send_mouse_input(MOUSEEVENTF_WHEEL, 0, 0, (DWORD)msg.lParam); } break; @@ -750,9 +780,10 @@ MSWindowsDesks::deskThread(void* vdesk) break; case SYNERGY_MSG_FAKE_INPUT: - keybd_event(SYNERGY_HOOK_FAKE_INPUT_VIRTUAL_KEY, - SYNERGY_HOOK_FAKE_INPUT_SCANCODE, - msg.wParam ? 0 : KEYEVENTF_KEYUP, 0); + send_keyboard_input( + SYNERGY_HOOK_FAKE_INPUT_VIRTUAL_KEY, + SYNERGY_HOOK_FAKE_INPUT_SCANCODE, + msg.wParam ? 0 : KEYEVENTF_KEYUP); break; } @@ -820,7 +851,7 @@ MSWindowsDesks::checkDesk() desk = index->second; } - // if we are told to shut down on desk switch, and this is not the + // if we are told to shut down on desk switch, and this is not the // first switch, then shut down. if (m_stopOnDeskSwitch && m_activeDesk != NULL && name != m_activeDeskName) { LOG((CLOG_DEBUG "shutting down because of desk switch to \"%s\"", name.c_str())); diff --git a/src/lib/platform/MSWindowsDesks.h b/src/lib/platform/MSWindowsDesks.h index 84ded7c33d..e608080b71 100644 --- a/src/lib/platform/MSWindowsDesks.h +++ b/src/lib/platform/MSWindowsDesks.h @@ -162,8 +162,8 @@ public: /*! Synthesize a press or release of key \c button. */ - void fakeKeyEvent(KeyButton button, UINT virtualKey, - bool press, bool isAutoRepeat) const; + void fakeKeyEvent(WORD virtualKey, WORD scanCode, + DWORD flags, bool isAutoRepeat) const; //! Fake mouse press/release /*! diff --git a/src/lib/platform/MSWindowsKeyState.cpp b/src/lib/platform/MSWindowsKeyState.cpp index 4e093bd358..d9543611ed 100644 --- a/src/lib/platform/MSWindowsKeyState.cpp +++ b/src/lib/platform/MSWindowsKeyState.cpp @@ -2,11 +2,11 @@ * synergy -- mouse and keyboard sharing utility * Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2003 Chris Schoeneman - * + * * This package is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * found in the file LICENSE that should have accompanied this file. - * + * * This package is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -68,10 +68,10 @@ const KeyID MSWindowsKeyState::s_virtualKey[] = /* 0x019 */ { kKeyKanzi }, // VK_HANJA, VK_KANJI /* 0x01a */ { kKeyNone }, // undefined /* 0x01b */ { kKeyEscape }, // VK_ESCAPE - /* 0x01c */ { kKeyHenkan }, // VK_CONVERT - /* 0x01d */ { kKeyNone }, // VK_NONCONVERT - /* 0x01e */ { kKeyNone }, // VK_ACCEPT - /* 0x01f */ { kKeyNone }, // VK_MODECHANGE + /* 0x01c */ { kKeyHenkan }, // VK_CONVERT + /* 0x01d */ { kKeyNone }, // VK_NONCONVERT + /* 0x01e */ { kKeyNone }, // VK_ACCEPT + /* 0x01f */ { kKeyNone }, // VK_MODECHANGE /* 0x020 */ { kKeyNone }, // VK_SPACE /* 0x021 */ { kKeyKP_PageUp }, // VK_PRIOR /* 0x022 */ { kKeyKP_PageDown },// VK_NEXT @@ -286,15 +286,15 @@ const KeyID MSWindowsKeyState::s_virtualKey[] = /* 0x0f3 */ { kKeyZenkaku }, // VK_OEM_AUTO /* 0x0f4 */ { kKeyZenkaku }, // VK_OEM_ENLW /* 0x0f5 */ { kKeyNone }, // OEM specific - /* 0x0f6 */ { kKeyNone }, // VK_ATTN - /* 0x0f7 */ { kKeyNone }, // VK_CRSEL - /* 0x0f8 */ { kKeyNone }, // VK_EXSEL - /* 0x0f9 */ { kKeyNone }, // VK_EREOF - /* 0x0fa */ { kKeyNone }, // VK_PLAY - /* 0x0fb */ { kKeyNone }, // VK_ZOOM + /* 0x0f6 */ { kKeyNone }, // VK_ATTN + /* 0x0f7 */ { kKeyNone }, // VK_CRSEL + /* 0x0f8 */ { kKeyNone }, // VK_EXSEL + /* 0x0f9 */ { kKeyNone }, // VK_EREOF + /* 0x0fa */ { kKeyNone }, // VK_PLAY + /* 0x0fb */ { kKeyNone }, // VK_ZOOM /* 0x0fc */ { kKeyNone }, // reserved - /* 0x0fd */ { kKeyNone }, // VK_PA1 - /* 0x0fe */ { kKeyNone }, // VK_OEM_CLEAR + /* 0x0fd */ { kKeyNone }, // VK_PA1 + /* 0x0fe */ { kKeyNone }, // VK_OEM_CLEAR /* 0x0ff */ { kKeyNone }, // reserved /* 0x100 */ { kKeyNone }, // reserved @@ -320,15 +320,15 @@ const KeyID MSWindowsKeyState::s_virtualKey[] = /* 0x114 */ { kKeyNone }, // VK_CAPITAL /* 0x115 */ { kKeyHangul }, // VK_HANGUL /* 0x116 */ { kKeyNone }, // undefined - /* 0x117 */ { kKeyNone }, // VK_JUNJA - /* 0x118 */ { kKeyNone }, // VK_FINAL + /* 0x117 */ { kKeyNone }, // VK_JUNJA + /* 0x118 */ { kKeyNone }, // VK_FINAL /* 0x119 */ { kKeyHanja }, // VK_HANJA /* 0x11a */ { kKeyNone }, // undefined /* 0x11b */ { kKeyNone }, // VK_ESCAPE - /* 0x11c */ { kKeyNone }, // VK_CONVERT - /* 0x11d */ { kKeyNone }, // VK_NONCONVERT - /* 0x11e */ { kKeyNone }, // VK_ACCEPT - /* 0x11f */ { kKeyNone }, // VK_MODECHANGE + /* 0x11c */ { kKeyNone }, // VK_CONVERT + /* 0x11d */ { kKeyNone }, // VK_NONCONVERT + /* 0x11e */ { kKeyNone }, // VK_ACCEPT + /* 0x11f */ { kKeyNone }, // VK_MODECHANGE /* 0x120 */ { kKeyNone }, // VK_SPACE /* 0x121 */ { kKeyPageUp }, // VK_PRIOR /* 0x122 */ { kKeyPageDown }, // VK_NEXT @@ -543,15 +543,15 @@ const KeyID MSWindowsKeyState::s_virtualKey[] = /* 0x1f3 */ { kKeyNone }, // VK_OEM_AUTO /* 0x1f4 */ { kKeyNone }, // VK_OEM_ENLW /* 0x1f5 */ { kKeyNone }, // OEM specific - /* 0x1f6 */ { kKeyNone }, // VK_ATTN - /* 0x1f7 */ { kKeyNone }, // VK_CRSEL - /* 0x1f8 */ { kKeyNone }, // VK_EXSEL - /* 0x1f9 */ { kKeyNone }, // VK_EREOF - /* 0x1fa */ { kKeyNone }, // VK_PLAY - /* 0x1fb */ { kKeyNone }, // VK_ZOOM + /* 0x1f6 */ { kKeyNone }, // VK_ATTN + /* 0x1f7 */ { kKeyNone }, // VK_CRSEL + /* 0x1f8 */ { kKeyNone }, // VK_EXSEL + /* 0x1f9 */ { kKeyNone }, // VK_EREOF + /* 0x1fa */ { kKeyNone }, // VK_PLAY + /* 0x1fb */ { kKeyNone }, // VK_ZOOM /* 0x1fc */ { kKeyNone }, // reserved - /* 0x1fd */ { kKeyNone }, // VK_PA1 - /* 0x1fe */ { kKeyNone }, // VK_OEM_CLEAR + /* 0x1fd */ { kKeyNone }, // VK_PA1 + /* 0x1fe */ { kKeyNone }, // VK_OEM_CLEAR /* 0x1ff */ { kKeyNone } // reserved }; @@ -959,7 +959,7 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap) // deal with certain virtual keys specially switch (vk) { case VK_SHIFT: - // this is important for sending the correct modifier to the + // this is important for sending the correct modifier to the // client, a patch from bug #242 (right shift broken for ms // remote desktop) removed this to just use left shift, which // caused bug #2799 (right shift broken for osx). @@ -1075,6 +1075,13 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap) } } + // add the extended printscreen (alt+printscreen) + // or maybe it's the non-extended printscreen? + // scancodes and keyboard inputs are complicated + if (m_buttonToVK[0x54u] == 0) { + m_buttonToVK[0x54u] = VK_SNAPSHOT; + } + // set virtual key to button table if (activeLayout == m_groups[g]) { for (KeyButton i = 0; i < 512; ++i) { @@ -1176,7 +1183,7 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap) } } } - + // save each key. the map will automatically discard // duplicates, like an unshift and shifted version of // a key that's insensitive to shift. @@ -1209,7 +1216,7 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap) item.m_required |= KeyModifierControl; item.m_sensitive |= KeyModifierControl; break; - +#if 0 case VK_SNAPSHOT: item.m_sensitive |= KeyModifierAlt; if ((i & 0x100u) == 0) { @@ -1218,6 +1225,7 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap) } break; } +#endif addKeyEntry(keyMap, item); } } @@ -1234,7 +1242,7 @@ MSWindowsKeyState::fakeKey(const Keystroke& keystroke) switch (keystroke.m_type) { case Keystroke::kButton: { LOG((CLOG_DEBUG1 " %03x (%08x) %s", keystroke.m_data.m_button.m_button, keystroke.m_data.m_button.m_client, keystroke.m_data.m_button.m_press ? "down" : "up")); - KeyButton button = keystroke.m_data.m_button.m_button; + KeyButton scanCode = keystroke.m_data.m_button.m_button; // windows doesn't send key ups for key repeats if (keystroke.m_data.m_button.m_repeat && @@ -1244,24 +1252,27 @@ MSWindowsKeyState::fakeKey(const Keystroke& keystroke) } // get the virtual key for the button - UINT vk = keystroke.m_data.m_button.m_client; + WORD vk = (WORD)keystroke.m_data.m_button.m_client; + DWORD flags = 0; + + if (keystroke.m_data.m_button.m_press = false) + flags |= KEYEVENTF_KEYUP; // special handling of VK_SNAPSHOT - if (vk == VK_SNAPSHOT) { - if ((getActiveModifiers() & KeyModifierAlt) != 0) { - // snapshot active window - button = 1; - } - else { - // snapshot full screen - button = 0; - } - } + if (vk == VK_SNAPSHOT) + scanCode = (getActiveModifiers() & KeyModifierAlt) ? 0x54 : 0x137; + + if (scanCode & 0x100) + flags |= KEYEVENTF_EXTENDEDKEY; + + //vk,sc,flags,keystroke.m_data.m_button.m_repeat + + m_desks->fakeKeyEvent(vk, scanCode, flags, keystroke.m_data.m_button.m_repeat); // synthesize event - m_desks->fakeKeyEvent(button, vk, - keystroke.m_data.m_button.m_press, - keystroke.m_data.m_button.m_repeat); + //m_desks->fakeKeyEvent(button, vk, + // keystroke.m_data.m_button.m_press, + // keystroke.m_data.m_button.m_repeat); break; } @@ -1374,7 +1385,7 @@ MSWindowsKeyState::getIDForKey(synergy::KeyMap::KeyItem& item, virtualKey, button, keyState, unicode, sizeof(unicode) / sizeof(unicode[0]), 0, hkl); KeyID id = static_cast(unicode[0]); - + switch (n) { case -1: return synergy::KeyMap::getDeadKey(id);