w3m inline image Kterm 版は 、 ここで どんどん 進化している。
240x320 の画面を想定して 40x26 で 使っているんだけど、ちゃんと見れる。
付けているのは こんなオプション exec kterm-img -geometry 40x26 +sb -fl '-alias-fixed-medium-r-normal--12-*' -flb '-alias-fixed-bold-r-normal--12-*' -e /usr/local/bin/w3m -ppc 6 -ppl 12 $*
こんど、ぞろよしフォントで試そうとしたのだが、vine では なんかうまくいかない。
付けているのは こんなオプション exec kterm-img -geometry 48x32 +sb -fl '-alias-fixed-medium-r-normal--10-*' -flb '-alias-fixed-bold-r-normal--10-*' -e /usr/local/bin/w3m -ppc 5 -ppl 10 $*
とかやると elisa フォント で みることはできた 。
仕事場では既に重宝している。小さい画面で Web検索とかして web 見るのに 便利。これが mgterm 壁紙ON で動けば十分なのか..そういう気は まだあまり しない。make していないつうのもあるけど。メモリとか性能とか厳しいから mgl 版に期待はしている。.. ただ機能的にどうよと言われると... kterm 版で マウス使えるし、カシオペアで カーソルキーが使えるようになったから ボタンがあるかどうか... ぐらい?。ボタン付けるとか ...いじる立場だと mgl 版の方がいじりやすいかも知れない。
そろそろこのWikiNameじゃ内容とあわない気もしますが(^^;
で、ktermの方はダウンロードしたプロセスが描画する、という作りなんでしたっけ。
よく覚えてませんが。
となるとMGL的には難しいですね。
現状のロードの仕組みで使えるので、
ktermと同じにするのは諦めます。
ただ、同じようなコードを二人別々に実装するのは無駄も多い気がしますが、
そろそろ機能も出揃ってきたし。--有野
そういえば、カシオペアEXX で、軽いブラウザが手にはいるのならば
cgi つかって、ツールつくれば十分じゃんとか書いた覚えがある。
軽いブラウザは手に入ってしまった(or 手に入ったも同然な)わけだから、
それも試してみたいなぁ。cgi のツールって何がいいんだろうか。
それはともかく イメージが 貼れるということは、もっと変なものでも貼れるかも 知れないわけだ。なんか 遊ぶ base として すごいものを手にいれてしまったのかも しれない。
とりあえず火つけ役らしいです(^^;
こっちの方はまだまだですが、
一応公開してみました。
問題点はたくさんありますが、
一応表示されてて嬉しいです。
ただ、いくつか表示されない事も。
ktermの方のソースが出たら、
いろいろと改善も出来るかもしれませんが、
kterm版が出来たらmgtermと共用、
という路線でもいいかも。
とりあえずこっちは細かい所をつぶしたら、
ボタンとか付けてみようかなぁ、
とか思ってますが、どうなる事やら。--有野
ところで、image のロード中止まるという件。こんな風にしたらどうだろうか。
うーん。このへんでお手伝いできるかも知れない。ちょっと考えてみます。
お願いします。 実はここ、かなりネックです。--有野
process_img のところでは
実際に表示しようとするときに
イメージがキャッシュになければ、
表示すべきページがなくなるときには、
で、実際にイメージをロードするのは、キー入力のところ。
GIF DGifOpen(&gif_buffer, read_gif_buffer); が成功したとき。 PNG png_create_read_struct() が成功したとき(たぶん) JPG jpeg_read_header(&cinfo, TRUE); が成功したとき。
なんか構想が固まってきました。
モジュール名: bgl --- バックグラウンドローダ。
構想:
バックグラウンドでのロードとキャッシングを このモジュールでサポートする。
ロード機能:
バックグラウンドでのロードをするためには、
callback と ロードする URL, ロードするためのメソッドを登録しなければならない。
また、bgl_proc() という関数を定期的に呼ぶ必要がある。
登録しないといけないものは、次のもの
ロードオプション open_method fileno_method read_method close_method callback と callback を call するときに渡す引数
ロードオプションで、ptherad() か fork() を使う コンカレントなロードも サポートする。ただし、どちらを使うにしても 面倒な手続きが必要。
fork() を使った場合、fork safe になっている必要がある。 たとえば、atexit() を登録していると... 子プロセスが exit したときに atexit() が動いてしまうとまずい。そのため、bgl が fork した時に呼ぶ関数を 登録する必要がある。また、SIGCHLD を 受け取った場合、 bgl の 関数を呼んで終了ステータスを渡す必要がある。
また、pthread を使う場合は、プログラム全体が thread safe になっている 必要がある。fork 使う場合より面倒かも知れない。
なお、コンカレントなロードをするときも、bgl_proc() は、 定期的に呼ばないといけない。
コンカレントなロードを使わない場合に
ファイルディスクリプタを返すfileno_method を登録して、
select を使えるように できる。
( select を使わないと、bgl_proc() が read 待ちでしばしば止まり、
ロード中は レスポンスが低下する。)
ファイルディスクリプタは、select するためにのみ使う。read_method で
バッファリングすると 途中で止まるので、実装には注意が必要。
read_method で エラーを返したときに、それまで読んだデータを キャッシュに
保持する ロードのオプションも提供する。
( これは イメージファイルのヘッダだけ読む ことを想定 )
バックグラウンドでのロードではなく、すぐに ロードするオプションも提供 する。(これもイメージファイルのヘッダだけ読む ことを想定 )
なお、同時にロードする最大数の設定をサポートする。
キャッシュ機能:
キャッシュ機能は、URL に対応する データを得るための メソッドを次のようなインターフェイスで、提供する。
p = bgl_cache_opne(URL); p が NULL なら データなし。 bgl_cache_read(p,buf,len); bgl_cache_close(p);
いまのところ tmpfile() を使って open しっぱなし にしようかと考えている。
( close するだけで データを消せるため。 )
また、キャッシュデータの容量制限と キャッシュデータの個数制限をサポートする。
なんか、一応形になってきました。
ステータス:
make ぐらいはできて、なんか良く分からないテストプログラムを動かすことが できます。
USE_FORK を define してやると、(テストプログラムでは) fork しての コンカレントなロードもすることができました。
USE_PTHERAD はゼンゼンだめ。こんな感じで作ろうかなというところ。
SELECT 使うのは 、 うまくいっているみたい。
テストプログラム 以外のテストは、全然できていない。 不安なのは、だれかがロードしているときに、async_read をかけたケース。 とくに、IMMEDIATELY オプションを組み合わせたときの動き。
わかっている問題点としては、少し読んだファイルを 読み込みなおすとき
一旦 サイズが 0 になるタイミングがあること。
これは、サイズが単調に増加するようにしたいと思う。
( あらたに読んだファイルが 元のサイズを越えたところで 切替える)
ちなみに、テストは popen 使って シェルスクリプトからデータをロードする もの。
bgl_atfork(mgl_ignore_auto_close);として、子プロセスの exit 時に 終了処理が走らないようにする必要がある。
そんなイメージで考えてます。 ちょっとまだw3mの方がいろいろありすぎるので、まだこのページの内容とのすりあわせの所までは行ってませんが。 とりあえずソースの方のイメージは進んでいるのですが、 このページの成果を今週末に取り込めるかは微妙な所です。--有野
了解です。bgl も テストちゃんとできていないし、足りないメソッドもあるんで、 こちらも ボチボチやります。
作ってみたものの、今の w3m の構造に これを使うのは難しいかも知れない。 ちょっとしかソースみていないが、レンダリングまわりより、 read の メソッドを作ること自体が難しいような気がする。
レンダリングした時点で、w3m 側のページのデータ構造が決まり、イメージ が欲しいということになるはず。ここで、async_read をかけてやればいいと 思う。
で、レンダリングした後に表示ってことになるから、この時点で cache_read を 使ってデータを見る。なかったらしかたがないので無視。 ( 上のところで aync_read をかけずに、ここでかけてもいいかも知れない。)
あとで 完了通知がくるわけだが... 任意のID を 設定できる。 このID が、ページの中の該当イメージを指すようにしてやればいいと思う。
通知が来たときに ページがたまたま表示中なら、イメージを描画してやる。 違うかったら無視。( イメージだけ表示すると、TEXT と重なるようなら、 ページ全体か、表示領域を指定して(それができるならだけど) redraw かけてやってもいいかも知れない。)
あと、ページのデータ構造が消えてなくなった後に通知が来ると困るから、 ページのデータ構造がなくなるタイミングで、キャンセルを発行しとかないと いけないケースがあるはず。( たとえ GC がかってにデータを消すような構造だと まずいんだけども、逆に bgl が ページへのリンクを持っていれば、 read して通知しようとするまで ページデータは消えないはず。 .. だから対応のしようはあると思う。)
ここらへんの処理は問題ないと思うんだけど...。GC に対応しておかない といけないとか、そういうレベルの問題はありそうだけど、 プログラムの構造とは多分関係ないはず。
それより、read method が作れるのかどうか。作ったとして、fork した 子プロセスで動かしても問題ないかどうかの方がネックだと思う。
ポーリング自体は、多少工夫の余地がある。ただ、get_key(-1) したとしても mgl の内部で 100ms ぐらいでポーリングしているんで、get_key(100) としても あんまり変わらないと思う。
なんとなく...コネクションが1本しかないとか そういう構造になっているかも。 そうだとすると、そもそも コネクションを複数作れるようにしないといけない。 そこいらへん、どこみたらいいんだろう。
とりあえずここらへんの事については思う所がいくつかあります。
今週末に現状のから、結構大きく変更する予定です。
コネクションに関してはloadSomethingとかですか?--有野
ちょっと w3m のコードをみて 思ったんですが、どうも w3m 側を open/read/write に分割するところが難しいような 感じがします。
単に file の load だから 大丈夫かと思っていたんだけども。甘かったかも。 ただ w3m 側でループを持たせることができるように するのは 割と簡単。proc(url,handle) という メソッドを定義して、逆に bgl にたいして bgl_xx_write(handle,xxx) と bgl_xx_close(handle) を呼んで もらう API を追加したら、対応が簡単になるかも。
少しbgl.cのmainを読んでみました。
で、実際に使おうとすると、ここに書いてあるように少し組み込みづらいです。
外部のモジュールとするよりも、
すなおにw3mの中の関数使ってthread使って実装する方が楽に思えてきました。
少しthread使っていろいろやってみます。--有野
で、いろいろやってみました。
thread使って、一通り実装して、
一応ちゃんと動いてますが、GCがthread対応してるのが、
winとかLinuxとかSolarisだけで、
しかもちゃんと対応してるのはSolarisだけっぽいので、
NetBSDには使えなさそうです。
こっちのミスかGCのせいかはわかりませんが、
時々まずい動きをします。
ただ、fork使うバージョンに書きかえる時でも、
コードのほとんどはそのまま使えると思うので、
一応アップしておきます。
ここです。
bglのasync_readで作り直す事になりそうです。 file.cのimg_processで使う、asave2tmpを書き直せばよさそう、 とか思ってますが、、、甘いかなぁ。--有野
連絡欄
たぶん見てくれると思うから ここに書いときます。 w3mmgl.tgz で terms.c が ないっす。> 有野さん。
あっ、ほんとだ。了解です。直しました。--有野
受け取りました。ようやく make できました。
いろいろみているんだけども、問題が多々あると 作っている人がいっているのが なんとなくわかりました。それでもイメージを見れるってのは大きい。 嬉しいです。
うーん、今の所ウケはいいですね。 改善の優先順位としてはどんなのがいいですかね?--有野
レイアウトに関して、 具体的な課題が何かってのが 実は良くわかっていないんです。 だから、うまく書けない。それ以外では、w3m のいいところスポイルしちゃダメだと 漠然と思っています。で非同期なロードにこだわっています。本文のロードが 終るまで、オペレーションできないのは我慢するとしても、イメージのロード で止まるのは我慢できない。やっぱり
なるほど。やっぱり現在の、
非同期実現が最重要、という僕の認識でよさそうですね。
使ってみるとやはりあそこが一番目につきますし。
まだサイズ指定が無い時にどうするか、とか悩んでる部分も多いですが、
いろいろやってみます。
Threadでは駄目だ、とかもやってみないと気付かなかったと思うし。
イメージのキャッシュは基本的にはディスク(及びフラッシュメモリ)上にファイルとして保存しているので問題は無いと思いますが?
レンダリングの方は後回しにする予定です。最後までやらないかも。--有野
あ、ここで書いたのは、展開後の イメージデータのことです。
これって容量くうわけですが、もってなくてスクロールのたびに データ展開
するのもなぁ。と 思うわけです。というわけで 1 ページ分ぐらいはもっていて
よいのかなぁと。あと、キャッシュデータは file に書くから 沢山使えるという
のは幻想かも。
たとえば 私は、/tmp を RAMDISK に しているんで.. メモリと変わることが
ありません。RAMDISK 使うのは、flush 自体に 空きがないというのもありますが、
flush を あまり頻繁に書き換えるの 恐いって理由もあります。
日記 みましたが、w3m の方の 非同期化って難しそうですね。
まずは、コピペ->修正でいいんじゃないでしょうか。本体系に影響を与えず 修正できますから.... 最終形も コピペのコードのままっていうのがいいか 、 ちゃんとマージした方がいいかは、やってみてから分かるんじゃないだろうか。
あと、fork での注意としては、fork した子プロセスは、親プロセスに影響を 与えられないから、おもに 子プロセスが使うリソースにのみ注意して やればいいです。そこいらへん共通のコードでちゃんとコントロールするのは 難しいんで、 子プロセスで、動かす コードは独立させた方がちゃんと動くコードを 作るのは楽かなぁなんて思います。
あと、シグナルって、発生元を知ることはできません。また、複数のシグナル
が来ても1つに 縮退されてしまう。
で、終了ステータスのみは、wait とか waitpid で 取得することができる。
やっぱり、shell のように fork して1つの仕事をして
exit というのが基本だと思います。それが嫌なら プロセス間で通信しないと
いけない。で、そういうやりかたする場合、クッキーだとか いろんな状態も
送らなくてはいけなくて、相当たいへんかも。
なるほど。 ではそういう路線でも考えてみます。--有野
hsaka さんの kterm 版 試してみました。なんか PC WATCH とか ZDNET とかが 見れるぐらい レイアウトできています。びっくり。
差と思われるところをチェック。
<CENTER> <IMG SRC="xxx.gif"><BR> <IMG SRC="xxx.gif"> </CENTER>
hsaka さんの kterm 版 キーが入力されたらキャンセルされるようになったみたい。 同期ロードではあるけれども、fork 使って非同期なキャンセルを実現している っていうか。そんなかんじのデザイン。
もう少し工夫加えるとかなり使えるかなぁという気も。 hpcmips みたいな遅いマシンで試したわけではないので、 十分軽くなるかどうかまでは分かりませんが...
(... squid なんか使っている場合だと、
一回リクエストだせばロードが始まってしまうので、
あとで リクエストだせばキャッシュされている。)
という訳でktermの方のレンダリング、真似してみました。 結構違いますね、真面目に作られてました。 まだよく理解してない所とかもあって、妙な挙動する事もありますが、 おおむねよさそうです。ここにおいときます。--有野
日記鯖が落ちてるようなので、
ここに書いておきます。
前回のは、configureスクリプトがバージョン違いでうまくmake出来なかったアーカイブになってしまってました。
今回幅指定が無い時も読み込みを後回しにするバージョンにしたついでにXXMakefileをいれる前のバージョンに戻してしまいました。
後はイメージマップに対応すればkterm版と同じ機能のはずです。
上に書いた場所と同じ所に置いときました。
これでだいぶ実用になりそうです。--有野
インターフェイス: (決めたところまで)
キャッシュ関係
int bgl_cache_status(char *URL); URL に対応するキャッシュデータの 状態を返す。 -1: まったくなし。 0: データが完全に読み込めている。 1: 途中まで読み込んで、中断。 2: だれかが 読み込もうとしている。( が、まだ読んでいない) 3: だれかが 読み込もうとしていて、read 中。 void * bgl_cache_open(char *URL); URL に対応するキャッシュデータがあれば、ハンドラを返す。 bgl_cache_read(void *p, void *buf,int len); キャッシュデータを読み込む。戻り値 read したバイト数。 0 のとき は EOF。エラーは -1 。 void bgl_cache_close(void *p) ハンドラを開放。 int bgl_set_cache_limit(int size, int number); キャッシュの 容量/数 の limit を設定。
ロード関係
int bgl_async_read(char * URL,void *arg,struct bgl_async_param *param); struct bgl_async_param { int opt; void *(*open)(char *); int (*fileno)(void *); int (*read)(void *,void *,int); void (*close)(void *); void (*notice)(void *arg,int status); }; opt : BGL_OPT_CONCURRENTLY コンカレントな READ を試みる。できない場合は無視。 BGL_OPT_IMMEDIATELY すぐに: この場合 戻り値は、notice の status BGL_OPT_KEEPDATA エラーになったところまでの データをキャッシュに保持。 callbacks : open -- URL を引数にして、call される。必須。 fileno -- open したハンドラに対応する ファイルディスクリプタを返す関数。 オプション read -- read メソッド 必須。 close -- close メソッド必須。 notice -- 終了したか エラーになったとき call される。 arg: bgl_async_read の引数の arg と 同一値。 status: -1: エラー 0: データが完全に読み込めた。 1: 途中まで読み込んで、中断。 戻り値: -1: エラー 0: キャッシュに データがあった。 それ以外: リクエスト ID int bgl_cancel_async_read(int req_id); リクエスト ID に対応する async_read をキャンセル。 キャンセルした場合、notice コールバックは、呼ばれない。 int bgl_set_async_concurrency(int n); read する 並列数を指定。
その他
bgl_proc() 定期的に呼ぶこと。 FORK を使うときのみ必要: bgl_atfork(void (*func)()) bgl が、fork した後に呼ぶ 関数を登録。 void bgl_sigchld_handler() SIGCHLD ハンドラで 最初に この関数を呼ぶこと。 waitpid を中で使うので、本来の機能に影響はないはず。 呼べない場合は... SIGCHLD ハンドラを登録しないこと。 bgl が exit ステータスを 得られなかったことを検出したら、 エラーになる。