diff --git a/docs/dev/protocol_reference.md b/docs/dev/protocol_reference.md index 21f023179..bde8826fe 100644 --- a/docs/dev/protocol_reference.md +++ b/docs/dev/protocol_reference.md @@ -155,8 +155,8 @@ This table lists all protocol messages in alphabetical order. For a typical sequ | [**DDRG**](@ref kMsgDDragInfo) | @ref kMsgDDragInfo | Data | Server→Client | Drag file info | [MsgSize](#constraint-protocol-max-message-length), [ListSize](#constraint-max-list) | 1.5+ | | [**DFTR**](@ref kMsgDFileTransfer) | @ref kMsgDFileTransfer | Data | Both | File transfer data | [MsgSize](#constraint-protocol-max-message-length) | 1.5+ | | [**DINF**](@ref kMsgDInfo) | @ref kMsgDInfo | Data | Client→Server | Screen information | [MsgSize](#constraint-protocol-max-message-length) | 1.0+ | -| [**DKDL**](@ref kMsgDKeyDownLang) | @ref kMsgDKeyDownLang | Data | Server→Client | Key down with language | [MsgSize](#constraint-protocol-max-message-length), [KeyMap](#constraint-keymap) | 1.8+ | -| [**DKDN**](@ref kMsgDKeyDown) | @ref kMsgDKeyDown | Data | Server→Client | Key down | [MsgSize](#constraint-protocol-max-message-length), [KeyMap](#constraint-keymap) | 1.1+ | +| [**DKDL**](@ref kMsgDKeyDown) | @ref kMsgDKeyDown | Data | Server→Client | Key down with language | [MsgSize](#constraint-protocol-max-message-length), [KeyMap](#constraint-keymap) | 1.8+ | +| [**DKDN**](@ref kMsgDKeyDown1_1) | @ref kMsgDKeyDown1_1 | Data | Server→Client | Key down | [MsgSize](#constraint-protocol-max-message-length), [KeyMap](#constraint-keymap) | 1.1+ | | [**DKDN**](@ref kMsgDKeyDown1_0) | @ref kMsgDKeyDown1_0 | Data | Server→Client | Key down (legacy) | [MsgSize](#constraint-protocol-max-message-length), [KeyMap](#constraint-keymap) | 1.0 | | [**DKRP**](@ref kMsgDKeyRepeat) | @ref kMsgDKeyRepeat | Data | Server→Client | Key repeat | [MsgSize](#constraint-protocol-max-message-length), [KeyMap](#constraint-keymap) | 1.1+ | | [**DKRP**](@ref kMsgDKeyRepeat1_0) | @ref kMsgDKeyRepeat1_0 | Data | Server→Client | Key repeat (legacy) | [MsgSize](#constraint-protocol-max-message-length), [KeyMap](#constraint-keymap) | 1.0 | @@ -288,8 +288,8 @@ A modifier (modifier mask) represents the state of modifier keys (like Shift, Co | **1.4** | Nov 2012 | Synergy | Encryption support (@ref SecureSocket) | 1.4+ | | **1.5** | Sep 2013 | Synergy | File transfer | 1.5+ | | **1.6** | Jan 2014 | Synergy | Clipboard streaming | 1.6+ | -| **1.7** | Nov 2021 | Synergy | Secure input notifications | 1.7+ | -| **1.8** | Jun 2025 | Synergy | Language synchronization | 1.8+ | +| **1.7** | Sep 2021 | Synergy | Secure input notifications | 1.7+ | +| **1.8** | Nov 2021 | Synergy | Language synchronization | 1.8+ | ### Version Migration Guide diff --git a/src/lib/client/ServerProxy.cpp b/src/lib/client/ServerProxy.cpp index 26f8c3993..6f16a3c77 100644 --- a/src/lib/client/ServerProxy.cpp +++ b/src/lib/client/ServerProxy.cpp @@ -221,23 +221,23 @@ ServerProxy::ConnectionResult ServerProxy::parseMessage(const uint8_t *code) mouseWheel(); } - else if (memcmp(code, kMsgDKeyDown, 4) == 0) { + else if (memcmp(code, kMsgDKeyDown1_1, 4) == 0) { uint16_t id = 0; uint16_t mask = 0; uint16_t button = 0; - ProtocolUtil::readf(m_stream, kMsgDKeyDown + 4, &id, &mask, &button); + ProtocolUtil::readf(m_stream, kMsgDKeyDown1_1 + 4, &id, &mask, &button); LOG_VERBOSE("recv key down id=0x%08x, mask=0x%04x, button=0x%04x", id, mask, button); keyDown(id, mask, button, ""); } - else if (memcmp(code, kMsgDKeyDownLang, 4) == 0) { + else if (memcmp(code, kMsgDKeyDown, 4) == 0) { std::string lang; uint16_t id = 0; uint16_t mask = 0; uint16_t button = 0; - ProtocolUtil::readf(m_stream, kMsgDKeyDownLang + 4, &id, &mask, &button, &lang); + ProtocolUtil::readf(m_stream, kMsgDKeyDown + 4, &id, &mask, &button, &lang); LOG_VERBOSE("recv key down id=0x%08x, mask=0x%04x, button=0x%04x, lang=\"%s\"", id, mask, button, lang.c_str()); keyDown(id, mask, button, lang); diff --git a/src/lib/deskflow/ProtocolTypes.cpp b/src/lib/deskflow/ProtocolTypes.cpp index b8a104d99..cac481e65 100644 --- a/src/lib/deskflow/ProtocolTypes.cpp +++ b/src/lib/deskflow/ProtocolTypes.cpp @@ -13,6 +13,7 @@ const char *const kMsgHello = "%7s%2i%2i"; const char *const kMsgHelloArgs = "%2i%2i"; const char *const kMsgHelloBack = "%7s%2i%2i%s"; const char *const kMsgHelloBackArgs = "%2i%2i%s"; + const char *const kMsgCNoop = "CNOP"; const char *const kMsgCClose = "CBYE"; const char *const kMsgCEnter = "CINN%2i%2i%4i%2i"; @@ -22,9 +23,13 @@ const char *const kMsgCScreenSaver = "CSEC%1i"; const char *const kMsgCResetOptions = "CROP"; const char *const kMsgCInfoAck = "CIAK"; const char *const kMsgCKeepAlive = "CALV"; -const char *const kMsgDKeyDownLang = "DKDL%2i%2i%2i%s"; -const char *const kMsgDKeyDown = "DKDN%2i%2i%2i"; + +// This is weird, it goes from DKDN to DKDL. Someone misunderstood the pattern (keep the +// code, pick the form by negotiated version). Do not copy this. +const char *const kMsgDKeyDown = "DKDL%2i%2i%2i%s"; +const char *const kMsgDKeyDown1_1 = "DKDN%2i%2i%2i"; const char *const kMsgDKeyDown1_0 = "DKDN%2i%2i"; + const char *const kMsgDKeyRepeat = "DKRP%2i%2i%2i%2i%s"; const char *const kMsgDKeyRepeat1_0 = "DKRP%2i%2i%2i"; const char *const kMsgDKeyUp = "DKUP%2i%2i%2i"; diff --git a/src/lib/deskflow/ProtocolTypes.h b/src/lib/deskflow/ProtocolTypes.h index 24eaba77d..b27c2214f 100644 --- a/src/lib/deskflow/ProtocolTypes.h +++ b/src/lib/deskflow/ProtocolTypes.h @@ -504,7 +504,7 @@ extern const char *const kMsgCKeepAlive; */ /** - * @brief Key press with language code (v1.8+) + * @brief Key press event * * **Message Code**: `"DKDL"` * **Direction**: Primary → Secondary @@ -524,34 +524,6 @@ extern const char *const kMsgCKeepAlive; * "DKDL\x00\x61\x00\x00\x00\x1E\x00\x00\x00\x02en" * ``` * - * Enhanced version of kMsgDKeyDown that includes language information - * to help clients handle unknown language characters correctly. - * - * @see kMsgDKeyDown - * @since Protocol version 1.8 - */ -extern const char *const kMsgDKeyDownLang; - -/** - * @brief Key press event - * - * **Message Code**: `"DKDN"` - * **Direction**: Primary → Secondary - * **Format**: `"DKDN%2i%2i%2i"` - * **Parameters**: - * - `$1`: KeyID (2 bytes) - Virtual key identifier, often called a "keysym" on Linux/X11. This is platform-dependent - * and corresponds to values like `XK_a` on X11/Linux, `'a'` on macOS, and `'A'` on Windows. - * - `$2`: KeyModifierMask (2 bytes) - Active modifier keys - * - `$3`: KeyButton (2 bytes) - Physical key code, often called a "keycode" or "scancode". This is the raw, - * platform-dependent scan code of the key pressed. - * - * **Example**: - * - * 'a' key (KeyID 0x61), no modifiers, physical key (KeyButton 0x1E) - * ``` - * "DKDN\x00\x61\x00\x00\x00\x1E" - * ``` - * * **Key Mapping Strategy**: * The KeyButton parameter is crucial for proper key release handling. * The secondary screen should: @@ -564,11 +536,42 @@ extern const char *const kMsgDKeyDownLang; * - Different keyboard layouts may produce different KeyIDs * - Modifier keys released before the main key can alter KeyID * - * @see kMsgDKeyUp, kMsgDKeyDownLang - * @since Protocol version 1.1 + * The language code helps clients handle characters from a keyboard layout + * they do not have active. Only sent to clients that replied 1.8 in their hello. + * + * @see kMsgDKeyUp, kMsgDKeyDown1_1 + * @since Protocol version 1.8 */ extern const char *const kMsgDKeyDown; +/** + * @brief Key press event (v1.1 to v1.7) + * + * **Message Code**: `"DKDN"` + * **Direction**: Primary → Secondary + * **Format**: `"DKDN%2i%2i%2i"` + * **Parameters**: + * - `$1`: KeyID (2 bytes) - Virtual key identifier + * - `$2`: KeyModifierMask (2 bytes) - Active modifier keys + * - `$3`: KeyButton (2 bytes) - Physical key code + * + * **Example**: + * + * 'a' key (KeyID 0x61), no modifiers, physical key (KeyButton 0x1E) + * ``` + * "DKDN\x00\x61\x00\x00\x00\x1E" + * ``` + * + * Version without the language code. Used when communicating with + * protocol version 1.1 through 1.7 clients (Synergy 1.4 to 1.14.1, + * Barrier, Input Leap). The key mapping strategy is the same as for + * kMsgDKeyDown. + * + * @see kMsgDKeyDown + * @since Protocol version 1.1 + */ +extern const char *const kMsgDKeyDown1_1; + /** * @brief Key press event (legacy v1.0) * @@ -582,8 +585,8 @@ extern const char *const kMsgDKeyDown; * Legacy version without KeyButton parameter. Used only when * communicating with protocol version 1.0 clients. * - * @deprecated Use kMsgDKeyDown for protocol version 1.1+ - * @see kMsgDKeyDown + * @deprecated Use kMsgDKeyDown1_1 for protocol version 1.1+ + * @see kMsgDKeyDown1_1 * @since Protocol version 1.0 */ extern const char *const kMsgDKeyDown1_0; diff --git a/src/lib/server/ClientProxy1_1.cpp b/src/lib/server/ClientProxy1_1.cpp index 1503037a8..ea512cf1f 100644 --- a/src/lib/server/ClientProxy1_1.cpp +++ b/src/lib/server/ClientProxy1_1.cpp @@ -23,7 +23,7 @@ ClientProxy1_1::ClientProxy1_1(const std::string &name, deskflow::IStream *strea void ClientProxy1_1::keyDown(KeyID key, KeyModifierMask mask, KeyButton button, const std::string &) { LOG_VERBOSE("send key down to \"%s\" id=%d, mask=0x%04x, button=0x%04x", getName().c_str(), key, mask, button); - ProtocolUtil::writef(getStream(), kMsgDKeyDown, key, mask, button); + ProtocolUtil::writef(getStream(), kMsgDKeyDown1_1, key, mask, button); } void ClientProxy1_1::keyRepeat( diff --git a/src/lib/server/ClientProxy1_8.cpp b/src/lib/server/ClientProxy1_8.cpp index 1bf0116e8..14cefa5ac 100644 --- a/src/lib/server/ClientProxy1_8.cpp +++ b/src/lib/server/ClientProxy1_8.cpp @@ -36,5 +36,5 @@ void ClientProxy1_8::keyDown(KeyID key, KeyModifierMask mask, KeyButton button, (CLOG_VERBOSE "send key down to \"%s\" id=%d, mask=0x%04x, button=0x%04x, layout=%s", getName().c_str(), key, mask, button, language.c_str()) ); - ProtocolUtil::writef(getStream(), kMsgDKeyDownLang, key, mask, button, &language); + ProtocolUtil::writef(getStream(), kMsgDKeyDown, key, mask, button, &language); }