首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 开发>linux 内核>文章内容
Linux操作系统核心的汉字显示机制
来源:http://www.unix5.com 作者:linuxfans 发布时间:2008-04-28  

我们一方面寻找更好的排除组合算法,一方面试图寻找其他的解决方案,要想从根本上解决这个问题,必须利用其他的辅助信息,仅仅利用缓冲区的字符来判断是不够的。

经过一番努力,我们发现,在UNIX中使用扩展字符时,都要先输出字符转义序列(Escape sepuence)来切换当前字符集。字符转义序列是以控制字符Ecs为首的控制命令,在UNIX的虚拟终端中完成终端控制命令,这种命令包括移动光标座标、卷屏、删除、切换字符集等等。也就是说,在输出代表制表的字符串之前,通常是要先输出特定的字符转义序列,在console.c里,有根据字符转义序列命令来记录字符状态的变量,结合该变量提供的信息,就可以非常准确地把制表符与汉字区别开来。

在如上思路的指引下,我们又产生了新的解决方案,经过改动得到了另一版本。

在这个新的版本上,turbonetcfg在初次绘制的时候,制表符与汉字被清晰地区分开,但还有问题:turbonetcfg在重绘的时候(如切换虚拟终端或是移动鼠标光标的),制表符还是变成了汉字,因为重绘完全领带于缓冲区,而这时用来记录字符集状态的变量并不反映当前字符集状态。问题还是没有最终解决,我们又回到了起点。

看来问题的最终解决手段必须是把字符集的状态伴随着每一个字符在每一个字符占用16位的缓冲区,低6、8位是ASCII值,完全被利用,高8位饮食前量颜色和背景颜色的属性,也没有多余的空间可以利用,因而只能另外开辟新的缓冲区。为了保持一致性,我们决定在原来的缓冲区后面添加相同大小的缓冲区,用来存放是否汉字的信息。vhYLinux联盟

也许有读者会问,只需要为每个字符添加一位信息来标志是否是汉字就足够了,为什么还要开辟与原缓冲区大小相同的双倍缓冲区,这是不是太浪费呢?

我们先放下这个问题,稍后再作回答。

其实,如果再添加一位来标志当前字符是汉字的左半边还是历半边的话,就会省去扫描屏幕上当前整行字符串的工作,这样一来,编程会更简单,但是有读者会问,即使是这样,使用8位总够用了吧?为什么还要使用16位呢?

我们的做法是:用低8位来存放汉字另外一半的内码,用高8位中的2位来存放上面所讲的辅助信息,高8位的剩余6位可以用来存放汉字或其他编码方式(如 BIG5或日文、韩文)的信息,从而使我们可以实现同屏显示多种双字节语言的字符而不会相互干扰。另外,在编程时,双倍缓冲也比较容易计算。这样我们就回答了如上的两个问题。

迄今为止,我们有了一套彻底解决汉字和制表符相互干扰,半个汉字的刷新、重绘等问题的方案。剩下的就是具体编程来实现的问题了。

但是,由于Framebuffer的驱动程序很多,修改每一个驱动程序的xxxx_putc()函数和xxxx_putcs()函数会是一项不小的工作,而且,改动驱动程序后,每种驱动程序的测试也是很麻烦的,尤其是对于有硬件加速的显卡,修改和测试会更不容易。

那么,是否存在一种不需要修改显卡驱动程序的方法呢?经过一番努力,我们发现,可以调用xxxx_putcs()或xxxx_putc()函数输出汉字之前,修改VGA字库指针使其指向所需显示的汉字在汉字字库中的位置,即把一个汉字当成两个VGA ASCII字符输出。也就是说,在内核中存在两个字库,一个是原有的VGA字符字库,另一个是汉字字库,当我们需要输出汉字的时候,就把VGA字库的指针指向汉字字库的相应位置,汉字输出完之后,再把该指针指向VGA字库的原有位置。

这样一来,我们就只需要修改fbcon..c和console.c,其中console.c负责维护双倍缓冲区,把每一个字符的信息存入附加的缓冲区中;而fbcon.c负责利用双倍缓冲区中的附加的信息,调理 VGA字库的指针,调用底层的显示驱动程序。

这里还有几个需要注意的地方:

1、由于屏幕重绘等原因,调用底层xxxx_putc()和xxxx_putc()的地方有多处,我们做了两个函数分别馐这两上调用,完成替换字库、调用xxxx_putcs()或xxxx_putc()、恢复字库等功能。

2、为了实现向上滚屏时也能看到汉字,我们需要作另外的修改。Linux在设计虚拟终端的时候,提供了回顾被滚出屏幕以外的信息的功能,这就是用热键来向上滚屏(Shift+Pageup)。当前被使用的虎虚拟终端的时候,公共缓冲区的内容会被清除而被新的虚拟终端使用,向上滚屏的时候,显示的是公共缓冲区中的内容。因此,如果我们想在向上滚屏的时候看到汉字,则公共缓冲区也必须加倍,以确保没有信息丢失。当滚出屏幕的住处向公共缓冲区填写的时候,必须把盯应的附加信息也填写进公共缓冲区的附加区域中,这就要求fbcon.c必须懂得利用公共缓冲区的附加信息。当然,另外有一处偷懒的方法,那就是不允许用户向上滚屏,从而避免对公区缓冲区的处理。

3、把不同的编码方式(GB、BIG5、日文和韩文)写成不同的模块,以实现动态加载,从而使得扩展新的编码方式不需要重新编译核心。

小结

通过这次针对inux核心的探索,我们发现,目前Linux的核心设计中,完全没有考虑到双字节编码字符的显示,我们在这种情况下摸索出一套解决核心汉字显示的方法,并编码实现了该方案。遵循核心的GPL版权声明,我们同时公布了实现这一技术的源代码,当然,这些改动仍然是GPL的。如果能对研究核心的朋友有所帮助,养活一些大家对核心的神秘感,将是我们最大的收获。

但是对核心和中文化来说,这仅仅是一种尝试,远不是终点。这种改动多少带有一些黑客的色彩,不太可能融合进权威的核心里去。我们仍在积极探索圆满解决这一问题的方法,当然这一目标必然需要通过国内外Linux群体的共同努力才能实现。我们也非常欢迎大家和我们共同讨论这一问题 。


共4页: 上一页 [1] [2] 3 [4] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·使用 Linux 系统调用的内核命令
·Linux 2.6.11内核文件IO系统调用
·Linux操作系统的源代码目录树结
·Linux用户态与内核态的交互讲解
·Linux内核对I/O端口的管理实现(
·深入分析 Linux操作系统的内核链
·Linux内核可装载模块对设备驱动
·概述Linux系统的驱动框架及驱动
·详解Linux 2.6内核新文件系统变
·Linux系统可卸载内核模块完全指
·FreeBSD手册讲解(一)--配置FreeB
·编译Linux操作系统的内核讲解
  相关文章
·Linux操作系统“警惕”内核汉化
·如何利用异常表处理Linux内核态
·简析Linux与FreeBSD的syscall
·Linux下的中文显示和支持常见问
·如何在Linux内核中的实现SYN Coo
·Linux内核源代码学习概述
·Linux系统内核漏洞分析
·深入学习LINUX内核之七(图文讲解
·深入学习LINUX内核之六(图文讲解
·深入学习LINUX内核之五(图文讲解
·深入学习LINUX内核之四(图文讲解
·深入学习LINUX内核之三(图文讲解

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!