2015年1月30日金曜日

fbterm で w3m-img をつかおう

VAIO PCG-C1 VRX/K をもう10年以上使っている。
通常の業務に使うにはかなり無理があるが、用途を限定すれば、使えなくはない。
主記憶の容量の問題で、Xがほぼ利用できないので、fbterm + uim-fepでつかう。20年前に戻ったと思って、コンソールアプリを作て遊べばいいだろう。
atyfb.koを改造すれば、1024x480の広い画面(?)が使えるので、むしろ20年前よりもいい。

若かりし頃を思い出しながらプログラミングをしていても、今は今だ。20年前ではない。
コンソールアプリを作っていても、しばしば調べごとをしたい事もあるし、/usr/share/doc/の下のドキュメントが時々HTMLで書いてあったりするので、webブラウザも使いたい。
しかし、Xが動かないので、FireFoxもChromeも使えない。コンソールでも使えるブラウザが必要になる。
コンソールで、動くブラウザにはいくつかあるが、私はw3mを使っている。
xterm等のグラフィックが使える端末上ならば、w3mは、画像も表示されるので、HTMLで書かれたドキュメント内に画像イメージが入っていても表示できる。

残念なことに、fbterm上では、そのままではw3mは画像を表示できない。
"fbterm"よりも古い"jfbterm"や、fbconでは表示できるのに、だ。
じゃ、jfbtermやfbconを使えばいいと思うかもしれないが、そうは行かない。
jfbtermは不安定で古くメンテナスも行われていない。終了しようとすると、画面がフリーズしてしまう。
(見えないだけで、文字入力はできる。正確に'sudo shutdown -r now'と打って、パスワードを入力すれば、shtdown可能)
fbconは、日本語が表示できないので、仮にw3mが動いたとしても、表示される情報はひどく制限されてしまう。

なんとかfbtermでw3mを使いたい。そして画像も表示させたい。
というわけで、jfbterm と fbterm そして、w3m のソースコードを取ってきて調べた。
そして、なぜjfbterm上ならば、w3mが画像を表示できるのかがわかった。
w3mが特別にjfbtermを認識して、画像表示機能を有効にしている。

w3m-0.5.3/w3mimg/fb/fb_w3mimg.c の以下の部分。
 :
172         return NULL;
173     memset(wop, 0, sizeof(w3mimg_op));
174 
175     if (!check_tty_console(getenv("W3M_TTY")) && strcmp("jfbterm", getenv("TERM")) != 0) {
176         fprintf(stderr, "w3mimgdisplay/fb: tty is not console\n");
177         goto error;
178     }
 :

環境変数 TERM の内容が "jfbterm" だとエラーとしないようになっている。
じゃ、ここで fbterm もエラーとしなければいいのだが、実は fbterm が動作している時の環境変数TERMの値は"linux"である。
そして、この"linux"は、画像が扱えないコンソールでも同じである。そのため、"linux"を許可するわけにはいかない。
ちょっとずるいが試しに、fbterm上から、以下のようにして起動してみると、
$ TERM=jfbterm w3m www.google.com

ちゃんと画像も表示できた。
これに安心して、jfbtermをアンインストールする。
その後、もう一度w3mを動かすと、以下のようになって動かない。
Can't find termcap entry jfbterm
jfbtermをアンインストールしたんだから当然だ。
そもそもfbtermに、jfbtermと名乗るのはいかがなものか?
fbtermには"fbterm"と名乗らせるべきだ。/usr/share/terminfo/f/fbterm もinstallしているんだから。

というわけで、改造することにした。
fbtermがどこで環境変数をセットしているのか探してみたら、
fbterm-1.7/src/lib/shell.cpp の以下の部分。
 :
 79 
 80         case 0:  // child process
 81                 initShellProcess();
 82                 setenv("TERM", "linux", 1);
 83 
 84                 if (command) {
 85                         execvp(command[0], command);
 :
"linux" となっているのを "fbterm" にする。
そして、w3mも fbterm を受け付けるように改造する。
 :
148 #ifdef W3MIMGDISPLAY_SETUID
149 static int
150 check_tty_console(char *tty)
151 {
152     if (tty == NULL || *tty == '\0')
153         return 0;
154     if (strncmp(tty, "/dev/", 5) == 0)
155         tty += 5;
156     if (strncmp(tty, "tty", 3) == 0 && isdigit(*(tty + 3)))
157         return 1;
158     if (strncmp(tty, "vc/", 3) == 0 && isdigit(*(tty + 3)))
159         return 1;
160     return 0;
161 }
162 static int
163 check_TERM( const char *term )
164 {
165     static const char const *capableTerminals[] = {
166         "jfbterm", "fbterm", NULL
167     };
168     int i;
169     for( i=0; capableTerminals[i]!=NULL; i++ ) {
170         if( strcmp( term, capableTerminals[i] ) == 0 ) {
171                 return 1;
172         }
173     }
174     return 0;
175 }
176 #else
177 #define check_tty_console(tty)  1
178 #define check_TERM(term)        1
179 #endif
180 
181 w3mimg_op *
182 w3mimg_fbopen()
183 {
184     w3mimg_op *wop = NULL;
185     wop = (w3mimg_op *) malloc(sizeof(w3mimg_op));
186     if (wop == NULL)
187         return NULL;
188     memset(wop, 0, sizeof(w3mimg_op));
189 
190 //  if (!check_tty_console(getenv("W3M_TTY")) && strcmp("jfbterm", getenv("TERM")) != 0) {
191     if ((check_tty_console(getenv("W3M_TTY"))==0)&&
192         (check_TERM(getenv("TERM"))          ==0)) {
193         fprintf(stderr, "w3mimgdisplay/fb: tty is not console\n");
194         goto error;
195     }
 :
やややり過ぎ感もあるが、どうせなら思い切って、改造がわかりやすいほうがいいので、こうした。

両方共 debchange や、dpkg-buildpackage をおこなって、バイナリパッケージをビルドする。
出来上がったバイナリパッケージをinstallして動作確認すると、ちゃんと動いた。


ついでに… fbtermで、ambiguous-wideを指定すると、UnicodeのAmbiguous文字(詳しくは、このへんとかこのへんを参照)が倍角になる。フォントのグリフは倍角で書かれているので、こっちのほうがいい。
w3mもそれに対応する機能がある。
オプション画面にして、下の方の「ある種のUnicode文字を全角にする」を「(*)YES」とする。
両方共あってないと表示が崩れる。注意せよ。

0 件のコメント:

コメントを投稿