下一页 上一页 目录

5. X 的配置

当 X 服务器处于活动状态时,它会将计算机的键盘置于一种称为 raw(原始)的操作模式,与称为 cooked(熟制)的正常模式相反。在原始模式下,操作系统不处理重音-字母序列。X 服务器是少数几个必须“低级别”处理键盘的应用程序之一。

X 配备了一个用于配置键盘的实用程序,称为 xmodmap,其功能类似于 loadkeys 命令,即读取 X 键盘映射文件,指定 键码 和相应的 键符号 之间的等效关系。

以下是此文件的一个摘录

    keycode 47 = ccedilla Ccedilla dead_acute dead_doubleacute
    keycode 48 = masculine ordfeminine dead_circumflex dead_caron
    keycode 49 = backslash bar notsign
    keycode 50 = Shift_L
    keycode 51 = dead_tilde dead_circumflex dead_grave dead_breve
请注意,与 loadkeys 不同,xmodmap 没有在其中搜索文件的默认目录。

X 的配置完全不影响文本模式的配置。事实上,有可能您的 X 配置良好,但尚未对文本模式进行任何类型的配置,反之亦然。另一个需要注意的重点是,X 中的按键数字代码与控制台中的代码不对应。例如,退格键在控制台中编号为 14,而在 X 中为 22(在 IBM-PC 类型的计算机上)。

XFree86 的 3.2 及更高版本允许定义 dead-keys(死键),但它们的处理是应用程序的责任,如 文本模式与 X 窗口系统 一节中所见。有一些方法可以绕过此限制,并使 dead-keys 的处理对应用程序透明,如 绕过 X 的限制 一节所示。

我们将配置分为两部分:一部分必须在用户登录之前完成,另一部分在之后完成。

5.1 xinit 的配置

本文档附带了多个用于 X 的键盘映射。为了自动化键盘配置过程,只需将适当的文件复制到目录 /usr/X11R6/lib/X11/xinit,该目录通常是 X 中工作会话的启动文件所在的位置。在 Slackware 发行版中,此目录是指向 /var/X11R6/lib/xinit 的符号链接,在 Debian 和 Red Hat 中是指向 /etc/X11/xinit 的符号链接。

在 Slackware 和 Red Hat 发行版中,检查上述目录中是否存在名为 .Xmodmap 的文件。如果存在,将 Xmodmap.<某些内容> 复制到它,或者创建一个链接。通常,配置文件 xinitrc 具有自动加载它的命令。请看以下摘录

    #!/bin/sh
    # $XConsortium: xinitrc.cpp,v 1.4 91/08/22 11:41:34 rws Exp $

    userresources=$HOME/.Xresources
    usermodmap=$HOME/.Xmodmap
    sysresources=/usr/X11R6/lib/X11/xinit/.Xresources
    sysmodmap=/usr/X11R6/lib/X11/xinit/.Xmodmap

    # merge in defaults and keymaps

    if [ -f $sysresources ]; then
        xrdb -merge $sysresources
    fi

    if [ -f $sysmodmap ]; then
        xmodmap $sysmodmap
    fi

在 Debian 发行版中,X 的默认键盘映射是 /etc/X11/Xmodmap,只需将所需的映射复制到该文件即可。它将由 xinitrc 加载,而 xinitrc 本身是指向 /etc/X11/Xsession 的符号链接,每当用户启动工作会话时都会加载。

5.2 XDM 的配置

仍然存在一个小问题:例如,在我的计算机上,系统在启动时直接加载 X,并且登录是通过 X Display Manager (xdm) 完成的。由于 xdm 在启动工作会话之前进行登录,因此键盘映射不会被加载,如果用户在其密码中使用诸如“['' 或 ``]'' 之类的字符,则可能会产生问题,因为在 ABNT-2 和葡萄牙语键盘中,这些符号是由键码与美国键盘不同的按键生成的。

