BBS水木清华站∶精华区

 
             第15章  定义应用程式的预设选项 -- Resources 
 
 
    大多数的X程式接受命令列选项,以便让你指定前景和背景的颜色、字型 
、起始位置等等。这种需求是有必要的,因为如果你在程式内硬性规定使用某 
种字型,而在执行此程式的机器上并没有这种字型,则将使得程式无法执行, 
所以你不应硬性规定某些参数。 
 
    当你每次执行程式时不太可能在命令列中指定所有需要的选项,因为有太多种 
可能的组合了,所以X提供了一个叫做resources 的一般性结构,用来传递预 
设的设定给应用程式。当你阅读指南页时,你可能已经注意到要你参照resources 
,但却不知道什麽是resources ,我们将在此解释。 
 
    你在系统中几乎所有的定制动作都将运用到resources ,事实上你为一 
个应用程式所选择的每一个选项的设定都要用到resources ,从简单的项目例 
如色彩或字型,到定制你的键盘或管理你的显示器如何工作,它非常的方便, 
而且在系统中到处都用得到。 
 
    本章我们描述什麽是resources ,及关於它们是如何发展的资讯,接下来 
我们描述X Toolkit(工具),它完全地使用到了resources 的结构;然後 
告诉你一些resources 工作的细节,你该如何设定它们,及你能用它们设定哪些 
型态。 
 
    这是相当长的一章,有几个新的观念被加进来,一开始会有些困难,但不 
需太担心,原则上resources 结构非常地简单,只是第一眼看起来好像有许多 
 "魔术符号" 而已,也许你应该先很快地浏览一遍,然後再详细地重读一遍。 
 
 
15.1  什麽是resources ? 
 
    在X的文献中,”resources ”有两种意义。第一种是相当低阶的,意指 
被server管理或建立而被应用程式使用的东西。视窗、游标、字型等均属於这 
种意义。 
 
    另一种意义也就是通常你在指南页中常看到”resources ”的意义:它是 
一种传递预设设定、参数和其它值给应用程式的方法。在本章中我们局限於 
讨论此种意义之resources 。在解释现行系统如何工作前,先回顾一下X的早 
期版本是如何掌握这些功能的,因为现行的结构由此产生。 
 
 
  15.1.1  ”预设”的背景 
 
    在X较早的版本,对於像视窗背景颜色、视窗边界的颜色、应用程式所使 
用的字型这类项目你可以轻易地设定其预设值。 
 
    预设值的设定方式很直接,你只需指定一个视窗的属性和它的预设值。例如: 
 
    .Border : red 
 
意即所有的视窗均为红色的边(除非你在命令列中重新设定边的颜色),你也 
可以把程式的名称放在属性之前,则只有被指名的程式才会改变,所以把以下 
这个规格 
 
        xclock.Border:blue 
 
和先前的规格结合在一起的意义为:预设所有视窗均为红色的边,只有xclock 
的视窗为蓝色的边。 
 
    每当你设定预设值,程式会自动取用该值,所以你□需每次均指定你的选 
择,它让你依照适合你的工作习惯来使用字型,不论是你要用较小的字型以获 
得更多的资讯显示,或是用较大的字型以便阅读,它让你为特定的应用程式选 
择颜色,你可以定义应用程式的起始位置,所以你可以自行设计一些启始萤 
幕的布置,因为许多的预设值(字型、色彩等)实际上精确的意义为”resources” 
,所以”resources ”的意义逐渐扩增为”预设值设定(default setting) ” 
或”设定预设选项(setting default options) ”。 
 
 
  15.1.2 Resources 传递资讯到应用程式 
 
随著X的发展,应用程式也随之扩增,需要有一个设施传递大量的资讯到应 
用程式以定制或指定它们的行为,而不再只是有关色彩和字型的资讯而已, 
例如你可以告诉 xbiff检查信件的频率,或定义 xterm的功能键(function-key) 
12为插入某一特定的字串,或在 xedit中连续碰触两次滑鼠中按钮代表选择目 
前这段本文等等。 
 
    所以逐渐地,resource及预设设施已遂一被发展出来,直到目前对於传递 
任何资讯到一个应用程式已是一个一般性的结构。你可以像文字串一样地指定 
资讯,应用程式会在内部解释它:例如把这字串当作一个滑鼠按钮的名称,或一种颜 
色,或由应用程式所发出的一个功能和 "resources"是如何指定的。 
 
    这个结构也逐渐地复杂起来以便让你能正确地指定在何处应用预设值。在 
