September 13, 2008

XIMプロトコルの闇

XIMプロトコルにはトリガーキーをライブラリ側へあらかじめ通知することできる。最近の実装ではこれらのイベントフローを使わずに常にキーイベントをすべてXIMサーバ側にforwardさせ、然るべきキーを受け取ったらpreedit開始/終了などのようにやっているようだけれど。
このトリガーキーを通知するイベント、XIM_REGISTER_TRIGGERKEYSというイベントなのだけど、次のように解説される:

Using the Dynamic Event Flow model, an IM Server sends
XIM_REGISTER_TRIGGERKEYS message to the IM library before
sending XIM_OPEN_REPLY message. Or the IM library may sup-
pose that the IM Server uses the Static Event Flow model.
まあここまではへえそうなんだ、で済むのだけれど、問題はそのフォーマット:

    XIM_REGISTER_TRIGGERKEYS (IM Server -> IM library)
2 CARD16 input-method-ID
2 unused
4 n byte length of on-keys
n LISTofXIMTRIGGERKEY on-keys list
4 m byte length of off-keys
m LISTofXIMTRIGGERKEY off-keys list

input-method IDってXIM_OPEN_REPLYで初めて通知される。つまり先にこっちを送ると宛先が不明になる。実際このような挙動をする実装のパケットを除いてみるとinput-method IDは0となっている。まあ0以外送りようがないわな。
ちなみに、リファレンス実装に近いkinput2のソースコードには興味深いコメントがある:

/*
* Notify conversion trigger keys.
*
* Note:
* The spec says that XIM_REGISTER_TRIGGERKEYS message should
* be sent to the client bofore XIM_OPEN_REPLY message, in
* order to use dynamic event flow model. However, this
* does not work with current Xlib implementation. So we
* send XIM_REGISTER_TRIGGERKEYS just after XIM_OPEN_REPLY,
* which works fine.
*/
どの実装ならあの仕様は動くんだろう?

[Update: 2008-11-05] しばらく更新してないのでお茶濁しに。XIM_SET_EVENT_MASKの説明にこんな記述がある。


If input-context-ID
is set to zero, the default value of the input-method-ID
will be changed to the event masks specified in the request.

まあXIM_REGISTER_TRIGGERKEYSも同様に、ってことなんだろう。にしても0しか送りようがないんだからだったら初めからいらんだろう、ってのが正直な感想だけど。