Add encrypted LAN mouse and keyboard sharing with four-edge handoff

This commit is contained in:
agrynco committed 2026-11-06 16:28:43 +02:00
1 parent 9b565dd55e
commit e0bfdd9a90
15 files changed
+1093 -104

No files matched your search

+36 -1
View File
@@ -725,7 +725,11 @@ bool App::registerHotkeys(const Settings &s, bool rollback)
Bytes App::lanCommand(const Bytes &command)
{
if (!lanService) lanService = std::make_unique<LanService>(data);
return lanService->command(command);
auto reply = lanService->command(command);
if (lanService->inputEnabled()) SetTimer(window, 7, 10, nullptr);
else KillTimer(window, 7);
if (lanService->takeInputChange()) resetInput();
return reply;
}
void App::applySettings(const Settings &requested)
{
@@ -1124,6 +1128,13 @@ void App::replayTyping()
}
LRESULT CALLBACK App::keyProc(int code, WPARAM wp, LPARAM lp)
{
if (code == HC_ACTION && current && current->lanService &&
(wp == WM_KEYDOWN || wp == WM_SYSKEYDOWN || wp == WM_KEYUP || wp == WM_SYSKEYUP))
{
bool consumed = current->lanService->keyboard(*(KBDLLHOOKSTRUCT *)lp, wp == WM_KEYDOWN || wp == WM_SYSKEYDOWN);
if (current->lanService->takeInputChange()) current->resetInput();
if (consumed) return 1; // Forwarded keys must not reach local hotkeys/snippets or other routers.
}
// MWB suppresses source-machine events that it forwards elsewhere. Let
// downstream hooks route the event before tracking it or starting a snippet.
// Call the chain exactly once; a local event can still be consumed below.
@@ -1153,6 +1164,13 @@ LRESULT CALLBACK App::mouseProc(int code, WPARAM wp, LPARAM lp)
{
if (code == HC_ACTION && current)
{
if (current->lanService)
{
bool consumed = current->lanService->mouse(UINT(wp), *(MSLLHOOKSTRUCT *)lp,
!current->busy && !current->suspended && !current->hotkeyCapture);
if (current->lanService->takeInputChange()) current->resetInput();
if (consumed) return 1;
}
// KSwitcher generates no mouse input. Remote clicks invalidate a typing
// range just like local clicks, including while a transaction is pending.
if (wp == WM_LBUTTONDOWN || wp == WM_RBUTTONDOWN || wp == WM_MBUTTONDOWN || wp == WM_MOUSEWHEEL)
@@ -2127,6 +2145,13 @@ LRESULT CALLBACK App::windowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
case WM_HOTKEY:
app->dispatch((int)wp);
return 0;
case WM_POWERBROADCAST:
if (wp == PBT_APMSUSPEND && app->lanService)
{
app->lanService->cancelInput();
app->resetInput();
}
return TRUE;
case ReplayTypingMessage:
app->replayTyping();
return 0;
@@ -2198,6 +2223,15 @@ LRESULT CALLBACK App::windowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
return TRUE;
}
case WM_TIMER:
if (wp == 7)
{
if (app->lanService)
{
if (app->suspended) app->lanService->cancelInput();
if (app->lanService->tickInput(!app->busy && !app->hotkeyCapture)) app->resetInput();
}
return 0;
}
if (wp == 6)
{
if (app->notificationRegistration && WaitForSingleObject(app->notificationRegistration, 0) == WAIT_OBJECT_0)
@@ -2341,6 +2375,7 @@ int App::execute()
if (!smoke && std::filesystem::exists(data / L"lan-pairing.bin"))
try { lanService = std::make_unique<LanService>(data); }
catch (const std::exception &e) { report(L"LAN module: " + wide(e.what())); }
if (lanService && lanService->inputEnabled()) SetTimer(window, 7, 10, nullptr);
SetTimer(window, 1, 60000, nullptr);
if (!smoke) SetTimer(window, 6, 1000, nullptr);
SetThreadExecutionState(ES_CONTINUOUS |