Ivy Bridgeで作るフェニックス3号

4/29にIvy Bridgeが出るのでその構成のメモ。

4/30 追記

爆熱という噂なので3770Sを買ったけど、定格ならアイドル時30度、ロード時45度で全く問題なし。
ちなみにチップセットの温度はアイドル時もロード時も32度。

Contac 30+の金具が何故かベタベタしていたのは謎。

smart J05の静音フィルターはオプションでいい。
そもそも無意味だし、すぐ傷つくし、あいつのせいで裏配線用の領域が狭くなる。

あと芯のケースファンがかなり煩さかったのでNF-P12 PWMに変更した。

SKK用の2ch顔文字辞書を作る

2chの一行AAの顔文字辞書は、MatsuConにいいのがあるけど、SKK用がない。

なのでHaskellで変換ツールを書いた。
Google日本語入力用の辞書(UTF-8なので)をソースにして、以下のように使える。
最後にskkdic-expr2をしてるのは、文字コードEUC-JPに変換してるのでソートしなおす必要があるため。

$ runghc skkdic-from-imedic.hs < google_std.txt | nkf -ex | skkdic-expr2

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の動作を確認してみます。

  1. 左右の同時クリック検知する
  2. "ボタン2"が押されたというイベントを生成
  3. 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

鳥Haskellerコンテスト

  • 副作用が無いと俺はプログラミングも出来ないのかよ
  • もう半分くらい正格評価をしている、速くなるのかこれで
  • 悪いね、純粋関数型言語
  • 参照透明性だけは一流のところをみせてやるぜ
  • 遅延評価だぜ、信じらんねぇ
  • 型は推論した、でもこれじゃだめなんだろ
  • Haskellの評価戦略は晴れ時々大荒れ いいね、いい評価戦略だよ
  • Monadを…Monadを使うんだ…!
  • スペースリークしてる・・・分かってる! うぅぅわあああああ!!
  • unsafePerformIOだと!!うぅうわあああああああ!!!
  • かかか型推論がああああ!!うっっごけええええ!!
  • ああー!遅いっ!
  • 自動導出!自動導出せんかああ!

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)