第17章 定制你的鍵盤和滑鼠 -- 轉譯
電腦的鍵盤通常含有一些 "特殊功能" (special function)鍵,在此有一
些方法來 "制定"(program)這些特殊功能鍵,使它們能完成特定的功能以適合
你工作的方式。例如,你可以定義一些鍵來輸入那些你常用的命令,或只需按
一個鍵便能夠輸入一些程式的片段。
在X中,你能制定的不只是功能鍵而已,其它一般的鍵和滑鼠的按鈕也都
可制定。對每一個應用程式,你均可指定特別的功能給鍵盤和滑鼠按鈕,或兩
者之組合。 (例如在 xedit中你可以結合SHIFT 鍵和滑鼠的右按鈕來讓你向前
移動一個單字)。 所有使用X Toolkit的程式均允許使用者利用一個被稱之為
鍵盤轉譯 (translations) 的設施來執行此種定義,且此種定義藉著正規的
resources 結構傳遞給應用程式。 (那些不使用X Toolkit的應用程式,同樣
地也可以用相同的設施來制定, 但它們需個別的定義所以不能廣泛地應用,從
現在起,我們假設每當討論有關轉譯的種種,均為對那些使用X Toolkit的應
用程式而言。)
就如同所有的 resources一樣,轉譯是當應用程式執行時才被處置。例如
你可以擁有數個具備不同轉譯設定的 xedit,在同時一起執行。( 你可以讓一
個xedit 適合編輯本文,另一個適合編輯程式碼,而另一個適合編輯文書)。
本章討論轉譯 -- 包刮它們的定義格式,如何將它們設定到應用程式,和
它們所涵蓋功能的范圍。我們首先以實例來介紹,逐漸地導引你看到不同的角
度。而後比較正式和詳細地討論轉譯。最後,我們列出當你使用轉譯時常會碰
到的錯誤,並給你一些如何克服這些問題的提示。
17.1 實際使用轉譯
Toolkit 轉譯結構最簡單的用途便是讓你制定你鍵盤的鍵。例如,當你使
用xterm 為一個執行一般shell 命令的視窗時,你可能希 定義一些特殊功能
鍵來輸入你常用的命令,且希 指定的關系如下:
當我按下這個鍵時... 我希 這個字串被輸入
F1 rm core *.tmp
利用Toolkit 達到此目的方法為:指定一個值給使用轉譯的widget中的resources
。此值設定應用程式中所必需的定制 (customisation),且被Toolkit 的 Trans-
lation Manager (轉譯管理器) 所處理。此 resources屬於類別Translation,
且其成員名稱幾 一定是translations。
在下一節我們將看到設定到resources 中的值的格式。
17.1.1 如何對一個應用程式指定轉譯
對前述xterm 的例子,我們定義 (在即將被應用程式讀入的resource資料
庫中或一些resource檔案中) 一個規格類似:
xterm*VT100*Translations: (contd.)
F1: string("rm core *.tmp") 注意:不完整!!
其意為在任何類別 VT100的 xterm widget 中,當鍵 F1 被按下時, 入
字串 "rm core *.tmp")。
不幸的是,並沒有這麽簡單,轉譯管理器會把上面的規格解釋為 "去掉所
有現存的轉譯,且加入... " ,所以所有正常的像 " A鍵是 入一個 A" 這種
系結 (binding)都會消失。為了克服這點,你必需使用一些被稱為 directive
(指引)的語法 入在 resource 值之前:
xterm*VT100*Translations: #override(contd.)
F1: string("rm core *.tmp")
通常你會希 保持大部份現存的系結,而只是把你明確指定的值覆蓋上去
,所以你一般都是在你的轉譯表中,指定 #override。
現在這個規格可以開始工作了,藉著啟始一個 xterm且把此規格 (在兩個
單引號 ()中間的部份) 當成選項 -xrm 的引數來測試它:
xterm -xrm xterm*VT100*Translations: ... 等等
按下特殊功能鍵 F1,你將看到指定的字串成功的 入,但並未包含新列字元
(newline) ,你可以用一點語法的技巧來克服它,像:
xterm*VT100*Translations: #override(contd.)
F1: string("rm core *.tmp")string(0xd)
這解釋了以下兩點:
1. string()的作用和它的引數相關。你可以直接輸入本文 (例如 string(lpq))
,但如果本文包含空白或非字母字元,則必需在本文前後加上雙引號。
如果引數是以 "0X" 開頭,則將其後解釋為十六進位,並 入相對的
ASCII 字元。(例如,0xd是RETURN)
2. 在你指定此功能時可結合一個以上的作用,在上例,我們用到 string()
作用兩次,如果我們知道其它的作用,我們也一樣可以系結起來。
定義許多的轉譯在一起
你可以根據需求在一個表中定義許多的轉譯。假設,我們在前面的轉譯中增加
系結:
當我按下這個鍵時... 我希 這個字串被輸入
F2 lpq-Plpa3
對此的轉譯為:
F2: string("lpq-Plpa3")string(0xd)
所以可以將本列加入前面的表中。但是轉譯管理器的格式規則告訴我們必需將
兩個轉譯以 "\n" 分開且獨立成為一列:
xterm*VT100*Translations: #override(contd.)
F1: string("rm core *.tmp")sting(0xd) \n(cond.)
F2: string("lpq-Plpa3")string(0xd)
以上的形式將造成管理上的困難,你可以藉著包含 "隱藏的新列字元" 來使它
具可讀性一些: (新列字元以倒斜線 "\"處理)
xterm*VT100*Translations: #override\n\
F1: string("rm core *.tmp")sting(0xd)\n\
F2: string("lpq-Plpa3")string(0xd)
你可以放置任意多個你所需的 "隱藏的新列字元" , 且幾 在任何地方均可,
它們只是被忽略而已。 (只要和轉譯管理器相關,甚至你每隔一個單字便使用
一個也沒關系。但千萬不要在一個規格的 resource 特徵部份使用它們,它們
無法被resource manager解釋,也沒有相同的效果。) 如果你感覺有些混淆,
不用擔心。簡單地說,resource結構需要的是要在一列中的一個resource規格
的 "值" 的部份,而轉譯管理器以分開的列來分開 (也就是以\n終結),而使用
者剛好以每一個實際分開的列代表一個意義以增加可讀性,所以規則很簡單:
在除了最後一列的每一個轉譯列均加上一個 "\n\"。
17.1.2 轉譯可系結許多型式的作用
上述的 xterm范例,展示了如何能夠當你按下一個鍵時, 入任意的字串。但
轉譯結構的功能比這更多 -- 它可以系結任何widget所提供的作用到按鍵,讓
我們詳細一點地看一下這些作用。
前述的例子,我們在 xterm的 VT100 widget完成了鍵F1和F2在 string()
上的對應。我們將仍以 xterm為例,說明更多的作用。
查閱xterm 的指南頁,在標題KEY TRANSLATIONS 和 KEY/BUTTON BINDINGS
你將發現列有數個作用。我們將定義一個轉譯對應鍵F3到insert-selection()
作用之上,所以我們可以用鍵盤來取代滑鼠,將先前 "剪"下的本文 "貼"出。
指南頁告訴我們此作用需要一個引數,從列出的預設系結,我們可以看出預設
的 "剪貼" 結構為使用 CUT_BUFFER0, 所以我們將CUT_BUFFER0當作引數。我們
的resource規格是:
xterm*VT100*Translations: #override\n\
F3: insert-selection(CUT_BUFFER0)
到目前為止,這只是一點小小的便利。然而,假定說你花了許多時間在本文文
件上工作,你用 tbl格式化,你用 nroff在螢幕上預視 (preview)它們,用
troff 排版,且將輸出送到你的一個用過濾器 (filter) 為tr2printer的印表
機上。設定轉譯為:
xterm*VT100*Translations: #override\n\
F3: string("ed") insert-selection(CUT_BUFFER0)\
string(0xd)\n\
F4: string("tbl") insert-selection(CUT_BUFFER0)\
string(" nroff -man") string(0xd)\n\
F5: string("tbl") insert-selection(CUT_BUFFER0)\
string(" troff -man -t tr2printer") string(0dx)
xterm 會確定這些轉譯是以xrdb自資料庫載入或是在一個resource檔案中,並
加以處理。現在當你啟始xterm,用滑鼠 "剪"取你所需的工作的檔案名稱。接
下來,便可按F3鍵編輯它,按F4鍵預視它,和按F5鍵在硬拷貝上排版它。
更多的widget作用范例 -- xbiff
查閱xbiff 的指南頁:在ACTIONS 的標題下,你將看到Mailbox widget所支援
作用的名單。它惟一預設的轉譯為當你按下任何按鈕時降下信件 (mail)的旗幟
(flag)(作用unset())。我們將設定轉譯讓你以鍵盤來運用這些作用,將這些作
用對應到 "?" 和 "UP" "DOWN"兩個方向鍵如下:
? check() 有新的信件嗎?
UP set() 升起信件的旗幟
DOWN unset() 降下信件的旗幟
以下是相關的轉譯表:
xbiff*Mailbox*Translations: #override\n\
?: check()\n\
Down: unset()\n\
Up: set()
以此測試之:用xrdb從你的resource資料庫載入這些設定,然後啟動xbiff ,
將指標移到視窗內。重復地按下Up和Down游標控制鍵以升
Down: unset()\n\
Up: set()
以此測試之:用xrdb從你的resource資料庫載入這些設定,然後啟動xbiff ,
將指標移到視窗內。重復地按下Up和Down游標控制鍵以升