synergy-plus の日本語対応+α

気がついたら半年ほど放置していた。まぁ気が向いたときの投稿ということで。

前振り

  1. Windows7を機にx64環境へ移行を計画
  2. 常用していて手放せないsynergyのx64版がない
  3. synergyは開発が長いことと待っていたのでforkしたsynergy-plusがあり、こちらはx86/x64ともにある

というかんじで、synergyのソースにx64パッチを当てている方もいらしたが、せっかくなので設定の互換等もあるsynergy-plusへ移行をすることにした。

synergy-plusへの日本語KB対応パッチ等の適用

synergyでもあったように、日本語キーボードの場合にいろいろと問題があるのはplusでも同じだった。なのでsynergy向けに公開されている情報を元にplusのソースコードにパッチを当ててビルドし直し。調査や情報公開をされていた方々に感謝。

Synergy - 斜に
http://naname.jp/index.php?Synergy
1.3.2 (正確にはr897)をビルド - 忘れないようにメモ
http://d.hatena.ne.jp/desutai/20080304/1204598380
memo/Synergy - wiki@nothing
http://wiki.nothing.sh/page/memo/Synergy

ベースが同じだけあり、全く差異がなかったためすんなりパッチの適用が完了。すでに先達の方が公開されている内容と同じだが、自分用メモのためにも下記にまとめておく。また、併せてALT押しっぱなし問題など上述ページにあるパッチも当てさせていただいた。

diff --git a/lib/platform/CMSWindowsKeyState.cpp b/lib/platform/CMSWindowsKeyState.cpp
--- a/lib/platform/CMSWindowsKeyState.cpp
+++ b/lib/platform/CMSWindowsKeyState.cpp
@@ -64,7 +64,7 @@
 	/* 0x01a */ { kKeyNone },		// undefined
 	/* 0x01b */ { kKeyEscape },		// VK_ESCAPE
 	/* 0x01c */ { kKeyHenkan },		// VK_CONVERT		
-	/* 0x01d */ { kKeyNone },		// VK_NONCONVERT	
+	/* 0x01d */ { kKeyMuhenkan },	// VK_NONCONVERT	
 	/* 0x01e */ { kKeyNone },		// VK_ACCEPT		
 	/* 0x01f */ { kKeyNone },		// VK_MODECHANGE	
 	/* 0x020 */ { kKeyNone },		// VK_SPACE