需要在配置文件 Xsetup_0 中进行一个小小的更改。此文件应位于目录 /usr/X11R6/lib/X11/xdm 中,在 Slackware 中,该目录是指向 /var/X11R6/lib/xdm 的符号链接,在 Debian 和 RedHat 中是 /etc/X11/xdm,-- 待确认 --。以下是此文件的完整内容

    #!/bin/sh
    #
    # /usr/X11R6/lib/X11/xdm/Xsetup_0
    #

    sysresources=/usr/X11R6/lib/X11/xinit/.Xresources
    sysmodmap=/usr/X11R6/lib/X11/xinit/.Xmodmap

    # merge in defaults and keymaps

    if [ -r $sysresources ]; then
        xrdb -merge $sysresources
    fi

    if [ -r $sysmodmap ]; then
        xmodmap $sysmodmap
    fi

    xconsole -geometry 480x130-0-0 -daemon -notify -verbose -exitOnFail

Debian 发行版在 /etc/X11/xdm/Xsetup_0 中有一个略有不同的 Xsetup_0,但只需向其添加以下内容即可

    sysmodmap=/etc/X11/Xmodmap
    sysresources=/etc/X11/Xresources

    if [ -f $sysresources ]; then
      xrdb -merge $sysresources
    fi

    if [ -f $sysmodmap ]; then
      xmodmap $sysmodmap
    fi

如果您的计算机上的用户登录也始终通过 xdm 完成,则无需像上一节所示那样修改 xinitrc,因为键盘映射将在用户会话开始之前加载。

5.3 Compose

当我们要使用通过 dead-keys 进行重音时,要定义的最重要的事情之一是 组合规则 集。这些规则确定,例如,字符 ' 与字母 e 的组合将生成一个 é

与控制台不同,在控制台中我们可以在键盘映射本身中定义组合规则,在 X 中,这些规则放在文件 /usr/X11R6/lib/X11/locale/???/Compose 中,其中 ??? 是正在使用的编码(在我们的例子中,iso8859-1)。

为了方便使用没有 c-cedilhado(ç 字符)的键盘的映射,例如 US+(见下文),我们最好定义一个新的组合规则,允许通过序列 'C 生成 Ç。如果我们不这样做,我们将被迫输入 <dead_cedilla-C>,其中 dead_cedilla 是由组合 AltGR-= 生成的,这很不舒服。此外,在美国键盘中,我们被迫使用双引号来生成分音符。

提供的 Compose 文件旨在尽可能模仿控制台的行为,并具有以下字符生成便利性

为了包含新规则,只需对原始定义应用更改即可。可以从 Portuguese HOWTO 页面上的 WWW 获取文件 Compose.patch。要应用更新,请将其复制到目录 /usr/X11R6/lib/X11/locale/iso8859-1/,创建原始 Compose 的备份副本,并调用实用程序 patch

    cp -p Compose Compose.backup
    patch < Compose.patch

如果您不想应用“patch”,则还提供了一个现成的 Compose 文件。记住在替换原始文件之前制作副本!

5.4 Locale(区域设置)

对于巴西用户,X 中可能还需要进行更多更改。正如我们在 libc 库 一节中看到的,环境变量(LANG 或 LC_ALL)配置了系统标准函数库 (libc) 中存在的国际支持。X 函数库 (Xlib) 使用 LANG 变量来标识正在使用的语言,但直到基于 XFree86 的 6.3 修订版,其中都不包含与葡萄牙语/巴西对应的组合“pt_BR”。因此,每次我们执行 LC_ALL 定义为“pt_BR”的 X 应用程序时,它都会发出消息“Warning: locale not supported by Xlib, locale set to C”。

要在 X11R6.3 中包含 pt_BR 区域设置,只需更改目录 /usr/X11R6/lib/X11/locale 中存在的三个文件。从 Portuguese HOWTO 页面上的 WWW 获取文件 Xlocale.patch。要应用更新,请将其复制到目录 /usr/X11R6/lib/X11/locale,创建要更改的文件的备份副本,并调用实用程序 patch

    cp -p compose.dir compose.dir.backup
    cp -p locale.alias locale.alias.backup
    cp -p locale.dir locale.dir.backup
    patch < Xlocale.patch