以前,你只能指定所有的程式或某一个特定的程式。现在的系统你可以设定的 
预设值如:”终端机视窗的选单选项”或”在所有视窗的标签”或甚至”除了 
xterm以外的所有编辑器视窗按钮盒中的功能按钮”。 
 
    X Toolkit, 使得resources在使用上有很大的包容性并且增进了应用的 
精确度。你需要先了解 Toolkit是什麽,才能适当地使用resource 结构,我 
们将在下一节讨论。 
 
 
15.2  X Toolkit 
 
    我们先前曾提过,X并不决定使用者介面,它只是提供一些结构,让应用 
程式设计者能组合成任何形式的介面。理论上这是非常合乎需求的 -- 它使得 
系统拥有一个一般性目的的工具且没有使用上的限制,但从另外的角度来看, 
它有很大的缺点: 
 
    .对一个使用者而言,不同的应用程式有不同的介面,不只是难学难记, 
      且应用程式无法平顺地 (smoothly) 相互协调工作(例如无法在视窗之间 
      做剪贴),你得到的是一群个别的、独立的程式,而不是一个一致的、 
      合作无间的系统。 
 
    .从程式设计师的立场,意味著基本视窗系统上的每一件事均需从头做起, 
      选单、卷动棒、时钟、功能钮等等都必须一一生产。甚至在单一的产品, 
      不同的程式师做了一点稍有不同的事,便会导致许多不相容的情况。 
 
为了克服上述的问题,Toolkit(工具)的方式应运而生。 
 
    在某些□围,Toolkit 会决定使用者介面的形式,但是无论如何,它会尽 
量减少这种影响,并让使用者介面发展者有更多选择的可能性,Toolkit 被分 
为两个部份: 
 
    1. 一组基本的结构和函数用以建构使用者介面的元素,被称为Toolkit 
        Intrinsics(内部的工具)。不论是什麽样的介面,任何工具均需使 
        用到它,所以我们可以把Toolkit Intrinsics视为”固定的”,也就 
        是无可替代的。 
 
    2. 一组提供特定的使用者介面(或介面的形式)的元素,这些元素被称 
        为 widgets (小工具),而Toolkit 的第二部份称为 widget set (小 
        工具组),我们认为这是可以替换的,不同的介面提供不同的Widget 
        Sets ,甚至它们都使用Intrinsics。 
 
下面两个小节更详细地说明这两个部份。 
 
 
  15.2.1  Toolkit 的第一个部份 -- Intrinsics 
 
    Intrinsics定义的实体称为widgets,并提供了所有建立、管理和毁坏widget 
所需的设施。理论上,一个widget是一个处理特定动作的使用者介面的元素,实际 
上一个widget是X视窗加上规则和功能以决定它的输入和输出的动作,也就是 
说,它如何对使用者有所反应。 
 
    为了帮助解释widget的观念,我们将给一点□例,但是请注意!它们并不 
是Intrinsics的一部份,而是我们将於下一小节讨论的一个特定的widget组的 
一部份,在此提出目的只是为了方便。 
 
    Command Widget(命令widget):这是一个在萤幕上含有一些文字的长方 
形”按钮”(也就是一个小视窗)。当指标在这个按钮之上时,它的边会呈现 
高亮度,当一个滑鼠按钮在这个widget被碰触时,一个被程式师指定的软体常 
式(routine) 便会被执行。 
 
    你已经使用过command widget好几次了:在xedit 的命令选单和在xman的 
主选项视窗。 
 
    Scrollbar Widget(卷动棒widget):同样的,你也已经使用过了好几次, 
在xterm 和xedit 中卷动本文,在xman中卷动本文和目录列。 
 
    Intrinsic 提供了基本的结构,任何一个提供介面的较高阶软体均需要使 
用到它,它提供了以下的功能: 
 
    .建立和毁坏widget。 
 
    .把一群widget当成一个单元(unit)来管理。 
 
    .掌握geometry,也就是说位置,包括从最高阶(也就是应用程式的 -geometry 
      选项)到最低阶(管理应用程式用到的sub-widget的位置(例如选单按钮 
      的位置))。 
 
    .掌握”事件”,例如在一个widget中, 当滑鼠按钮被碰触时呼叫适当的程 
      序、管理视窗的曝光 (exposure)和掌握键盘的输入。 
 
    .管理给resources 和预设的每一个widget。 
 
 
  15.2.2  Toolkit 的第二部份 -- Widget Sets 
 
    广义来说,Intrinsics只提供你建造一个使用者介面的骨架,Widget Set则 
