科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基于Linux操作系统内核汉化大揭秘 (4)

基于Linux操作系统内核汉化大揭秘 (4)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

这样一来,我们就又进了一步,得到了一个相对更好的版本。但仍有问题没有解决,敲入turbonetcfg,会发现菜单的边框字符也被当成汉字显示

作者:赛迪网技术社区 来源:赛迪网技术社区 2007年10月22日

关键字: 内核 Linux 汉化 揭秘

  • 评论
  • 分享微博
  • 分享邮件

这样一来,我们就又进了一步,得到了一个相对更好的版本。但仍有问题没有解决,敲入turbonetcfg,会发现菜单的边框字符也被当成汉字显示,这是因为,这种边框字符是扩展字符,也使用了字符的低8位,因而被当成汉字显示,这是因为,这种边框字符是扩展字符,也使用了字符的低8位,因而被当作汉字来赤示。例如,单线“—”的制表符内码为0xC4,当连成一条长线时就是由一连串0xC4组成的,而0Xc4c4正是汉字“哪”,于是水平的制表符被一连串的“哪”字替代了,因为制表符的种类比较多,而且垂直制表符与其后面字符的组合形式又多种多样,因而很难判断出相应位置的字符是不是制表符,从理论上说,无论采取什么样的排除算法,都必然存在误判的情况,因为总存在二义性,没有充足的条件来推断出当前字符究竟是制表符还是汉字。

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

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

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

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

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

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

其实,如果再添加一位来标志当前字符是汉字的左半边还是历半边的话,就会省去扫描屏幕上当前整行字符串的工作,这样一来,编程会更简单,但是有读者会问,即使是这样,使用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字库的指针,调用底层的显示驱动程序。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章