たわごと (04年1月分)

今月分(ホーム)先月分03年12月分03年11月分03年8-10月分03年6月分03年1月分02年12月分02年11月分02年10月分02年9月分02年8月分02年7月分02年6月分


04/01/30
●im-xim

あれ、こんなページがあったのか。一度読んだような気がするが、すっかり忘れていた。gtk+ 自体に変更を加えようとしているのか。「本来アプリが食うべきイベントをIMが食ってしまう」って本当? もし、食うとしたら IM の設計がおかしいと思うが。vi + im-xim (gtk) + kinput2 + canna で試してみたけど、入力を始めて未確定入力が残っている状態でなければ、Ctrl キーはすべてアプリに渡されているみたいだけど。

例に書いてある Ctrl-x 2 でウィンドウ分割っていうのは Emacs のことだろうけど、2 も IM が食ってしまうというは、Emacs 側の仕様そのものの問題なので Emacs のほうを変更すべきで XEmacsのXIM とか Emacs21とXIM を参考にすべきこと。

04/01/26 に書いた「日本語入力がオンになったとき」というのは、入力が始まって未確定入力が残っているときにしないといけないなあ。

あと、「並列に処理しようとする」というのはうそ。もし、並列に処理しようとしてれば、Ctrl-O でファイルを開くダイアログが出たとしても、文節がのびるというような IM の動作もするはずだけどしてない。
これだとシグナルをブロックするだけだとだめかもしれないなあ。
並列処理って言ったのは、メインループが

while(1){
    XNextEvent(display, ev);
    handler = first_handler;
    while (handler) {
        if (matched_handler(handler, ev))
            handeler->procedure(ev);
        handler = handler->next;
    }
}

みたいになっていると仮定してたんだけど

while(1){
    XNextEvent(display, ev);
    handler = first_handler;
    while (handler) {
        if (matched_handler(handler, ev)) {
            handeler->procedure(ev);
            break;
        }
        handler = handler->next;
    }
}

みたいになっているとすると、キーイベントに対してのシグナルをブロックすることで、matched_handler が FALSE を返すようになるのであれば問題ないが、handler->procedure が何もしないようになるだけだとするとうまくいかない。


04/01/29
●Sodipodi

Sodipodi って何よ。

●im-xim
04/01/28 に書いたやり方について調べてみる。

(1) キー・バインディングに対応するシグナルを block/unblock する
1. gtk_binding_set_by_class, g_signal_lookup 2. 不要 3. g_signal_handler_block 4. g_signal_handler_unblock
[疑問点] ドキュメントに何も書いていないのではっきり言ってわからない。gtk_binding_set_by_class の戻り値に対して、->entries->set_next をたどれば、すべてのキー・バインディングをパースできる?

(2) アクセラレーター・グループを使う
1. gtk_accel_groups_from_object, gtk_accel_group_find 2. 必要 3., 4. gtk_accel_group_connect
[問題点] ショートカットキー以外のキー・バインディングは停止できない。

(3) アクセラレータ・マップを使う
1. gtk_accel_map_foreach 2. 必要 3., 4. gtk_accel_map_change_entry
[疑問点] accelerator maps の解除は key=0 modifier=0 で、gtk_accel_map_change_entry を使えば可能だったりするか? でないとすると、gtk_accel_map_remove_entry という関数はないので不可能ということか?
[問題点] ショートカットキー以外のキー・バインディングは停止できない。

(4) XKeyEvent を使う
不可能?

(1) の方法はこんな感じか? 全く自身はない。いちばん美しいのはこの方法だと思うのだが。

static void block_handler(GtkWidget *widget)
{
    GtkBindingEntry *entry;

    entry = (GtkBindingEntry *) gtk_binding_set_by_class(G_OBJECT(widget))->entries;

    for (;;) {
        if (entry->modifiers == GDK_CONTROL_MASK) {
            guint id = g_signal_lookup(entry->signals->signal_name, G_TYPE_OBJECT);
            g_signal_handler_block((gpointer)widget, id);
        }
        if (!entry->set_next) break;
        entry = binding_entry->set_next;
    }
}