实际地提供了一个既定的介面,且不同的widget组提供不同形式的介面,虽然 
对任何□围的需求并无法预防混用widget,但一般仍希望一个系统固定在 
一致性的widget set上。 
 
    在X core 版上只有一个widget set提供,我们描述於下: 
 
Athena Widget Set (雅典娜widget set) 
 
    大部份的MIT core版的应用程式使用Toolkit 和Athena Widget Set.(名 
称的来源是X由MIT 的Athena计画产生出来)。这些widget的定义你已在许多 
的应用程式用过。 
 
    我们在前节提过了Command Widget和Scrollbar Widget,至於Athena Widget 
Set 的其它部份包含: 
 
    Label Widget:这个你可以想像 -- 在视窗中显示的一个字串或图。(例 
                  如在xman主选项选单中的”Manual Browser”的标题) 
 
    Text Widget :我们在第10章描述xedit 时提过的”building block”。 
                  它提供我们所使用的编辑功能。 
 
    Viewport Widget :一个具有卷动棒的视窗,让你可以卷动视埠(viewport) 
                  的内容,xman使用其中之一用以显示指南页之目录。 
 
    Box Widget:它以一个指定大小的盒管理sub-widget的布置,且试著将 sub- 
                widget尽量集中在一起,例如xmh 的Reply 、Forward 等命 
                令钮即是由Box Widget布置。 
 
    VPaned Widget :它管理sub-widget,将它们保存在垂直堆叠中,且显示了 
                  在两个sub-widget之间的分隔线上的”把手”(grip),把手 
                  可以选择性的让你改变一个widget的大小,而且另一个相 
                  关的widget大小亦伴随变化,例如我们在图10-12 看到的 
                  xman的视窗的主要的元素是被VPaned Widget 管理的。 
 
    Form Widget :另一种管理一组sub-widget的方法,但对位置的选择有更多 
                  的弹性。 
 
    List Widget :它管理一群字串,将它们安排在行列中,任何的字串藉 
                  著於其上碰触的动作而被选择:字串会转为高亮度,且呼叫 
                  一个指定的函数以完成特定的动作。xman使用一个List 
                  Widget来掌握在一个指南章节中指南页的表列。 
 
    我们现在来看一下如何组合widget以获得所需要功能,我们仍然以xman为 
例。xman的指南页之目录在它的低阶是list widget ,管理目录页名称的表列 
以及它本身的内容是用viewport widget (让使用者卷动至表列中所需的位置 
),将指南页的widget聚集在一起,它们是包含在一个VPaned Widget 中,所 
以事实上这是一个阶层状(hierarchy) 的widget,每一个可以完成它的专门 
功能,而所有的应用程式所使用的Toolkit 均含有这三个widget结构。 
 
 
 
  15.2.3  widget:名称和类别 (Names and Classes) 
 
    resource和预设结构是在widget名称的基础下工作,所以我们将以对名称 
的处理做一个概观方式来结束对Toolkit 的观察,并回到先前讨论的resource。 
 
    Toolkit 提供一个物件导向程式系统(object-oriented programming system) 
给程式设计师。它定义物件的类别(class) ,也就是指定何时物件被建立或如 
何操作等等的物件性质。这些物件即是widget,系统将确保它们和其它的widget 
以及其它部份的应用软体以定义明确的方式交谈。 
 
    当一个程式设计师建立一个特定类别的widget,它被称为该类别的成员 
(instance)(概括的说,一个类别是一个抽象的定义,而一个成员在某些地方 
实际地符合这些定义。)建立widget有必须一个名称,由程式设计师指定,( 
例如:程式码的实际型式为”Creat a widget, of the class Box Widget, 
and call it topBox ”)在某些环境下widget的类别名称也会被参考到。总 
结来说,一个widget有一个成员名称和类别名称;更简单的说,一个名称和一 
个类别。 
 
 
 
15.3  Resources 如何被管理 -- Resource管理器 
 
    让我们提醒自己一下我们试图用resource来做什麽?我们要能传递资讯给 
一个应用程式,告诉它以某些方式改变它的一般性动作,例如,将视窗的边 
以粉红色取代原来的黑色,或使用一些特别的字型。 
 
    X用下述的方式掌握这些需求。你设定一个包含许多项resource规格的资 
