« xp3_vfs | メイン | キーボード関係のメモ »

2008年01月21日

日常の備忘録:: Synergy の犯人はローレベルフック

    

やはり、クライアント側で入力できないのは辛いので、再び何とかしようとした。
で、気付いたのは、正攻法でやらなくてもいいということ。
クライアント側に移動すると IME バーが出て、フォーカスがどこかに奪われる。
どうも見えないウィンドウがフォアグラウンドになっているようだ。
つまり、このフォアグラウンドのウィンドウのプロシージャの WM_KEYDOWN などを処理してやればいいのではないかと気付いた。
で、最初は、サーバーとなる CMSWindowsScreen.cpp のウィンドウのプロシージャに書いたが無反応。
そこで、Spy++ で Synergy 関係のウィンドウを調べてみると、クライアントに移った時 "SynergyDesk" という名前のウィンドウがメッセージを受けていた。
と言うことで、"SynergyDesk"で Grep すると、CMSWindowsDesks.cpp にあった。
で、ここから サーバー側にメッセージを送らなければならないので、CMSWindowsScreen.cpp のクラス名とウィンドウ名を調べると共に"Synergy"となっていた。
と言うことで、::FindWindow( "Synergy", "Synergy" ); でウィンドウハンドルを得て、PostMessage で送る。
CMSWindowsScreen.cpp のウィンドウのプロシージャで、クライアントに送る。
が、どうも文字がおかしい。
まあ、通常ルートと完全に同じにようには書いていないので、それが原因だろう。
同じようにするのは結構面倒。
ここで行き詰るが、そもそもサーバー上にある時には、メッセージをフックせずにそのまま流してくれればいいのに、何か処理して自分に投げているのが問題なんじゃないかと気付く。
なら、サーバー上にある時は、フックハンドラでスルーするように作り変えればいいんじゃないか?と言うことで、再びフックDLLをいじりだす。
どうやら、g_mode == kHOOK_RELAY_EVENTS となっている時が、クライアント上にカーソルがある時のようだ。
と言うことは、g_mode != kHOOK_RELAY_EVENTS で doKeyboardHookHandler の最初でスルーするようにすればうまく行くはず……と思ったけど、やっぱり時々変換モードがおかしくなる。
なんだろうと思って、ローレベルフックの部分をよく見てみる。
この中でも doKeyboardHookHandler をコールしているので、doKeyboardHookHandler 内ではじけばいいと思ったのだが……って、パラメータ変換してるし。
なんか lParam にフラグ追加している。
で、それを次のフックハンドラにそのまま流しているんですがこの人。
ほぼ間違いなくこれが原因だろう。
ここだけ直せば済むかもしれないけど、サーバー上にある時はスルーした方がいいだろうと言うことで、上の doKeyboardHookHandler はそのままにして、このローレベルフックの処理を g_mode == kHOOK_RELAY_EVENTS で囲んで、クライアントに流す時のみ通るようにした。
で、ビルドして実行。
問題なさそうだ。
この対応で、突然ローマ字入力になったり、全角英数字入力になったりしない。
このブログ書いている間で一度も切り替わらなかったので大丈夫だろう。
たぶん、ALT キーをつかんだままになる問題も修正されているはずだ。

後は、かな打ち時の「を」か。
これは、対応するキーコードがないので難しいと日本語対応版を作っているいろいろなページで書かれている。
確かに、いろいろやるもうまくいかない。
s_decomposeTable で何とかできるんじゃないかと言う気もするがよくわからない。
で、無理やり渡してやることにした。
「を」は、仮想キーコード 0xE5 + shift で、「0」は 0x30 。
サーバー側で変換できなくて、仮想キーが 0x30 で shift が押されている時、0xE5 + shift を送る。
これをクライアント側で受けると変換できないので、変換できない時に 0xE5 + shift なら scan code を 0x0B, 仮想キーを 0x30 として押してやる。
こうすれば「を」が入力できるようになった。
ピンポイントで特別対応なので問題ないとは思うが、もしかしたら何かあるかもしれない。
まあ、これで少し使ってみよう。



投稿者 Takenori : 2008年01月21日 01:09



コメント

大変参考になりました。変更差分のパッチを公開してもらえると助かります。

投稿者 desutai : 2008年03月01日 12:12

desutaiさん、こんにちは。

ローレベルフック周りの処理は特に問題ないのですが、かな打ちの「を」の対応がピンポイントで対応しているので、汎用性がありません。
そこが気がかりで公開を控えていましたが、折を見て注意文付きで公開しようと考え中でした。
後で Wiki の方へ貼り付けようと思います。

それでは。

投稿者 Takenori : 2008年03月01日 14:21

早速お返事頂き恐縮です。
ローレベルフック周りが興味深いです。その辺りだけでも先に公開頂けると幸いです。

投稿者 desutai : 2008年03月02日 00:27

desutaiさん、こんばんは。

このページへ貼り付けました。
http://wiki.nothing.sh/page/memo/Synergy

修正自体はたいしたものではなく、このエントリーに書いてある通りです。

それでは。

投稿者 Takenori : 2008年03月02日 00:38


comments powered by Disqus
Total : Today : Yesterday : なかのひと