UNIXの話ですが。
昔懐かしいDOSのような、テキストのユーティリティを作る際に楽になるcurses.hをいじって遊んでみた。ちなみに、テキスト処理はPerlでやっちゃえば楽だし、ユーティリティ系ならX上でJava/Swingの方が全然楽ちんなんで、今時あえてC言語でやる意味はほとんどありません。
ご存じの通り、UNIX系のOSのコンソールは基本は「カノニカルモード」で動作しています。コイツ、大昔のキーボード+プリンタという構成のコンソールで動くことまで考えていて、色々な端末(Vt100とかxtermとかdttermとかetc..etc..)入出力にバッファが噛んでたりと、大変素晴らしいのですが、スクリーンどころかウインドウが標準の今はかえってじゃまな代物。1文字入力させたくても、必ずEnterまで入力する必要があったり...と、不便。viとかのフルスクリーンエディタとかだと、DOSの如く画面とキーボードの制御を乗っ取って動作してますよね。それが、ノンカノニカルモードとかRAWモードって奴。でも、全部自分で面倒見なきゃならなくて、とっても大変なのですよ。という事で、curses.hというのが用意されてて、その辺の面倒は引き受けてくれるのらしいのです。
(ちなみに手でRawモードにするには、#include <termios.h>して、tcgetattrとかtcsetattrを呼び出して、とりあえず現在の状態を保存しておいたり、termios構造体のc_lflagフィールドのICANONフラグをオフにしたり、cbreakモードに変更したり...と非常に面倒。その上、Rawモードに変更した後も端末種別毎に制御が必要だったりして...そんなの、手で書いてたらいつまでたっても終わりません。)
Cで書いた例ですが、とりあえずインクルードして、
#include <curses.h>
と思ったのですが、MacOS X 10.4のGCC-4.0だと標準ライブラリに含まれてないようなので、コンパイル時は次のようにgccのオプションでcurses.hを明示します。(LinuxとかSolarisだと問題ないです。)
gcc -o test test.c -lcurses
プログラムの頭でこんな感じで呼び出しておきます。
/* cursesの初期化 */
initscr();
cbreak();
noecho();
おっと、initscr();した後はprintfとかscanfとかは使わないでください。
画面の表示には
move( cy, cx);
printw("%c", chr);
mvprintw( cy, cx, "%c", chr);
とかが使えます。
キーの入力は
*c = (char)getch();
とか、1文字ずつ入力になります。けど、Enterキーが不要になるので、スクリーンで操作するアプリが作りたいなら、便利です。
最後に、プログラムを終了するときは
endwin();
をしてください。それ以後、元のコンソールに戻ります。
おおざっぱ過ぎですが、以上の手順でスクリーンとキーボードが自由に使えるようになる...という事らしいです。
これで、テキストのユーティリティ作ったり、古ゲーもどき作ったり出来ますね。
ちなみにPerldocにもioctlの云々が書いてあって、perlでもユーティリティが作れそうです。(そっちは全然知りませんが)
ちなみにcurses.hで懐かしの3D迷路ゲーム作ったのですが、ソース上げられないのでスクリーンショットだけ。
コメント