料库,每一个resource规格以一个应用程式的某些特徵命名,且设定一个值给 
这个特徵当预设值,也就是说,一个规格 (spec) 的形式为: 
 
        characteristic : value    (特徵:值) 
 
    当应用程式开始执行时,它会先询问资料库是否有任何特徵符合自己所要 
的设定,或使用相关的值,例如: 
 
        xclock*foreground:blue 
 
    意为将值blue设定给特徵xclock*foreground 。用以决定一个程式的需求 
是否符合在资料库中之规格的系统部份,被称作Resource管理器。 
 
    Resource预设值能被应用到一个应用程式中的物件(通常是widget),就 
如同设计整个程式一般,(例如你可以对一个特定的子视窗在某一个命令按钮 
的背景色设定预设值,而不是只能针对所有应用程式的视窗背景)。为了能达 
到这一点,我们需要一些严谨的命名方法,以设定物件应用预设值。 
 
 
  15.3.1  指定一个Resource预定应用到何处 
 
    Resource管理器根据特徵值(characteristic)决定一个预设规格是否能应 
用在特别的情况,我们可将特徵值分为三个部份。 
 
    1.  你用以设定预设值的程式属性,例如:背景色、字型等。 
 
        你必需指定属性 (attribute) -- 意即你设定什麽值给它。给定一个 
        resource的规格 而不说明它的值是无意义的。 
 
        注意:在X的文献和手册中,属性通常被称为”resource”或 
        ”resource name”,”Resource”也通常被用来当作我们称为特徵值。 
 
        特徵值的其它两个部份指定预设值在何处使用。例如只在特定的程式 
        使用或在特定型态的物件,或两者均是。 
 
    2.  应用到这个规格的应用程式的名称,如果你省略它,规格将应用到 
        所有的应用程式。 
 
    3.  一连串的限定(restrictions)条件:当物件符合限定条件时,才会产 
        生指定的应用。限定通常为widget的名称,你可以指定从零开始任何 
        数目的限定。例如: 
 
          xclock*foreground:blue 
          xedit*row1*Command*Cursor:Cntr_ptr 
 
        第一个例子没有任何限定,第二个例子有两个限定(row1 和Command) 
 
        三个部份依序排列 
 
        [<program name>] [<restrictions>] <attribute> 
 
        并以特殊的分隔符号分开,我们将於稍後说明分隔符号的细节,但我 
        们先看一些特徵值的□例(为了简单起见,我们在□例中只用到颜色 
        属性)。 
 
 
一些说明Resource规格的□例 
 
    .指定在任何地方中的前景色预设值为黄色。 
 
          *foreground:yellow 
 
    我们未指定任何应用程式的名称,所以此规格可应用到所有的应用程式; 
我们也未指定任何限制,所以对一个应用程式在任何地方都适用。("*" 这个 
符号就是我们方才提及的特殊分隔号的一种) 
 
    .指定只有在xclock应用程式中的前景色预设值为粉红色。 
 
          xclock*foreground:pink 
 
      这个规格仅能在xclock适用,但是只要项目中的属性叫做 
”foreground”的均适用。 
 
    .现在,针对一个特定应用程式的特定地方: 
 
          xman*topBox*foreground:blue 
 
      这个规格仅能在xman适用,而且只能在xman主选项选单中名为topBox的 
物件适用。(应该适用於xman中所有叫topBox的物件,但实际上只有一个 
topBox物件) 
 
    .在第二个□例(粉红色)中我们包含了应用程式名称,但忽略了任何限 
      制,现在我们反过来: 
 
          *command*foreground:green 
 
      也就是说,我们指定在任何应用程式中物件名称为command 的前景色预 
设值为绿色。 
 
 
 
  15.3.2  用类别名称一般化规格说明 
 
    前述的例子说明了我们对预设值结构所需的大部份功能,但它们有一个限 
制:你必须知道应用程式设计师设计在每一个应用程式中的widget名称,这 
些资讯有时包含在程式的指南页中的一部份,但通常被省略。 
 
    无论如何,Resource管理器有一个尽量减低这个问题的方式:当你在特徵 
中不论何处用到一个应用程式名称、限制或属性名称,你均可类别名称(class 
name)来代替它。 
 
    应用程式类别名称(Application class name):描述程式的型态,例如 
        xterm 可以是Term Emul (终端机模拟器)的类别,xedit 和emacs 
        是Editor(编辑器)的类别。(但如果xterm 是xterm 的类别,xedit 
        是xedit 的类别则失去意义。) 
 
    限定类别名称 (Restriction class name):限定几乎是一定不变的widget 
        名称,所以在此地你可以用widget类别名称。 
 
    属性类别名称 (Attribute class name) :属性是如同widget一般的一个 
        型态或类别的成员(instance)。 
 
    传统上,所有的类别名称以一个大写的字母开头,其後则为小写字母,例 
如属性”foreground”是属於”Foreground”类别,我们将简单的解释你如何 
去发现你需要用来指定项目的类别名称。首先,我们将看一些更多的□例,这 
次用到了类别或一个混合了类别和成员的□例。 
 
 
含有类别名称的Resource规格说明□例 
 
    这些□例展示出你如何在Resource规格中使用类别,而较前述以更一般性 
的方式设定预设值,它们也解释了你如何能使用一个类别来设定一个预设值给 
较大□围的情况,和将类别与成员结合起来以拒绝预设值在某些特殊情况下设 
定。 
 
    .指定在任何地方前景色的预设值为黄色 
 
          *Foreground:yellow 
 
    这个□例和先前□例的区别在於我们是对Foreground类别指定预设值。这 
个区别之所以重要,是因为并非所有在类别Foreground的属性,它的成员名称 
都是叫foreground。例如,xclock的指针的颜色可由类别Foreground的属性来 
决定,但它的成员名称不叫foreground而叫hand。 
 
    .我们可以用这种结构来帮助我们在文件不清楚的情况下,藉著以强烈对 
      比的组合设定预设值来分辨物件的类别: 
 
          xmh*Command*Foreground:khaki        (土黄色) 
          xmh*Command*Background:maroon       (粟色) 
 
      如此将使所有的命令widget(command widget)呈现醒目而美丽的颜色。 
 
    .对所有的本文widget(text widget) 视窗设定一个预设值,除了xedit 
      视窗以外: 
 
          *Text*Background:pink 
          xedit*Text*Background:navy 
 
    .和上例原理相同: 
 
          *Command*Backgrond:green 
          xman*Command*Backgrond:white 
          xman*manualBrowser*Command*Background:orange 
 
 
如何发现成员和类别名称 
 
    这很困难,因为没有简单和一致的widget名称、类别、属性等等的文件, 
我们只能列出每一个最好的来源,并且提示你如何获得更多的资讯。 
 
    应用程式成员名称(Application instance name) :这很容易--它就是你 
执行的应用程式名称。如果此程式使用Toolkit ,你能在命令列以选项-name 
string明确地指定一个不同的应用程式名称,为何你需如此作?因为它让你在 
单一应用程式中定义超过一组的预设值,而你可以使用-name 在其间切换。例 
如,你可以定义一个xterm 的正常预设值,但对名为demo的应用程式定义一个 
很大的视窗尺寸和大尺寸的字型,你可以用: 
 
          xterm -name demo 
 
给你一个用来展示或教学的xterm。 
 
    应用程式类别名称(Application class name):这没有文件说明,最简 
单找寻它的方法是启动应用程式并在视窗中使用xprop ,性质 (property)当中 
的WM_CLASS会给你应用程式成员及类别的名称,例如,对xterm 你会得到: 
 
          WM_CLASS(STRING) = "xterm","XTerm" 
 
    Restriction/Object/Widget 成员名称:程式的指南页会列出你最想要存 
取的物件名称,例如:xman列出topBox,help,manualBrowser 等等,如果指 
南页并未给你成员名称,则唯一的方法是如果可能,直接看它们的原始程式码 
。(这种方法通常无法令人满意) 
 
    Restriction/Object/Widget 类别名称:这容易些,大部份的指南页会告 
诉你有兴趣的物件类别,即使没有的话,大部份的物件也是标准集合中的 
widget,当你从系统中使用它们时,你通常能猜出它们属於哪一个类别。(例 
如:你从未被告知scrollbar 的成员名称,但它99.9% 的机会是类别Scrollbar 
的widget (成员)。) 
 
    属性名称和类别:大多数的指南页会列出名称,通常也会有类别,xclock 
的指南页便是非常清楚的□例。 
 
    无论如何,利用Toolkit 写的程式通常使用标准的widget,它的属性并不 
