第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)
三個部份依序排列
[
] []
並以特殊的分隔符號分開,我們將於稍後說明分隔符號的細節,但我
們先看一些特徵值的□例(為了簡單起見,我們在□例中只用到顏色
屬性)。
一些說明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來定制你的鍵盤。