Merge pull request #6618 from symless/v1-issue-4288-printscreen-issue

Send Print Screen key to Windows clients
This commit is contained in:
Jnewbon 2020-01-21 15:47:24 +00:00 committed by GitHub
commit bbdc842b04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 105 additions and 80 deletions

View file

@ -88,6 +88,34 @@
// enable; <unused> // enable; <unused>
#define SYNERGY_MSG_FAKE_INPUT SYNERGY_HOOK_LAST_MSG + 12 #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 // MSWindowsDesks
// //
@ -245,21 +273,9 @@ MSWindowsDesks::getCursorPos(SInt32& x, SInt32& y) const
} }
void void
MSWindowsDesks::fakeKeyEvent( MSWindowsDesks::fakeKeyEvent(WORD virtualKey, WORD scanCode, DWORD flags, bool /*isAutoRepeat*/) const
KeyButton button, UINT virtualKey,
bool press, bool /*isAutoRepeat*/) const
{ {
// synthesize event sendMessage(SYNERGY_MSG_FAKE_KEY, flags, MAKELPARAM(scanCode, virtualKey));
DWORD flags = 0;
if (((button & 0x100u) != 0)) {
flags |= KEYEVENTF_EXTENDEDKEY;
}
if (!press) {
flags |= KEYEVENTF_KEYUP;
}
sendMessage(SYNERGY_MSG_FAKE_KEY, flags,
MAKEWORD(static_cast<BYTE>(button & 0xffu),
static_cast<BYTE>(virtualKey & 0xffu)));
} }
void void
@ -468,10 +484,10 @@ MSWindowsDesks::deskMouseMove(SInt32 x, SInt32 y) const
// the primary screen. // the primary screen.
SInt32 w = GetSystemMetrics(SM_CXSCREEN); SInt32 w = GetSystemMetrics(SM_CXSCREEN);
SInt32 h = GetSystemMetrics(SM_CYSCREEN); 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 * x) / (w - 1) + 0.5f),
(DWORD)((65535.0f * y) / (h - 1) + 0.5f), (DWORD)((65535.0f * y) / (h - 1) + 0.5f),
0, 0); 0);
} }
void void
@ -501,7 +517,7 @@ MSWindowsDesks::deskMouseRelativeMove(SInt32 dx, SInt32 dy) const
} }
// move relative to mouse position // 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 // restore mouse speed & acceleration
if (accelChanged) { if (accelChanged) {
@ -699,12 +715,16 @@ MSWindowsDesks::deskThread(void* vdesk)
break; break;
case SYNERGY_MSG_FAKE_KEY: 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; break;
case SYNERGY_MSG_FAKE_BUTTON: case SYNERGY_MSG_FAKE_BUTTON:
if (msg.wParam != 0) { if (msg.wParam != 0) {
mouse_event((DWORD)msg.wParam, 0, 0, (DWORD)msg.lParam, 0); send_mouse_input((DWORD)msg.wParam, 0, 0, (DWORD)msg.lParam);
} }
break; break;
@ -721,7 +741,7 @@ MSWindowsDesks::deskThread(void* vdesk)
case SYNERGY_MSG_FAKE_WHEEL: case SYNERGY_MSG_FAKE_WHEEL:
// XXX -- add support for x-axis scrolling // XXX -- add support for x-axis scrolling
if (msg.lParam != 0) { 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; break;
@ -750,9 +770,10 @@ MSWindowsDesks::deskThread(void* vdesk)
break; break;
case SYNERGY_MSG_FAKE_INPUT: case SYNERGY_MSG_FAKE_INPUT:
keybd_event(SYNERGY_HOOK_FAKE_INPUT_VIRTUAL_KEY, send_keyboard_input(
SYNERGY_HOOK_FAKE_INPUT_SCANCODE, SYNERGY_HOOK_FAKE_INPUT_VIRTUAL_KEY,
msg.wParam ? 0 : KEYEVENTF_KEYUP, 0); SYNERGY_HOOK_FAKE_INPUT_SCANCODE,
msg.wParam ? 0 : KEYEVENTF_KEYUP);
break; break;
} }
@ -820,7 +841,7 @@ MSWindowsDesks::checkDesk()
desk = index->second; 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. // first switch, then shut down.
if (m_stopOnDeskSwitch && m_activeDesk != NULL && name != m_activeDeskName) { if (m_stopOnDeskSwitch && m_activeDesk != NULL && name != m_activeDeskName) {
LOG((CLOG_DEBUG "shutting down because of desk switch to \"%s\"", name.c_str())); LOG((CLOG_DEBUG "shutting down because of desk switch to \"%s\"", name.c_str()));

View file

@ -162,8 +162,8 @@ public:
/*! /*!
Synthesize a press or release of key \c button. Synthesize a press or release of key \c button.
*/ */
void fakeKeyEvent(KeyButton button, UINT virtualKey, void fakeKeyEvent(WORD virtualKey, WORD scanCode,
bool press, bool isAutoRepeat) const; DWORD flags, bool isAutoRepeat) const;
//! Fake mouse press/release //! Fake mouse press/release
/*! /*!

View file

@ -2,11 +2,11 @@
* synergy -- mouse and keyboard sharing utility * synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd. * Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2003 Chris Schoeneman * Copyright (C) 2003 Chris Schoeneman
* *
* This package is free software; you can redistribute it and/or * This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file. * found in the file LICENSE that should have accompanied this file.
* *
* This package is distributed in the hope that it will be useful, * This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@ -68,10 +68,10 @@ const KeyID MSWindowsKeyState::s_virtualKey[] =
/* 0x019 */ { kKeyKanzi }, // VK_HANJA, VK_KANJI /* 0x019 */ { kKeyKanzi }, // VK_HANJA, VK_KANJI
/* 0x01a */ { kKeyNone }, // undefined /* 0x01a */ { kKeyNone }, // undefined
/* 0x01b */ { kKeyEscape }, // VK_ESCAPE /* 0x01b */ { kKeyEscape }, // VK_ESCAPE
/* 0x01c */ { kKeyHenkan }, // VK_CONVERT /* 0x01c */ { kKeyHenkan }, // VK_CONVERT
/* 0x01d */ { kKeyNone }, // VK_NONCONVERT /* 0x01d */ { kKeyNone }, // VK_NONCONVERT
/* 0x01e */ { kKeyNone }, // VK_ACCEPT /* 0x01e */ { kKeyNone }, // VK_ACCEPT
/* 0x01f */ { kKeyNone }, // VK_MODECHANGE /* 0x01f */ { kKeyNone }, // VK_MODECHANGE
/* 0x020 */ { kKeyNone }, // VK_SPACE /* 0x020 */ { kKeyNone }, // VK_SPACE
/* 0x021 */ { kKeyKP_PageUp }, // VK_PRIOR /* 0x021 */ { kKeyKP_PageUp }, // VK_PRIOR
/* 0x022 */ { kKeyKP_PageDown },// VK_NEXT /* 0x022 */ { kKeyKP_PageDown },// VK_NEXT
@ -286,15 +286,15 @@ const KeyID MSWindowsKeyState::s_virtualKey[] =
/* 0x0f3 */ { kKeyZenkaku }, // VK_OEM_AUTO /* 0x0f3 */ { kKeyZenkaku }, // VK_OEM_AUTO
/* 0x0f4 */ { kKeyZenkaku }, // VK_OEM_ENLW /* 0x0f4 */ { kKeyZenkaku }, // VK_OEM_ENLW
/* 0x0f5 */ { kKeyNone }, // OEM specific /* 0x0f5 */ { kKeyNone }, // OEM specific
/* 0x0f6 */ { kKeyNone }, // VK_ATTN /* 0x0f6 */ { kKeyNone }, // VK_ATTN
/* 0x0f7 */ { kKeyNone }, // VK_CRSEL /* 0x0f7 */ { kKeyNone }, // VK_CRSEL
/* 0x0f8 */ { kKeyNone }, // VK_EXSEL /* 0x0f8 */ { kKeyNone }, // VK_EXSEL
/* 0x0f9 */ { kKeyNone }, // VK_EREOF /* 0x0f9 */ { kKeyNone }, // VK_EREOF
/* 0x0fa */ { kKeyNone }, // VK_PLAY /* 0x0fa */ { kKeyNone }, // VK_PLAY
/* 0x0fb */ { kKeyNone }, // VK_ZOOM /* 0x0fb */ { kKeyNone }, // VK_ZOOM
/* 0x0fc */ { kKeyNone }, // reserved /* 0x0fc */ { kKeyNone }, // reserved
/* 0x0fd */ { kKeyNone }, // VK_PA1 /* 0x0fd */ { kKeyNone }, // VK_PA1
/* 0x0fe */ { kKeyNone }, // VK_OEM_CLEAR /* 0x0fe */ { kKeyNone }, // VK_OEM_CLEAR
/* 0x0ff */ { kKeyNone }, // reserved /* 0x0ff */ { kKeyNone }, // reserved
/* 0x100 */ { kKeyNone }, // reserved /* 0x100 */ { kKeyNone }, // reserved
@ -320,15 +320,15 @@ const KeyID MSWindowsKeyState::s_virtualKey[] =
/* 0x114 */ { kKeyNone }, // VK_CAPITAL /* 0x114 */ { kKeyNone }, // VK_CAPITAL
/* 0x115 */ { kKeyHangul }, // VK_HANGUL /* 0x115 */ { kKeyHangul }, // VK_HANGUL
/* 0x116 */ { kKeyNone }, // undefined /* 0x116 */ { kKeyNone }, // undefined
/* 0x117 */ { kKeyNone }, // VK_JUNJA /* 0x117 */ { kKeyNone }, // VK_JUNJA
/* 0x118 */ { kKeyNone }, // VK_FINAL /* 0x118 */ { kKeyNone }, // VK_FINAL
/* 0x119 */ { kKeyHanja }, // VK_HANJA /* 0x119 */ { kKeyHanja }, // VK_HANJA
/* 0x11a */ { kKeyNone }, // undefined /* 0x11a */ { kKeyNone }, // undefined
/* 0x11b */ { kKeyNone }, // VK_ESCAPE /* 0x11b */ { kKeyNone }, // VK_ESCAPE
/* 0x11c */ { kKeyNone }, // VK_CONVERT /* 0x11c */ { kKeyNone }, // VK_CONVERT
/* 0x11d */ { kKeyNone }, // VK_NONCONVERT /* 0x11d */ { kKeyNone }, // VK_NONCONVERT
/* 0x11e */ { kKeyNone }, // VK_ACCEPT /* 0x11e */ { kKeyNone }, // VK_ACCEPT
/* 0x11f */ { kKeyNone }, // VK_MODECHANGE /* 0x11f */ { kKeyNone }, // VK_MODECHANGE
/* 0x120 */ { kKeyNone }, // VK_SPACE /* 0x120 */ { kKeyNone }, // VK_SPACE
/* 0x121 */ { kKeyPageUp }, // VK_PRIOR /* 0x121 */ { kKeyPageUp }, // VK_PRIOR
/* 0x122 */ { kKeyPageDown }, // VK_NEXT /* 0x122 */ { kKeyPageDown }, // VK_NEXT
@ -543,15 +543,15 @@ const KeyID MSWindowsKeyState::s_virtualKey[] =
/* 0x1f3 */ { kKeyNone }, // VK_OEM_AUTO /* 0x1f3 */ { kKeyNone }, // VK_OEM_AUTO
/* 0x1f4 */ { kKeyNone }, // VK_OEM_ENLW /* 0x1f4 */ { kKeyNone }, // VK_OEM_ENLW
/* 0x1f5 */ { kKeyNone }, // OEM specific /* 0x1f5 */ { kKeyNone }, // OEM specific
/* 0x1f6 */ { kKeyNone }, // VK_ATTN /* 0x1f6 */ { kKeyNone }, // VK_ATTN
/* 0x1f7 */ { kKeyNone }, // VK_CRSEL /* 0x1f7 */ { kKeyNone }, // VK_CRSEL
/* 0x1f8 */ { kKeyNone }, // VK_EXSEL /* 0x1f8 */ { kKeyNone }, // VK_EXSEL
/* 0x1f9 */ { kKeyNone }, // VK_EREOF /* 0x1f9 */ { kKeyNone }, // VK_EREOF
/* 0x1fa */ { kKeyNone }, // VK_PLAY /* 0x1fa */ { kKeyNone }, // VK_PLAY
/* 0x1fb */ { kKeyNone }, // VK_ZOOM /* 0x1fb */ { kKeyNone }, // VK_ZOOM
/* 0x1fc */ { kKeyNone }, // reserved /* 0x1fc */ { kKeyNone }, // reserved
/* 0x1fd */ { kKeyNone }, // VK_PA1 /* 0x1fd */ { kKeyNone }, // VK_PA1
/* 0x1fe */ { kKeyNone }, // VK_OEM_CLEAR /* 0x1fe */ { kKeyNone }, // VK_OEM_CLEAR
/* 0x1ff */ { kKeyNone } // reserved /* 0x1ff */ { kKeyNone } // reserved
}; };
@ -959,7 +959,7 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap)
// deal with certain virtual keys specially // deal with certain virtual keys specially
switch (vk) { switch (vk) {
case VK_SHIFT: 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 // client, a patch from bug #242 (right shift broken for ms
// remote desktop) removed this to just use left shift, which // remote desktop) removed this to just use left shift, which
// caused bug #2799 (right shift broken for osx). // 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 // set virtual key to button table
if (activeLayout == m_groups[g]) { if (activeLayout == m_groups[g]) {
for (KeyButton i = 0; i < 512; ++i) { for (KeyButton i = 0; i < 512; ++i) {
@ -1176,7 +1183,7 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap)
} }
} }
} }
// save each key. the map will automatically discard // save each key. the map will automatically discard
// duplicates, like an unshift and shifted version of // duplicates, like an unshift and shifted version of
// a key that's insensitive to shift. // a key that's insensitive to shift.
@ -1210,14 +1217,8 @@ MSWindowsKeyState::getKeyMap(synergy::KeyMap& keyMap)
item.m_sensitive |= KeyModifierControl; item.m_sensitive |= KeyModifierControl;
break; break;
case VK_SNAPSHOT:
item.m_sensitive |= KeyModifierAlt;
if ((i & 0x100u) == 0) {
// non-extended snapshot key requires alt
item.m_required |= KeyModifierAlt;
}
break;
} }
addKeyEntry(keyMap, item); addKeyEntry(keyMap, item);
} }
} }
@ -1234,7 +1235,7 @@ MSWindowsKeyState::fakeKey(const Keystroke& keystroke)
switch (keystroke.m_type) { switch (keystroke.m_type) {
case Keystroke::kButton: { 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")); 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 // windows doesn't send key ups for key repeats
if (keystroke.m_data.m_button.m_repeat && if (keystroke.m_data.m_button.m_repeat &&
@ -1244,24 +1245,27 @@ MSWindowsKeyState::fakeKey(const Keystroke& keystroke)
} }
// get the virtual key for the button // 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 // special handling of VK_SNAPSHOT
if (vk == VK_SNAPSHOT) { if (vk == VK_SNAPSHOT)
if ((getActiveModifiers() & KeyModifierAlt) != 0) { scanCode = (getActiveModifiers() & KeyModifierAlt) ? 0x54 : 0x137;
// snapshot active window
button = 1; if (scanCode & 0x100)
} flags |= KEYEVENTF_EXTENDEDKEY;
else {
// snapshot full screen //vk,sc,flags,keystroke.m_data.m_button.m_repeat
button = 0;
} m_desks->fakeKeyEvent(vk, scanCode, flags, keystroke.m_data.m_button.m_repeat);
}
// synthesize event // synthesize event
m_desks->fakeKeyEvent(button, vk, //m_desks->fakeKeyEvent(button, vk,
keystroke.m_data.m_button.m_press, // keystroke.m_data.m_button.m_press,
keystroke.m_data.m_button.m_repeat); // keystroke.m_data.m_button.m_repeat);
break; break;
} }
@ -1374,7 +1378,7 @@ MSWindowsKeyState::getIDForKey(synergy::KeyMap::KeyItem& item,
virtualKey, button, keyState, unicode, virtualKey, button, keyState, unicode,
sizeof(unicode) / sizeof(unicode[0]), 0, hkl); sizeof(unicode) / sizeof(unicode[0]), 0, hkl);
KeyID id = static_cast<KeyID>(unicode[0]); KeyID id = static_cast<KeyID>(unicode[0]);
switch (n) { switch (n) {
case -1: case -1:
return synergy::KeyMap::getDeadKey(id); return synergy::KeyMap::getDeadKey(id);