会在指南页中列出,但通常由一组全部或部份的属性组成,要找到这些属性, 
你必须在Toolkit 文件中寻找: 
 
     . "X Toolkit Intrinsics" 手册中的附录E 列出所有标准的"resource" 
        (也就是属性)名称和类别。成员名称项目看起来类似: 
 
          #define XtNborderWidth "borderWidth" 
 
        所有的名称均以XtN 开头,跟随其後的名称则以小写字母开头,而类 
        别的名称则以XtC 开头,类别的项目看起来像: 
 
          #define XtCBorderWidth "BorderWidth" 
 
        在双引号中的便是名称,也就是说,borderWidth 是成员名称, 
        BorderWidth 是类别名称。 
 
     . 查看"X Toolkit Athena Widgets"手册的2.3 节("Common Arguments 
        in the Widget Argument list"),可看到被所有widget使用到的 
        resource名单,包括名称、型态、预设值和一段文字叙述。名称的 
        定法如上所述,也就是以XtN 开头,XtN 之後则为属性名称。 
 
     . 查看"X Toolkit Athena Widgets"手册中对widget的描述,每一个会 
        列出它所使用的"resource",和上述相同。 
 
     . 如果以上均行不通时,你可以查看 widget 的原始程式 (source code), 
        resources 可用到的部份列在 XtResource 资料结构中。例如,Athena 
        Scrollbar Widget的程式内包含: 
 
          static XtResource resource[]= 
          {XtNwidth, XtCWidth,...}, 
          {XtNheight, XtCHeight,...}. 
 
    附录A中”文件指引”中会告诉你如何找到类似像这个项目的原始程式。 
 
    注意:Resource Manager对设定的规格(spec)并无限制,均能接受,对於属 
          性、元素名称或类别并无事先定义的清单。你所给定的规格可能毫 
          无意义,但毋需介意,它将存在资料库中,所以事实上一个resource 
          规格被接受并不意味你已经得到正确的规格和正确的属性或物件或应 
          用程式;无论如何,它的一个重要的用途为在属性未被设定前你可先 
          设定其预设值。 
 
 
  15.3.3  Resource规格之分隔号概观 
 
    你可以用星号 (*)或点号 (.)来分隔resource规格的元素,星号比较通用 
一些,它让你指定那些符合□围的案例的特徵。我们看到 
 
          xclock*foreground:pink 
 
用来指定xclock中任何东西均使用foreground属性,所以在此□例中可以看出 
;星号具有通用字元的效果,甚至可以再一般化一点: 
 
          *Foreground:yellow 
 
它将适合任何应用程式,而句点只是分隔组件,它表示每个组件都必须一一对 
应,所以规格: 
 
          xman.Manual Browser.Help.background:black 
 
并不会适用於命令按钮,或含有xman的视窗的不同widget。在我们对这两种分 
隔号作更精确描述前,我们需要更详细的看一下Resource Maneger的操作。 
 
 
Resource Manager如何运作 
 
    稍早,我们曾说过一个应用程式会查询resource预设规格的资料库看是否 
符合,现在我们描述查询如何掌握这些规格。 
 
    Resource被应用程式中的个别物件(通常是widget)所使用,而物件则被 
在应用程式上端hierarchicallyixwidget + hierarchy安排,然後可能由一个 
widget管理其它的widget配置,例如本文视窗、命令选单等等。例如应用程式 
xeditixwidget 在+ xprognxxedit中的阶层结构如图15-1(每一行物件名称之 
後括弧内为类别名称)。 
 
        ┌————————————————————┐ 
        │      p181  fig 15.1                    │ 
        │                                        │ 
        │    图15-1 xedit中物件(widget)的阶层    │ 
        └————————————————————┘ 
 
 
    对每一个物件,应用程式欲查询Resource资料库时,它必须传递物件的成 
员全名和类别全名给Resource Manager,和物件所用的一群属性,和类别名称 
的一群属性,例如对SAVE按钮,应用程式指定: 
 
          full instance name    xedit.vpaned.row1.Save 
          full class name       Xedit.VPaned.Box.Command 
          attribute instance-names borderWidth,cursor,font,label,... 
          attribute class-names    BorderWidth,Cursor,Font,Label,... 
 
    而後Resource Manager检查每一个在资料库中的规格,看它是否和应用程 
式所传来的属性和物件名称相符。如果相符发生,在资料库中规格值的部份会 
传回应用程式。 
 
    在这种相符的操作中,星号和句号的区别非常重要。简单来说,我们可以 
想到Resource Manager只是以单字为基准来对应文字串,句号正是每一个单字 
的区隔号,星号也是分隔号,但不同的是它可以通用字元的方式代表从零到任 
意数目的单字,对於对应唯一的限制是在资料库中规格的属性必需对应查询应 
用程式所传来的属性,你不可对属性用通用字元。 
 
    现在你可以看到不同的规格如何工作: 
 
          *foreground:yellow 
 
可以应用於任何应用程式中的任何物件。因为星号对应到所有的应用程式和所 
有的限定和物件名称。 
 
          *Command.Foreground:violet 
 
应用於任何应用程式中任何Command 型态中Foreground类别的任何属性。 
 
          xedit.vpaned.row1.Help.background:navy 
 
是一个完整的规格但是将只影响到命名当中的物件名称的属性。(本例中, 
尽管事实上是大写的,"Help"是一个成员名称,它的类别是"Command" 。) 
 
    除非你有一些非常特别的需求,最好不要用句点当分隔号,尽量以星号代 
替,如此可减少错误发生的可能,而且在重写应用程式时,比较不会受到阶层 
结构改变的影响。 
 
    上述的对应结构解释了为什麽你可以输入奇怪的规格,或者resource 
和属性尚未定义:意即一个规格只有当应用程式查询资料库才会附著,甚至□ 
围的意义也是不足道的 -- 规格对应或不对应到查询。 
 
 
  15.3.4  当多种Resorce规格对应的居先(precedence) 规则 
 
    我们现在有一个非常弹性的方法来指定应用程式的resource,但正因它太 
笼统,以致当一个应用程式查询resources 资料库时常常有数种规格与之对应, 
如何解决呢? 
 
    简单地说,如果同时有超过一个规格对应,则最具体的(specific)一个会 
被使用,Resource Manager有一组的居先规则用来决定是否一个规格较另一个 
具体。 
 
    .使用句号为分隔号较使用星号为具体,例如:*Command.Foreground 较 
      *Command*Foreground 为具体。 
 
    .成员名称较类别名称具体,例如:*foreground 较*Foreground 具体。 
 
    .指定一个元素较省略它具体,例如:xmh*command*foreground较 
      xmh*foreground具体。 
 
    .元素靠近规格左边的星号较靠近右边的具体,例如:xmh*foreground较 
      *command*foreground具体。 
 
    这些规则相当直接,它们大部份可用另一种方法来说明:”如果一个规格 
对应到另一个规格而为其子集合者,则前者较後者具体。” 
 
 
  15.3.5  在Toolkit 程式中应用程式Resource 
 
    通常一个应用程式使用Resource Manager来定义程式阶层中widget的属性 
预设值,但有时需要有和widget不直接相关的设定预设值(或传值)的能力。 
 
    为了达到这点,Toolkit 提供了一个叫做Application Resource的设施, 
它和非Toolkit 预设的外表原则相同 -- 应用程式定义了它本身选择的属性。 
类别名称也相同,所以事实上这些属性和一般常见的阶层没有什麽不同。 
 
    xman使用到一点这个设施,它让你能在求助视窗(help window) 指定不同 
的本文档案,是否在主选择视窗中指定一个你要的视窗,或当程式启动时直接 
进入一个指南页等。(查看指南页,在X Default那一节,它会明确地列出它 
的”应用程式特定的resources ”)。 
 
 
 
  15.3.6  Resource和non-toolkit 应用程式 
 
    并非所有的程式均使用Toolkit ,但Toolkit 几乎掌握了所有对一个应用 
程式的resource管理,特别是应用程式的widget结构定义了物件和子物件的阶 
层,并能适当地查询Resource Manager。但是non-Toolkit 应用程式要如何使 
用Resource Manager? 
 
    答案是应用程式只需明确地查询每一个它有兴趣的属性。稍早我们曾说过 
Resource Manager对resource无限制,因此应用程式能使用任何它想要的属性 
名称,只要程式的文件告诉使用者它们在何处,它们就如同其它的应用程式一 
样。 
 
    xcalc 应用程式是一个不使用Toolkit 的程式□例,它也利用上述方式掌 
握resource规格。 
 
    有几点需要注意: 
 
    .此种型态的预设值没有类别。 
 
    .程式以类似类别名称(也就是说,第一个字母大写)来定义属性,例如 
      xcalc 使用Background, Foreground, BorderWidth 等等。 
 
    .如果大小写错误,你的规格不会工作,例如:规格 
 
          xcalc.foreground:green 
 
      会被xcalc 忽略。 
 
    .即使这个程式定义的属性并非阶层的一部份,你仍能使用星号当分隔号, 
      例如: 
 
          xcalc*Foreground:orange 
 
 
15.4  Resources 的型态----如何指定值 
 
    直到现在我们仍然只看resource规格的”左半边”,而忽略了值(value) 
的部份,或只是用色彩名称。现在,我们来看一看”右半边”(值的部份)。 
 
    简单地说,值只是一个传递到应用程式的本文字串,和Resource Manager 
完全相关,之後,应用程式以此值做它所要做的事。当然,在实际的操作上, 
应用程式必须明确地做某些事,而Toolkit 的确也掌握了大多数这一部份的工 
作,所以你可获得一致地介面。 
 
    所以当我们以一个Resource值传递我们所需时,实际上我们使用少数的型 
态,你已看过它们的大部份,你在任何地方均可以resource规格来使用它们: 
 
    Colours (色彩):我们已广泛的使用过它们----毋需多做解释。 
 
    Fonts   (字型):在一般的方法我们已描述过,在resource规格,你也 
可使用通用字元或全名。例如: 
 
          *Font: *-courier-medium-r-*-140-* 
          xterm*Font: 8*13 
          xterm*boldFont: 8*13 
          demo*font: *-courier-medium-r-*-240-* 
          demo*boldFont: *-courier-bold-r-*-240-* 
 
设定一个整体性的预设字型,但使用一个正常的xterm 指定一个明确的一对字 
型,和一对被demo应用程式使用的较大的字型。(可用xterm -name demo) 
 
    Numeric quantities:在不同的情形,例如: 
 
          xclock*update:30 
          xclock*update:60 
          BorderWidth:10 
          xlogo*Width:120 
          xterm*saveLines:200 
 
    Boolean values:指定"yes" 或"no",你可以使用"yes" 、"on"、"true" 
和"no"、"off" 、"false" ,例如: 
 
          xterm*scrollBar:false 
          xman*bothShown:true 
 
    Cursor names:指定在/usr/include/X11/bitmaps中包含你所要的游标的 
档案名称,例如: 
 
          xterm*pointer Shape:cntr_ptr 
 
    注意:如果被指定的游标不包含 "热点" (hot spot),你可能得到错误讯 
          息。 
 
    Geometry spec :全部或部份。 
 
          xcalc*Geometry: 180*240-0-0 
          xcolock*Geometry: -0+0 
 
设定一个计算器的预设尺寸及其启始位置在右下角,时钟的启始位置在右上角。 
 
    键盘转换(keyboard translations) :安排特定的字串给一个键,或安排 
特殊(非印出)动作给键或按钮,这相当的复杂,第17章会全面专门讨论它。 
 
    Pixmaps :Pixmaps 是像位元映像纹理(texture) 一般的图样,像位元映 
像或游标一样的指定它们。当你在单色萤幕上工作时非常方便,一旦为不同类 
别的widget设定背景,你便能看到应用程式在何处使用到它们。例如:以下的 
resource规格: 
 
          *Pixmap: mensetmanu; 
          List*backgroundPixmap: scales 
          Box*backgroundPixmap: cntr_ptr 
          Command*backgroundPixmap: sipb 
 
    导致你的应用程式看起来很讨厌----你得到杂乱的视窗,每一个空间以某 
种图样填满----但它们的确在作用,有时这样做可能会有用,backgroundPixmap 
是类别Pixmap的属性。 
 
 
15.5  结论 
 
    在这复杂的一章中,你看到了什麽是”resource”,和你如何使用它们指 
定预设值或其它的值给应用程式,我们勾绘出Toolkit 大致轮廓,和widget的 
阶层观念,并说明如何利用widget结构或应用程式的其它物件来设定较大□围 
的预设值。从这里我们介绍类别的概念,它可以让你指定物件而无需知道它们 
个别的名称,接著谈到Resource Manager和它在资料库中对应resource规格的 
规则以便程式查询预设值,最後,我们大致说明如何指定它们的值。 
 
    本章专注於resources 结构运作的规则,现在是告诉你如何在系统下实际 
使用的时候了。在下一章,我们告诉你如何及在何处储存预设规格,也就是说 
,如何管理我们前述的”resource资料库”。在这章之後,我们解释如何使用 
resource来定制你的键盘。 
 

BBS水木清华站∶精华区