@@ -1154,6 +1154,12 @@
 				else {
 					// found in table
 					switch (m_buttonToVK[i]) {
+					case VK_KANJI:
+					case VK_OEM_AUTO:
+					case VK_OEM_ENLW:
+						item.m_id       = kKeyZenkaku;
+						break;
+
 					case VK_TAB:
 						// add kKeyLeftTab, too
 						item.m_id         = kKeyLeftTab;
diff --git a/lib/synergy/KeyTypes.h b/lib/synergy/KeyTypes.h
--- a/lib/synergy/KeyTypes.h
+++ b/lib/synergy/KeyTypes.h
@@ -103,7 +103,8 @@
 static const KeyID		kKeyScrollLock	= 0xEF14;
 static const KeyID		kKeySysReq		= 0xEF15;
 static const KeyID		kKeyEscape		= 0xEF1B;
+static const KeyID		kKeyMuhenkan	= 0xEF22;	/* Cancel Conversion */
 static const KeyID		kKeyHenkan		= 0xEF23;	/* Start/Stop Conversion */
 static const KeyID		kKeyHangulKana	= 0xEF26;	/* Hangul, Kana */
 static const KeyID		kKeyHiraganaKatakana = 0xEF27;	/* Hiragana/Katakana toggle */
 static const KeyID		kKeyZenkaku		= 0xEF2A;	/* Zenkaku/Hankaku */
@@ -106,8 +107,8 @@
 static const KeyID		kKeyHenkan		= 0xEF23;	/* Start/Stop Conversion */
 static const KeyID		kKeyHangulKana	= 0xEF26;	/* Hangul, Kana */
 static const KeyID		kKeyHiraganaKatakana = 0xEF27;	/* Hiragana/Katakana toggle */
 static const KeyID		kKeyZenkaku		= 0xEF2A;	/* Zenkaku/Hankaku */
-static const KeyID		kKeyHanjaKanzi	= 0xEF2A;	/* Hanja, Kanzi */
+static const KeyID		kKeyHanjaKanzi	= 0x0060;	/* Hanja, Kanzi */
 static const KeyID		kKeyDelete		= 0xEFFF;	/* Delete, rubout */
 
 // cursor control
diff --git a/lib/platform/CSynergyHook.cpp b/lib/platform/CSynergyHook.cpp
--- a/lib/platform/CSynergyHook.cpp
+++ b/lib/platform/CSynergyHook.cpp
@@ -202,6 +202,9 @@
 bool
 doKeyboardHookHandler(WPARAM wParam, LPARAM lParam)
 {
+	if( g_mode != kHOOK_RELAY_EVENTS )
+		return false;
+
 	// check for special events indicating if we should start or stop
 	// passing events through and not report them to the server.  this
 	// is used to allow the server to synthesize events locally but
@@ -682,21 +685,22 @@
 keyboardLLHook(int code, WPARAM wParam, LPARAM lParam)
 {
 	if (code >= 0) {
-		// decode the message
-		KBDLLHOOKSTRUCT* info = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
-		WPARAM wParam = info->vkCode;
-		LPARAM lParam = 1;							// repeat code
-		lParam      |= (info->scanCode << 16);		// scan code
-		if (info->flags & LLKHF_EXTENDED) {
-			lParam  |= (1lu << 24);					// extended key
-		}
-		if (info->flags & LLKHF_ALTDOWN) {
-			lParam  |= (1lu << 29);					// context code
-		}
-		if (info->flags & LLKHF_UP) {
-			lParam  |= (1lu << 31);					// transition
-		}
-		// FIXME -- bit 30 should be set if key was already down but
-		// we don't know that info.  as a result we'll never generate
-		// key repeat events.
+		if( g_mode == kHOOK_RELAY_EVENTS ) {
+			// decode the message
+			KBDLLHOOKSTRUCT* info = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
+			WPARAM wParam = info->vkCode;
+			LPARAM lParam = 1;							// repeat code
+			lParam      |= (info->scanCode << 16);		// scan code
+			if (info->flags & LLKHF_EXTENDED) {
+				lParam  |= (1lu << 24);					// extended key
+			}
+			if (info->flags & LLKHF_ALTDOWN) {
+				lParam  |= (1lu << 29);					// context code
+			}
+			if (info->flags & LLKHF_UP) {
+				lParam  |= (1lu << 31);					// transition
+			}
+			// FIXME -- bit 30 should be set if key was already down but
+			// we don't know that info.  as a result we'll never generate
+			// key repeat events.
 
@@ -702,7 +706,8 @@
 
-		// handle the message
-		if (keyboardHookHandler(wParam, lParam)) {
-			return 1;
+			// handle the message
+			if (keyboardHookHandler(wParam, lParam)) {
+				return 1;
+			}
 		}
 	}

ログウィンドウの日本語化

現在ログウィンドウには2バイト文字が表示されると表示が崩れるので、これに対してのパッチを当てる。原因はロケールの設定がされていないためのようなので、アプリケーション起動時にシステムロケールを取得して設定するように変更。

diff --git a/cmd/synergyc/synergyc.cpp b/cmd/synergyc/synergyc.cpp
--- a/cmd/synergyc/synergyc.cpp
+++ b/cmd/synergyc/synergyc.cpp
@@ -852,6 +852,9 @@
 int WINAPI
 WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
 {
+	// Change locale to system locale for 'wctomb' etc...
+	setlocale(LC_CTYPE, setlocale(LC_CTYPE, ""));
+
 	try {
 		CArchMiscWindows::setIcons((HICON)LoadImage(instance,
 									MAKEINTRESOURCE(IDI_SYNERGY),
diff --git a/cmd/synergys/synergys.cpp b/cmd/synergys/synergys.cpp
--- a/cmd/synergys/synergys.cpp
+++ b/cmd/synergys/synergys.cpp
@@ -1266,6 +1266,9 @@
 int WINAPI
 WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
 {
+	// Change locale to system locale for 'wctomb' etc...
+	setlocale(LC_CTYPE, setlocale(LC_CTYPE, ""));
+
 	try {
 		CArchMiscWindows::setIcons((HICON)LoadImage(instance,
 									MAKEINTRESOURCE(IDI_SYNERGY),

次なる課題は

synergyクリップボードの内容についてテキストとビットマップは共有できるが、エクスプローラのファイルについては現在できない。そこで、ファイルについてもクリップボードを経由して共有できるようになると非常に便利なのでこの機能を synergy-plus へ実装したいと思う。せっかくオープンソースで公開されている訳だし、いじらにゃ損(?)ということで。

蛇足

CMAKEってのを初めて使ってみたけど便利!自分のビルド環境を使えるというのがいい。synergyの場合、無理矢理VS2008でビルドするといろいろ警告が出たりと気になっていたけど、plusでCMAKEからVS2008のソリューションを生成すればそんなことはなかった。