1不进行conv_uni_to_pc( )的转换 。
2加载符合双字节处理的映射关系,即对非控制字符进行1对1的不变映射 。我们自己定制的符合这种映射关系的UNICODE码表是direct.uni 。
要想查看/装载当前系统的unicode映射表,可使外部命令loadunimap 。经过conv_uni_to_pc( )转换之后,"hello, world.n"中的字符被一个一个地填写到tty1的缓冲区中 。然后do_con_write( )调用下层的驱动,把缓冲区中的内容输出到显示器上(也就相当于把缓冲区的内容拷贝到VGA显存中去) 。
sw->con_putcs(vc_cons〔currcons〕.d, (u16 *)draw_from, (u16
*)draw_to-(u16 *)draw_from, y, draw_x);
之所以要调用底层驱动,是因为存在不同的显示设备,其对应VGA显存的存取方式也不一样 。上面的Sw->con_putcs( )就会调用到fbcon.c中的fbcon_putcs()函数(con_putcs是一个函数的指针,在Framebuffer模式下指向fbcon_putcs()函数) 。也就是说在do_con_write( )函数中是直接调用了fbcon_putcs()函数来进行字符的绘制 。比如说在256色模式下,真正负责输出的函数是:
void fbcon_cfb8_putcs(struct vc_data *conp,
struct display *p,const unsigned short *s, int count, int
yy, int xx)
显示中文
比如说我们试图输出一句中文∶putcs(你好n );(你好的内码为0xc4,0xe3,0xba,0xc3) 。这时候会怎么样呢,有一点可以肯定,"你好"肯定不会出现在屏幕上,原因有∶核心中没有汉字字库,中文显示就是无米之炊了.
在负责字符显示的void fbcon_cfb8_putcs( )函数中,原有操作如下∶对于每个要显示的字符,依次从虚拟终端缓冲区中以WORD为单位读取(低位字节是ASCII码,高8位是字符的属性),由于汉字是双字节编码方式,所以这种操作是不可能显示出汉字的,只能显示出xxxx_putcs()是一个一个VGA字符 。
要解决的问题∶
确保在do_con_write( )时uni□pc转换不会改变原有编码 。一个很直接的实现方式就是加载一个我们自己定制的UNICODE映射表,loadunimapdirect.uni,或者直接把direct.uni置为核心的缺省映射表 。
针对如上问题,我们要做的第一个尝试方案是如下 。
首先需要在核心中加载汉字字库,然后修改fbcon_cfb8_putcs()函数,在fbcon_cfb8_putcs( )中一次读两个WORD,检查这两个WORD的低位字节是否能拼成一个汉字,如果发现能拼成一个汉字,就算出这个汉字在汉字字库中的偏移,然后把它当成一个16 x 16的VGA字符来显示 。
试验的结果表明∶
1能够输出汉字,但仍有许多不理想的地方,比如说,输出以半个汉字开始的一串汉字,则这半个汉字后面的汉字都会是乱码 。这是半个汉字的问题 。
2光标移动会破坏汉字的显示 。表现为,光标移动过的汉字会变成乱码 。这是因为光标的更新是通过xxxx_putc( )函数来完成的 。
xxxx_putc( )函数与xxxx_putcs( )函数实现的功能类似,但是xxxx_putc()函数只刷新一个字符而不是一个字符串,因而xxxx_putc()的输入参数是一个整数,而不是一个字符串的地址 。Xxxx_putc( )函数的声明如下∶void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
下一个尝试方案就是同时修改xxxx_putcs( )函数和xxxx_putc()函数 。为了解决半个汉字的问题,每一次输出之前,都从屏幕当前行的起始位置开始扫描,以确定要输出的字符是否落在半个汉字的位置上 。如果是半个汉字的位置,则进行相应的调整,即从向前移动一个字节的位置开始输出 。
这个方案有一个困难,即xxxx_putc( )函数不用缓冲区的地址,而是用一个整数作为参数 。所以xxxx_putc( )无法直接利用相邻的字符来判别该定符是否是汉字 。
解决方案是,利用xxxx_putc( )的光标位置参数(yy, xx),可以逆推出该字符在缓冲区中的位置 。但仍有一些小麻烦,在Linux的虚拟终端下,用户可能会上卷该屏幕(shift pageup),导致光标的y座标和相应字符在缓冲区的行数不一致 。相应的解决方案是,在逆推的过程中,考虑卷屏的参量 。
推荐阅读
- Linux文件系统被破坏时的处理方法介绍
- Linux操作系统的内存使用机制研究
- 删除Linux后如何找回Windows启动菜单
- 如何查看Linux操作系统使用的Shell类型
- Linux的高效的数据传输技术-Relay
- Linux操作系统上定时运行Java程序的方法
- 基于Linux操作系统的目录服务的实现
- 基于Linux的虚拟主机搭建
- win7系统中出现音量图标不见具体处理方法
- 教你制作Linux操作系统的USB启动盘
