“Terminals”的版本间差异

来自osdev
跳到导航 跳到搜索
(创建页面,内容为“This page is about the very essentials of how to implement video terminal functionality. Terminals are connected to the OS over serial port, but could use network too with the telnet and ssh protocols. ==History== 200px|thumb|A real terminal 200px|thumb|PuTTY with serial port option 200px|thumb|Minicom running in xterm Originally terminals were line print…”)
 
 
第1行: 第1行:
This page is about the very essentials of how to implement video terminal functionality. Terminals are connected to the OS over [[Serial_Ports|serial port]], but could use network too with the [[telnet]] and [[ssh]] protocols.
本页是关于如何实现视频终端(video terminal)功能的基本要素。 终端通过 [[Serial_Ports | 串行端口]] 连接到操作系统,也可以通过网络使用 [[telnet]] [[ssh]] 协议。


==History==
==历史==
[[File:VT220_Irssi.jpg|200px|thumb|A real terminal]]
[[File:VT220_Irssi.jpg|200px|thumb|一个真实的终端]]
[[File:PuTTY_Ubuntu.png|200px|thumb|PuTTY with serial port option]]
[[File:PuTTY_Ubuntu.png|200px|thumb|带串行端口选项的PuTTY]]
[[File:Minicom_cs_xterm.png|200px|thumb|Minicom running in xterm]]
[[File:Minicom_cs_xterm.png|200px|thumb|运行在xterm中的Minicom]]


