To determine screen width and height without any external (OS specific) commands, I use:
<?php
ncurses_init();
$fullscreen = ncurses_newwin ( 0, 0, 0, 0);
ncurses_getmaxyx($fullscreen,&$a,&$b);
ncurses_end();
echo "Width:$b\nHeight:$a\n";
?>
XCVII. Ncurses 端末画面制御関数
導入
ncurses (new curses) は、System V Rel 4.0(及びそれ以前)の curses の フリーなソフトウエアエミュレーションです。ncurses は terminfo 型式を 使用し、パッド、カラー、複数のハイライト、フォーム文字、 ファンクションキーマッピングをサポートします。 このライブラリは対話的なものであるため、 Web アプリケーションを作成する際にはほとんど使用されませんが、 コマンドラインから PHP を使用 するスクリプトを書く際には有用です。
| 警告 |
この拡張モジュールは、 実験的 なものです。この拡張モジュールの動作・ 関数名・その他ドキュメントに書かれている事項は、予告なく、将来的な PHP のリリースにおいて変更される可能性があります。 このモジュールは自己責任で使用してください。 |
Ncurses は以下のプラットフォームで利用可能です。
AIX
BeOS
Cygwin
Digital Unix (aka OSF1)
FreeBSD
GNU/Linux
HPUX
IRIX
OS/2
SCO OpenServer
Solaris
SunOS
注意: この拡張モジュールは PECL レポジトリに移動 されており、以下のバージョン以降 PHP にバンドルされなくなっています。 PHP 6.0.0
要件
ncurses ライブラリおよびヘッダファイルが必要です。最新のバージョンを ftp://ftp.gnu.org/pub/gnu/ncurses/ あるいは他の GNU ミラーサイトからダウンロードしてください。
インストール手順
これらの関数を動作させるには、--with-ncurses[=DIR]を指定して CGI または CLI バージョンの PHP をコンパイルする必要があります。
リソース型
リソース型は定義されていません。
定義済み定数
以下の定数が定義されています。 この関数の拡張モジュールが PHP 組み込みでコンパイルされているか、 実行時に動的にロードされている場合のみ使用可能です。
エラーコード
エラー時に、ncurese 関数は NCURSES_ERR を返します。
カラー
表 2. ncurses カラー定数
| 定数 | 意味 |
|---|---|
| NCURSES_COLOR_BLACK | 色なし(黒) |
| NCURSES_COLOR_WHITE | 白 |
| NCURSES_COLOR_RED | 赤 - 端末がカラーモードの場合のみサポート |
| NCURSES_COLOR_GREEN | 緑 - 端末がカラーモードの場合のみサポート |
| NCURSES_COLOR_YELLOW | 黄 - 端末がカラーモードの場合のみサポート |
| NCURSES_COLOR_BLUE | 青 - 端末がカラーモードの場合のみサポート |
| NCURSES_COLOR_CYAN | シアン - 端末がカラーモードの場合のみサポート |
| NCURSES_COLOR_MAGENTA | マゼンタ - 端末がカラーモードの場合のみサポート |
キー
表 3. ncurses キー定数
| 定数 | 意味 |
|---|---|
| NCURSES_KEY_F0 - NCURSES_KEY_F64 | ファンクションキー F1 - F64 |
| NCURSES_KEY_DOWN | 下矢印 |
| NCURSES_KEY_UP | 上矢印 |
| NCURSES_KEY_LEFT | 左矢印 |
| NCURSES_KEY_RIGHT | 右矢印 |
| NCURSES_KEY_HOME | ホームキー(upward+左矢印) |
| NCURSES_KEY_BACKSPACE | バックスペース |
| NCURSES_KEY_DL | 行削除 |
| NCURSES_KEY_IL | 行挿入 |
| NCURSES_KEY_DC | 文字削除 |
| NCURSES_KEY_IC | 文字挿入あるいは挿入モード移行 |
| NCURSES_KEY_EIC | 文字挿入モード終了 |
| NCURSES_KEY_CLEAR | 画面消去 |
| NCURSES_KEY_EOS | 画面最下部までを消去 |
| NCURSES_KEY_EOL | 行末までを消去 |
| NCURSES_KEY_SF | 1 行スクロール |
| NCURSES_KEY_SR | 1 行逆スクロール |
| NCURSES_KEY_NPAGE | 次ページ |
| NCURSES_KEY_PPAGE | 前ページ |
| NCURSES_KEY_STAB | タブ |
| NCURSES_KEY_CTAB | タブ消去 |
| NCURSES_KEY_CATAB | 全タブ消去 |
| NCURSES_KEY_SRESET | ソフト(部分)リセット |
| NCURSES_KEY_RESET | リセットあるいはハードリセット |
| NCURSES_KEY_PRINT | 印刷 |
| NCURSES_KEY_LL | 左下 |
| NCURSES_KEY_A1 | キーパッドの左上 |
| NCURSES_KEY_A3 | キーパッドの右上 |
| NCURSES_KEY_B2 | キーパッドの中央 |
| NCURSES_KEY_C1 | キーパッドの左下 |
| NCURSES_KEY_C3 | キーパッドの右下 |
| NCURSES_KEY_BTAB | バックタブ |
| NCURSES_KEY_BEG | 先頭 |
| NCURSES_KEY_CANCEL | キャンセル |
| NCURSES_KEY_CLOSE | 閉じる |
| NCURSES_KEY_COMMAND | cmd (コマンド) |
| NCURSES_KEY_COPY | コピー |
| NCURSES_KEY_CREATE | 作成 |
| NCURSES_KEY_END | 行末 |
| NCURSES_KEY_EXIT | 終了 |
| NCURSES_KEY_FIND | 検索 |
| NCURSES_KEY_HELP | ヘルプ |
| NCURSES_KEY_MARK | マーク |
| NCURSES_KEY_MESSAGE | メッセージ |
| NCURSES_KEY_MOVE | 移動 |
| NCURSES_KEY_NEXT | 次 |
| NCURSES_KEY_OPEN | オープン |
| NCURSES_KEY_OPTIONS | オプション |
| NCURSES_KEY_PREVIOUS | 前 |
| NCURSES_KEY_REDO | やり直し |
| NCURSES_KEY_REFERENCE | ref (参照) |
| NCURSES_KEY_REFRESH | リフレッシュ |
| NCURSES_KEY_REPLACE | 置換 |
| NCURSES_KEY_RESTART | 再起動 |
| NCURSES_KEY_RESUME | 再開 |
| NCURSES_KEY_SAVE | 保存 |
| NCURSES_KEY_SBEG | shiftet beg (beginning) |
| NCURSES_KEY_SCANCEL | shift + キャンセル |
| NCURSES_KEY_SCOMMAND | shift + command |
| NCURSES_KEY_SCOPY | shift + コピー |
| NCURSES_KEY_SCREATE | shift + create |
| NCURSES_KEY_SDC | shift + 文字削除 |
| NCURSES_KEY_SDL | shift + 行削除 |
| NCURSES_KEY_SELECT | 選択 |
| NCURSES_KEY_SEND | shift + end |
| NCURSES_KEY_SEOL | shift + 行末 |
| NCURSES_KEY_SEXIT | shift + exit |
| NCURSES_KEY_SFIND | shift + 検索 |
| NCURSES_KEY_SHELP | shift + ヘルプ |
| NCURSES_KEY_SHOME | shift + ホーム |
| NCURSES_KEY_SIC | shift + input |
| NCURSES_KEY_SLEFT | shift + 左矢印 |
| NCURSES_KEY_SMESSAGE | shift + メッセージ |
| NCURSES_KEY_SMOVE | shift + 移動 |
| NCURSES_KEY_SNEXT | shift + 次 |
| NCURSES_KEY_SOPTIONS | shift + オプション |
| NCURSES_KEY_SPREVIOUS | shift + 前 |
| NCURSES_KEY_SPRINT | shift + 印刷 |
| NCURSES_KEY_SREDO | shift + やり直し |
| NCURSES_KEY_SREPLACE | shift + 置換 |
| NCURSES_KEY_SRIGHT | shift + 右矢印 |
| NCURSES_KEY_SRSUME | shift + 再開 |
| NCURSES_KEY_SSAVE | shift + 保存 |
| NCURSES_KEY_SSUSPEND | shift + サスペンド |
| NCURSES_KEY_UNDO | 元に戻す |
| NCURSES_KEY_MOUSE | マウスイベントが発生 |
| NCURSES_KEY_MAX | 最大のキーの値 |
マウス
表 4. マウス定数
| 定数 | 意味 |
|---|---|
| NCURSES_BUTTON1_RELEASED - NCURSES_BUTTON4_RELEASED | ボタン (1-4) が離された |
| NCURSES_BUTTON1_PRESSED - NCURSES_BUTTON4_PRESSED | ボタン (1-4) が押された |
| NCURSES_BUTTON1_CLICKED - NCURSES_BUTTON4_CLICKED | ボタン (1-4) がクリックされた |
| NCURSES_BUTTON1_DOUBLE_CLICKED - NCURSES_BUTTON4_DOUBLE_CLICKED | ボタン (1-4) がダブルクリックされた |
| NCURSES_BUTTON1_TRIPLE_CLICKED - NCURSES_BUTTON4_TRIPLE_CLICKED | ボタン (1-4) がトリプルクリックされた |
| NCURSES_BUTTON_CTRL | クリック中に ctrl が押された |
| NCURSES_BUTTON_SHIFT | クリック中に shift が押された |
| NCURSES_BUTTON_ALT | クリック中に alt が押された |
| NCURSES_ALL_MOUSE_EVENTS | すべてのマウスイベントを報告する |
| NCURSES_REPORT_MOUSE_POSITION | マウスの位置を報告する |
- 目次
- ncurses_addch -- カレント位置に文字を追加し、カーソルを進める
- ncurses_addchnstr -- カレント位置に指定した長さの属性付き文字列を追加する
- ncurses_addchstr -- カレントの位置に属性付き文字列を追加する
- ncurses_addnstr -- カレントの位置に、指定した長さの文字列を追加する
- ncurses_addstr -- カレント位置にテキストを出力する
- ncurses_assume_default_colors -- カラー 0 のデフォルト色を定義する
- ncurses_attroff -- 指定した属性を無効とする
- ncurses_attron -- 指定した属性を有効にする
- ncurses_attrset -- 指定した属性を設定する
- ncurses_baudrate -- 端末のボーレートを返す
- ncurses_beep -- 端末のビープを鳴らす
- ncurses_bkgd -- 端末画面の背景属性を設定する
- ncurses_bkgdset -- 画面背景を制御する
- ncurses_border -- 属性付きの文字で画面周囲に境界を描画する
- ncurses_bottom_panel -- パネルをスタックの最下部に移動する
- ncurses_can_change_color -- 端末の色を変更可能かどうか確認する
- ncurses_cbreak -- 入力のバッファリングを変更する
- ncurses_clear -- スクリーンをクリアする
- ncurses_clrtobot -- カレント位置から最下部までスクリーンをクリアする
- ncurses_clrtoeol -- カレント位置から行末までスクリーンをクリアする
- ncurses_color_content -- 色の RGB 値を取得する
- ncurses_color_set -- 前景/背景色を設定する
- ncurses_curs_set -- カーソル状態を設定する
- ncurses_def_prog_mode -- 端末(プログラム)モードを保存する
- ncurses_def_shell_mode -- 端末(シェル)モードを保存する
- ncurses_define_key -- キーコードを定義する
- ncurses_del_panel -- パネルをスタックから取り除き、削除する (しかし、関連付けられているウィンドウは削除しない)
- ncurses_delay_output -- パディング文字を用いて端末出力を遅延させる
- ncurses_delch -- カレント位置の文字を削除し、残った部分を左に移動する
- ncurses_deleteln -- カレント位置の行を削除し、残りの部分を上に上げる
- ncurses_delwin -- ncurses ウインドウを削除する
- ncurses_doupdate -- 準備中の全ての出力を書き込み、端末をリフレッシュする
- ncurses_echo -- キーボード入力のエコーを有効とする
- ncurses_echochar -- リファレッシュを行いつつ 1 文字出力する
- ncurses_end -- ncurses を終了し、画面を消去する
- ncurses_erase -- 端末画面を消去する
- ncurses_erasechar -- カレントの erase 文字を返す
- ncurses_filter -- iniscr() および newterm() の LINES を 1 に設定する
- ncurses_flash -- 端末画面をフラッシュする(ビジュアルベル)
- ncurses_flushinp -- キーボード入力バッファをフラッシュする
- ncurses_getch -- キーボードから 1 文字読み込む
- ncurses_getmaxyx -- ウィンドウの大きさを返す
- ncurses_getmouse -- マウスイベントを読みこむ
- ncurses_getyx -- ウィンドウ内の現在のカーソル位置を返す
- ncurses_halfdelay -- 端末をハーフディレイモードにする
- ncurses_has_colors -- カラー端末かどうか確認する
- ncurses_has_ic -- 挿入/削除機能の有無を確認する
- ncurses_has_il -- 行挿入/削除機能の有無を確認する
- ncurses_has_key -- 端末キーボードにおいてファンクションキーの有無を調べる
- ncurses_hide_panel -- パネルをスタックから取り除き、見えなくする
- ncurses_hline -- カレント位置に属性付きの文字を用いて最大 n 文字長の線を水平に描画する
- ncurses_inch -- カレント位置の文字と属性を取得する
- ncurses_init_color -- 新規にRGB値を設定する
- ncurses_init_pair -- 色の組を確保する
- ncurses_init -- ncurses を初期化する
- ncurses_insch -- 文字を挿入し、カレント位置にある文字を含む残りの行を移動する
- ncurses_insdelln -- カレント行の後に複数の行を挿入し、スクロールダウンする(負の数を指 定すると削除し、スクロールアップする)
- ncurses_insertln -- 行を挿入し、残りの部分をスクロールダウンする
- ncurses_insstr -- カレント位置に文字列を挿入し、残りの行を右に移動する
- ncurses_instr -- 端末画面から文字列を読み込む
- ncurses_isendwin -- Ncurses が endwin モードの場合、通常の画面出力が実行可能
- ncurses_keyok -- キーコードを有効または無効にする
- ncurses_keypad -- キーパッドを on あるいは off にする
- ncurses_killchar -- カレントの行削除文字を返す
- ncurses_longname -- 端末の説明を返す
- ncurses_meta -- 8 ビットのメタキー情報を有効/無効にする
- ncurses_mouse_trafo -- 座標を変換する
- ncurses_mouseinterval -- マウスボタンクリックのタイムアウトを設定する
- ncurses_mousemask -- マウスオプションを設定する
- ncurses_move_panel -- 左上が [startx, starty] となるようにパネルを移動する
- ncurses_move -- 出力位置を移動する
- ncurses_mvaddch -- カレント位置を移動し、文字を追加する
- ncurses_mvaddchnstr -- 位置を移動し、指定長の属性付きの文字列を追加する
- ncurses_mvaddchstr -- 位置を移動し、属性付きの文字列を追加する
- ncurses_mvaddnstr -- 位置を移動し、指定長の文字列を追加する
- ncurses_mvaddstr -- 位置を移動し、文字列を追加する
- ncurses_mvcur -- 直ちにカーソルを移動する
- ncurses_mvdelch -- 位置を移動し、文字を削除、行の残りを左シフトする
- ncurses_mvgetch -- 位置を移動し、新しい位置で文字を得る
- ncurses_mvhline -- 位置を新しく設定し、属性付きの文字を用いて最大n文字の水平線を描画
- ncurses_mvinch -- 位置を移動し、新しい位置の属性付きの文字を取得する
- ncurses_mvvline -- 位置を新しく設定し、属性付きの文字を用いて最大 n 文字の垂直線を 描画する
- ncurses_mvwaddstr -- ウインドウの新規位置に文字列を追加する
- ncurses_napms -- スリープ
- ncurses_new_panel -- 新しいパネルを作成し、それをウィンドウに関連づける
- ncurses_newpad -- 新しいパッド (window) を作成する
- ncurses_newwin -- 新規ウインドウを作成する
- ncurses_nl -- 改行と復改/ラインフィードを変換
- ncurses_nocbreak -- 端末を cooked モードに変更する
- ncurses_noecho -- キーボード入力エコーを無効にする
- ncurses_nonl -- 改行と復改/ラインフィードを変換しない
- ncurses_noqiflush -- シグナル文字のフラッシュを無効とする
- ncurses_noraw -- 端末を raw モード以外に変更する
- ncurses_pair_content -- 色の RGB 値を取得する
- ncurses_panel_above -- パネルの上のパネルを返す
- ncurses_panel_below -- パネルの下のパネルを返す
- ncurses_panel_window -- パネルに関連付けられたウィンドウを返す
- ncurses_pnoutrefresh -- パッドから仮想画面にリージョンをコピーする
- ncurses_prefresh -- パッドから仮想画面にリージョンをコピーする
- ncurses_putp -- パディング情報を文字列に適用し、それを出力する
- ncurses_qiflush -- シグナル文字のフラッシュを有効とする
- ncurses_raw -- 端末を raw モードに変更する
- ncurses_refresh -- 画面をリフレッシュする
- ncurses_replace_panel -- パネルに関連付けられたウィンドウを置き換える
- ncurses_reset_prog_mode -- def_prog_mode で保存したプログラムモードをリセットする
- ncurses_reset_shell_mode -- def_shell_mode で保存したシェルモードをリセットする
- ncurses_resetty -- 保存した端末モードに復帰する
- ncurses_savetty -- 端末の状態を保存する
- ncurses_scr_dump -- 画面の内容をファイルにダンプする
- ncurses_scr_init -- ファイルダンプから画面を初期化する
- ncurses_scr_restore -- ファイルダンプから画面を復帰する
- ncurses_scr_set -- ファイルダンプから画面を継承する
- ncurses_scrl -- カレント位置を変更せずに画面の内容をスクロールアップまたはダウンする
- ncurses_show_panel -- 不可視のパネルをスタックの最上部に置き、見えるようにする
- ncurses_slk_attr -- カレントのソフトラベルキー属性を返す
- ncurses_slk_attroff -- ソフトファンクションキーラベルの指定した属性を無効にする
- ncurses_slk_attron -- ソフトファンクションキーラベルの指定した属性を有効にする
- ncurses_slk_attrset -- ソフトファンクションキーラベルに、指定した属性を設定する
- ncurses_slk_clear -- 画面からソフトラベルをクリアする
- ncurses_slk_color -- ソフトラベルキーの色を設定する
- ncurses_slk_init -- ソフトラベルキー関数を初期化する
- ncurses_slk_noutrefresh -- 仮想画面にソフトラベルキーをコピーする
- ncurses_slk_refresh -- ソフトラベルキーを画面にコピーする
- ncurses_slk_restore -- ソフトラベルキーを復帰する
- ncurses_slk_set -- ファンクションキーラベルを設定する
- ncurses_slk_touch -- ncurses_slk_noutrefresh を実行する際に強制的に出力する
- ncurses_standend -- 'standout' 属性の使用を停止する
- ncurses_standout -- 'standout' 属性の使用を開始する
- ncurses_start_color -- 色の使用を開始する
- ncurses_termattrs -- 端末でサポートされる全ての属性フラグの論理和を返す
- ncurses_termname -- 端末の(簡略)名を返す
- ncurses_timeout -- 特別なキーシーケンスのタイムアウトを設定する
- ncurses_top_panel -- 可視パネルをスタックの最上部に移動する
- ncurses_typeahead -- typeahead 確認用に別のファイル記述子を指定する
- ncurses_ungetch -- 入力ストリームに 1 文字戻す
- ncurses_ungetmouse -- マウスイベントをキューにプッシュする
- ncurses_update_panels -- 仮想画面を再描画し、スタック内のパネルとの関係を反映させる
- ncurses_use_default_colors -- 端末のデフォルト色をカラー ID -1 に割り付ける
- ncurses_use_env -- 端末の大きさに関する環境情報の使用を制御する
- ncurses_use_extended_names -- terminfo 記述において拡張名の使用を制御する
- ncurses_vidattr -- video attribute モードで、端末上に文字列を表示する
- ncurses_vline -- カレント位置に最大n文字の属性付きの文字を用いて垂直線を描画する
- ncurses_waddch -- ウィンドウ内の現在位置に文字を追加し、カーソルを進める
- ncurses_waddstr -- ウィンドウ内の現在位置にテキストを出力する
- ncurses_wattroff -- ウィンドウの属性をオフにする
- ncurses_wattron -- ウィンドウの属性をオンにする
- ncurses_wattrset -- ウィンドウの属性を設定する
- ncurses_wborder -- 属性文字を使用してウィンドウの周囲に線を描画する
- ncurses_wclear -- ウィンドウをクリアする
- ncurses_wcolor_set -- ウィンドウの色の組み合わせを設定する
- ncurses_werase -- ウィンドウを消去する
- ncurses_wgetch -- キーボートから文字を読み込む (ウィンドウ)
- ncurses_whline -- 指定した属性文字を用いて、最大 n 文字分の長さの水平線を ウィンドウに描画する
- ncurses_wmouse_trafo -- ウィンドウ/標準画面の座標系を変換する
- ncurses_wmove -- ウィンドウの出力位置を移動する
- ncurses_wnoutrefresh -- ウィンドウを仮想画面にコピーする
- ncurses_wrefresh -- 端末画面のウインドウをリフレッシュする
- ncurses_wstandend -- ウィンドウの standout モードを終了する
- ncurses_wstandout -- ウィンドウの standout モードに入る
- ncurses_wvline -- 指定した属性文字を用いて、最大 n 文字分の長さの垂直線を ウィンドウに描画する
Here is a small example, how to use STDIN to read keys combinations in console.
$stdin = fopen('php://stdin', 'r');
stream_set_timeout($stdin, 1);
while (1) {
$temp="";
while (1) {
if(stream_select($read = array($stdin), $write = NULL, $except = NULL, 0))
$temp .= ord(fgetc($stdin));
else break;
}
// F1 : $temp == 27914949126
// ALT+F1 : $temp = 2727914949126
// ....
usleep("50000");
}
An implementation of a scrolling selection box:
<?php
function ncurses_menu_select( $options, $values, $max_height = 7, $max_width = 20, $y = 2, $x = 2 ) {
// Size inside of borders
$height = $max_height - 2;
$width = $max_width - 2;
// Number of options
$num_options = count( $options );
// Trim all values to fit
foreach( $options as $key => $value ) {
$options[ $key ] = substr( $value, 0, $width );
}
// Create Window
$menu_window = ncurses_newwin( $max_height, $max_width, $y, $x );
ncurses_wborder( $menu_window, 0, 0, 0, 0, 0, 0, 0, 0 );
// Initialize Window
$current = 0; // Currently selected
$position = 1; // Position in list
$topitem = 0; // Top menu item
for ( $a = 0; $a < min( $height, $num_options ); $a++ ) {
if ( $a == $current ) {
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $options[ $a ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
} else {
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $options[ $a ] );
}
}
ncurses_mvwaddstr( $menu_window, 1, 0, '*' );
ncurses_wrefresh( $menu_window );
// Loop until a selection is made
while( ! in_array( $key = ncurses_getch( $menu_window ), array( 13, 10 ) ) ) {
if ( $key == NCURSES_KEY_UP && $current > 0 ) {
$move = -1;
} else if ( $key == NCURSES_KEY_DOWN && $current < $num_options - 1 ) {
$move = 1;
} else {
continue;
}
$current += $move;
$position += $move;
// If we scroll off the window, redraw items.
if ( $position < 1 || $position > $height ) {
if ( $position < 1 ) {
$position = 1;
} else {
$position = $height;
}
$topitem += $move;
for ( $a = 1; $a <= $height; $a++ ) {
ncurses_mvwaddstr( $menu_window, $a, 1, str_repeat( ' ', $width ) );
if ( $a == $position ) {
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, $a, 1, $options[ $topitem + $a - 1 ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
} else {
ncurses_mvwaddstr( $menu_window, $a, 1, $options[ $topitem + $a - 1 ] );
}
}
} else { // Just update changed items
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, $position, 1, $options[ $current ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, $position - $move, 1, $options[ $current - $move ] );
}
// Update 'scroll bar dot'
ncurses_wborder( $menu_window, 0, 0, 0, 0, 0, 0, 0, 0 );
$dot_position = round ( ( $current / $num_options ) * ( $height - 1 ) );
ncurses_mvwaddstr( $menu_window, 1 + $dot_position, 0, '*' );
ncurses_wrefresh( $menu_window );
}
return $values[ $current ];
}
?>
Not calling ncurses_end() can (will) cause issues with terminals. Although registering a shutdown function which includes ncurses_end() may help, sometimes things go awry and you're stuck with a terminal that is acting in strange ways.
This can be fixed! *NIX systems (FreeBSD, Linux, UNIX, et al.) usually support the 'reset' command which resets the terminal settings and allows you to get things back to normal.
Here is a function that takes an associative array, presents a menu in a new window, allows the user to make a choice using up and down arrows and the enter key, and returns the value of the menu item.
Limitations include:
No way of scrolling a long list, either horiontally or vertically;
No arguments for placement on screen, although this is easy to add;
No multiple selection;
Will produce all kinds of errors and warnings if the terminal is smaller than is necessary to create the window.
I'm very new at using the ncurses library; Comments and improvements would be greatly appreciated!
<?php
/**
* Create a simple selection menu
* @param array Associative array; The value will be shown on the menu, while the key will be returned when the associated value is selected.
* @return mixed
*/
function ncurses_menu_select( $menu ) {
$keys = array_keys( $menu );
$values = array_values( $menu );
$height = $width = 0;
$height = count( $menu ) + 2;
foreach( $values as $value ) {
$width = max( $width, strlen( $value ) + 2 );
}
$menu_window = ncurses_newwin( $height, $width, 5, 5 );
ncurses_wborder( $menu_window, 0,0, 0,0, 0,0, 0,0 );
$current = 0;
for( $a = 0; $a < count( $values ); $a++ ) {
if ( $a == $current ) {
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $values[ $a ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
} else {
ncurses_mvwaddstr( $menu_window, 1 + $a, 1, $values[ $a ] );
}
}
ncurses_wrefresh( $menu_window );
while( ! in_array( $key = ncurses_getch( $menu_window ), array( 13, 10 ) ) ) {
if ( $key == NCURSES_KEY_UP AND $current > 0 ) {
$move = -1;
} else if ( $key == NCURSES_KEY_DOWN and $current < count( $values ) - 1 ) {
$move = 1;
} else {
$move = 0;
}
ncurses_mvwaddstr( $menu_window, 1 + $current, 1, $values[ $current ] );
$current += $move;
ncurses_wattron( $menu_window, NCURSES_A_REVERSE );
ncurses_mvwaddstr( $menu_window, 1 + $current, 1, $values[ $current ] );
ncurses_wattroff( $menu_window, NCURSES_A_REVERSE );
ncurses_wrefresh( $menu_window );
}
ncurses_delwin( $menu_window );
return $keys[ $current ];
}
?>
Example Use:
<?php
// Initialie ncurses
$ncurse = ncurses_init();
// A full screen window
$fullscreen = ncurses_newwin ( 0, 0, 0, 0);
// Add a pretty border
ncurses_border(0,0, 0,0, 0,0, 0,0);
// Draw everything so far
ncurses_refresh();
// Set up menu array
$menu_items = array(
'one' => 'Menu Item #1',
'two' => 'Menu Item #2',
'three' => 'Menu Item #3' );
// Display menu and return selection
$selection = ncurses_menu_select( $menu_items );
// Print selection
ncurses_mvaddstr( 1, 1, 'You selected ' . $menu_items[$selection] . ' with the value ' . $selection );
// Draw updates
ncurses_refresh( $fullscreen );
// End
ncurses_end();
?>
What if you want to draw a new window and after removing it, showing the pervious screen again? Unfortunately, there is no such a thing in php/ncurses as there is in original curses library (touchwin if I'm not mistaken - It has been a long time!).
However, you can do this by a simple trick! You can
dump the screen to a temp file and then restore it back
again!
Take a look at this function:
# Function: show_a_win()
# - Displays a small window and writes something in it.
# - waits for a key
# - shows the pervious screen again
function show_a_win()
{
# Dump the current screen into a temp file:
$tmpfile = tempnam("/tmp", "dump.");
# Create a new window.
$newwin = ncurses_newwin(4, 60, 10, 10);
# Write something and then refresh it
ncurses_mvwaddstr($newwin, 1, 1, "This is a test.");
ncurses_wrefresh($newwin);
# Wait for a key
ncurses_wgetch($newwin);
ncurses_delwin($newwin); /* delete the window */
/* Restore the screen the same way it was before entering
* into the function:
*/
ncurses_scr_restore($tmpfile);
unlink($tmpfile); /* Remove temp file */
}
Here is a function which would do the job for missing
ncurses_wclrtoeol() function:
/* wclrtoeol()
* Erases the current line to the right of the cursor
*/
function wclrtoeol($win)
{
# get current position
ncurses_getyx($win, &$crow, &$ccol);
# get maximum row and col for this window:
ncurses_getmaxyx($win, &$max_row, &$max_col);
for ($col = $ccol; $col < $max_col; $col ++){
ncurses_wmove($win, $crow, $col);
ncurses_waddch($win, 32);
}
}
This is not meant as spam to get people to use my client.
I have been working on a PHP4 IRC client with ncurses interface and I think it is a useful example of how ncurses with php could be used.
It is GPL licensed so you can just go and take a loot at it.
It can be found at http://torc.sourceforge.net or http://www.darkwired.org/projects/torc/
I hope this will help out some of you because php ncurses can be quite difficult I experienced :]
For any questions about the code you can ofcourse just mail me.
I had a small problem building php+ncurses support.
ncurses include files were installed in:
ncurses_installed_dir/include/ncurses
This caused problems when building php with ncurse support.
php was looking for include files in:
ncurses_installed_dir/include
However, include files were located in include/ncurses
I had to make symbolic links of files in ncurses directory so php could see them:
# cd ncurses_insalled_directory/include
# ln -s ncurses/* .
After that it worked.
For those of you who want to check if <ENTER> key is passed,
you have to check the key agains both NL and CR keys:
function get_str()
{
for ($str = "";;){
$key = ncurses_getch();
switch ($key){
case 10: // newline
case 13: // Carrige Return
return($str);
default:
$str .= chr($key);
ncurses_refresh();
} // switch
} // for
} // get_str()
Hope that would help.
In the example above, if you run resize from a C shell it will output the sizes in C shell syntax, run resize with -u to force Bourne syntax:
The $win parameter is just for future compatibility.
function ncurses_getmaxyx($win, &$y, &$x)
{
exec("/usr/X11R6/bin/resize -u", $output);
$cols = explode("=", $output[0]);
$rows = explode("=", $output[1]);
$x = intval($cols[1]);
$y = intval($rows[1]);
}
See the documentation for ncurses_border and ncurses_wrefresh for some more examples of doing windowing and dynamic sizing.. I also posted some information to the zend.com code-gallery for doing ncurses under php.
I noticed a lack of a getxy() function so I wrote one.
You may need to change the path for your resize cmd.
<?
function getxy(){
$rez = `/usr/X11R6/bin/resize`;
$rez = explode("\n",$rez);
while(list($key,$val)=each($rez)){
$a=explode("=",$val);
if(trim($a[0])=="COLUMNS"){ $COLUMNS = $a[1]; }
if(trim($a[0])=="LINES"){ $LINES = $a[1]; }
}//
$retval[0]=$COLUMNS;
$retval[1]=$LINES;
return $retval;
}
print_r(getxy());
?>
This is from the examples that come with the latest release.
From:
php-4.3.0RC3/ext/ncurses/example1.php
I found this useful...
<?php
$n=0;
ncurses_init();
if(ncurses_has_colors()){
ncurses_start_color();
ncurses_init_pair(1,NCURSES_COLOR_RED,NCURSES_COLOR_BLACK);
ncurses_init_pair(2,NCURSES_COLOR_GREEN,NCURSES_COLOR_BLACK);
ncurses_init_pair(3,NCURSES_COLOR_YELLOW,NCURSES_COLOR_BLACK);
ncurses_init_pair(4,NCURSES_COLOR_BLUE,NCURSES_COLOR_BLACK);
ncurses_init_pair(5,NCURSES_COLOR_MAGENTA,NCURSES_COLOR_BLACK);
ncurses_init_pair(6,NCURSES_COLOR_CYAN,NCURSES_COLOR_BLACK);
ncurses_init_pair(7,NCURSES_COLOR_WHITE,NCURSES_COLOR_BLACK);
}
while(1){
for ($x=0; $x<80; $x++) {
for ($y=0; $y<24; $y++) {
$n++;
ncurses_move($y,$x);
ncurses_addch($n+64);
ncurses_color_set($n%8);
ncurses_refresh();
if($n>26)$n=0;
}
}
ncurses_getch();
}
?>
actually *that* example does not work...
here is one that I took and trimmed down from the ncurses examples.
I will do some more and post them here..
<?
ncurses_init();
##############################################
ncurses_noecho();
$large = ncurses_newwin(20, 60, 2, 10);
$small = ncurses_newwin(10, 30, 7, 25);
ncurses_refresh();
ncurses_wrefresh($large);
ncurses_wrefresh($small);
ncurses_mvwaddstr($small, 5, 5, " Test String ");
ncurses_wrefresh($small);
ncurses_getch();
##############################################
ncurses_end(); // Clean up, and quit
?>
This is from PHP 4.3.0RC0 compiled with the following flags..
./configure --prefix=/wwwroot/php --with-config-file-path=/wwwroot/php --with-mysql --enable-pcntl --with-tsrm-pthreads --enable-sysvsem --enable-sysvshm --with-curl --enable-bcmath --enable-sigchild --enable-sockets --with-ncurses
With your CGI version of PHP compiled with ncurses support, console apps are amazingly easy!
For example:
whack the following into a file, chmod +x it, and run it.
#!/usr/local/bin/php -q
<?php
ncurses_init();
ncurses_border(25,25,18,18,24,24,23,23); // Do a lovely border
ncurses_move(1,1); // Start top left(inside border)
ncurses_addstr("Welcome to NCurses");
ncurses_addstr(" with PHP!");
ncurses_refresh(); // Send buffer to screen
ncurses_end(); // Clean up, and quit
?>
Youll notice the second addstr simply tacks onto the first.
