Text UI

来自osdev
跳到导航 跳到搜索

文本用户界面 TUI 是一种用户界面,其中所有输出都以文本形式呈现,与 图形用户界面 相反,图形用户界面使用图形和文本来显示输出。

知名度和用途

早在gui普及之前的DOS时代,几乎所有应用程序都使用某种文本UI。 其中一些很简单,显示菜单或不可移动的面板,但其他一些包括功能齐全的窗口系统,如 Turbo_Pascal Turbo Pascal IDE 或ms-dos编辑应用程序 (你不能从维基上的截图中看出,但是文件窗口实际上是可调整大小和可移动的,并且它们是堆叠的)。

随着图形UI的兴起,基于文本的用户界面在爱好者操作系统项目中仍然是实用的,因为它们是最容易实现的界面类型,并且仍在大型和商业操作系统中使用,对于这些操作系统图形用户界面是不必要的,例如,在大型服务器中。 文本用户界面也很容易快速输出结果或调试数据,并输入命令来测试新功能,而不是编写复杂的图形应用程序。

如今,基于文本的UI主要用于pseudo-ttys,使用 VT escape sequences 而不是直接VGA缓冲区。 最著名的例子是Midnight Commander (DOS下的Norton Commander的Linux克隆) 和 VTM (功能齐全的桌面环境)。 这些UIs的最大优点是可以在基于tty的简单SSH隧道上使用,无需其他协议。 有关基于curses的文本接口的详细信息不在此页的范围之内,该页面仅关注 VGA 缓冲区文本接口。

输入

文本用户界面中的输入主要涉及使用 命令行 shell,通常是通过 keyboard 输入命令。 确实存在其他方法,例如可以向上和向下滚动的基于文本的菜单,并提示要求用户按下特定键以发生特定事件。

视频模式

文本UI使用最多的VGA视频模式是 “VGA mode 3”。 这是最常用的,因为它允许直接内存访问包含每个字符及其关联属性的线性地址。 VGA mode 3提供了80个字符宽的文本界面,每个屏幕25个字符行,尽管在现代计算机上 绘制线性帧缓冲区 是优选的,并且通常是强制性的。

视频存储器

在VGA模式3中,线性文本缓冲区位于0xB8000的物理位置。 在该地址之间进行读写将直接处理屏幕上的文本。 要从X和Y坐标访问屏幕上的特定字符,使用以下公式很简单:

position = (y_position * characters_per_line) + x_position;

每个字符在内存中占用两个字节的空间。 第一个字节分为两个部分,前景色和后彩。 第二个字节是要打印的字符的8位ASCII值。

颜色

每个字符都有一个颜色字节。 此颜色字节以前景色和背面颜色分开。

字节的布局,使用标准的调色板:

Bit 76543210
    ||||||||
    |||||^^^-fore colour
    ||||^----fore colour bright bit
    |^^^-----back colour
    ^--------back colour bright bit OR enables blinking Text

它很容易以十六进制值写入BL,半字节(Nibbles 4位)颜色 。
For Example:

0x01 sets the background to black and the fore colour to blue
0x10 sets the background to blue and the fore colour to black
0x11 sets both to blue.

启动时 BIOS 设置的默认显示颜色为0x0F: 背景为0 (黑色),前景为7 (白色) + 8 (亮度)。

在文本模式0中,可以使用以下标准调色板。 您可以使用VGA命令更改此调色板。

Number Colour Name Number + bright bit bright Colour Name
0 Black 0+8=8 Dark Gray
1 Blue 1+8=9 Light Blue
2 Green 2+8=A Light Green
3 Cyan 3+8=B Light Cyan
4 Red 4+8=C Light Red
5 Magenta 5+8=D Light Magenta
6 Brown 6+8=E Yellow
7 Light Gray 7+8=F White

控制台类示例

文本控制台类的文档记录很多且易于理解的示例来自Brandon的内核教程,该教程可在 http://osdever.net/bkerndev/Docs/printing.htm 获得

C打印字符的代码

以下C代码将在X和Y坐标处打印一个字符:

void WriteCharacter(unsigned char c, unsigned char forecolour, unsigned char backcolour, int x, int y)
{
     uint16_t attrib = (backcolour << 4) | (forecolour & 0x0F);
     volatile uint16_t * where;
     where = (volatile uint16_t *)0xB8000 + (y * 80 + x) ;
     *where = c | (attrib << 8);
}

滚动

滚动是通过将第二行字符复制到第一行字符上,将第三行复制到第二行字符上等来实现的。 然后用空字符清除最后一行文本 (通常是前/后颜色分别为7和0的空白)。 在文本模式0中,这通过将字符80-159复制到存储器位置0-79、160-239到80-159等来实现。

虚拟终端

虚拟终端与物理屏幕大同小异,但不是向参考屏幕的线性文本缓冲区写入文本,而是将文本写入存储在存储器中的线性文本缓冲区。 每个虚拟终端都有自己的文本缓冲区,当前在屏幕上显示的终端将其缓冲区复制到视频缓冲区以在屏幕上显示。 具有多个虚拟文本缓冲区具有其他优点,例如仅具有多个缓冲区的一部分同时输出到屏幕上。

缓冲数据

当使用基于文本的接口时,直接将文本写入视频存储器可能最终开始产生问题,特别是当处理键盘输入、处理来自菜单的输入或处理多个文本模式控制台时。 通常可以通过将字符和颜色数据写入单独的缓冲区 (未解析),并定期将缓冲区刷新到屏幕来克服此问题。 有多种方法可以实现文本缓冲区; 一个简单的解决方案可能具有一个平坦的内存块,在将文本和颜色字节复制到屏幕之前存储在该内存块中,尽管更高级的方法可能包括每行缓冲区,平面缓冲区或跟踪更新的线或屏幕部分的系统。

另见

外部链接

  • VTM Text-based Desktop Environment that uses curses and VT codes