im-cannaを作る
はじめに
このドキュメントは、im-cannaがどのように作られているかを説明するとともに、
im-cannaのような入力メソッドを作るにはどうしたらよいのかを知ってもらうための
実践的なものである。im-cannaの説明と言っても、C言語を研修で習っただけの人でも
理解できるような簡単なことばかりである。わざわざドキュメントを作らなければ
ならないほどのものか?というとまったく疑問である。しかし日本語GTK+ immoduleを
作ろうという人があまり増えない現状では、ソースコードをシンプルにするだけじゃ
足りなく、ドキュメントを書く必要があるのではないか、とも思うわけである。
im-cannaとは
im-cannaとは、かんなのためのGTK+ immoduleである。kinput2やIIIMFをGTK+
アプリケーションで使う場合とは異なり、GTK+ immoduleが直接かんなにアクセスする
ようになっている。
GTK+ immoduleとは
GTK+ immoduleは、GTK+2以降で導入された、入力メソッドモジュールであると言える。
入力メソッドを構成するためのインターフェースがGTK+によって用意されている
ので、XIMに比べてものすごく簡単に入力メソッドを作ることができる。IIIMFでも
Language Engineというモジュール形式の入力メソッドを作ることができるが、GTK+
の知識でプログラミングできるのがGTK+ immoduleのいいところと言える。
ユーザはさまざまなGTK+ immoduleを同時にインストールしておくことができ、
アプリケーションを再起動せずに切り替えることができる。切り替えはマウスの
右クリックメニューでできるので大変わかりやすい。
GTK+2では、kinput2などのXIMサーバやIIIMFのサポートも、それぞれGTK+ immoduleの
1つとして実装されている。
GTK+ immoduleを使うことができるのはGTK+アプリケーションに限られる。
GNOMEアプリケーションはすべてそうであるし、MozillaもGTK+アプリケーションで
あるので使うことはできる。OpenOffice.orgも将来的なバージョンでGTK+ immodule
をサポートする予定らしい。
かんなクライアントの仕組みと実装
かんなクライアントを書くのは非常に簡単である。かんなのサーバにアクセスする
ためのライブラリlibcannaが用意されているし、libcannaのAPIのドキュメントは十分に
そろえられている。かんなを使うオープンソースのアプリケーションは多数存在し、
ソースコードを参照することもできる。
かんなマニュアル(http://www.nec.co.jp/canna/docs/index.html)
にも基本的なlibcannaの使い方も日本語でのっているし、かんなの配付パッケージに
付いているマニュアルにもくわしい説明が日本語で書かれている。
im-cannaが使っているlibcannaの関数は、jrKanjiControl()とjrKanjiString()の2つ
だけである。したがってjrKanjiControl(3)とjrKanjiString(3)のマニュアルを
参照するだけでも入力メソッドを作ることができる。
実際にかんなAPIを使う基本的な手順を示す。
- かんなの初期化
- GUIから入力された文字をかんなに入力
- かんなの出力をGUIに出力
- 2,3の手順のくり返し
- かんなの終了
である。コードも以下に示す。
1. かんなの初期化
jrKanjiControl(0, KC_INITIALIZE, 0);
だけである。
jrKanjiControlは、かんなをコントロールするためのコマンドを送るための
関数である。最初の引数0はコンテキストIDであるが、さしあたっては0で
構わない。3番目の引数は返り値が入るところであるが、KC_INITIALIZEの
返り値は参照しない場合は0でよい。
2. GUIから入力された文字をかんなに入力
char buffer[1024];
jrKanjiStatus ks;
int ret;
ret = jrKanjiString(0, KEYCODE, buffer 1024, &ks);
buffer[ret] = '\0';
引数はコンテキストID, キーコード、確保したバッファ、バッファのサイズ、
jrKanjiStatusである。結果はバッファに格納され、かんなの状態はksに
格納される。バッファは初期化されないので最後の行でヌル文字をセット
している。
キーコードにはアルファベットの他に、C-aなどのかんなのコントロールコードを
使うこともできる。ただしかんなのコントロールコードはGTK+のキーコードとは
異なるのでマッピングが必要である。im-cannaではgdk2canna_keytable配列
でマッピングしている。
3. かんなの出力をGUIに出力
2の結果が格納されているbufferをGUIに反映するだけである。
5. かんなの終了
jrKanjiControl(0, KC_FINALIZE, 0);
だけである。
KC_FINALIZEの返り値を参照しない場合は、最後の引数は0でよい。
GTK+ immoduleの仕組みと実装
GTK+ immoduleは、GtkIMContextクラスをベースにして作る。基本的な手順は
以下の通りである。
- キーボードのキーが押されるとfilter_keypressにセットした関数が呼ばれる。
im-cannaの場合はim_canna_filter_keypress()である。
- "preedit_changed"イベントが送出されると、get_preedit_stringにセットした関数がアプリケーション側から呼ばれる。
im-cannaでは、im_canna_get_preedit_string()である。この関数で文字列をセットすると、アプリケーションはそれをプリエディット文字列として表示する。なお、表示するプリエディット文字列をアプリケーションに更新してほしいときにimmoduleの内部から"preedit_changed"イベントを送出する。
- 文字列を確定(commit)したいときは、immodule側から"commit"イベントを
確定文字列とともに送出する。するとアプリケーションはプリエディット文字列を
消去し、確定文字列をアプリケーションに入力してくれる。
im-cannaの構造
im-cannaでは、GtkIMContextクラスを継承してIMContextCannaクラスを作っている。
重要なファイルはimcanna.cだけである。imsss.cは、今後書き直す予定である。
かんなの日本語コードセットはEUCであるが、GTK+2のコードセットはUTF-8である。
したがってどこかでEUCとUTF-8の変換をしなくてはならない。im-cannaでは
euc2utf8()関数で変換を行なっている。注意しなければならないのは、
かんなはEUC-JPにないけれど、EUC-JPの範囲(0xA1A1-0xFEFE)にある文字を
出力することがある。一方、g_convert()関数(内部ではiconv()を呼んでいる)は、
EUC-JPの文字だけをUTF-8に変換し、それ以外はエラーを返す。euc2utf8では
エラー処理をしてこの問題を解決している。
日本語GTK+ immoduleにあっていい機能
- ホイールマウスによる候補選択
ホイールマウスで候補選択ウィンドウをナビゲーションすることができる。
kinput2や従来の日本語入力メソッドにはない機能である。Emacsにさえ見当たらない。
すばやく移動できるのでなかなか便利ではあるものの、マウスだけでは操作が完結せず、
結局キーボードとマウスの間を行ったり来たりしなくてはならない。上級ユーザには
向かないと言える。また、片手でマウスを握りしめているだけでは選択操作が完結
しないので、左で肩肘をしながら作業をするのが好きな、ものぐさなユーザにも
向かない。こうした要望(?)にこたえるには、immoduleだけではできず、GTK+側の
支援が必要になる。
なお、かな漢字変換エンジンはできるだけ正しい侯補を最初に表示できるように
改良されるべきものである。正しい侯補にいかにすばやく移動できるかは
重要ではあるものの、2次的なものにすぎない。
- 候補選択にGTK+テーマを反映させる
GTK+ immoduleはGTK+のものであるので、GTK+ならではのテーマ機能があっても
いいはずである。im-freewnnでは実装した。
- 手書き入力インターフェース
MS-IMEではマウスによる手書き入力から文字の侯補を推測し、入力することができる。
GTK+の手書き入力アプリケーションのkanjipadを組み合わせると、immoduleでも
手書きを実装できる。im-jaでは、すでに実装されている。
nakai at gnome.gr.jp