static void unblock_handler(GtkWidget *widget)
{
    GtkBindingEntry *entry;

    entry = (GtkBindingEntry *) gtk_binding_set_by_class(G_OBJECT(widget))->entries;

    for (;;) {
        if (entry->modifiers == GDK_CONTROL_MASK) {
            guint id = g_signal_lookup(entry->signals->signal_name, G_TYPE_OBJECT);
            g_signal_handler_unblock((gpointer)widget, id);
        }
        if (!entry->set_next) break;
        entry = binding_entry->set_next;
    }
}

(2) も書いてみる。gedit ならうまくいくのでは、ということで。

static GClosure *closure_save[26];

static void null_function()
{
}

static gboolean find_accel_and_save_closures(GtkAccelKey *key, GClosure *closure, gpointer data)
{
    // C-a から C-z まですべて停止。C-x C-c C-v とか停止しなくていいかもしれないけど。
    if (key->accel_mods == GDK_CONTROL_MASK && key->accel_key >= 'a' && key->accel_key <= 'z') 
    {
        closure_save[key->accel_key - 'a'] = closure;
        return gtk_true();
    }
    else
        return gtk_false();
}

static gboolean find_accel(GtkAccelKey *key, GClosure *closure, gpointer data)
{
    if (key->accel_mods == GDK_CONTROL_MASK) 
        return gtk_true();
     else
        return gtk_false();
}

static void save_accel(GtkWidget *widget)
{
    GtkAccelGroup *accel_group;

    accel_group = (GtkAccelGroup *) gtk_accel_groups_from_object(G_OBJECT(widget))->data;

    for (;;) {
        GClosure *closure;
        GtkAccelKey *key = gtk_accel_group_find(accel_group, find_accel_and_save_closures, NULL);
        if (!key) break;
        closure = g_cclosure_new(null_function, NULL, g_free);
        gtk_accel_group_connect(accel_group, key->accel_key, key->accel_mods, key->accel_flags, closure);
    }
}

static void restore_accel(GtkWidget *widget)
{
    GtkAccelGroup *accel_group;

    accel_group = (GtkAccelGroup *) gtk_accel_groups_from_object(G_OBJECT(widget))->data;

    for (;;) {
        GClosure *closure;
        GtkAccelKey *key = gtk_accel_group_find(accel_group, find_accel, NULL);
        if (!key) break;
        gtk_accel_group_connect(accel_group, key->accel_key, key->accel_mods, key->accel_flags, closure_save[key->accel_key - 'a']);
    }
}

04/01/28
●Shift + Zenkaku_Hankaku

kinput2 + Wnn では、Shift + Zenkaku_Hankaku で日本語モードに切り替わらない。しかし、日本語モードの終了はできる。どうなってるんだろう。ここらへんに書いてあるXIC属性と関係がある? 違うかな。

●im-xim
下の gedit の件、なんとなくわかったような気がするのでメモしておく。

・キーイベントはプロセスごとに送られる。
・Xアプリでは、日本語入力がオンになったとき、キーイベントが送られるプロセスがXIMに切り替わるためすべてのキーイベントをXIMが受け取れる。
・gtkアプリでは、日本語入力がオンになっても、キーイベントが送られるプロセスは切り替わらずアプリのままであり、im-ximを経由してXIMに送られる。
・im-ximはすべてのキーイベントを受け取れるようにはなっているが、ショートカットキーが設定されている場合、並列に処理しようとしてしまうため、im-ximへのキーイベントを処理しただけでは期待通りには動作しない。

すなわち、日本語入力がオンになったとき

1. 使用したいキーがショートカットキーに割り当てられていないかどうかを探し、
2. 割り当てられていたらそのキーイベントの内容を必要なら保存し、
3. それを一時停止または解除し、

日本語入力がオフになったとき

4. それを再開または再登録

することで実現できるのではないかと考えられる。


04/01/26
●im-xim

