diff --git a/src/lib/platform/MSWindowsDesks.cpp b/src/lib/platform/MSWindowsDesks.cpp index 325e4578..3cc9e98d 100644 --- a/src/lib/platform/MSWindowsDesks.cpp +++ b/src/lib/platform/MSWindowsDesks.cpp @@ -352,7 +352,7 @@ void MSWindowsDesks::queryHookLibrary(HINSTANCE hookLibrary) { // look up functions - if (m_isPrimary && !m_noHooks) { + if (!m_noHooks) { m_install = (InstallFunc)GetProcAddress(hookLibrary, "install"); m_uninstall = (UninstallFunc)GetProcAddress(hookLibrary, "uninstall"); m_installScreensaver = @@ -690,7 +690,7 @@ MSWindowsDesks::deskThread(void* vdesk) continue; case SYNERGY_MSG_SWITCH: - if (m_isPrimary && !m_noHooks) { + if (!m_noHooks) { m_uninstall(); if (m_screensaverNotify) { m_uninstallScreensaver(); diff --git a/src/lib/platform/MSWindowsHook.cpp b/src/lib/platform/MSWindowsHook.cpp index b81d9373..f127ae98 100644 --- a/src/lib/platform/MSWindowsHook.cpp +++ b/src/lib/platform/MSWindowsHook.cpp @@ -43,7 +43,7 @@ MSWindowsHook::~MSWindowsHook() } void -MSWindowsHook::loadLibrary() +MSWindowsHook::loadLibrary(BOOL isPrimary) { // load library m_instance = LoadLibrary(g_name); @@ -69,7 +69,7 @@ MSWindowsHook::loadLibrary() } // initialize library - if (init(GetCurrentThreadId()) == 0) { + if (init(GetCurrentThreadId(), isPrimary) == 0) { LOG((CLOG_ERR "failed to init %s.dll, another program may be using it", g_name)); LOG((CLOG_INFO "restarting your computer may solve this error")); throw XScreenOpenFailure(); @@ -83,12 +83,12 @@ MSWindowsHook::getInstance() const } int -MSWindowsHook::init(DWORD threadID) +MSWindowsHook::init(DWORD threadID, BOOL isPrimary) { if (m_initFunc == NULL) { return NULL; } - return m_initFunc(threadID); + return m_initFunc(threadID, isPrimary); } int diff --git a/src/lib/platform/MSWindowsHook.h b/src/lib/platform/MSWindowsHook.h index 988528f8..007d004e 100644 --- a/src/lib/platform/MSWindowsHook.h +++ b/src/lib/platform/MSWindowsHook.h @@ -30,9 +30,9 @@ public: MSWindowsHook(); virtual ~MSWindowsHook(); - void loadLibrary(); + void loadLibrary(BOOL isPrimary); HINSTANCE getInstance() const; - int init(DWORD threadID); + int init(DWORD threadID, BOOL isPrimary); int cleanup(); void setSides(UInt32 sides); void setZone(SInt32 x, SInt32 y, SInt32 w, SInt32 h, SInt32 jumpZoneSize); diff --git a/src/lib/platform/MSWindowsScreen.cpp b/src/lib/platform/MSWindowsScreen.cpp index bcb794e1..ce50c130 100644 --- a/src/lib/platform/MSWindowsScreen.cpp +++ b/src/lib/platform/MSWindowsScreen.cpp @@ -128,8 +128,8 @@ MSWindowsScreen::MSWindowsScreen( s_screen = this; try { - if (m_isPrimary && !m_noHooks) { - m_hook.loadLibrary(); + if (!m_noHooks) { + m_hook.loadLibrary(m_isPrimary); } m_screensaver = new MSWindowsScreenSaver(); @@ -985,15 +985,16 @@ MSWindowsScreen::onPreDispatch(HWND hwnd, if (m_isPrimary) { return onPreDispatchPrimary(hwnd, message, wParam, lParam); } - - return false; + else { + return onPreDispatchSecondary(hwnd, message, wParam, lParam); + } } bool MSWindowsScreen::onPreDispatchPrimary(HWND, UINT message, WPARAM wParam, LPARAM lParam) { - LOG((CLOG_DEBUG5 "handling pre-dispatch primary")); + LOG((CLOG_DEBUG1 "handling primary pre-dispatch primary")); // handle event switch (message) { @@ -1047,6 +1048,19 @@ MSWindowsScreen::onPreDispatchPrimary(HWND, return false; } +bool +MSWindowsScreen::onPreDispatchSecondary(HWND, + UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case SYNERGY_MSG_KEY: + case SYNERGY_MSG_MOUSE_BUTTON: + LOG((CLOG_DEBUG1 "local input detected")); + } + + return false; +} + bool MSWindowsScreen::onEvent(HWND, UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* result) diff --git a/src/lib/platform/MSWindowsScreen.h b/src/lib/platform/MSWindowsScreen.h index 4b1f2c18..5aafd577 100644 --- a/src/lib/platform/MSWindowsScreen.h +++ b/src/lib/platform/MSWindowsScreen.h @@ -151,10 +151,14 @@ private: // HACK // the message should not be dispatched. bool onPreDispatch(HWND, UINT, WPARAM, LPARAM); - // handle message before it gets dispatched. returns true iff + // handle primary message before it gets dispatched. returns true iff // the message should not be dispatched. bool onPreDispatchPrimary(HWND, UINT, WPARAM, LPARAM); + // handle secondary message before it gets dispatched. returns true iff + // the message should not be dispatched. + bool onPreDispatchSecondary(HWND, UINT, WPARAM, LPARAM); + // handle message. returns true iff handled and optionally sets // \c *result (which defaults to 0). bool onEvent(HWND, UINT, WPARAM, LPARAM, LRESULT* result); diff --git a/src/lib/synwinhk/synwinhk.cpp b/src/lib/synwinhk/synwinhk.cpp index 30ba1289..eb6fd931 100644 --- a/src/lib/synwinhk/synwinhk.cpp +++ b/src/lib/synwinhk/synwinhk.cpp @@ -120,7 +120,8 @@ static LPARAM g_deadLParam = 0; static BYTE g_deadKeyState[256] = { 0 }; static BYTE g_keyState[256] = { 0 }; static DWORD g_hookThread = 0; -static bool g_fakeInput = false; +static bool g_fakeServerInput = false; +static BOOL g_isPrimary = TRUE; #if defined(_MSC_VER) #pragma data_seg() @@ -198,7 +199,7 @@ doKeyboardHookHandler(WPARAM wParam, LPARAM lParam) if (wParam == SYNERGY_HOOK_FAKE_INPUT_VIRTUAL_KEY && ((lParam >> 16) & 0xffu) == SYNERGY_HOOK_FAKE_INPUT_SCANCODE) { // update flag - g_fakeInput = ((lParam & 0x80000000u) == 0); + g_fakeServerInput = ((lParam & 0x80000000u) == 0); PostThreadMessage(g_threadID, SYNERGY_MSG_DEBUG, 0xff000000u | wParam, lParam); @@ -208,7 +209,7 @@ doKeyboardHookHandler(WPARAM wParam, LPARAM lParam) // if we're expecting fake input then just pass the event through // and do not forward to the server - if (g_fakeInput) { + if (g_fakeServerInput) { PostThreadMessage(g_threadID, SYNERGY_MSG_DEBUG, 0xfe000000u | wParam, lParam); return false; @@ -628,6 +629,7 @@ LRESULT CALLBACK getMessageHook(int code, WPARAM wParam, LPARAM lParam) { if (code >= 0) { + if (g_screenSaver) { MSG* msg = reinterpret_cast(lParam); if (msg->message == WM_SYSCOMMAND && @@ -671,6 +673,12 @@ keyboardLLHook(int code, WPARAM wParam, LPARAM lParam) if (code >= 0) { // decode the message KBDLLHOOKSTRUCT* info = reinterpret_cast(lParam); + + bool const injected = (info->flags & LLKHF_INJECTED); + if (!g_isPrimary && injected) { + return CallNextHookEx (g_keyboardLL, code, wParam, lParam); + } + WPARAM wParam = info->vkCode; LPARAM lParam = 1; // repeat code lParam |= (info->scanCode << 16); // scan code @@ -709,6 +717,12 @@ mouseLLHook(int code, WPARAM wParam, LPARAM lParam) if (code >= 0) { // decode the message MSLLHOOKSTRUCT* info = reinterpret_cast(lParam); + + bool const injected = info->flags & LLMHF_INJECTED; + if (!g_isPrimary && injected) { + return CallNextHookEx(g_mouseLL, code, wParam, lParam); + } + SInt32 x = static_cast(info->pt.x); SInt32 y = static_cast(info->pt.y); SInt32 w = static_cast(HIWORD(info->mouseData)); @@ -871,10 +885,12 @@ void * __cdecl memcpy(void * _Dst, const void * _Src, size_t _MaxCount) #endif int -init(DWORD threadID) +init(DWORD threadID, BOOL isPrimary) { assert(g_hinstance != NULL); + g_isPrimary = isPrimary; + // try to open process that last called init() to see if it's // still running or if it died without cleaning up. if (g_processID != 0 && g_processID != GetCurrentProcessId()) { @@ -950,7 +966,7 @@ install() g_deadLParam = 0; // reset fake input flag - g_fakeInput = false; + g_fakeServerInput = false; // check for mouse wheel support g_wheelSupport = getWheelSupport(); diff --git a/src/lib/synwinhk/synwinhk.h b/src/lib/synwinhk/synwinhk.h index fe279248..6f20bb83 100644 --- a/src/lib/synwinhk/synwinhk.h +++ b/src/lib/synwinhk/synwinhk.h @@ -67,7 +67,7 @@ enum EHookMode { kHOOK_RELAY_EVENTS }; -typedef int (*InitFunc)(DWORD targetQueueThreadID); +typedef int (*InitFunc)(DWORD targetQueueThreadID, BOOL isPrimary); typedef int (*CleanupFunc)(void); typedef EHookResult (*InstallFunc)(void); typedef int (*UninstallFunc)(void); @@ -77,7 +77,7 @@ typedef void (*SetSidesFunc)(UInt32); typedef void (*SetZoneFunc)(SInt32, SInt32, SInt32, SInt32, SInt32); typedef void (*SetModeFunc)(int); -CSYNERGYHOOK_API int init(DWORD); +CSYNERGYHOOK_API int init(DWORD, BOOL); CSYNERGYHOOK_API int cleanup(void); CSYNERGYHOOK_API EHookResult install(void); CSYNERGYHOOK_API int uninstall(void);