ファイヤープロジェクト
terminfo
2003-07-20T15:13+09:00   matsu
terminfoを使用すると出力場所とかをイイ感じにできるかもしれない.
かつてのUNIXシステムではいろんな端末があって,それらの制御方法は標準化されていなかった.そこで,統一されたインタフェースでプログラムからの要求を受け取り,保持している各端末の制御方法に関するデータを参照して処理するパッケージとしてterminfoが登場した.terminfoはcursesと組み合わせて使用するが,両者の境界はなんだかあいまいらしい.
私のシステムではterminfoのデータが入っているterminfoファイルは/usr/share/terminfo/に沢山あった.これらはterminfoファイル名の頭文字ごとにディレクトリに分けられ,それぞれのterminfoファイルはticというコマンドでコンパイルされたもの(バイナリファイル)らしい.terminfoファイル内の各データは以下の3種類に分けられる.
ブール型
該当する機能をサポートするか否か.
数値型
サイズを表す.
文字列型
端末機能にアクセスするためのキーとか,キーボード入力をどんな文字列に変換してプログラムに渡すかを定義.
端末を制御するコーディングの流れは大体以下のようになる.
  1. setuptermで現在の端末に対応するTERMINAL構造体を取得
  2. tigetflag,tigetnum,tigetstrで現在の端末の状態を取得
  3. エスケープシーケンスを生成
  4. putp,tputsでエスケープシーケンスを端末に送る
エスケープシーケンスの生成についてちょっと書いておく.まず,どんな文字列型のデータがあるかは,man 5 terminfoに一覧がある(やたら多い).ここにある「Capname」をキーにしてtigetstrを呼び出すとその機能に対応したエスケープシーケンスが得られる.で,そこで得られるエスケープシーケンスの中にはそのままでは使用できないものがある.「カーソルを何行目の何列目に移動しろ」などという命令に対応するエスケープシーケンスは,数が膨大になるのを防ぐために,「何行目」とか「何列目」というのをパラメータ化している.このような場合,tparmを使用して取得したエスケープシーケンスのパラメータに具体的な値をいれるというステップが入る.
サンプルとしてclearコマンドを作成する.man clearによるとclearコマンド自体,tputをclear引数とともに呼んでいるらしい.
terminfoを使用するときは,コンパイル時にコンパイルオプションが必要である.私のシステムでは以下でコンパイルできた.
gcc -Wall -o my_clear my_clear.c -lncurses
-lncursesがないと怒られる.システムによっては-Iでncurses.hの場所を教える必要があるかもしれない(私のシステムでは/usr/include/ncurses.hがあった).コンパイル後実行するとclearコマンドと同様の結果が得られた.
もう一つの例としてカーソル移動のサンプルを作成してみた.
このサンプルはviみたくhjklでカーソルを移動する.文字は入力できない.あとqを入力すると終了する.
matsu(C)
Since 2002
Mail to matsu