Linux(X11)でKensingtonのExpert Mouse 7を使う
KensingtonのExpert Mouse 7(EM7)には4つボタンがあり、以下のようにレイアウトされています。
.----------. .---------. | 2:Middle | | 8:Back | `----------' `---------' .----------. .---------. | 1:Left | | 3:Right | `----------' `---------'
EM7にはスクロールホイールがないため、左上が中央ボタンで、右上が戻るボタンという変則的なレイアウトになっているようです。
このままでは使いづらいので、左上を戻るボタン、右上を進むボタンに設定します。ドライバはevdevを使ってxorg.confの該当セクションにButtonMappingを以下のように記述します。
Option "ButtonMapping" "1 8 3 4 5 6 7 9 2"
これで一般的な5ボタンマウスのレイアウトになりました。
.--------. .-----------. | 2:Back | | 8:Forward | `--------' `-----------' .--------. .-----------. | 1:Left | | 3:Right | `--------' `-----------'
注意すべきなのは、ButtonMappingでボタンのレイアウトを変えてもインデックスは変わらないという点です。
機能の割り当て
次に、各ボタンに機能を割り当てていきます。
EM7にはスクロールリングが付いていますが、ボタンを押しながらボールを転がすことでスクロールができるとより便利です。自分は、文章をじっくり読むときはスクロールリング、長いページから目当ての情報を探しだすときはボールでスクロールと使い分けています。ここでは、右上のボタン(8:Forward)をスクロールボタンに割り当てています。
Option "EmulateWheel" "true" Option "EmulateWheelButton" "8" Option "EmulateWheelInertia" "20" Option "XAxisMapping" "6 7" Option "YAxisMapping" "4 5"
続いて、先程ButtonMappingで潰してしまった中央ボタンを、左右の同時クリックに割り当てます。
Option "Emulate3Buttons" "true"
しかし、この設定だけでは意図した通り動作せず、実際には中央ボタンではなく戻るボタンが割り当てられてしまいます。
ここで一旦Emulate3Buttonsの動作を確認してみます。
- 左右の同時クリック検知する
- "ボタン2"が押されたというイベントを生成
- xf86PostButtonEvent()でイベントをポストする
ここで問題となるのが、xf86PostButtonEvent()がボタンの種類ではなくインデックスを取る点です。つまり、ButtonMappingでボタン2を別のボタンに置き換えてしまうと、Emulate3Buttonsで呼ばれるボタンもまた変化してしまいます。
これを修正するにはxf86PostButtonEvent()が呼ばれる前にMappingテーブルを走査して、中央ボタンが割り当てられたインデックスを探し出す必要があります。毎回テーブルを走査するのは無駄なので予めインデックスを格納しておけばよさそうですが、ButtonMappingはxmodmapなどでリアルタイムに変更できるので、それもまた問題があります。
とりあえず面倒なので、evdevのソースに中央ボタンを割り当てたインデックス"9"を決め打ちしました。以下にそのパッチを掲載します。
追記
ちゃんとしたパッチ書きました。
diff --git a/src/emuMB.c b/src/emuMB.c index 764b30e..287edc6 100644 --- a/src/emuMB.c +++ b/src/emuMB.c @@ -96,7 +96,7 @@ static signed char stateTab[11][5][3] = { { 0, 0, 0 }, /* nothing -> ground (no change) */ { 0, 0, 1 }, /* left -> delayed left */ { 0, 0, 2 }, /* right -> delayed right */ - { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ + { 9, 0, 3 }, /* left & right (middle press) -> pressed middle */ { 0, 0, -1 } /* timeout N/A */ }, /* 1 delayed left */ @@ -104,7 +104,7 @@ static signed char stateTab[11][5][3] = { { 1, -1, 0 }, /* nothing (left event) -> ground */ { 0, 0, 1 }, /* left -> delayed left (no change) */ { 1, -1, 2 }, /* right (left event) -> delayed right */ - { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ + { 9, 0, 3 }, /* left & right (middle press) -> pressed middle */ { 1, 0, 4 }, /* timeout (left press) -> pressed left */ }, /* 2 delayed right */ @@ -112,12 +112,12 @@ static signed char stateTab[11][5][3] = { { 3, -3, 0 }, /* nothing (right event) -> ground */ { 3, -3, 1 }, /* left (right event) -> delayed left (no change) */ { 0, 0, 2 }, /* right -> delayed right (no change) */ - { 2, 0, 3 }, /* left & right (middle press) -> pressed middle */ + { 9, 0, 3 }, /* left & right (middle press) -> pressed middle */ { 3, 0, 5 }, /* timeout (right press) -> pressed right */ }, /* 3 pressed middle */ { - { -2, 0, 0 }, /* nothing (middle release) -> ground */ + { -9, 0, 0 }, /* nothing (middle release) -> ground */ { 0, 0, 7 }, /* left -> released right */ { 0, 0, 6 }, /* right -> released left */ { 0, 0, 3 }, /* left & right -> pressed middle (no change) */ @@ -141,33 +141,33 @@ static signed char stateTab[11][5][3] = { }, /* 6 released left */ { - { -2, 0, 0 }, /* nothing (middle release) -> ground */ - { -2, 0, 1 }, /* left (middle release) -> delayed left */ + { -9, 0, 0 }, /* nothing (middle release) -> ground */ + { -9, 0, 1 }, /* left (middle release) -> delayed left */ { 0, 0, 6 }, /* right -> released left (no change) */ { 1, 0, 8 }, /* left & right (left press) -> repressed left */ { 0, 0, -1 }, /* timeout N/A */ }, /* 7 released right */ { - { -2, 0, 0 }, /* nothing (middle release) -> ground */ + { -9, 0, 0 }, /* nothing (middle release) -> ground */ { 0, 0, 7 }, /* left -> released right (no change) */ - { -2, 0, 2 }, /* right (middle release) -> delayed right */ + { -9, 0, 2 }, /* right (middle release) -> delayed right */ { 3, 0, 9 }, /* left & right (right press) -> repressed right */ { 0, 0, -1 }, /* timeout N/A */ }, /* 8 repressed left */ { - { -2, -1, 0 }, /* nothing (middle release, left release) -> ground */ - { -2, 0, 4 }, /* left (middle release) -> pressed left */ + { -9, -1, 0 }, /* nothing (middle release, left release) -> ground */ + { -9, 0, 4 }, /* left (middle release) -> pressed left */ { -1, 0, 6 }, /* right (left release) -> released left */ { 0, 0, 8 }, /* left & right -> repressed left (no change) */ { 0, 0, -1 }, /* timeout N/A */ }, /* 9 repressed right */ { - { -2, -3, 0 }, /* nothing (middle release, right release) -> ground */ + { -9, -3, 0 }, /* nothing (middle release, right release) -> ground */ { -3, 0, 7 }, /* left (right release) -> released right */ - { -2, 0, 5 }, /* right (middle release) -> pressed right */ + { -9, 0, 5 }, /* right (middle release) -> pressed right */ { 0, 0, 9 }, /* left & right -> repressed right (no change) */ { 0, 0, -1 }, /* timeout N/A */ },
これで左右同時押しが正しく動作するようになりました。
最後にxorg.confのEM7のセクションをまとめて掲載しておきます。
Section "InputClass" Identifier "Mouse0" MatchIsPointer "on" MatchProduct "Kensington Expert Mouse" Option "ButtonMapping" "1 8 3 4 5 6 7 9 2" Option "Emulate3Buttons" "true" Option "EmulateWheel" "true" Option "EmulateWheelButton" "8" Option "EmulateWheelInertia" "20" Option "XAxisMapping" "6 7" Option "YAxisMapping" "4 5" EndSection
rxvt-unicodeで半角カナが豆腐になる件
rxvt-unicodeでjisx0201なフォントを設定して半角カナを表示をすると、文字化けして豆腐になってしまう。
原因はsrc/table/jis0201_1976_0.hで定義されているunicodeをjisx0201にマップする処理がおかしいから。
これは以下のパッチで修正される。
--- a/src/table/jis0201_1976_0.h 2011-07-17 12:27:03.964003450 +0900 +++ b/src/table/jis0201_1976_0.h 2011-07-17 12:27:06.563003451 +0900 @@ -8,7 +8,7 @@ if (unicode <= 0x007d) return unicode; if (0x007f <= unicode && unicode <= 0x009f) return unicode; if (unicode == 0x203e) return 0x007e; - if (unicode <= 0xff61 && 0xff9f <= unicode) return unicode - 0xfec0; + if (unicode >= 0xff61 && 0xff9f >= unicode) return unicode - 0xfec0; return NOCHAR; }
tmuxでborderがまともに表示できない件
tmuxでTERMをscreenにして使うと、ncursesなどで使われるborderが"qqqqqqqq"の様になってしまう。
これは環境変数NCURSES_NO_UTF8_ACSを0に設定すると直る。
NCURSES_NO_UTF8_ACSの詳細はncursesのmanを参照。
tmuxで環境変数を設定するには以下のように書く。
set-environment -g NCURSES_NO_UTF8_ACS 0
さらに、tmux 1.4からは上記の設定してもborderが正常に表示できない場合がある。
理由はborderにvt100のline drawing charactersではなく、Unicodeの罫線を使うようになったから。
https://bitbucket.org/edogawaconan/tmux/changeset/2661dc9f9551
Unicodeの罫線は日本語のフォントだと全角なのでborderがずれてしまう。
そのため、パッチを書いてvt100のline drawing charactersを使う仕様に戻した。
diff -ur tmux-1.4.orig/tty-acs.c tmux-1.4/tty-acs.c --- tmux-1.4.orig/tty-acs.c 2010-09-19 00:43:53.000000000 +0900 +++ tmux-1.4/tty-acs.c 2011-05-21 16:26:44.263937939 +0900 @@ -81,7 +81,7 @@ struct tty_acs_entry *entry; /* If not a UTF-8 terminal, use the ACS set. */ - if (!(tty->flags & TTY_UTF8)) { + if (1) { if (tty->term->acs[ch][0] == '\0') return (NULL); return (&tty->term->acs[ch][0]); diff -ur tmux-1.4.orig/tty.c tmux-1.4/tty.c --- tmux-1.4.orig/tty.c 2010-12-07 06:57:56.000000000 +0900 +++ tmux-1.4/tty.c 2011-05-21 16:23:06.310937851 +0900 @@ -47,7 +47,7 @@ const struct grid_cell *, const struct grid_utf8 *); #define tty_use_acs(tty) \ - (tty_term_has(tty->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8)) + (tty_term_has(tty->term, TTYC_ACSC)) void tty_init(struct tty *tty, int fd, char *term)