普段 PC104 キーボードしか使わないので、気がつかなかったが Shift + Zenkaku_Hankaku というキーバインドでも日本語入力モードに切り替わる。kinput2 に一切そのような設定がされていなくても切り替わるので gtk から XIM を呼び出す部分 im-xim がそうしているとしか思えないのだが、それに対するドキュメントが見つけられない。それに対する設定ファイルは見つけられないし、ネット上で見られる CVS にはそのようなソースコードも見つけられない。
RedHat 独自のパッチなのだろうか? RPM の中に入っているパッチを見るしかないのかな。
gedit なんかだと Ctrl+W や Ctrl+L のショートカットキーが Canna に渡されず、一覧表示や文節伸張がすごくやり辛いんだけど im-xim をいぢればなんとかなるかな。
im-xim の改造を一人でやるよりは、gtk-uim と uim-xim の実装に協力したほうがいいかな。
uim の対応アプリケーションのページの gedit の記述を見ると gtk の内部をいぢらないと無理っぽい気もするけど。
あと、over-the-spot にならないのもなんとかなるかな。ここを見ると難しそうにも思えるけど、XIMを直で呼んだらどうなのよ。


04/01/25
●FreeType & X-TT

モトヤのフォントをインストールして mkfontscale をやり直したら、MS PGothic や MS UI Gothic など font 番号が 0 以外のものの記述が作られない。最初にやった時は作られたのに、なぜだ。よくわからない。とりあえず手作業で編集すれば大丈夫そうだけど。
試しに何も編集せず再起動してみたけど、書いてなくても MS PGothic とか使えちゃうみたい。わかんないけど。
やっと、下と同じやりかたを書いているペー ジを発見。freetype とか xtt でひっかかんなかったんで、なかなか見つけられなかった。そうか、fc-cache というコマンドを使うといいのか。フォントサーバーの再起動は、/etc/init.d/xfs reload とやるのがいいのか。


04/01/23
●FreeType & X-TT

下に「最近の freetype はほとんど x-tt の機能も入ってるはず」と書いたのはうそ。下のやり方だけだと太字が出ない。斜字 (italic) は出るんだけど。auto bold の設定方法とか探したけど結局ないようなので、x-tt の TTCap を使うしかないみたい。After X-TT Project によるパッチのあたった freetype (freetype-xtt2) を使うのが一番よさそうだけど、めんどくさいからいいや。


04/01/21
●FreeType & X-TT

