Terminals

来自osdev
Zhang3讨论 | 贡献2022年1月12日 (三) 07:45的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

本页是关于如何实现视频终端(video terminal)功能的基本要素。 终端通过 串行端口 连接到操作系统,也可以通过网络使用 telnetssh 协议。

历史

文件:VT220 Irssi.jpg
一个真实的终端
文件:PuTTY Ubuntu.png
带串行端口选项的PuTTY
文件:Minicom cs xterm.png
运行在xterm中的Minicom

最初的终端是一种行打印机。 用户键入命令,按enter键,然后计算机执行该命令并打印一行结果。 这就是 命令行界面 的来源。 它能理解基本的 ASCII控制字符,如ASCII 8 (退格) 、ASCII 10 (换行) 、ASCII 13 (回车) 等。 除此以外其它的都不做特殊操作。

尽管这种输入和输出方法适用于简单的程序,但是实现例如文本编辑器一类的程序非常复杂。 许多编辑器保留了行终端的遗留风格,比如Vi,但为了提供更舒适的界面,打印机被替换成了屏幕。 随之而来的是将光标定位在屏幕上,因此视频终端和视频终端序列诞生了。

有许多或多或少成功的终端 (最著名的是VT52),但最终DEC( Digital Equipment Corporation)公司的 VT100 变得广泛,其代码也变得标准化。 VT100码 (也称为ANSI转义码) 是有史以来最广泛的仿真序列。

通讯

当你的操作系统在通过串行通信时,表示在另一端有一个终端。 要么是真实的,要么是终端仿真器,如PuTTY或minicom。 终端的职责是处理 键盘,修饰键 (如Shift,Control,Alt) 和发送终端键序列。 终端也有责任解释接收到的终端代码 (有时也称为转义序列) 并正确地可视化它们。 这些序列总是以ASCII 27 (转义) 字符开头,在C文字中 “\ 033”,并以拉丁大写或小写字母或波浪号 (“〜”) 结尾。 之间可能有数字参数 (0-9) 用逗号 (“,” 和 “;”) 分隔,但此类参数始终以 “[” 为前缀。 这两个字节开始序列 “\ 033 [” 也称为控制序列引入器或简称为CSI( Control Sequence Introducer)。

接收按键

本节是关于你的操作系统可能从终端接收的字节。 重要的是要知道终端是不同的,有些是可配置的,因此它们可能会发送不同的代码。 有关所有可能的密钥代码的综合列表,请参阅 termcap数据库

Code Name Meaning
ASCII 3 Break (^C) the Break signal
ASCII 7 Bell (^G) makes a beep
ASCII 8 BS (^H) Backspace, moves the cursor left and delete, some terminals send ASCII 127 instead
ASCII 9 Tab (^I) Tabulator, moves to cursor to the next multiple of 8 coloumn on the right
ASCII 10 Line Feed (^J) move the cursor down (on modern machines line feed and carriage return is combined and called newline)
ASCII 13 Carriage Return (^M) Return or Enter key, move the cursor to the left most coloumn
ASCII 27 Escape (^[) start the command sequences
ASCII 32 - 126 keys "normal" keys
ASCII 127 or \033[3~ Delete delete without moving the cursor, some terminals send ASCII 127 instead of ASCII 8, but \033[3~ is standard
\033[A Up up arrow key
\033[B Down down arrow key
\033[C Right right arrow key
\033[D Left left arrow key
\033[5~ or \033[S PgUp the Page Up key
\033[6~ or \033[T PgDn the Page Down key
\033[7~ or \033[H Home the Home key
\033[8~ End the End key
\033[11~ to \033[21~ F1 - F10 function keys
\033[row;colR Status report answer to the \033[6n code

请注意,光标键是标准的,但是根据终端的不同,Home,End,PgUp,PgDn和Fn键可能会有所不同。 关键修饰符 (如Shift,Caps Lock,Control,Alt,Compose等) 始终由终端解释,并且没有代码。

发送序列

这些是你的操作系统可能发送到终端的字节。 终端和终端仿真器是不同的,它们通常理解不同的代码。 但是,有一部分代码可以保证全部理解,这些代码就是VT100代码。 现代终端仿真器通常支持更多,VT220 子集是最小的公分母。 以上所有内容都需要精确的终端类型检测和差异化代码。

编码 名称 含义
\033[nA CUU 向上移动光标 “n” 行
\033[nB CUD 将光标向下移动 “n” 行
\033[nC CUF 向右移动光标 “n” 颜色
\033[nD CUB 将光标向左移动 “n” 列
\033[nE CNL 将光标向下移动到行 “n” 的开头
\033[nF CPL 将光标向上移动到行 “n” 的开头
\033[nG CHA 将光标移动到颜色 “n”
\033[H CUP 将光标移动到屏幕的左上角
\033[row;colH CUP 移动光标
\033[row;colf HVP 移动光标
\033[J or \033[0J ED 从光标到末尾清除屏幕
\033[1J ED 从开始到光标清除屏幕
\033[2J ED 清除整个屏幕
\033[K or \033[0K EL 清除从光标到终点的线
\033[1K EL 清除从开始到光标的线
\033[2K EL 清除整条线
\033[S SU 向上滚动一页
\033[T SD 向下滚动一页
\033[m SGR 重置颜色属性
\033[1m SGR 选择粗体或密集颜色
\033[30-37m SGR 选择前景色
\033[40-47m SGR 选择背景颜色

选择图形再现 (或SGR) 代码通常连接成一个命令,例如选择蓝色背景上的亮白色 \ 033[1;37;0;44m。 一些终端理解颜色代码90-97 (与1;30-1;37相同) 和100-107 (与1;40-1;47相同)。

对于前景色和背景颜色代码,如下所示:

前景色 背景色 Name RGB (VGA colors)
30 40 Black 0,0,0
31 41 Red 170,0,0
32 42 Green 0,170,0
33 43 Yellow 170,85,0
34 44 Blue 0,0,170
35 45 Magenta 170,0,170
36 46 Cyan 0,170,170
37 47 White 170,170,170
1;30 1;40 Bright Black (Gray) 85,85,85
1;31 1;41 Bright Red 255,85,85
1;32 1;42 Bright Green 85,255,85
1;33 1;43 Bright Yellow 255,255,85
1;34 1;44 Bright Blue 85,85,255
1;35 1;45 Bright Magenta 255,85,255
1;36 1;46 Bright Cyan 85,255,255
1;37 1;47 Bright White 255,255,255

检测终端

首先也是最重要的是,你应该检测屏幕的大小。 这是通过将光标移到屏幕上,然后查询位置来完成的。

\033[999;999H\033[6n\033[H = your OS to the terminal

\033[row;colR = the terminal's answer, screen size

要检测确切的终端类型,以确定是否可以使用高级代码 (如 \ 033[38;2; 'R'; g';' 'b' 是RGB前景色),嗯,不可能,因为没有普遍支持的标识命令。 每个终端都有一个特殊的命令,其中包含你可以使用的特定答案。 或者简单地把它留给用户,许多操作系统使用术语环境变量从termcap数据库中选择一个代码集。

实施终端

一旦你的操作系统足够先进,你可能也希望在你的操作系统上实现终端仿真器,以便你可以接收连接。 为此,你必须解释这些序列,相应地在屏幕上显示它们,并将键盘扫描代码转换为ASCII序列。 在DOS下,这正是ANSI.SYS所做的。 对于Linux,看看minicom的源代码。

另见

外部链接