如果您不想应用“patch”,则还提供了现成的文件。记住在替换原始文件之前制作副本!

1998 年 9 月,X Window System 的 6.4 修订版的 fix-2 正式包含了对 pt_BR 区域设置的支持。不幸的是,在同一个 fix-2 中,Xlib 的 输入上下文 处理函数之一中引入了一个错误,该错误导致内存访问冲突。受影响的应用程序之一是 LyX 文本处理器。修复程序可能会包含在 fix-4 中。X11R6.4 应该是 XFree86 版本 4 的基础。

5.5 使用 XKeyCaps 生成映射

Jamie Zawinski 创建的 XKeyCaps 程序是 xmodmap 的图形界面,它在屏幕上显示键盘的图形,并允许交互式地修改每个按键生成的符号,并自动生成相应的 .Xmodmap 文件。

可以从 WWW http://www.jwz.org/xkeycaps/ 获取它,并且从 2.43 版本开始,它还包含了对巴西(ABNT2)布局的支持,这是 Andre Gerhard 的贡献。

5.6 绕过 X 的限制

正如在 文本模式与 X 窗口系统 一节中所解释的那样,重音的处理应由应用程序完成,但仍有许多程序没有考虑到这一点,例如 Netscape Navigator/Communicator 和 Nedit。由于无法修改它们中的许多程序,因此需要找到另一种解决方案。

更改 Xlib 库

Linux 与大多数现代操作系统一样,使用一种将程序链接到函数库的系统,称为“动态绑定”(dynamic binding)。这样,我们可以通过更改其中一个库来修改程序的行为。有关此主题的更多信息,可以从 Linux 手册中通过以下命令获得

    man ld.so
    man ldconfig
    man ldd
    man dlopen
Thomas Quinot 为 X 函数库 (Xlib) 创建了一个更改,在 XLookupString 函数中引入了重音处理。要做的就是用另一个文件替换包含此库的文件,该文件可以从互联网地址获得

http://web.fdn.fr/~tquinot/dead-keys.en.html

该文件有两个版本,一个用于 X 库支持安全使用 线程 的系统(Debian 2.x、Red Hat 5.x 等),另一个用于不具有此属性的系统(Slackware、Caldera 1.x)。如果您不知道线程是什么,请不要担心,但要知道它们允许创建一个能够分成子进程的程序,这些子进程可以在计算机上并发运行。要分析您的 Xlib,请运行以下命令

nm --dynamic /usr/X11R6/lib/libXext.so.6|grep _Xglobal_lock

如果出现“U _Xglobal_lock”,则您的系统支持线程,要获取的文件是 libX11-XF3.3.1-TS.tar.gz。如果未出现,则您的系统不支持线程,要获取的文件是 libX11-XF3.3.1.tar.gz。获取文件后,将其复制到临时目录并解压缩其内容。将文件 /usr/X11R6/libX11.so.6.1 移动到另一个目录以保留它。重命名它是不够的!将其删除到名称包含在 /etc/ld.so.conf 文件中的目录中。然后,将新文件移动到旧文件的位置,并运行程序 ldconfig(这必须由 root 用户完成)

    cp libX11-XF3.3.1-TS.tar.gz /tmp
    cd /tmp
    tar xzf libX11-XF3.3.1-TS.tar.gz
    mkdir /usr/X11R6/oldlib
    mv /usr/X11R6/lib/libX11.so.6.1 /usr/X11R6/oldlib
    mv libX11.so.6.1 /usr/X11R6/lib
    chown root:root /usr/X11R6/lib/libX11.so.6.1
    chmod 755 /usr/X11R6/lib/libX11.so.6.1
    /sbin/ldconfig

建议在没有 X 应用程序运行时执行此操作。接下来,编辑 X 服务器的配置文件,名为 XF86Config。此文件位于目录 /etc (Slackware) 或 /etc/X11 (Debian, Red Hat) 中。找到“Keyboard”部分并包含选项“XkbDisable”,如下所示

    Section "Keyboard"
       Protocol        "Standard"
       XkbDisable
    EndSection

选项 XkbDisable 禁用 X 服务器的 XKEYBOARD 扩展,在这种情况下,它用于向 XLookupString 函数发出信号,表明它应该处理重音。如果我们想恢复到正常行为,只需从 XF86Config 中删除该选项即可。

按照本文档前面章节中的说明配置 X 的键盘映射。要测试结果,请运行程序 xedit 并输入一些带重音的字符。

更改 Linux 内核

本节基于 Bruno Barberi Gnecco 发送的贡献和 diacrd 的文档。可能仍然存在一些错误,如果有人发现它们,请告诉我。

遵循 *nix 世界的一般规则,总是有一种以上的方式来解决同一个问题。正如我们前面看到的,键盘有两种操作模式,称为 rawcooked。可以使用程序 kbd_mode 更改这些操作模式,该程序是 kbd 包的组成部分,除非为了在 X 服务器发生灾难后恢复控制台状态,否则不建议这样做。在原始模式下,内核不处理变音符号(重音)。

Cedric Adjih 为内核创建了一个更改,即使在原始模式下也允许处理重音,最初是针对法语布局键盘的。Enéas Queiroz、André D. Balsa 和 Claudemir Todo Bom 进行了改进并将其适配到国际、葡萄牙语和 ABNT 键盘。重音的处理部分由内核完成,部分由在后台运行的进程(守护程序)完成,称为 diacrd,如下所述

可以从 FTP 匿名获取 diacrd,地址为

ftp://metalab.unc.edu/pub/Linux/system/keyboards
根据键盘类型有不同的版本,并且至少目前,不重新编译就无法重新配置它。要根据“README”文件进行安装,应执行以下操作(由 root 用户执行)

如果重音生成有效,则需要使必要的更改永久生效。可以将 diacrd 的加载包含在文件 /etc/rc.d/rc.local (Slackware) 中来完成此操作。

如果任何读者为 Debian 或 Red Hat 发行版创建了 diacrd 的激活脚本,请发送给我,以便将其包含在此处。
有关 diacrd 的更多信息,请参见 Claudemir Todo Bom 的“Dead keys Mini-HOWTO”,该文档可在 http://linux.unicamp.br/docs/diversos/deadkeys.html 中找到。

两种解决方案的比较

在实际结果方面,修改后的 Xlib 和 diacrd 是等效的。但是,两种解决方案之间存在一些差异,值得关注。

Diacrd 需要更改 Linux 内核以解决内核已经解决的问题,这似乎有点多余。对用户进程(守护程序 kerneld)的依赖是一个缺点,因为如果该程序停止工作,X 中的重音支持将丢失。这仍然是一个正在开发的解决方案,根据其附带的文档内容,理想情况是所有处理都由内核完成,而无需依赖另一个程序。

截至本 HOWTO 发布时,diacrd 尚不兼容 Linux 内核的 2.2 版本。

通过 Xlib 的解决方案至少在理论上对应用程序是完全透明的,并且允许在运行时重新配置,只需更改 X 的键盘映射和组合规则即可。如果我们要更换键盘类型,则需要重新编译 diacrd,但新版本可能会包含某些重新配置功能。

diacrd 仅在计算机自身的键盘上工作。如果我们想使用远程 显示器,无论是 X 终端还是另一台计算机,我们将没有重音支持。另一方面,更换 Xlib 完全符合 X 的理念,即服务器提供机制,将策略的定义留给应用程序。此范例优势的示例是能够在其他操作系统和 X 终端中使用 X 的配置 一节中描述的技术。

通过 Xlib 的解决方案在我看来更“干净”,并且是我的首选,但与往常一样,选择哪种替代方案取决于用户或系统管理员。无论如何,始终记住这两种解决方案都是权宜之计。考虑到自由软件领域正在发生的快速发展,随着 KDEGNOMEGNUStep 等工作环境的开发,我们可以假设,在不久的将来,这些权宜之计都不再需要。


下一页 上一页 目录