Originally terminals were line printers. The user typed in a command, pressed enter, and the computer executed that command and printed the results line by line. This is where [[Command_Line|command line interface]] originates. It understood the basic [https://en.wikipedia.org/wiki/ASCII#Control_characters ASCII control characters], like ASCII 8 (backspace), ASCII 10 (line feed), ASCII 13 (carriage  return) etc. but nothing else.
最初的终端是一种行打印机。 用户键入命令,按enter键,然后计算机执行该命令并打印一行结果。 这就是 [[Command_Line| 命令行界面]] 的来源。 它能理解基本的 [https://en.wikipedia.org/wiki/ASCII#Control_characters ASCII控制字符],如ASCII 8 (退格) 、ASCII 10 (换行) 、ASCII 13 (回车) 等。 除此以外其它的都不做特殊操作。


Although this input and output method works for simple programs, it is very complicated to implement a text editor for example. Many editors kept the line terminal heritage, like Vi, but to provide a more comfortable interface, the printer was replaced with a screen. With it come the need to position the cursor on the screen, hence video terminal and video terminal sequences was born.
尽管这种输入和输出方法适用于简单的程序,但是实现例如文本编辑器一类的程序非常复杂。 许多编辑器保留了行终端的遗留风格,比如Vi,但为了提供更舒适的界面,打印机被替换成了屏幕。 随之而来的是将光标定位在屏幕上,因此视频终端和视频终端序列诞生了。


There were many more or less successful terminals (most notably the VT52), but finally Digital Equipment Corporation's [[VT100]] got widespread and its codes got standardized. The VT100 codes (also called ANSI escape codes) are the most widely emulated sequences, ever.
有许多或多或少成功的终端 (最著名的是VT52),但最终DEC( Digital Equipment Corporation)公司的 [[VT100]] 变得广泛,其代码也变得标准化。 VT100码 (也称为ANSI转义码) 是有史以来最广泛的仿真序列。


==Communication==
==通讯==


When your OS is communicating over the serial like, it is very likely that on the other end there's a terminal. Either a real one, or a terminal emulator, like PuTTY or minicom. It is the terminal's duty to handle the [[Keyboard|keyboard]], the key modifier keys (like Shift, Control, Alt), and send terminal key sequences. It is also the terminal's duty to interpret the received terminal codes (sometimes also called escape sequences) and visualize them properly. These sequences always start with the ASCII 27 (escape) character, "\033" in C literals, and terminated by a latin uppercase or lowercase letter or tilde ("~"). In between there might be numeric parameters (0-9) separated by comma ("," and ";") but such arguments are always prefixed by "[". This two bytes start sequence "\033[" also called Control Sequence Introducer, or CSI.
当你的操作系统在通过串行通信时,表示在另一端有一个终端。 要么是真实的,要么是终端仿真器,如PuTTY或minicom。 终端的职责是处理 [[Keyboard|键盘]],修饰键 (如Shift,Control,Alt) 和发送终端键序列。 终端也有责任解释接收到的终端代码 (有时也称为转义序列) 并正确地可视化它们。 这些序列总是以ASCII 27 (转义) 字符开头,在C文字中 “\ 033”,并以拉丁大写或小写字母或波浪号 (“〜”) 结尾。 之间可能有数字参数 (0-9) 用逗号 (“,” 和 “;) 分隔,但此类参数始终以 “[” 为前缀。 这两个字节开始序列 “\ 033 [” 也称为控制序列引入器或简称为CSI( Control Sequence Introducer)。


===Receiving Keys===
===接收按键===


This section is about the bytes your OS might receive from a terminal. It is important to know that terminals are different, some are configurable, so they might send different codes. For a comprehensive list of all possible key codes, consult the [https://raw.githubusercontent.com/marcv81/termcap/master/termcap.src termcap database].
本节是关于你的操作系统可能从终端接收的字节。 重要的是要知道终端是不同的,有些是可配置的,因此它们可能会发送不同的代码。 有关所有可能的密钥代码的综合列表,请参阅 [https://raw.githubusercontent.com/marcv81/termcap/master/termcap.src termcap数据库]


{| {{wikitable}}
{| {{wikitable}}
第63行: 第63行:
| \033[''row'';''col''R || Status report || answer to the \033[6n code
| \033[''row'';''col''R || Status report || answer to the \033[6n code
|}
|}
Note that cursor keys are standard, but there might be differences with the Home, End, PgUp, PgDn and Fn keys depending on the terminal. Key modifiers (like Shift, Caps Lock, Control, Alt, Compose etc.) are always interpreted by the terminal, and have no codes.
请注意,光标键是标准的,但是根据终端的不同,Home,End,PgUp,PgDn和Fn键可能会有所不同。 关键修饰符 (如Shift,Caps Lock,Control,Alt,Compose等) 始终由终端解释,并且没有代码。


===Sending Sequences===
===发送序列===


These are the bytes that your OS might send to a terminal. Terminals and terminal emulators are different, they usually understand different codes. However there's a subset of codes that all guaranteed to understand, and those are the VT100 codes. Modern terminal emulators usually support more, the [https://vt100.net/docs/vt220-rm/ VT220] subset is the smallest common denominator. Everything above that requires exact terminal type detection and differentiated codes.
这些是你的操作系统可能发送到终端的字节。 终端和终端仿真器是不同的,它们通常理解不同的代码。 但是,有一部分代码可以保证全部理解,这些代码就是VT100代码。 现代终端仿真器通常支持更多,[https://vt100.net/docs/vt220-rm/ VT220] 子集是最小的公分母。 以上所有内容都需要精确的终端类型检测和差异化代码。


{| {{wikitable}}
{| {{wikitable}}
! Code
! 编码
! Name
! 名称
! Meaning
! 含义
|-
|-
| \033[''n''A || CUU || move the cursor up ''n'' rows
| \033[''n''A || CUU || 向上移动光标 “n” 行
|-
|-
| \033[''n''B || CUD || move the cursor down ''n'' rows
| \033[''n''B || CUD || 将光标向下移动 “n” 行
|-
|-
| \033[''n''C || CUF || move the cursor right ''n'' coloumns
| \033[''n''C || CUF || 向右移动光标 “n” 颜色
|-
|-
| \033[''n''D || CUB || move the cursor left ''n'' coloumns
| \033[''n''D || CUB || 将光标向左移动 “n” 列
|-
|-
| \033[''n''E || CNL || move the cursor to the beginning of line ''n'' down
| \033[''n''E || CNL || 将光标向下移动到行 “n” 的开头
|-
|-
| \033[''n''F || CPL || move the cursor to the beginning of line ''n'' up
| \033[''n''F || CPL || 将光标向上移动到行 “n” 的开头
|-
|-
| \033[''n''G || CHA || move the cursor to coloumn ''n''
| \033[''n''G || CHA || 将光标移动到颜色 “n”
|-
|-
| \033[H || CUP || move the cursor to the top left corner of screen
| \033[H || CUP || 将光标移动到屏幕的左上角
|-
|-
| \033[''row'';''col''H || CUP || move the cursor
| \033[''row'';''col''H || CUP || 移动光标
|-
|-
| \033[''row'';''col''f || HVP || move the cursor
| \033[''row'';''col''f || HVP || 移动光标
|-
|-
| \033[J or \033[0J || ED || clear the screen from cursor to the end
| \033[J or \033[0J || ED || 从光标到末尾清除屏幕
|-
|-
| \033[1J || ED || clear the screen from beginning to the cursor
| \033[1J || ED || 从开始到光标清除屏幕
|-
|-
| \033[2J || ED || clear the entire screen
| \033[2J || ED || 清除整个屏幕
|-
|-
| \033[K or \033[0K || EL || clear the line from cursor to the end
| \033[K or \033[0K || EL || 清除从光标到终点的线
|-
|-
| \033[1K || EL || clear the line from beginning to the cursor
| \033[1K || EL || 清除从开始到光标的线
|-
|-
| \033[2K || EL || clear the entire line
| \033[2K || EL || 清除整条线
|-
|-
| \033[S || SU || scroll up one page
| \033[S || SU || 向上滚动一页
|-
|-
| \033[T || SD || scroll down one page
| \033[T || SD || 向下滚动一页
|-
|-
| \033[m || SGR || reset color attributes
| \033[m || SGR || 重置颜色属性
|-
|-
| \033[1m || SGR || select bold or intensive color
| \033[1m || SGR || 选择粗体或密集颜色
|-
|-
| \033[''30-37''m || SGR || select foreground color
| \033[''30-37''m || SGR || 选择前景色
|-
|-
| \033[''40-47''m || SGR || select background color
| \033[''40-47''m || SGR || 选择背景颜色


|}
|}
The Select Graphic Rendition (or SGR) codes are often concatenated into one command, for example to select bright white on blue background \033[1;37;0;44m. Some terminals understands color codes 90 - 97 (same as 1;30 - 1;37) and 100 - 107 (same as 1;40 - 1;47).
选择图形再现 (或SGR) 代码通常连接成一个命令,例如选择蓝色背景上的亮白色 \ 033[1;37;0;44m。 一些终端理解颜色代码90-97 (与1;30-1;37相同) 和100-107 (与1;40-1;47相同)


For the foreground and background color codes, these are as follows:
对于前景色和背景颜色代码,如下所示:


{| class="wikitable"
{| class="wikitable"
|-
|-
! FG
! 前景色
! BG
! 背景色
! Name
! Name
! RGB (VGA colors)
! RGB (VGA colors)
第163行: 第163行:
|}
|}


===Detecting Terminal===
===检测终端===


First and most, you should detect the size of the screen. This is done by moving the cursor over the screen, and then query the position.
首先也是最重要的是,你应该检测屏幕的大小。 这是通过将光标移到屏幕上,然后查询位置来完成的。


\033[999;999H\033[6n\033[H = your OS to the terminal
\033[999;999H\033[6n\033[H = your OS to the terminal
第171行: 第171行:
\033[''row'';''col''R = the terminal's answer, screen size
\033[''row'';''col''R = the terminal's answer, screen size


To detect the exact terminal type to determine if you can use advanced codes (like \033[38;2;''r'';''g'';''b''m RGB foreground color), well, not possible, as there's no commonly supported identify command. Each terminal has a special command with a specific answer that you can use. Or simply leave it to the user, many OS use the TERM environment variable to select a code set from the termcap database.
要检测确切的终端类型,以确定是否可以使用高级代码 (\ 033[38;2; 'R'; ''g';' 'b' 是RGB前景色),嗯,不可能,因为没有普遍支持的标识命令。 每个终端都有一个特殊的命令,其中包含你可以使用的特定答案。 或者简单地把它留给用户,许多操作系统使用术语环境变量从termcap数据库中选择一个代码集。


==Implementing A Terminal==
==实施终端==


Once your OS is sufficiently advanced, you'll probably want to implement a terminal emulator on your OS too so that you can receive connections. For that, you must interpret these sequences, display them on screen accordingly, and convert the keyboard scancodes into ASCII sequences. Under DOS, this exactly what ANSI.SYS does. For Linux, take a look at minicom's source code.
一旦你的操作系统足够先进,你可能也希望在你的操作系统上实现终端仿真器,以便你可以接收连接。 为此,你必须解释这些序列,相应地在屏幕上显示它们,并将键盘扫描代码转换为ASCII序列。 在DOS下,这正是ANSI.SYS所做的。 对于Linux,看看minicom的源代码。


==See Also==
==另见==
*[[Keyboard]]
*[[Keyboard]]
*[[VGA Fonts]]
*[[VGA Fonts]]
*[[Serial ports]]
*[[Serial ports]]


===External Links===
===外部链接===
*[https://raw.githubusercontent.com/marcv81/termcap/master/termcap.src termcap database]
*[https://raw.githubusercontent.com/marcv81/termcap/master/termcap.src termcap database]
*[https://vt100.net/docs/vt220-rm/ VT220 Programmer's Manual]
*[https://vt100.net/docs/vt220-rm/ VT220 Programmer's Manual]

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的源代码。

另见

外部链接