1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
=============================================================================
pfterm - piaip's flat terminal system
also as the "Perfect Term"
API Manual
函式說明手冊
VERSION 1.0
最後更新: 2007/12/23 18:00 piaip
=============================================================================
pfterm 是為了解決 non-ANSI based terminal 處理日漸困難的問題而誕生的。
舊有的系統 (screen.c) 假設輸出的資料全是單純的 ASCII 文字,
所以在處理 DBCS以及 ANSI 碼的時候非常容易誤判或輸出不足的資料。
另外緩衝區字串大小 (ANSILINELEN) 造成的浪費也是個問題。
pfterm 的螢幕處理方式是自為一個虛擬的 DBCS-aware ANSI Terminal,
在更新時才即時產生最佳化的輸出。
=============================================================================
pfterm API 是以 ncurses-like 為基礎。
以 fterm_* 為開頭的 API, 多半是 pfterm 內部使用的函式;
而跟 ncurses 同名或相近的 API 則是一般程式使用的部份。
=============================================================================
//// common ncurse-like library interface
//// ncurse 相容部份
// initialization 初始化
void initscr (void); 初始系統
int resizeterm (int rows, int cols); 調整視窗大小為(rows,col)
// cursor 游標
void getyx (int *y, int *x); 取得目前游標位置
void move (int y, int x); 移動游標
// clear 清除畫面
void clear (void); 清除螢幕並回到原點(0,0)
void clrtoeol (void); 清至行尾
void clrtobot (void); 清至螢幕底部
// clear (non-ncurses) 清除(非標準,不建議使用)
void clrtoln (int ln); 從目前行往下清至(不包含)ln行:[y,ln)
void clrcurln (void); 清除目前行, 相當於 clrtoln(y+1)
void clrtobeg (void); 清至行首
void clrtohome (void); 清至螢幕原點(0,0)
void clrscr (void); 清除螢幕但不回到原點
void clrregion (int r1, int r2); 清除[r1,r2]或[r2,r1]的範圍 (雙向)
// flushing 更新畫面
void refresh (void); 更新畫面 (只送出改變的部份)
void redrawwin (void); 強制更新畫面 (全部重畫)
// scrolling 捲動
void scroll (void); 向上捲動一行
void rscroll (void); 向下捲動一行
void scrl (int rows); 捲動 rows 行 (正值往上負值往下)
// scrolling (non-ncurses) 捲動(非標準,不建議使用)
void region_scroll_up(int top, int bot); 上捲一行 [top,bot] 的內容
// attributes 顏色與屬性
ftattr attrget (void); 讀取目前屬性
void attrset (ftattr attr); 設定屬性
void attrsetfg (ftattr attr); 設定前景色 (0-7)
void attrsetbg (ftattr attr); 設定背景色 (0-7)
// output (non-ncurses) 輸出 (非 ncurses 風格)
void outc (unsigned char c); 輸出字元 (可含 ANSI 控制碼)
void outs (const char *s); 輸出字串 (可含 ANSI 控制碼)
void outstr (const char *str); 輸出完整字串 (可含ANSI控制碼)
P.S: 差異在於, outstr() 會先計算所需的空間,並把該處正確清除掉,
outstr() 內建 DBCS 的辨識能力,所以不會蓋字只蓋到一半變亂碼。
outc/outs 則是無視舊內容直接覆蓋。
但注意 outstr 目前並不會去考慮 str 本身是否真為完整 DBCS 字串。
// readback 讀取螢幕上的文字
int instr (char *str); 把游標處的字串讀回到 str 處
int innstr (char *str, int n); 把游標處最多 n 個字元讀回 str
int inansistr (char *str, int n); 讀回有 ANSI 控制碼格式的字串。
P.S: 注意 inansistr 通常需要比較長的空間 (建議使用 ANSILINELEN)
結尾會設回標準的屬性 (ESC[m),若空間不足則中間會掉字。
in*str 傳回的是所讀到的字元數。
// restore 回存
void scr_dump (void *psb); 將目前畫面存入 psb
void scr_restore (void *psb); 由 psb 讀出畫面並釋放資源
目前的 psb 接受的是 screen_backup_t*, dump 前不需初始
dump 會為它配置記憶體,restore 則會釋放,
所以一定要成對。
// grayout Grayout 淡入淡出系統
void grayout (int y, int end, int level);
將區間 [y, end] 的內容作淡出或淡入的處理。 level 控制色彩:
GRAYOUT_DARK: 轉為暗色字
GRAYOUT_BOLD: 轉為亮色字
GRAYOUT_NORM: 轉為無色彩的普通字
// deprecated 建議停用部份
void standout (void); 屬性設為反白
void standend (void); 重設屬性
註: pfterm 目前並未真的支援 stand 屬性,所以只是假的反白效果。
move() 至該位置再畫字則屬性會改變。
=============================================================================
//// flat-term internal processor
//// pfterm 內部函式
要將 pfterm 接上某個底層 (網路/BBS/檔案/...) 只要定義好幾個
轉接函式即可快速移植:
int fterm_inbuf (void); // raw input adapter
鍵盤輸入的轉接函式,傳回是否仍有未讀取的輸入。 (最佳化 refresh 用)
void fterm_rawc (int c); // raw output adapter
輸出的基本轉接函式,輸出一個字元到底層系統。
void fterm_rawnewline(void); // raw output adapter
輸出的基本轉接函式,輸出一個換行符號到底層系統。
void fterm_rawflush (void); // raw output adapter
輸出的基本轉接函式,送出所有已輸出的內容到底層系統。
------------------------------------------------------------------------------
下面是呼叫轉接函式的基本命令:
void fterm_raws (const char *s); 輸出字串
void fterm_rawnc (int c, int n); 輸出 n 個重複的字元 c
void fterm_rawnum (int arg); 輸出數字
void fterm_rawcmd (int arg, int defval, char c); 輸出 ANSI 命令
void fterm_rawcmd2 (int arg1, int arg2, int defval, char c);
rawcmd/rawcmd2 會輸出 ESC_CHR '[' arg ';' arg2 c 的命令
若 arg/arg2 與 defval 相等則該參數會忽略不印
void fterm_rawattr (ftattr attr); 改變底層輸出屬性與色彩
void fterm_rawclear (void); 輸出清除全部畫面(不移動)的命令
void fterm_rawclreol (void); 輸出清至行尾的命令
void fterm_rawhome (void); 輸出移至原點(0,0)的命令
void fterm_rawscroll (int dy); 捲動螢幕 dy 行,正往上負往下
void fterm_rawcursor (void); 更新底層游標的位置與屬性
void fterm_rawmove (int y, int x); 移動底層游標到指定的位置
void fterm_rawmove_opt(int y, int x); 最佳化移動游標
void fterm_rawmove_rel(int dy, int dx); 移動底層游標到指定的相對位置
int fterm_chattr (char *s, 將屬性從 oattr 轉為 nattr 所需的
ftattr oattr, ftattr nattr); ANSI 控制碼輸出至 s 處。
注意s要夠長(起碼要 FTATTR_MINCMD=16
字元), 考慮相容性建議 32 以上。
下面是內部函式,不建議直接使用:
void fterm_markdirty (void); 標記目前畫面需要更新
void fterm_exec (void); (內部用)執行已收集到的 ANSI 命令
void fterm_flippage (void); (內部用)切頁 (pfterm 為 dual buffer)
void fterm_dupe2bk (void); (內部用)同步背景頁
int fterm_prepare_str(int len); (內部用)安全清除長度為 len 的空間
=============================================================================
// vim:expandtab:sw=4:ts=4
|