
要解释图形模式控制台为何不能显示汉字,首先来了解一下虚拟终端是怎么管理屏幕上的文字显示的。虚拟终端的实现在 drivers/tty/vt/vt.c 。代表虚拟终端的数据是 struct vc。
struct vc{ struct vc_data struct work_struct } 故而 struct vc_data 才是要的虚拟终端的定义。
先来看看 struct vc_data 到底定义了什么东西。 struct vc_data 的定义在 include/linux/console_struct.h, 定义摘录如下,为了不延长篇幅,有省略的部分: struct vc_data { struct tty_port port/* Upper level data */ unsigned short vc_num/* Console number */ unsigned int vc_cols/* [#] Console size */ unsigned int vc_rows 省略 ... const struct consw *vc_sw unsigned short *vc_screenbuf /* In-memory character/attribute buffer */ unsigned int vc_screenbuf_size 省略 ... }
其中 vc_screenbuf 存储了虚拟终端要显示在屏幕上的文字。
const struct consw *vc_sw 指向控制台驱动提供的函数。虚拟终端利用里面的函数指针调用相应的 *** 作,比如重绘屏幕,绘制一个字符等等。这些 *** 作由 vgacon 和 fbcon 等控制台驱动实现。当你切换终端的时候,实际上就是把当前终端设置为你要切换过去的终端,并且重新绘制当前终端 vc_data->vc_screenbuf 存储的内容。
当从键盘输入命令或者程序运行过程中要输出内容的时候,虚拟终端首先将输出的字符进行编码转化,转化为对于字符的 GLYPH 代码,并且将 GLYPH 和当前字符属性结合,最后将合成结果写入当前光标所处的位置。
内核中实际的算法要复杂的多,还牵涉到中断,但是为了简单快递的把我们关心的部分的核心表达出来,使用一下伪代码表示不那么严谨的过程。希望了解全部的可以自行查看内核相关的代码,主要代码在 drivers/tty/vt.c 的 do_con_write() 中。
我们知道,使用ls命令列出文件列表时,不同的文件类型会用不同的颜色显示。那么如何实现这样带颜色的文本输出呢?答案并不复杂,不管是用shell还是C语言。一、shell下的实现方法
先来讲在shell下,如何实现。用echo命令就可以实现,参看以下例子:
echo -e "\033[32mHello, world!"
当你在终端里敲下这条命令后,是不是发现系统用绿色输出了"Hello,world!",不止如此,连之后的命令提示符都变成了绿色?不要着急,听我继续说。echo命令-e选项的作用是激活终端对反斜线转义符(即\)的解释。引号内\033用于引导非常规字符序列,在这里的作用就是引导设置输出属性,后边的[32m就是将前景色设置为绿色,字母m表示设置的属性类别,数字代表属性值。设置可以单独使用,例如:
echo -e "\033[0m"
这行命令的作用是恢复属性为默认值,也就是说0m设置项用于恢复默认值。现在你的终端是不是又一切正常了?
理解了这些,剩下的就简单了。用这种命令,除了设置文本前景色,还可以设置很多属性。下边列出其他的设置项:
--------------------------------------------------------------------------
\033[0m 关闭所有属性
\033[1m 设置高亮度
\033[4m 下划线
\033[5m 闪烁
\033[7m 反显
\033[8m 消隐
\033[30m 至 \33[37m 设置前景色
\033[40m 至 \33[47m 设置背景色
\033[nA 光标上移n行
\033[nB 光标下移n行
\033[nC 光标右移n行
\033[nD 光标左移n行
\033[yxH设置光标位置
\033[2J 清屏
\033[K 清除从光标到行尾的内容
\033[s 保存光标位置
\033[u 恢复光标位置
\033[?25l 隐藏光标
\033[?25h 显示光标
--------------------------------------------------------------------------
各数字所代表的颜色如下:
字背景颜色范围:40----49
40:黑
41:深红
42:绿
43:黄色
44:蓝色
45:紫色
46:深绿
47:白色
字颜色:30-----------39
30:黑
31:红
32:绿
33:黄
34:蓝色
35:紫色
36:深绿
37:白色
另外,同类的多种设置项可以组合在一起,中间用分号()隔开。如下:
echo -e "\033[201H\033[1432mHello,world\033[0m"
这行命令首先\033[201H将光标移动到终端第20行第1列,之后的\033[1432m将文本属性设置为高亮、带下划线且颜色为绿色,然后输出Hello,world;最后\033[0m将终端属性恢复为默认值,这样就不会看到连命令完成后的命令提示符也变了样儿了。
通过以上各种命令的组合就可以实现对终端输出地复杂控制。
二、如何在C编程中实现?
理解了以上在Shell中的实现方法,关于在C中如何实现就很简单了。可以说只需要用printf函数代替上边的echo -e就OK了。参见下例:
int color = 32
printf("\033[201H\033[14%dmHello, world.\033[0m", color)
这个例子类似上边shell中最后那个例子,只是这里颜色值通过变量color来指定(当然,也可以直接指定)。
三、联想
看到这里你可能会想,是不是在其他编程语言里也可以用类似的方法实现对终端输出的控制呢?答案是肯定的!比如在Python中,可以如下输出:
color=32
print “\033[201H\033[14%dHello, world.\033[0m"%color
这个例子的效果跟上边C的例子是相同的。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)