📄 00000021.htm
字号:
shift <BR>+ pageup),导致光标的y座标和相应字符在缓冲区的行数不一致。相应的解决方 <BR>案是, <BR>在逆推的过程中,考虑卷屏的参量。 <BR>这样一来,我们就又进了一步,得到了一个相对更好的版本。但仍有问题没有解决 <BR>。敲入 <BR>turbonetcfg,会发现菜单的边框字符也被当成汉字显示。这是因为,这种边框字 <BR>符是扩 <BR>展字符,也使用了字符的第8位,因而被当作汉字来显示。例如,单线“一”的制 <BR>表符内 <BR>码为0xC4,当连成一条长线就是由一连串0xC4组成,而0xC4C4正是汉字“哪”。于 <BR>是水平 <BR>的制表符被一连串的“哪”字替代了。要解决这个问题就非常不容易了,因为制表 <BR>符的种 <BR>类比较多,而且垂直制表符与其后面字符的组合型式又多种多样,因而很难判断出 <BR>相应位 <BR>置的字符是不是制表符,从理论上说,无论采取什么样的排除算法,都必然存在误 <BR>判的情 <BR>况,因为总存在二义性,没有充足的条件来推断出当前字符究竟是制表符还是汉字 <BR>。 <BR>我们一方面寻找更好的排除组合算法,一方面试图寻找其它的解决方案。要想从根 <BR>本上解 <BR>决定个问题,必须利用其它的辅助信息,仅仅从缓冲区的字符来判断是不够的。 <BR>经过一番努力,我们发现,在UNIX中使用扩展字符时,都要先输出字符转义序列( <BR> <BR>Escape sequence)来切换当前字符集。字符转义序列是以控制字符Esc为首的控制 <BR>命令, <BR>在UNIX的虚拟终端中完成终端控制命令,这种命令包括,移动光标座标、卷屏、删 <BR>除、切 <BR>换字符集等等。也就是说在输出代表制表符的字符串之前,通常是要先输出特定的 <BR>字符转 <BR>义序列。在console.c里,有根据字符转义序列命令来记录字符状态的变量。结合 <BR>该变量 <BR>提供的信息,就可以非常干净地把制表符与汉字区别开来。 <BR>在如上思路的指引下,我们又产生了新的解决方案。经过改动得到了另一各版本. <BR> <BR>在这个新版本上,turbonetcfg在初次绘制的时候,制表符与汉字被清晰地区分开 <BR>来,结 <BR>果是非常正确的。但还有新的问题存在∶turbonetcfg在重绘的时候(如切换虚拟 <BR>终端或 <BR>是移动鼠标光标的时候),制表符还是变成了汉字,因为重绘完全依赖于缓冲区, <BR>而这时 <BR>用来记录字符集状态的变量并不反映当前字符集状态。问题还是没有最终解决。我 <BR>们又回 <BR>到了起点。∶—( <BR>看来问题的最终解决手段必须是把字符集的状态伴随每一个字符存在缓冲区中。让 <BR>我们来 <BR>研究一下缓冲区的结构。 <BR>每一个字符占用16bit的缓冲区,低8位是ASCII值,完全被利用,高8位包含前景颜 <BR>色和背 <BR>景颜色的属性,也没有多余的空间可以利用。因而只能另外开辟新的缓冲区。为了 <BR>保持一 <BR>致性,我们决定在原来的缓冲区后面添加相同大小的缓冲区,用来存放是否是汉字 <BR>的信息 <BR>。 <BR>也许有读者会问,我们只需要为每个字符添加一bit的信息来标志是否是汉字就足 <BR>够了, <BR>为什么还要开辟与原缓冲区大小相同的双倍缓冲区,是不是太浪费呢? <BR>我们先放下这个问题,稍后再作回答。 <BR>其实,如果再添加一bit来标志是当前字符是汉字的左半边还是右半边的话,就会 <BR>省去扫 <BR>描屏幕上当前整行字符串的工作,这样一来,编程会更简单。但是有读者会问,即 <BR>使是这 <BR>样,使用8bit总够用了吧?为什么还要使用16bit呢? <BR>我们的作法是∶用低8位来存放汉字另外一半的内码,用高8位中的2 bit来存放上 <BR>面所讲 <BR>的辅助信息,高8位的剩余6位可以用来存放汉字或其它编码方式(如BIG5或日文、 <BR>韩文) <BR>的信息,从而使我们可以实现同屏显示多种双字节语言的字符而不会有相互干扰。 <BR>另外, <BR>在编程时,双倍缓冲也比较容易计算。 <BR>这样我们就回答了如上的两个问题。 <BR>迄今为止,我们有了一套彻底解决汉字和制表符相互干扰、半个汉字的刷新、重绘 <BR>等问题 <BR>的方案。剩下的就是具体编程实现的问题了。 <BR>但是,由于Framebuffer的驱动很多,修改每一个驱动的xxxx_putc( )函数和 <BR>xxxx_putcs( )函数会是一项不小的工作,而且,改动驱动程序后,每种驱动的测 <BR>试也是 <BR>很麻烦的,尤其是对于有硬件加速的显卡,修改和测试会更不容易。 <BR>那么,存不存在一种不需要修改显卡驱动程序的方法呢? <BR>经过一番努力,我们发现,可以在调用xxxx_putcs( )或xxxx_putc( )函数输出汉 <BR>字之前 <BR>,修改vga字库的指针使其指向所需显示的汉字在汉字字库中的位置,即把一个汉 <BR>字当成 <BR>两个vga ASCII字符输出。也就是说,在内核中存在两个字库,一个是原有的vga字 <BR>符字库 <BR>,另一个是汉字字库,当我们需要输出汉字的时候,就把vga字库的指针指向汉字 <BR>字库的 <BR>相应位置,汉字输出完之后,再把该指针指向vga字库的原有位置。 <BR>这样一来,我们只需要修改fbcon.c和console.c,其中console.c负责维护双倍缓 <BR>冲区, <BR>把每一个字符的信息存入附加的缓冲区;而fbcon.c负责利用双倍缓冲区中附加的 <BR>信息, <BR>调整vga字库的指针,调用底层的显示驱动程序。 <BR>这里还有几个需要注意的地方∶ <BR>1.由于屏幕重绘等原因,调用底层驱动xxxx_putc( )和xxxx_putcs( )的地方有多 <BR>处。我 <BR>们作了两个函数分别包装这两个调用,完成替换字库、调用xxxx_putcs( )或 <BR>xxxx_putc( <BR>)、恢复字库等功能。 <BR>2.为了实现向上滚屏(shift + pageup)时也能看到汉字,我们需要作另外的修 <BR>改。 <BR>Linux在设计虚拟终端的时候,提供了回顾被卷出屏幕以外的信息的功能,这就是 <BR>用热键 <BR>来向上滚屏(shift + pageup)。当前被使用的虚拟终端拥有一个公共的缓冲区( <BR>soft <BR>back),用来存放被滚出屏幕以外的信息。当切换虚拟终端的时候,公共缓冲区的 <BR>内容会 <BR>被清除而被新的虚拟终端使用。向上滚屏的时候,显示的是公共缓冲区中的内容。 <BR>因此, <BR>如果我们想在向上滚屏的时候看到汉字,公共缓冲区也必须加倍,以确保没有信息 <BR>丢失。 <BR>当滚出屏幕的信息向公共缓冲区填写的时候,必须把相应的附加信息也填写进公共 <BR>缓冲区 <BR>的附加区域。这就要求fbcon.c必须懂得利用公共缓冲区的附加信息。 <BR>当然,有另外一种偷懒的方法,那就是不允许用户向上滚屏,从而避免对公区缓冲 <BR>区的处 <BR>理。 <BR>3.把不同的编码方式(GB、BIG5、日文和韩文)写成不同的module,以实现动态 <BR>加载, <BR>从而使得扩展新的编码方式不需要重新编译核心。 <BR> <BR> <BR>小结 <BR> <BR>通过这次针对Linux核心的探索,我们发现,目前Linux的核心设计中,完全没有考 <BR>虑到双 <BR>字节编码字符的显示。我们在这种情况下摸索出一套解决核心下汉字显示的方法, <BR>并编码 <BR>实现了该方案. <BR>遵循核心的GPL版权声明,我们同时公布了实现这一技术的源代码,当然,这些改 <BR>动仍然 <BR>是GPL的.如果能对研究核心的朋友有所帮助,减少一些大家对核心的神秘感,将 <BR>是我们 <BR>最大的收获。 <BR>但是对核心和中文化来说,这仅仅是一种尝试,远不是终点.这种改动多少带有一 <BR>些hack <BR>的色彩,不太可能融合进权威的核心里去.我们仍在积极探索圆满解决这一问题的 <BR>方法, <BR>相信这一结果必然需要通过国内外Linux群体的共同努力才能实现.我们也非常欢 <BR>迎大家 <BR>和我们共同讨论这一问题. <BR> <BR>测试 <BR> <BR>本文实现的Kernel Patch文件(patch.kernel.chinese)可以从<A HREF="http://www.">http://www.</A> <BR>turbolinux. <BR>com.cn下载。 <BR>cd /usr/src/(该目录下应有Linux核心源程序所在的目录linux/) <BR>patch -p0 -b < patch.kernel.chinese <BR>make menuconfig <BR>请选择Console drivers选项中的 <BR>[*] Double Byte Character Display Support(EXPERIMENTAL) <BR>[*] Double Byte GB encode (module only) <BR>[*] VESA VGA graphics console <BR><*> Virtual Frame Buffer support (ONLY FOR TESTING!) <BR><*> 8 bpp packed pixels support <BR><*> 16 bpp packed pixels support <BR><*> VGA characters/attributes support <BR>[*] Select compiled-in fonts <BR>[*]VGA 8x8 font <BR>[*]VGA 8x16 font <BR> <BR>make dep <BR>make bzImage <BR> <BR>make modules <BR>make install <BR>make modules_install <BR>然后用新的核心启动。 <BR>Insmod encode-gb.o <BR> <BR> <BR> <BR>------------------------------------------------------------------------ <BR>------ <BR>-- <BR> <BR>Document converted from word 8 by MSWordView (mswordview 0.5.2) <BR>MSWordView written by Caolan McNamara <BR> <BR>-- <BR>※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.34.143] <BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -