BBS水木清华站∶精华区

寄信人: <bbs@captain.net.tsinghua.edu.cn>  
标  题: 6 -- Alex 整理 
发信站: 华南理工大学 BBS木棉站 
日  期: Tue Aug 20 08:35:08 1996 
 
作用的格式和作用的表列 
 
每一个转译在一或多个作用之上系结一个序列的一或多个事件。在表列中的个 
别作用是以空白分开的。 (不可用逗点分开,那将会导致错误)。 
 
    个别的作用格式如下: 
 
      action-name(parameters) 
 
即使没有参数被指定,在作用名称 (action-name)後的括弧,仍然不可省略。 
例如: 
 
      start-selection() 
 
如果在作用名称和左括弧中间留有空白,你将会得到一个错误。 
 
    作用名称只包含了字母、数字、钱号($)、底线(_)四种字元。每一个widget 
提供它自己的作用集合 (如果有的话) ,且自我包含这些作用名称的硬码 
(hard-coded)表列。 
 
    参数(parameters)是一个零到多个字元字串的表列,中间以逗点分开。参 
数的意义为对特定的作用作指定 (事实上大多数的作用并没有任何参数) 。参 
数字串可以不加引号,例如: 
 
    insert-selection(PRIMARY) 
 
或者前後加上双引号,这种情形通常为参数字串内包含了空白或一个逗点,例 
如: 
 
    string("plot<x,y>") 
 
没有一个一般性的方法,让你在参数字串中的任何位置包含一个双引号,虽然 
像这样 string(ab"cd)'将双引号放在字串中间是可被处理的。也没有一般性的 
方法在同一个参数字串中同时包含字串和双引号。因为如此,有些widget在解 
释它们自己的参数时,可以自行加入它们自己的语法规则。例如:对xterm 的 
VT100 widget的 string()作用,如果一个不带双引号且开头为 "0x"的字串, 
此字串被解释为代表一个ASCII 字元的十六进位数。 
 
    在此结束我们对转译规格及格式的描述。由此,你应有能力了解在不同X 
手册列出的转译,且可写你自己的转译。为了帮助你,下节列出你常见的问题 
,以及如何克服它们。 
 
17.3 在转译规格中常见的问题 
 
转译在观念上简单,但实际上很混乱。即使你常常使用,语法仍然复杂而难解。 
无论如何,如果你是初学者,最好的方式是你以别人的转译当作自己的转译的 
基础。在指南页中有几个对xbiff、xdm(目前尚未介绍过,将於第20章介绍 
)、xterm 的转译范例,将对你有所帮助。 
 
    如果你发现你的转译有错误的话,有几点值得去检查: 
 
    .转译只能应用在使用Toolkit的程式上。如果你试图对非Toolkit应用程 
      式定义转译,看起来不会有任何问题,只是转译不会作用而已。 
 
      让我们来看一下为什麽,以对xcalc (这是一个非Toolkit程式)使用转译 
      为例。你对一个resource名称像 *xcalc*translations定义一个转译表, 
      且用xrdb载入至你的资料库。xrdb并不会抱怨,因为它不知道是那一个 
      应用程式使用到resource,它只会设定资料库,稍後供Resource Manager 
      查询。现在你执行xcalc ,它对转译是一无所知,所以不会向资料库查 
      询转译,当然也绝不会编译它们了。 
 
    .不要省略 #override,除非你确实知道你要做什麽。如果你因错误省略 
      它,例如在xedit 中,你将发现没有任何的键可输入任何的东西 (因为 
      预设的转译 "<Key>:insert-char()"被去掉了)。 
 
    .检查你对每一列均有终结。如果你在转译表中的一列忽略了"\n\"或"\n" 
      ,在其後所有的转译都会被忽略。如果你在最後一列的末端加上一个倒 
      斜线(\) ,或是省略了档案中最後一个新列字元(newline),整个转译表 
      都会被忽略。(不过这是xrdb的问题,而非转译管理器的问题)。 
 
      这种错误在你编辑一个现存的转译表时特别容易发生。 
 
    .当你定义的转译和预设有冲突时,可能会导致奇怪的行为,特别是对滑 
      鼠按钮事件,每一次按下或"Down"事件,会相关到一个松开或"Up"事件 
      ,当你对此部份没有明确定义时,可能会有一个预设的系结仍然存在, 
       (键盘的按下和松开也是成对的事件) .所以: 
 
           1.检查预设系结的文件。 
 
      2.如果你只对按下/松开配对的一半指定一个转译,确定另一半并非预设 
        转译的一部份,如果是的话,需对它明确地指定一个转译。 
 
      3.如果你仍然不能解决,暂时由表中移去#override,这将去掉所有的预 
        设转译,让你了解问题是由於和预设转译冲突所造成,还是因为你的 
        转译表有错误。 
 
    .转译管理器对语法不正确的问题,无法很好的告诉你原因何在。例如如 
   果你有一个转译像: 
 
          <Key>F6: string("abc""def") 
 
      参数的语法并不正确,F6键将没有作用,但你也看不到错误讯息。 
 
    .如果你转译一序列的事件,且需要对每一个均指定修饰键,你必需明确 
      地对每一个都指定。例如如果你需要一个转译使用ctl-X ctl-K: 
 
          Ctrl <Key>X, Ctrl <Key>K: ... 
 
      而如果你使用: 
 
          Ctrl <Key>X, <Key>K: ... 
 
     你的指定为 ctl-X K 
 
    .检查你所需的widget是否有你指定的名称和类别。例如对xterm ,你可 
      以在一个表的开头指定: 
 
          xterm*Text*translations: 
 
      这将什麽事也没作,xterm 正规视窗widget的类别VT100。通常,不论 
      xrdb或转译管理器均不会有反应,因为看起来没错。 
 
    .转译可能指定正确,也可以工作,但它的作用和你预期的不符。例如对 
      xterm 的转译: 
 
          Meta Ctrl <Key>m: mode-menu() 
 
      是正确的,且会工作。但mode-menu()实际上检查滑鼠左或中按钮是否有 
      招唤它,其它方面不做任何事。 
 
    .在一个转译中不指定修饰键,并不意味著当修饰键按下时转译会无效。 
      它真正的意义为: "我并不在乎有没有修饰键" 。如果需要的话,使用 
       "None",""或!符号。使用时要小心预设的转译是否会妨碍到你。 
 
    .转译是针对widget而指定的,所有在转译中的作用必需由widget提供。 
      在你指定转译resource名称的地方很容易忘掉这一点。例如: 
 
          xman*translations: \ 
          <EnterWindow>: reset()\n\ 
          <LeaveWindow>: set() 
 
      将导致许多错误:set()和reset()作用只有被Command widget定义,但 
      xman有数种其它型态的widget可接受转译,且转译管理器会抱怨这些 
      widget并未提供set()和reset()。解决之道为更完整些的指定resource 
      名称,例如在本例为 xman*Command*translations 。 
 
    .对任何给定的resource,当resource资料库被询问时,Resource Manager 
      会传回一个值给widget,这个传回的值的 "特徵值" (characteristic) 
       (resource名称)大多与widget的和属性的完整类别/成员名称相符。所 
      以你对所有的Text widget指定一个一般性的转译後,又对xedit指定一 
      个转译,希望它们并存是不可能的,只有一个转译表会传给widget。例 
      如: 
 
          *Text*Translation: #override\ 
          (对Text一般性的转译) 
          ... 
          xedit*Text*Translation: #override\ 
          (对xedit 的Text特定的转译) 
          ... 
 
      你只能得到在xedit 中特定的转译,或是在别处得到一般性的转译。 
 
      #override 会有所混淆,它的意义为 "把转译加入现存的之中" 。但这 
      完全由转译管理器处理,当时候到时,转译管理器会决定传递哪个值给 
      由Resource Manager所造的widget。对Resource Manager而言,#override 
      只是传递给widget值的部份中的一个文字字串而已。 
 
    因为你使用resource来指定转译,所以错误可能在两个领域均会发生。为 
了减少错误的范围,当你对转译颇有经验时,在你已载入转译resource之後, 
最好能明确地列印出你的resource资料库。例如:如果你对xprog 写入转译, 
且转译在档案mytrans 中,以下列命令来执行程式: 
 
      xrdb mytrans ; xrdb -q ; xprog ... 
 
17.4 结论 
 
    这漫长的一章涵盖了被X Toolkit 所使用的标准转译结构,它让你指定 
按下一个键或按钮会有什麽影响。这些转译指定到每一个widget,且你藉著使 
用标准resource结构传送转译表给widget。你看到如何对一个键盘的键、滑鼠 
按钮和其它像移动一个指标进入视窗的事件作指定转译。然後我们藉著指定不 
同状态的修饰键所造成的影响,比较严谨地定义我们需要转译的事件。 
 
    本章的第二个部份涵盖相同的领域,但较为正式,且详细解释在转译规格 
中,可用到的语法,特别是修饰键。 
 
    最後,我们简列使用转译常见的问题,及一些如何解决它们的建议。 
 
    本章包含了许多材料。它们运用了极少的观念,但语法复杂,易生错误, 
且不显而易见。如果一开始觉得困难,不必担心。从一些简单的转译著手 (也 
许是xterm),且以指南页中的范例或别人的转译表为基础来发展修改。当你有 
经验之後会进展快速;你将洞悉语法且能看出其後会发生什麽状况。 
 
===== 
 
第18章  键盘和滑鼠 -- 对应和参数 
 
在前章我们看到了Toolkit 所提供的转译结构,它让你对一个应用程式的个别 
成员,定制你的键盘和滑鼠。在本章,我们来看另一种较低层次的定制,它是 
由server所管理,称之为对应(mapping) ,你只需要告诉server你的键盘所需 
的不同的配置,它就会被每一个连接到你server上的应用程式应用到。例如: 
取代通常的QWERTY键盘,你可能希望重新安排键盘以适应那些对键盘并不熟悉 
的使用者 (你可能把键盘按ABCDEF... 重新排过,当然键盘按钮上所印的字也 
需更改成相符)。你也能对一些Control,Shift等等的修饰键作指定。对滑鼠 
按钮,一样有一个相关的对应,可将 "逻辑的" 按钮对应到实际动作。整体而 
言,你使用这些键盘和滑鼠的对应的频率,将小於转译。 
 
    此外,尚有非常常用的第三种型态的定制可用:你可以设定有关你键盘和 
滑鼠各种不同的参数。例如响铃声音的大小,按下键时是否有滴答声等等。 
 
    在本章,我们先描述键盘、滑鼠和修饰键的对应,接下来描述你如何使用 
xset程式,来定义类似像键盘有无滴答声的参数设定。 
 
18.1 键盘和滑鼠对应 -- xmodmap 
 
server本身处理一个层次的定制,它对於所有使用到此server或显示器的应用程 
式均发生效用:这就是键盘对应 (keyboard mapping)。 
 
    每一个键,有一个单独的码对应它,称之为键码(keycode)。键和键码之间 
的关系是绝对固定的。 (粗略来说,你可以说 "键码就是键")。 
 
    连接到每一个键码 (或键)的是一个keysym的表列。一个keysym是一个代表 
印在键盘符号上的数字常数。在预设的情况,大多数的键只有一个keysym 与之 
对应,例如 SHIFT,A,B,Delete,Linefeed等等。keysym既非ASCII或EBCDIC 
字元,也非server用以维持keysym和字元的关系。你可以对每一个键有两个 
keysym。在预设对应中,有很多连接到两个keysym的键,例如冒号(:) 和分号(;) 
,7 和 &等等。对一个键附属的keysym表列中,第一个keysym是未按下修饰键 
的状况下的键。第二个keysym是指当SHIFT (或Lock)已被同时按下时的键,如 
果在表列中只有一项,且为字母,则系统自动假设第二项为相对的大写字母。 
超过两项的keysym并没有特别的意义,键盘和keysym之间的关系被称之为键盘 
对应。 
 
    尽量地以server处理一般的键和keysyms 。它对键码没有附属意义,且它 
自己本身不会使用对应从键码对应至keysyms :它只是传递资讯给client应用 
程式。特别的是,server对ASCII 或其它的字元集合 (character sets) 毫无 
概念;它只是说明 "某键被按下,某修饰键也同时被按下,keysym表列中某 
keysym和某键相关" 。它是client (典型的使用标准的X Library) 对keysym 
和修饰键附属的意义:例如,它决定如果keysym产生时ctrl也被按下,它必需 
被解释为ASCII 字元 hex 0x1,也就是说ctl-A。 特定的client可以决定特殊 
的修饰键的意义;例如在xterm 中,当你和MTEA键同时按下一个键,程式将此 
转换为ESC 後面跟随著被按下的字元。 (也就是说,如果你按下meta-A,实际 
上会产生两个字元 ASCII 0x1b, ASCII 0x41)。 
 
    server在此领域内提供一个额外的设施。你可以定义让server将键码解释 
成修饰键,例如 "当键码为若干的键被按下时,它相同於CONTROL修饰键被实际 
按下"。这种定义并不互斥:如果你定义键F7为Shift 修饰键,它并不会影响任 
何现存的修饰键。此种设施称之为修饰键对应 (modifier mapping)。X提供八 
个修饰键:Shift、Lock(caps-lock)、Control、Mod1到Mod5。习惯上,Mod1被 
解释为Meta。 
 
    最後,对滑鼠按钮有一个类似的指标对应 (pointer mapping)。对每一个 
实际的按钮,你可以对它们指定一个相关的逻辑按钮数字。 
 
    实际上,如果你改变你的键盘或滑鼠的对应,你相当於是说制造厂商对你 
的输入装置配置不当,你将把它修正为适合你所需要的。当然,如果你改变了 
对应,你应该把对应键上面所印的符号也随之修改;不过,通常更改的都是一 
些控制和修饰键,所以就不是那麽需要了。换句话说,如果你改变了对应,使 
得键盘配置和一个特定国家标准 (例如:法国或德国) 相符,你必需更换实际 
键盘上的符号。 
 
    你可以预期得到,改变键盘对应是一件相当稀罕的事,你可能设定它一次 
之後就不再改变它。在以下几节,我们将很快的看一看如何使用程式xmodmap 
,查看现有的对应和修改它们。 
 
18.1.1 查看现有的对应 
 
你使用xmodmap 来列出现有的对应,就如同改变它们一样。你可以指定不同的 
命令列选项,来选择想要印出的不同的对应: 
 
    列出现有键的对应:指定 -pk选项。 
 
    列出现有修饰键的对应:指定 -pm选项 (或是什麽选项也不选,因为这是 
        xmodmap的预设作用)。 
 
    列出现有指标 (按钮)的对应:指定 -pp选项。 
 
例如,将所有的对应一起印出,使用命令: 
 
    xmodmap -pm -pk -pp 
 
列出键、修饰键、指标的对应之范例如图18 - 1,18 - 2,18 - 3。(键对应只 
有列出一部份,因为完整的对应实在太长了。) 
 
        ┌————————————————————┐ 
        │      p228  fig 18.1                    │ 
        │                                        │ 
        │    图18-1 列出键盘对应的范例           │ 
        └————————————————————┘ 
 
        ┌————————————————————┐ 
        │      p229  fig 18.2                    │ 
        │                                        │ 
        │    图18-2 列出修饰键对应的范例         │ 
        └————————————————————┘ 
 
        ┌————————————————————┐ 
        │      p229  fig 18.3                    │ 
        │                                        │ 
        │    图18-3 列出指标对应的范例           │ 
        └————————————————————┘ 
 
18.1.2 执行 xmodmap 改变对应 -- 一般性选项 
 
当xmodmap 用来改变或设定对应,它可以处理一或多个表式 (expression) 的 
作用。你可以把这些输入在一个档案中,假设此档案名称叫myfile,可用下列 
命令两者之一: 
 
    xmodmap myfile 
    xmodmap - <myfile 
 
第二列的短横线是必需的,如果少了它,程式将只完成预设的作用 (列出修饰 
键的对应) 。除了在档案中输入规格之外,你也可以在命令列中用 -e 选项直 
接指定它们: 
 
    xmodmap -e expression 
    xmodmap -e expression-1  -e expression-2 
 
为了得到更多有关xmodmap 作用的资讯,可以指定冗赘 (verbose)选项,-v 或 
-verbose。你可以藉著使用 -n 选项不实际的改变对应而获得相同的列印输出 
 (printout) 。 (此功能和Unix中make命令的 -n 选项相同,其意为 "假装执 
行我要求你做的事,正确的告诉我你将如何进行,但并不实际地完成作用")。 
这个选项对新手或不确定自己是否做的正确的情况非常有用。 
 
    每一个表式的语法并不相同,但一般性的格式为: 
 
    keyword target = value(s) 
 
 (等号的两边均需为空白)。 
 
18.1.3 改变指标对应 
 
指标对应是一个逻辑按钮数字的表列。 (逻辑的button-1我们称为LEFT,逻辑 
的 button-2 称为MIDDLE等等,实际的 button-1 是滑鼠左边的按钮,button-2 
是隔壁的按钮等等,所以预设的逻辑的按钮和实际的一致)。在表列中的第一个 
项目是逻辑的按钮和实际的 button-1 的关系,下一个则是对实际的 button-2 
的关系,以此类推。例如,颠倒按钮的次序,使用命令: 
 
    xmodmap -e "pointer = 3 2 1 " 
 
结果按下滑鼠右边的按钮,会被解释成LEFT。 
 
18.1.4 改变键对应 
 
xmodmap 让你将一个键 (也就是说键码) 连结到一个新的keysym表列,使用表 
式: 
 
    keycode keycode = keysym-1 [keysym-2 ...] 
 
安排keysym-1连结到键时没有修饰键,当SHIFT 按下时keysym-2连结到键,如果 
还有下一个keysym的话,对keycode 而言是第三顺位等等。 (请记住,在前两个 
之後的keysym,系统并未附属特别的意义,应用程式如果需要的话可以附属意义 
)。 
 
    让我们举实际的例子。一些键盘把一些非字母数字 (alphanumeric)键放在 
不标准的地方,所以我们假设你要将F6键重定义当没有修饰键按下时为 "9", 
当SHIFT 按下时为 "("。要写入这个xmodmap 的表式,你需要知道三件事:F6 
的键码,和 "9"与 "("的keysym。我们在第12章提到过,执行xev 便可获得 
这些:分别按下"F6", "9", "("三个键,你便可得到它们的键码和keysym。然 
後将它们放入你的表式中。例如在我们的系统中我们使用命令: 
 
    xmodmap -e "keycode 21 = 9 parenleft" 
 
    为了容易一些,你通常不需要查问键码,xmodmap 允许你使用下列格式: 
 
    keysym target-keysym = keysym-1 [keysym-2 ...] 
 
它的意义为 "附属在此键的keysym表列现在改由target-keysym来附属"。例如 
针对我们方才的范例,我们可以用: 
 
    xmodmap -e "keysym F6 = 9 parenleft" 
 
如果你将相同的keysym附属到数个键,xmodmap 会搞混掉,像这种情况你应坚 
持使用keycode ... 这种符号表示法。 
 
18.1.5 改变修饰键对应 
 
在server中修饰键对应是一个表列的集合,每个修饰键有一个表列。对一个修 
饰键的表列中,包含了所有当此修饰键被按下时会有意义的键 (键码) 。xmodmap 
允许你在一个表列中增加项目,去除项目,或完全清除一个表列。对此三个操 
作的格式为: 
 
    add modifier = list-of-keysyms 
    remove modifier = list-of-keysyms 
    clear modifier 
 
不幸的是,语法有点儿混淆,因为取代你所需的键码,你必需指定keysym附属 
到键码。 
 
    举一个例子:假如你需要在你键盘的右边有一个第二个的Ctrl键。在我们 
的键盘上有一个Alternate 键没有被用来做任何事,所以我们将修改它,命令 
为: 
 
    xmodmap -e "add Control = Alt_R" 
 
为了多解释一些情况,让我们假设你没有一个多馀的键,但有一个第二个的 
Meta键在键盘的右手边,而我们要用它。我们首先必需去除它的Mod1对应 (你 
必须使用 "Mod1" ,"Meta"没有用) ,而後将它加入Control 对应。 (如果有 
需要的话,我们可以拥有双重的对应,所以在Control-Meta组合键时才会有作 
用,在一些编辑器中常会用到)。命令为: 
 
    remove Mod1 = Meta_r 
    add Control = Meta_r 
 
将上述命令列放入一个比方说叫mymaps的档案中,执行命令xmodmap mymaps。 
它可以工作,但如果你用xmodmap -pm 去查看,你会发觉Control 和Meta混合 
在一起,所以最好改变键上的keysym为: 
 
    remove Mod1 = Meta_R 
    add Control = Meta_R 
    keysym Meta_R = Control_R 
 
在xmodmap 的指南页中,有几个更多的交换修饰键的范例。 
 
    注意:当增加一个键到修饰键对应,keysym只是用来指定xmodmap 中的键 
。它完全是xmodmap 本地的,且只是一个符号而已:只有当相关的键码传递到 
server,才实际上的改变对应。同样地,keysym 和 keycode 表式对修饰键对 
应绝对没有影响。一个常见的错误是执行下面这个命令: 
 
    xmodmap -e "keysym F1 = Contrl_R" 
 
期望F1键能像一个control 键般作用。它不会 -- 因为你相当於告诉系统 "我 
已经把这个符号印在F1键上面" 而已。你应该这样作: 
 
    xmodmap -e "add Control = F1" 
 
如果你合并上一列的命令会使得对应表列看起来清楚些。 
 
我们对不同对应的处理的描述到此告一结束。 
 
 
 
18.2 键盘和滑鼠参数设定 -- xset 
 
最後我们来看一看最平常的设施,对你的键盘、滑鼠和萤幕设定不同的参数的 
设施。这些参数使用xset程式 (我们曾经用来控制server的字型搜寻路径) 来 
设定。在以下的叙述,我们只用一组引数来展示xset,但你可以同时指定多组 
你所要的不同定义的设定。 
 
控制终端机响铃 
 
用xset你可以让铃声响或不响,设定它的音调 (pitch),和它持续的时间 (假 
设你的机器提供这些操作): 
 
    让铃声不响                    xset -b 
                                  xset b off 
 
    让铃声能响                    xset b 
                                  xset b on 
 
    设定铃声的音量                xset b vol 
     (最大音量之vol%)             例:xset b 50 
 
    设定铃声的音量,和            xset b vol p 
    音调(单位Hertz(赫))           例:xset b 50 300 
 
    设定铃声的音量,音调,        xset b vol p d 
    和持续的时间(单位百万         例:xset b 50 300 100 
    分之一秒) 
 
控制键的滴答(click) 
 
    让键的滴答不作用              xset -c 
                                  xset c off 
 
    让键的滴答作用                xset c 
                                  xset c on 
 
    设定滴答声的音量              xset c vol 
     (最大音量之vol%)             例:xset c 50 
 
控制键的自动重复(auto-repeat) 
 
    让键的自动重复不作用          xset -r 
                                  xset r off 
 
    让键的自动重复作用            xset r 
                                  xset r on 
 
滑鼠参数 -- 加速和门槛 
 
指标在萤幕上的移动和滑鼠的移动是成比例的。加速 (multiplier) 是应用在 
指标移动上的一个乘数,例如你的加速是四,当你移动滑鼠时,指标将以正常 
四倍的速度移动。 (如果指标正常时移动n 个像素,现在则会移动 4 X n个像 
素)。 
 
    当你希望在萤幕上将指标移动一段长距离时,相当高的加速是很方便,但 
当你要作一些细部的指引时,它看起来就很笨拙 -- 指标看起来在来回跳动。 
为了克服此点,server提供了一个门槛 (threshold):如果当指标一次移动超 
过门槛个像素,加速也会被带进来执行。 
 
    设定滑鼠的加速到a             xset m a 
                                  例:xset m 5 
 
    设定加速,设定门槛到t         xset m a t 
                                  例:xset m 5 10 
 
控制萤幕节约器结构 
 
萤幕节约器 (screen saver)是一种设施,它意图降低一个固定的图样(pattern) 
老是燃烧你萤幕的萤光体的机率。它的理念为萤幕损害大都起因於让系统闲置 
(idle)一长段时间,所以萤幕节约器在一段特定的时间内如果没有输入动作後 
,不是整体性的闪动萤幕,便是显示一个不同的图样。 
 
    如果你选择的是显示一个不同的图样,根视窗的背景涵盖整个萤幕,一个 
大X 的游标出现在萤幕上,且会周期性的移动。当大X 游标在移动时,会改变 
大小,而且背景也会随机的变动。 (在背景图样较小时你可能不会注意到,但 
若比较大时,你可以看到它在跳动)。 
 
    当萤幕节约器结束作用後,如果要花许多的时间才能重画应用视窗,你可 
以指定只有在重画萤幕而不需产生任何曝光(exposure)事件 (也就是不必要求 
应用程式重画它们自己的视窗) 的情况下,萤幕节约器才会作用。 这只应用 
於显示不同的图样的情况,整体性的闪动萤幕纯为硬体作用,不会影响到应用 
程式。 
 
    让萤幕节约器能作用           xset s 
 
    让萤幕节约器不能作用         xset s off 
 
    用萤幕闪动的方式             xset s blank 
 
    只有在无曝光事件下才作用     xset s noexpose 
 
    允许有曝光事件下仍然作用     xset s expose 
 
    用不同图样的方式             xset s noblank 
 
    当系统闲置t 秒後作用         xset s t 
                                 例:xset s 600 
 
    每p 秒之後改变图样           xset s t p 
                                 例:xset s 600 10 
 
让我们将这些组合起来,假设我们希望萤幕节约器在系统闲置80秒後开始作用 
,用不同的图样的方式,周期为3 秒,不介意曝光事件是否发生: 
 
    xset s noblank s 80 3 s expose 
 
注意:xset s 并不提供 on 这个值。 
 
 
 
18.3 结论 
 
本章的第一个部份,告诉你如何改变从实际的到逻辑的键和按钮的对应,这些 
对应可被client应用程式解释。你看到如何使用xmodmap 来列出或改变每一个 
键盘的键、修饰键和滑鼠按钮的对应。这些对应由server维护,所以可以被每 
一个使用到此server的应用程式应用到。这种结构让你有改变键盘配置的自由 
,不论是个人的喜好或是一个额外的标准。 
 
    在本章的第二个部份,你看到如何使用xset对一些常见的特性作设定,如 
键的滴答声、终端机的响铃、萤幕节约器和滑鼠的速度 ("加速")。 
 
===== 
 
第19章  进一步介绍 uwm 和如何定制它 
 
在第6章,你学到如何使用uwm 来完成基础的视窗建构工作需求,而能以一个 
舒服的方式使用视窗。现在我们继续谈视窗,集中於两个主要的范围: 
 
    1.此程式所提供的一些特别的特色,特别是: 
 
      .不使用选单,直接使用滑鼠建构视窗。 
 
      .我们尚未描述过的一些选单选择。 
 
      .编辑现存表徵图的标题。 
 
    2.如何定制uwm ,包含: 
 
      .对任何你所需的命令定义你自己的选单。 
 
      .将各种不同的视窗管理器功能系结到滑鼠按钮和修饰键 (SHIFT, 
        CONTROL 等等)。 
 
19.1 uwm 的新特色 
 
现在我们来讨论一些在先前介绍视窗管理器时,为了保持尽量地简单,而省略 
的标准的uwm 功能。 
 
19.1.1 不使用uwm 的选单来管理视窗 
 
直到目前,你仍然依赖著uwm 的选单来建构你的视窗 -- 移动它们、对它们重 
定大小等等。如果所有的情况都使用选单,是相当慢的,所以uwm 提供你可直 
接完成它任何命令的选项。 
 
    你可以使用滑鼠按钮和修饰键,来指定你要执行的功能,和所要操作的视 
窗。你现在应该已非常熟悉各种不同的视窗管理器功能和它们如何工作,所以 
我们将很快地说明如何不使用选单来选择这些功能。 
 
    Move:移动一个视窗 
 
        1.按下META键,保持按住。 
        2.指标位置所在的视窗将被移动。 
        3.用右按钮,拖拽视窗到新的位置。 
 
    Resize:重定一个视窗的大小 
        1.按下META键,保持按住。 
        2.指标位置所在的视窗将被重定大小。 
        3.用中按钮,拖拽视窗的外框到新的大小。 
 
    Lower:将一个视窗送到堆叠的底部 
        1.按下META键,保持按住。 
        2.将欲被送到堆叠的底部的视窗,碰触一下左按钮。 
 
    Raise:将一个视窗升到堆叠的顶端。 
        1.按下META键,保持按住。 
        2.将欲被送到堆叠的顶端的视窗,碰触一下右按钮。 
 
    Circulate up:将最底层被遮蔽的视窗升到最上层,你有两种选择: 
        1.按下META键,保持按住。 
        2.在根视窗上,碰触一下右按钮。 
    或 
        1.同时按下META和SHIFT 键,保持按住。 
        2.在萤幕上的任何地方,碰触一下右按钮。 
 
    Circulate Down:将最上层的视窗移到最底层,作法同Circulate Up,但 
        改为左按钮。 
 
    Iconify:之前我们曾提过两种形式的表徵图化,一种是视窗曾经表徵图 
        化过(已定义过表徵图的位置) ,另一种为对 "新" 的视窗表徵图化 
        。 
 
      表徵图化一个新的视窗: 
 
        1.按下META键,保持按住。 
        2.将指标位置移至欲被表徵图化的视窗。 
        3.按下LEFT按钮,保持按住... 
        4. ... 拖拽表徵图的外框到你所需的位置。 
        5.松开按钮和META键。 
 
      注意它和Lower 操作程序的不同点,在此你是按下... 拖拽... 松开滑 
      鼠按钮,而对Lower ,你只是碰触一下按钮。 
 
      表徵图化一个曾经表徵图化过的的视窗: 
 
        1.同时按下META和CTRL键,保持按住。 
        2.在你欲表徵图化的视窗上,碰触一下左按钮。 
 
       (如果你对先前并未表徵图化的视窗作这个操作,或经由resource结构 
        无法取得表徵图的位置,表徵图将出现在指标所在的位置)。 
 
    De-Iconify:将表徵图还原为它的视窗 (在视窗原来的位置): 
 
        1.按下META键,保持按住。 
        2.在表徵图上,碰触一下中按钮。 
 
    如果你觉得这些对滑鼠按钮功能的结合十分笨拙且不易记忆,别担心,很 
多人都是如此。有更好的法子,刚才那些只是预设的设定,你可以完全由自己 
来建构。在本章的後半部,我们将告诉你如何做。现在我们先来看一看,在标 
准选单的一些功能和它们能做些什麽。 
 
19.1.2 一些更多的选单选择 
 
这是一些我们在第6章中没有解释的标准的选单选择。 
 
    Focus:让你设定键盘的焦点(focus),也就是说,将键盘附属於一个视窗 
        ,所以不论萤幕上的指标在何处,键盘的输入总是在同一个视窗。一 
        般键盘的输入总是指向目前指标所在的视窗。 
 
        设定焦点到一个特定的视窗:选择focus ,出现手指形游标,在你所 
          欲指定的视窗碰触一下按钮。 
 
        恢复正常:选择focus ,在背景视窗上碰触一下。 
 
    Restart:停止uwm ,重新启动它,重新读入建构档 (下节说明) 且执行它 
        。在你改变建构档且希望马上执行新的设定时 (否则将等到你重新启 
        动一个新的周期) 使用此选择。 
 
    Freeze:暂停萤幕上所有的显示,当你要对你的萤幕摄影时可以使用这个 
        选择。欲重新恢复显示,使用 ... 
 
    Unfreeze:重新恢复显示,所有的视窗会立即更新。 
 
    Exit:中止uwm 。当你要杀掉uwm 时使用,例如在启动一个不同的视窗管 
        理器之前。 
 
Perferences 选单 
 
    我们在第6章提过,有两种方法叫用uwm 的WindowOps选单 -- 在背景视 
窗上按下中按钮,或在按住META和SHIFT 两个键的情况下,在任何地方碰触一 
下中按钮。用第二种方法让你呼叫出第二个选单,只要将指标移到WindowOps 
选单的外边,标头为Preferences 的视窗就会出现。 
 
    在Preference中的选择,只是一些xset程式中设定滑鼠和键盘的选项而已。 
 
    注意:Lock On 和 Lock Off选择是和记录有关的,可能会导致一个错误 
的讯息在你的主控台视窗印出。 
 
19.1.3 改变现存表徵图上的标题 
 
uwm 的预设表徵图 -- 灰色的盒中有一个名称 -- 如果你对同一个应用程式执 
行数次拷贝後会有缺点,例如有三个xterm 的表徵图,你无法明确的区分它们 
。为了克服这点,uwm 允许你可以编辑表徵图中的字串为你所需的任何字串。 
 (这只能在uwm 自己预设的表徵图使用,例如你无法编辑在xclock的特定表徵 
图中的字串)。 
 
    欲编辑在一个表徵图中的名称: 
 
    1.将指标移至所欲编辑的表徵图。 
    2.键入你所希望的任何文字。 
    3.你可以去掉文字,不论是先前存在或方才才输入的,方法如下: 
 
      去掉前一个字元:按DELETE。 
      去掉整个名称:按ctl-U。 
 
19.2 定制uwm 
 
uwm 具有高度的可建构性。你可以将整个范围的参数和定义储存在一个建构档 
中,当uwm 启始时会将之读入。我们前节曾经提过,你可以在中途改变建构档 
,藉著在WindowOps选单中Restart选项,告诉uwm 重新读入它。 
 
uwm 的建构档 
 
预设uwm 有两个建构档,其中之一为 
 
    /usr/lib/X11/uwm/system.uwmrc 
 
通常由系统管理者设定,且第一个被读入。另一个 
 
    $HOME/.uwmrc 
 
是你自己的建构档。两个档案均需要存在,uwm 硬性规定了预设设定。 
 
    注意:如果你用不正确的语法设定一个建构档,当uwm 读入时,你会得到 
一个错误讯息像: 
 
    uwm: /usr/nmm/.uwmrc: 38: syntax error 
    uwm: Bad .uwmrc file...aborting 
 
uwm 将不会启动。当在一个新的周期启动时,这没有什麽大问题。然而,如果 
你是在中途重新设定uwm ,你可以结束但没有视窗管理器,且没有xterm ,没 
有编辑视窗来编辑这个错误的档案,无法启始其它的视窗。如果此种情况发生 
,你必需从其它的终端机或机器关闭X,或毁坏 (crash)你的系统。 
 
uwm 的命令列选项 
 
如果你不需要系统建构档案,也不需要任何预设的设定,你可以藉著uwm 的命 
令列选项 -b 抑制它们。 
 
    如果你要使用其它的档案,就像两个预设的建构档一般,你可以用 
-f filename 来指定它。 
 
19.2.1 系结功能到键和按钮 
 
uwm 让你定义当一个特定的滑鼠按钮按下时,有某个功能会作用,例如当你在 
一个视窗中碰触一下中按钮,它将被升到堆叠的顶层。这种系结结构和Toolkit 
转译并没有牵连,它完全由uwm 本身来完成。 
 
为了让这些结构更有用,你可以指定其它的条件来运用更多的功能,或许一个 
修饰键 (像META) 需被按下,或许作用只发生在指标位於一个表徵图上而非应 
用程式视窗或背景视窗。我们已实际的看过这些例子: 
 
  此功能发生     ... 只有在这些        ... 只有指标在      ... 当这个 
  於...          修饰键被按下,        此种型态的视窗      滑鼠事件发 
                 而且...               ,而且...           生时 
 
  Resize         META                  一般视窗            按住中按钮 
                                                           且移动 
 
  WindowOps      没有                  背景视窗            按住中按钮 
  选单 
 
  WindowOps      META 和               没有关系            按住中按钮 
  选单           SHIFT 
 
    你藉著你的 .uwmrc(或其它的建构档)所包含的系结规格来指定系结。规格 
的格式和上面的表格类似,就像: 
 
    uwm-function = modifiers : window context : mouse events 
    ( uwm 功能   =  修饰键   :  视窗的环境    :  滑鼠事件  ) 
 
这些元素为: 
 
  uwm 功能:uwm 的内建功能之一的名称。例如功能f.move即是你用以移动视 
      窗的功能,f.lower 将视窗降低一层等等。这些功能将於下更完整地描 
      述。 
 
      功能名称必需跟随著一个等号(=)。 
 
  修饰键:在运用上述功能时,当指定的滑鼠事件发生时,必需被按下的修饰键 
      表列。正确的修饰键名称为: 
 
      ctrl(或c),对CONTROL键。 
 
      meta(或m或mod1),对META键。 
 
      shift(或s),对SHIFT键。 
 
      lock(或l),对CAPSLOCK键。 
 
    这些名称必需正确的列出。你可以使用一或二个修饰键,如果你使用两个 
键,用一个 "|"符号来分开它们。 
 
    你可以省略整个修饰键表列 (即此功能对应於滑鼠事件发生时并没有修饰 
    键被按下),但尾端的冒号 ":" 不可省略。 
 
  视窗的环境:限制只有指标在萤幕上指定位置的型态符合特定条件时,功能 
      才会发生。正确的环境如下: 
 
    window(或w):指标必需位於一个应用视窗中。 
 
    icon(或i):指标必需位於一个表徵图中。 
 
    root(或r):指标必需位於根视窗或背景视窗中。 
 
    你可以指定任何数目的环境,用 "|" 来区隔它们。如果你没有指定,则功能 
    的发生与指标位置无关。 
 
  滑鼠事件:何种滑鼠事件对应到此功能。指定的事件为一个按钮名称 -- 任何的 
 
      left(或l) 
 
      middle(或m) 
 
      right(或r) 
 
    跟随著一个动作: 
 
      down : 当按钮被按下时会符合。 
      up : 当按钮被松开时会符合。 
      delta : 当按钮被按下且移动超过一定数目的像素时会符合。 
 
  所有的这些你已实际使用过它们,在本章开头所描述的一些作用的系结为: 
 
      f.resize = meta : window : middle delta 
      f.iconify = meta : icon : middle up 
      f.raise = meta : window|icon : right down 
 
  uwm 的预设系结在档案 $TOP/clients/uwm/default.uwmrc,见图19 - 1。 
 
        ┌————————————————————┐ 
        │      p242-243  fig 19.1                │ 
        │                                        │ 
        │    图19-1 预设的 .uwmrc 建构档         │ 
        └————————————————————┘ 
 
uwm 的内建功能 
 
uwm 的指南页列出可应用的功能。你已经从图19 - 1见过其中大部份,你可以 
看出,功能是和WindowOps及Preferences中的选项相关。 
 
    然而,有一个有关pushing视窗(f.pushleft, f.pushup等等)的功能集合你 
从未见过。pushing的意思为:你朝一个特定的方向移动一个视窗,移动的距离 
固定。这和f.move不同的是,後者以交谈的方式,指定视窗移动的方向和距离。 
 
    预设f.pushdown系结到同时按下CONTROL和META键,且按住中按钮。试它几 
次,你将发现你的视窗稍微移动了一点 -- push 功能对细部移动视窗非常有用。 
 
    另一个功能为f.moveopaque。它也移动一个视窗,但不像f.move,它并不会 
给你一个指示视窗新的位置的方格,你直接拖拽整个视窗本身。这可以让整个萤 
幕清爽些,但比较慢,且一般视窗移动时会有抖动的现像。 
 
19.2.2 定义你自己的选单 
 
f.menu是一个非常强大的uwm 的功能:它让你定义你自己的选单。此选单可选 
用到uwm 本身的功能,或任何的shell 命令,或一个特定的动作,像是在一个 
剪缓冲区插入本文。 
 
    在你的建构档中定义一个选单共有两个步骤。首先你定义选单上所需的 
系结,其次你定义选单本身的内容。系结的部份像我们先前所用过的,但在尾 
端增加了一栏选单名称。例如WindowOps 选单 (藉著在背景视窗中按下中按钮 
来呼叫)的系结是: 
 
    f.menu = : root : middle down : "WindowOps" 
 
在此,选单名称既是用以显示选单出现时的名称,也连结到建构档中的选单内 
容规格。 
 
    选单内容的格式很简单:对每一个选择项,包含了一列当选择项出现在选 
单的 "名称" ,和当它被选择到时所做的动作。让我们观察一个缩水的WindowOps 
定义: 
 
    menu = "WindowOps" { 
    New Window : !"xterm &" 
    RefreshScreen : f.refresh 
    Redraw : f.redraw 
    Move : f.move 
    } 
 
从这里,我们可以看到其语法为: 
 
    menu = "menu name" { 
    ... 
    selection lines 
    ... 
    } 
 
选单名称和系结所指定的相同。选择项列包含了选择项名称,分隔的冒号,和 
负责的动作。这些动作为下列三者之一: 
 
    1.一个uwm 的功能:只用到它们的名称,在上例为move那一列。 
 
    2.一个shell 命令:命令包含在双引号中间 (用shell 的& 语法使其在背 
      景视窗中执行) 且在前面加一个惊叹号。在上例为xterm 那一列。 (如 
      果你省& ,uwm 将被悬置 (hang) 起来,等待命令的完成,如果此程式 
      为X的应用程式,它需要uwm 来安排它的视窗,这将会招致麻烦)。 
 
    3.一个本文字串:这将插入到一个 "剪" 的缓冲区,而後你可以像平常一 
      样的 "贴" 它。 
 
多种的选单连结到同一个键系结 
 
通常你对一个特定的键/按钮的组合,只会系结到一个选单,但你可以对同一个 
系结有多种选单:如果你在一个选单中不选择任何项目且把指标移动到选单的 
边上,你将得到下一个选单。你已经实际地看过这种例子:在同时按下META和 
SHIFT 键的情况下按下中按钮,你可以得到WindowOps 选单,然後是Preferences 
选单。 
 
    系结多种选单非常的容易,只要在定义每一个系结时当作其它的系结并不 
存在,而在定义选单的内容时用标准的方式即可。例如uwm 的预设设定包含了 
系结: 
 
    f.menu = meta | shift : : middle down : "WindowOps" 
    f.menu = meta | shift : : middle down : "Preferences" 
 
注意一个选单只能定义一次,但你可以用它来做任意多次的系结。 (查看预设 
设定,你将看到WindowOps 选单被定义了一次但使用到两次)。 
 
指定选单的颜色 
 
你可以指定在一个选单中所用的色彩。对选单名称标题、每一个选择项、指标 
所在的高亮度选择项,你都可以指定一个前景和背景色彩。一个有色彩的选单 
的格式如下: 
 
    menu = "menu name" (head-fg : head-bg : hilite-bg : hilite-fg) { 
    ... 
    selection-name : (item-fg : item-bg) : action 
    ... 
    } 
 
以下为一个混合的范例,使你的WindowOps 能拥有更多的色彩: 
 
    menu = "WindowOps" (yellow : blue : red : green) { 
    New Window : !"xterm &" 
    RefreshScreen : f.refresh 
    Redraw : (navy : magenta) : f.redraw 
    Move : f.move 
    } 
 
此选单标题为蓝底黄字,大多数的选择项为白底黑字 (预设值),只有 "Move" 
选择项为紫红色底海蓝色字,而目前指标所在的选择项为绿底红字。 
 
19.2.3 控制uwm 的参数变数 
 
到目前为止,你可以用指定滑鼠和键的前後关系,来改变所指定的功能。在此 
有一个另一种型态的uwm 的定制:你可以藉此改变许多内建功能操作的作法 ( 
mode) 和风格 (style),例如你可以指定在resize或move操作下,指示视窗新 
的位置的九宫格,改变为只是一个外框而已。在指南页中有列出所有的变数和 
它的意义,在此我们只提一些特别有用的,和解释一些比较模糊的。 
 
    让预设建构档中的设定无效:uwm 并没有结构抑制读取系统和使用者建构 
档。(-b 不会影响 $HOME/.uwmrc)。欲取消早先档案中的设定,可以含入uwm 
的变数resetbinding、resetmenus和resetvariables,将会分别的取消早先定 
义的系结、选单和变数。 (确定你将这些变数放在档案的顶端,否则它将取消 
在档案中所有在它之前的定义)。 
 
    限制视窗和表徵图在萤幕的范围以内:X允许你指定你的视窗位於萤幕的 
任何位置,甚至部份或全部在萤幕之外,这样有时会引起麻烦。当你建立一个 
视窗,uwm 并未提供任何的帮助。但当你使用f.newiconify对一个表徵图作解 
除表徵图化,如果变数normalw 被设定,则视窗会被完整的放在萤幕中,且尽 
量接近你用指标指定的位置。 (如果你包含了normali 变数,同样可用於表徵 
图)。 
 
    控制push作用:预设f.pushxxx 功能将一个视窗往适当的方向推动一个像 
素的距离。你可以藉著指定 push=num 来推动num 个像素。你也可以完全地改 
变操作的作法:取代通常的推动固定数目的像素的作法 (叫做pushabsolute) 
,你可以指定pushrelative:这种情况视窗会被推动num 分之一大小的视窗。 
例如如果你指定 
 
    push=5 
    pushrelative 
 
则一个f.pushup将把视窗向上推动视窗本身高度五分之一的距离。 
 
    防止uwm 功能锁定应用程式:预设一些uwm 的操作,像resize和move会导 
致所有其它的client应用程式被冻结,也就是说,防止它们输出到它们的视窗 
。你可以藉著指定nofreeze取消它。 
 
    如果你需要获得一些uwm 所属短暂视窗的视窗倾印,则这是必需的 (如在 
图6 - 6 的resize盒)。 它的副作用为当使用resize和move时,外框格会大量 
的闪动,以致难以看到。 
 
19.3 结论 
 
 
本章告诉你如何使用一些更多的uwm 的功能,现在你对系统有更多的经验且可 
以利用它们。特别是看到不用预设选单如何建构视窗,它使你工作的更迅速。 
 
    本章的第二个部份,列出你如何能定制uwm :如何附属uwm 的内建功能到 
指定修饰键和滑鼠动作的组合,如何定义一般性的选单,如何使用uwm 的参数 
变数修改操作的作法。 
 
在结束之前说一点题外话,uwm 和 xterm、xclock、xedit等一样,只是server 
的一个client程式而已。所以,远端地执行uwm 是可能的,例如在saturn执行 
uwm ,但是指定 -display venus:0,所以它是venus 的视窗管理器。这解释 
了网路元素深殖於系统,在一般工作站,这只是好奇,但在X终端机 (它不提 
供一般性目的的处理 (processes)) 它实际地需要。 
 
我们现在接近尾声:你已有所有你执行视窗系统的所需的功能。你有视窗管理 
器、应用程式、便利的工具、视窗有关的公用程式、大范围的设施所以可以修 
改以适合你的显示器、你网路上的建构和你比较喜欢的工作。下一章,我们将 
会把目前所学的放在一起,告诉你如何管理你完整的工作周期,且我们将包含 
定义uwm 选单和perferences的实际的范例。 
 
===== 
 
第20章  全部放在一起 -- xdm 
 
    现在我们已涵盖了你需要用到X的所有个别的项目,你知道如何启动系统, 
如何设定一个视窗管理器的执行,如何执行应用程式,如何从不同的角度定制 
系统,最後,如何退出系统。 
 
    本章中,我们把这些分开的部份放在一起,且描述一个完整的档案设定, 
用来定制涵盖所有的范例功能系统机器环境。在本章我们将看到我们所要介绍 
给你的最後一个X的工具:显示管理器(display manager) -- xdm,它提供一 
个精巧和清楚的方法在你的机器上启动X。 
 
 
20.1  我们需要做些什麽 
 
    当我们启动之後,我们需要安排萤幕,让一些我们在整个执行期间中都会 
使用的应用程式适得其所,让一些偶然用到的则以表徵图为开始时的表示方式。 
我们需要执行视窗管理器,对某些种类的功能做一些设定。详细来说,我们需 
要下列的程式: 
 
    .一个xterm 的主控台,在萤幕左上角。 
 
    .uwm 在背景下执行。 
 
    .一个我们的(正常)编辑器的全萤幕xterm 视窗,以表徵图启始。 
 
    .在右上角一个(较一般为小)的时钟。 
 
    .xbiff 在时钟之下。 
 
    .一个计算器在右下角。 
 
    .一个用到我们所有最小的字型的表徵图化的xterm ,它的高度为screen高。 
 
    .在xbiff 之下,排列我们使用远方机器的频率图。 
 
    除了程式之外的项目: 
 
    .设定背景视窗为亮灰色。 
 
    .启动键盘滴答(key-click) 的功能。 
 
    .从我们常用的网路主机存取到我们的server。 
 
    .载入我们对所有client用到的server设定的resource,在16章我们定义 
      的$HOME/.Xresources 档案中,根视窗RESOURCE_MANAGER性质之上。 
 
    .启动一个screen saver。 
 
    并且我们需要uwm 有选单让我们能够: 
 
    .容易地存取在网路上其它的主机。 
 
    .变更一些键盘和滑鼠的设定,且设定背景视窗的颜色。 
 
    .启动那些我们偶而会用到的应用程式。 
 
    .启动一些被选定的示范程式。 
 
    对这些我们自己的设定,在我们网路上其它的使用者需要不同的初始设定, 
所以我们需要安排每一个使用者依他们自己的喜好设定,理想上,使用者应能 
自行设定而毋需藉系统管理者的帮助,下一节我们来看程式xdm 如何能帮助我 
们达成这些目的。 
 
 
20.2  xdm  -- X显示管理器(X Display Manager)的概观 
 
    xdm 管理一或多个显示器,xdm 可在同一机器或远方的机器上执行。它可 
以做到所有xinit 能做到的,而且更多。它所隐含的概念为它应控制当你在X 
工作时的完整周期 (session),意即从你进入直到结束视窗系统的周期。(用 
xinit ,有效周期为当你执行xinit 开始,到你结束(logout)最初的xterm 
视窗和关闭server。) 
 
    xdm 较这更进一步:你可以用它执行一个不确定的周期。当一个结束,下 
一个便准备开始。实际上,如果你有需要,它让你不变地指定一个显示器。 
 
    xdm 完全取代xinit 。从现在起你可忘掉xinit ,而且不再需要使用它, 
我们在最初使用xinit 的原因为它较易观察和了解系统的运作。 
 
    xdm 是一个非常灵活的程式,你几乎可用它建构任何你所需要的,在进一 
步深入之前,让我们观察一个范例周期的预设行为,然後我们来看一看你如 
何改进当一个使用者进入X系统所看到的初始介面。 
 
 
20.2.1  一个用xdm 的范例周期 
 
    我们将使用xdm 来设定在我们机器上执行的X。你的机器已经启动,但尚 
未有视窗系统在其上执行。用下列的命令启始xdm 
 
        xdm 
 
    xdm 开始执行,你几乎立刻又看到你的shell 提示。然後萤幕背景变更为 
通常灰色形式,且你看到一个大的X游标,所以你知道server已经启始。 
 
    接下来是一长段修止状态 -- 大约接续15秒或更久 -- 而後突然间一个带 
著欢迎标题的视窗出现了,要求你的登录名称(login name)和密码(password), 
如图20-1(这是xdm 的authentication widget )。输入你的使用者名称和密 
码,又过了一会儿,你可以看到一个xterm 视窗在左上角出现,就如同图5-3 
一般,从现在起,你工作的方式和以前相同 -- 启动你的视窗管理器,执行应 
用程式等等。 
 
          ┌——————————————————————┐ 
          │   FIG 20.1        P.251                    │ 
          │                                            │ 
          │  图20-1  xdm 的 authentication widget      │ 
          └——————————————————————┘ 
 
 
    当你需要结束时,你也可用像以前相同的方式结束:logout最初始的xterm 
视窗。但这里xdm 和xinit 有不相同的地方,代之关掉server的是,回到非X 
的环境,萤幕回到最初始灰色的背景,过一下子之後,你又再度看到X的登录 
视窗。事实上,xdm 是执行一个循环的周期。 
 
    注意:就像许多的Unix程式,最大的登录名称长度为8 个字元 -- 如果超 
过这个长度,login 将会失败。(如果你的实际login 程式允许你使用较长的 
名称,这种限制也许让你感到奇怪。) 
 
关闭xdm 
 
    有时你可能需要完全地关闭X。为了做到这点,你需要关闭xdm 。 
 
    在MIT 版中的server,会依循如果收到Unix讯号SIGTERM ,便会执行中止 
程序。xdm 利用到这点:如果你送给它一个SIGTERM ,它将中止所有它所控制 
的server後离开。这就是你中止系统的方法。 
 
    欲实际地中止xdm ,可以在一个xterm 视窗(在你的机器上)用ps来找出 
xdm 的process-id,而後用kill送给它SIGTERM (你将看到数个xdm 处理的执 
行:那个最年轻的便是你要的,也就是说,最低的process-id)。例如,在我 
们的机器上执行中止的动作: 
 
    venus% ps ax 1 grep xdm 
    1997 ? IW 0:00 xdm 
    1998 ? IW 0:00 xdm 
    2000 ? IW 0:00 xdm 
    2078 p0 S 0:00 grep xdm 
    venus% kill -TERM 1997 
 
    你所有的应用程式将被强迫中止,server也随之关闭。 
 
    注意:当相关於X的每一件事都结束後,你的萤幕可能只显示通常X背景 
的灰色形式,没有任何的shell 提示或任何事。不要被愚弄了:你的shell 已 
准备好接受你的命令 -- 按下RETURN键你将会看到。(因为在你以交谈式下 
xdm 命令之後,shell 已将提示号送出,所以不再重覆 -- 除非你按下RETURN)。 
 
 
20.3  有关xdm 的更多 
 
    我们在前所述为xdm 的预设模式的操作,所以看起来并没有比xinit 提供 
得更多,如果你使用一个正常的工作站或显示器,一些外貌将不是很有趣。无 
论如何,X终端机(x-terminal)是一个日渐增加的大众化设备,而xdm 可大量 
地简化管理类似的系统。X终端机通常没有它自己的档案系统,且不能支援一 
般目的的程式,必需在网路的某处执行包含视窗管理器和显示管理器的控制终 
端机软体,xdm 正是符合此需要的软体。 
 
xdm 在下列这些场合较xinit 为优: 
 
    .它可控制数个server,也暗示说,其中有一些为远方的server,也许是 
      在X终端机或相当小的工作站上。 
 
    .它提供密码来存取系统,同样地,在X终端机上非常有用(但在一个你 
      已经login 的工作站会有一点困扰。) 
 
    .它提供无限期的X的周期。你可以建构显示器经常性地以X操作,所以 
      使用者毋需担心如何启始系统。 
 
    .它具有高度的建构性,系统管理者可以设定依机器特性的启始和结束程 
      序,掌握这些项目以供记帐(accounting),授权(authorization) ,档 
      案系统等之用,且能让每一个个别的使用者全范围性地修定他们所需的 
      自己的环境。 
 
    .从使用者的观点,它提供一个乾净而简单的方法来启动系统。 
 
    所以大体上,xdm 主要是一个系统管理工具,但它也提供让一个普通使用 
者定制他所希望的一致和一贯地系统架构。 
 
    xdm 的指南页包含了大量的有关如何使用系统的教学资讯和指引,在此我 
们不再重覆,我们将在以下的章节说明如何正确地建构xdm 以提供在本章一开 
头所描述的环境。 
 
    xdm 真的非常有弹性,且你可以用许多不同的方式选择设定,我们将使用 
    最简单的处理,并试著大致和指南页的描述保持一致,偶而我们在一些档 
案中使用不同的名称,用以强调此名称并非硬性的规定。 
 
    在我们工作的周期中,请对我们事实上在扮演两个不同的角色保持概念: 
第一是系统管理者,对於使用系统的任何人来设定xdm ,第二是一般的使用者 
,为我们自己的需求设定xdm 。 
 
 
20.3.1  系统管理者对xdm 的建构 
 
    预设xdm 先查看档案 
 
        /usr/lib/X11/xdm/xdm-config 
 
如果它存在,会把它当成多设定几个其它参数的resource档案。我们将使用它, 
因为它可简化我们的工作。 
 
    指南页会列出所有你能藉xdm-config档案设定的参数,但我们较有兴趣的有: 
 
    .包含一个server的目录的档案名称。 
 
    .当任何错误发生时,xdm 用来记录的档案名称。 
 
    .包含和启始系统有关的档案系统名称。 
 
    .当server启动後执行程式的名称,这个程式定义了你的”周期” -- 当 
      这个程式中止时,xdm 视其意义为你的周期已结束,且回到它login 时 
      的顺序,预设这个程式为xterm ,就和使用xinit 一样,你的周期持续 
      直到你logout你初始的xterm 。 
 
    这是我们已在系统上定义的设定: 
 
        DisplayManager.severs:   /usr/lib/X11/xdm/our-server 
        DisplayManager.errorLogFile:   /usr/lib/X11/xdm/errors 
        DisplayManager*resources:   /usr/lib/X11/xdm/our-resources 
        DisplayManager*session:   /usr/lib/X11/xdm/our-session 
 
(我们已选择保持所有xdm 相关的档案在目录/usr/lib/X11/xdm,这只是代表 
名称,你可以用任何你喜欢的目录。) 
 
    所以你可以看到我们使用xdm-config,实际上是一个两步骤的处理方法, 
首先我们定义在xdm-config中的一些档案名称,接著我们来设定方才命名的档 
案。现在我们来看一下我们在xdm-config中定义的每一个resource。 
 
xdm 的server的名单 
 
    这个被DisplayManager.servers设定的档案的resources 包含了一个xdm 
能管理的server的名单。每一列中包含了server的名称(也就是显示器), 
server的型态(type),和型态有关的项目。 
 
    型态指出了显示器是本地的或远方的。和是否为无限或单一的周期(详见 
xdm 指南页)。我们将使用型态localTransient -- 单一周期在本地显示器上 
 -- 因为以此方式,如果发生任何错误,我们不致於陷入无穷回圈中。稍後, 
当我们每件事都设定好且执行无误的话,我们会将型态改为本地而循环的周期。 
 
    对本地的显示器而言,和型态相关的讯息是在此显示器上执行的server程 
式的名称及其任何所需的引数。对远方的显示器,此讯息可被忽略,但你仍需 
输入一个假的(dummy) 程式名称。 
 
    所以,在我们所建立的档案/usr/lib/xdm/our-servers包含这一行: 
 
        :0 localTransient   /usr/bin/X11/X  :0 
 
(如果我们喜欢执行循环周期,此档案便不再需要 -- 预设设定会做到我们所 
需要的 -- 所以我们在建构档中不需定义DisplayManagers.servers resource。) 
 
xdm 的错误登录档案 
 
    此档案从xdm 和xdm 的周期程式接收所有错误的讯息,且如果你的xdm 设 
定工作发生问题的话,这是第一个需要查看的地方。 
 
    当你开始设定你的系统,对此档案设定任何人均可写入,否则,有问题的 
程式可能因没有写入许可而无法在档案中记录。 
 
启始时的resource档案 
 
    此档案包含一个resource的名单,在Authentication Widget 启始之前被 
xrdb载入。因此,你能用它来为那些widget设定resource。(你当然也能放置 
任何其它的resource规格,但通常周期程式的使用者设定载入时会凌驾其上, 
所以通常不把其它的规格放在这里。) 
 
    authentication widget resource的预设设定在某些情况是很细的,但为 
了举例,我们只设定和bunner不同的标题,我们建立我们的档案 
 
        /usr/bin/X11/xdm/our-resources      包含一行: 
 
xlogin.Login.greeting:X-Window on the Plants network 
 
xdm 的"Session(周期)"程式 
 
    你可以指定任何程式为你周期中所需的程式,可是当周期结束,你通常选 
择一个程式让你能启始其它的程式,你能依赖xdm 的预设设定执行xterm ,但 
这种方式每当xterm 执行时你仍必需手动所有你的设定。我们需要定义我们的 
周期程式来做所有我们的设定,且保持活动(active)的状态直到我们结束它为 
止,但记住,我们希望使用者如果需要能定义他们自己的周期程式,所以我们 
将使用两阶段的处理,如果是系统管理者,我们将设定一个一般性目的,基础 
的,周期程式来召换一个使用者自己的程式(如果它存在),但其它方面将执 
行一个合理预设。当个别的使用者,我们将定义我们自己的设定周期,它将被 
xdm 的一般目的程式执行(我们在另外一节讨论它)。 
 
    我们的基本的site-wide 周期程式非常简单,如果使用者有设定档案 
$HOME/.Xsession 的常规我们便使用之,否则,我们将执行合理的预设 -- 启 
动uwm 而後传递控制到一个xterm(xterm为我们指定在萤幕左上方的那一个) 
。但在做之前,我们先检查是否使用者设定了档案$HOME/.Xresources(其它的 
常规),如果有的话,我们用xrdb载入它。一个完整的程式名单如图20-2。 
 
          ┌——————————————————————┐ 
          │   FIG 20.2        P.257                    │ 
          │                                            │ 
          │  图20-2  程式/usr/lib/X11/xdm/our-session  │ 
          └——————————————————————┘ 
 
20.3.2  我们自己对於xdm 的建构 
 
    现在我们改变角色:我们不再是系统管理者,而是一个使用者。我们可以 
依赖系统管理者已定义之预设周期,但我们比较喜欢定义自己的周期,所以我 
们要获取那些说明我们所需的起始设定。 
 
我们的实例.Xsession 
 
    我们已建立我们自己的$HOME/.Xsession,如图20-3,且此萤幕初始的建构 
在它执行之後会如图20-4。此程式的操作十分直接,但当你自行设定时有一些 
要点需要注意,且当你建立site-wide 周期程式也是一样。我们假设你的周期 
程式是一个shell :虽非必定,但通常都是(除非你要写一个xetrm 的复杂的 
代替品)。 
 
          ┌——————————————————————┐ 
          │   FIG 20.3        P.258                    │ 
          │                                            │ 
          │  图20-3 $HOME/.Xsession 程式               │ 
          └——————————————————————┘ 
 
          ┌——————————————————————┐ 
          │   FIG 20.4        P.259                    │ 
          │                                            │ 
          │  图20-4 我们初始化後的萤幕                 │ 
          └——————————————————————┘ 
 
    .档案中的命令依序排列,所以最後一行所执行的是一个程式,它可以持 
      续整个你的周期。(因为,当此程式结束,则周期程式结束,且每一件 
      事也均将结束)。 
 
    .除了在背景中最後的命令所有的命令均被执行,也就是说,在命令列最 
      後加一个ampersand(&)  号。如果你不这样做,此周期将从不获取过去 
      的任何不确定地执行的程式。例如:在我们的实例程式,如果我们在uwm 
      那一行省略"&" 号,uwm 会启动,但在uwm 结束时,它的下一行将不会 
      继续执行,绝不! 
 
    .最後的命令必为exec的命令,所以它继续执行且保持你的周期继续活动。 
      (如果你像其它命令一样在背景中执行它,它会好好的执行,但此周期 
      程式执行至档案结束将会中断,而结束周期。如果你不用exec,且省略 
      "&" 号,则它会执行且此周期将完美地持续工作,你只是较你所需的多 
      执行了一个处理,就如同你仍有最後的程式(last program)和周期程式 
      本身。) 
 
    .对所有的程式建立视窗时设定geometry规格 -- 否则当它们启动时你将 
      以”手动”方式指定它们的位置。 
 
    .在档案中最後一行的程式通常用来启动xterm ,因为它定义了你周期的 
      生命期,在你执行X时此视窗总是存在,所以你通常设定两个特别的选 
      项: 
 
      1 .使用-C选项使得xterm 为一个”主控台”,所以系统讯息会在它的 
          视窗显示。 
 
      2 .设定-ls 选项使它的shell 为login shell 。如此使得shell 读入 
          你的.login或.profile,所以你的环境变数会适当地设定。(如果 
          你不这样做,你只有一点儿定义:DISPLAY,HOME,USER,PATH和SHELL.) 
 
      3 .此周期程式档案必需有执行许可。使用上述site-wide 周期程式, 
          这对使用者周期script不是绝对需要,它实际是对site-wide 程式 
          本身。(如果那不能执行,你只能获得xdm 的预设设定。) 
 
    在装设你的.Xsession 和依赖它启始你的视窗周期之前,最好能够从一个 
xterm 视窗启动你的.Xsession 以严格测试它。 
 
20.4  我们自己的uwm 建构 
 
    我们需要设定四个uwm 选单:一是连接到其它的主机,二是执行一些X的 
应用程式,三是设定一些键盘和滑鼠参数(有点儿像预设的Preference选单), 
四是执行展示程式。 
 
    对我们的”主机”选单,我们现在希望只要藉著从选单中选取主机名称便 
可在任何主机上启动xterm 。我们常常需在mars上做一些系统管理,所以我们 
将设定选择在其上为超级使用者(super user),我们将在左下角建立一个超级 
使用者视窗,但对一般的xterm ,我们省略geometry规格,所以当它建立时, 
我们可以明确地定位它。我们将以META-SHIFT-LEFT 系结 (bind) 此选单。所 
以在我们的$HOME/.uwmrc中我们包含了此列。如图20 - 5. 
 
          ┌——————————————————————┐ 
          │   FIG 20.5        P.260                    │ 
          │                                            │ 
          │  图20-5  在$HOME/.uwmrc的主机选单          │ 
          └——————————————————————┘ 
 
    其它三个选单我们不常用,所以我们均以META-SHIFT-MIDDLE 系结它们, 
这没什麽特别,但注意Misc. 不包含一个内建的混杂的uwm 和shell 命令。这 
些对应到.uwmrc的项目如图20 - 6。 
 
          ┌——————————————————————┐ 
          │   FIG 20.6        P.261                    │ 
          │                                            │ 
          │  图20-6  在$HOME/.uwmrc中其它的选单        │ 
          └——————————————————————┘ 
 
    uwmrc 剩馀的部份 (见图20 - 7),我们用以设定定制系结和一般视窗建构 
操作的参数。注意下列几点: 
 
    .我们选择一个较预设稍大的字型 (用"menufont=fixed"),降低选单选项 
      中的空白空间 (用"vmenupad=1"),所以选单不会很大。(menufont 可能 
      未在指南页中描述) 
 
    .我们设定所有的选单,系结和变数可被重设(用resetmenus等等),这 
      清除了uwm 的建构,所以我们不用混杂的预设建构和我们自己的建构做 
      结束。 
 
    .如果可能,我们较愿意使用滑鼠的UP事件函数而非DOWN:这种方式你能 
      藉著在松开按钮之前按下其它的按钮,来改变你的主意或中止操作。 
      (但你不能将move操作系结到一个UP事件。) 
 
    .我们已包含一些定义uwm 选单的功能 -- 一个是杀掉应用程式视窗,另 
      一个是重新启始uwm 。它们不是必要的,但当你对系统很有经验时会很 
      有用。 
 
          ┌——————————————————————┐ 
          │   FIG 20.7        P.262                    │ 
          │                                            │ 
          │  图20-7  在$HOME/.uwmrc中系结和参数的设定  │ 
          └——————————————————————┘ 
 
20.5  结论 
 
    你已涵盖了core版中所有使用者层次的程式和如何使用它们。 
 
    你现在能够自行设定和修订成你所需的系统。大部份的修订局限於你的家 
目录(home directory)中的三个档案 -- .Xsession, .Xresources和.Uwmrc 
-- 所以它很容易控制你的环境,且可在你的系统管理者所设定的任何设计下 
执行。 
 
    我们涵盖了一大堆的材料,且有许多的新观念包含进来,所以你尚未能完 
全吸收它,这不是我们所预期的,现在因为你已用过系统一段期间,所以回头 
重读系统的观念概观,你将发现你了解更多,且你可看到在系统表面之後的动 
机。 
 
    当你使用系统越多次,你将发现有一些面貌是你不喜欢的,但这些系统并 
没有。有一些工具和视窗相关程式可简化你的工作,且有一些应用程式对X提 
供介面有大利益,但不包含在此版本中,别失望! -- 看contrib 版软体来取 
代它。现在你知道基本系统的限制和能力,看一看其他的人利用它们做了什麽 
,这也是你可能需要系统做的。 
 
    本书的目的是让你有一个开始 -- 它并无意当一本完整的参考手册。在某 
些地方我们忽略了一些程式不常用的细节和那些对初学者易产生混淆和较复杂 
的部份。但现在你能回头重读系统提供的文件,指南页和其它的资料是非常庞 
大的,如果你知道你要做什麽和只是要某一点复习一下你的记忆,或找出某些 
事如何正确的执行,你将在其中的某处找到它们。现在你已会使用系统和中止 
系统,你能明白参考手册的意义,为了帮助你找出你自己贯通文件的方法,我 
们有一个附录包含了在这个版本中的资料名单,告诉你在何处找到它们,和如 
何更进一步的去探讨系统。 
 
    所以,现在我们只剩下一句话给您:祝一切顺利! 

BBS水木清华站∶精华区