Windows の TrueType フォントを使うにはというような内容が書いてあるページを検索してみると、なぜか freetype をやめて x-tt を使え、というようなことが書いてある。そんなことしなくてもできるよなあ。最近の freetype はほとんど x-tt の機能も入ってるはずだし。
という訳で試してみる。やり方は、

  1. フォントのリンク
    /mnt/win98/windows/fonts に windows のフォントがあるものとして
    cd /usr/share/fonts
    mkdir windows
    cd windows
    ln -s /mnt/win98/windows/fonts/*.tt? .
  2. 日本語フォントに対して ttindex で、*.tti をつくる。
    ttindex msmincho.ttf
    ttindex msgothic.ttf
  3. fonts.* ファイルの作成、fonts.alias は kochi のファイルをコピーして編集する。
    mkfontscale
    mkfontdir
    cp ../ja/TrueType/fonts.alias .
    vi fonts.alias
  4. /etc/X11/fs/config の /usr/share/fonts/ja が書いてある次あたりに /usr/share/fonts/windows, を追加。設定の途中には , が必要なのに注意。
  5. フォントサーバーの再起動。

以上で問題なく使用可能。

●Canna
MS-IME は基本的には WX2+ であるが、いくつかのキーを ATOK をまねて増やしている。これに合わせて MS-IME 風というのを作ってみる(こんな感じ)。touroku-mode, extend-mode は MS-IME風というわけじゃないけど追加。

  ATOK風 WX2+風 MS-IME風
次候補 Space Space Space
一覧 Ctrl+w Ctrl+w Ctrl+w
確定 Ctrl+nまたはEnter Ctrl+nまたはEnter Ctrl+nまたはEnter
文節伸張 Ctrl+lまたは Shift+→ Ctrl+lまたはShift+→
文節短縮 Ctrl+kまたは Shift+← Ctrl+kまたはShift+←
中止 Escape Escape Escape
次へ Ctrl+sまたはShift+→ Ctrl+sまたは
前へ Ctrl+dまたはShift+← Ctrl+dまたは
字種変更
字種変更      
ひらがな変換 Ctrl+uまたはF6 F6 Ctrl+uまたはF6
カタカナ変換 Ctrl+iまたはF7 F7 Ctrl+iまたはF7
半角(カタカナ)変換 Ctrl+oまたはF8 F8 Ctrl+oまたはF8
全角英数変換 Ctrl+pまたはF9 F9 Ctrl+pまたはF9
最初へ Ctrl+aまたはCtrl+←   Ctrl+aまたはCtrl+←
最後へ Ctrl+またはCtrl+→   Ctrl+またはCtrl+→
ぁぃぅぇぉ la ... lo la ... lo, xa ... xo la ... lo, xa ... xo
登録モード     Ctrl+rまたはF2
拡張モード     Ctrl+eまたはF3

04/01/20
●Fedora Core 1

結局、逆戻り。これの gVim って GTK 版ってやつ?

[RedHat9より悪くなった点]
gVim で XIM挿入ができなくなっている。--enable-xim でコンパイルされていないのか? 下手にできるようして、XIM が落ちると gVim を巻き添えにしてしまうのよりはいいかもしれないけど。
/var/lib/canna/sample がなくなっている。まあ、ほかからコピーするからいいけど。
UTF8 !!!

[良くなった点]
GNOMEアプリでの kinput2 入力で文節伸張・短縮をしたときの表示がまともになった。
gVim のフォント変更がまともにできるようになった。デフォルトがゴシックなのも良し。

[まだまだ残る問題点]
Canna + kinput2 で一覧での選択が入力位置の表示に反映しない。
Canna + kinput2 で入力モード終了の変更ができない。しかたがないのでこんなパッチをつくってみる。

●Canna メモ

  Default ATOK風
次候補 Space Space
一覧 Ctrl+w Ctrl+w
確定 Ctrl+nまたはEnter Ctrl+nまたはEnter
文節伸張 Ctrl+o Ctrl+lまたは
文節短縮 Ctrl+i Ctrl+kまたは
中止 Ctrl+g Escape
次へ Ctrl+fまたは Ctrl+sまたはShift+→
前へ Ctrl+bまたは Ctrl+dまたはShift+←
字種変更 Ctrl+pまたは
字種変更 Ctrl+nまたは  
ひらがな変換   Ctrl+uまたはF6
カタカナ変換   Ctrl+iまたはF7
半角(カタカナ)変換   Ctrl+oまたはF8
全角英数変換   Ctrl+pまたはF9
最初へ Ctrl+a Ctrl+a
最後へ Ctrl+e Ctrl+
ぁ-ぉ xa ... xo la ... lo

ATOK風にして矢印キーを使わなければ、ATOK/IME/Canna をほとんど同じキーで使うことができる。
ATOK風の設定ファイルの do-not-use-extend-mode は t にしないと一覧表示のとき文節の伸張・短縮ができない。(extend-mode に移行するキー設定がないんだけど…)


04/01/17
●Mandrake Linux
@IT:リアル タイムアンケート集計結果には選択肢すらない(笑)
Gentooもないけどね。


04/01/16
●GNU GLOBAL
gtags が遅いのは sort コマンドのせいだという事を教えていただいたので再び試してみた。

LANG=C gtags

のように実行すれば (bash の場合)、実用上問題があるほどの時間はかからない。
cscope との比較をするため、とりあえずこんな Vim Script を作ってみた。CTRL-\ x のキーバインドでカーソル上の単語を global コマンドのオプションなしで検索し、結果を quickfix リストにする。
といいながら、ほとんどコマンドを手で打っていろいろ試してみる。気が付いた点としては、たとえば、

typedef struct structTag {
    int member;
} structType;

のようにあったとき、structType なら検索できるが、structTag および member では検索できない。オプションをいろいろつけて試してみたが、できないようである。
cscope ならどれでも検索できるので、まだまだってとこかな。
機能的に上回ってるところがない訳ではないのだが、便利と思えるものは今のところない。


04/01/02
●Mandrake Linux
う〜ん、やっぱり使い物にならない。GStreamerを追加インストールしたら、使いやすいと思った設定ツールがメニューから消えて しまった。コマンドラインから起動する方法なんてわからないし、どうやっても復帰できない。復帰しようといろいろやってるときにウィンドウマネージャーい ろいろ試したけど、ほんと使えないのばっかりだなあ。この会社のテスティング体制を疑うよ、まったく。