打印

X WINDOWS 系统使用指南

X WINDOWS 系统使用指南

BBS水木清华站∶精华区
X  WINDOWS  系统使用指南

前言

目录

本书导读

第壹部  系统概观

第1章  使用者对X WINDOWS系统的概观
 
  1.1 X有什麽特点?
  1.2 什麽是视窗系统?
  1.3 X简史
  1.4 X的成品
  1.5 MIT 发行的X

第2章  从基本系统模式概观X

  2.1 X的基本元素
  2.2 Server和Client如何交谈
  2.3 X的网路风貌
  2.4 摘要

第3章  从使用者介面的面貌概观X

  3.1 管理介面:视窗管理器
  3.2 应用程式介面和工具箱
  3.3 其它的系统面貌
  3.4 结论


第贰部 使用X系统

第4章 术语和符号

  4.1 术语
  4.2 符号
  4.3 本书范例的场景
  4.4 本书使用的工作站架构

第5章 启动和关闭退出X

  5.1 启动X
  5.2 如何执行一些X程式
  5.3 关闭X
  5.4 总结

第6章  视窗管理器基础  -- uwm

  6.1 什麽是视窗管理器
  6.2 启动 uwm
  6.3 基本视窗操作 -- uwm 的选单
  6.4 移动视窗
  6.5 重定视窗大小
  6.6 建立新视窗
  6.7 管理你的萤幕空间
  6.8 中止应用程式视窗
  6.9 叫用 uwm选单的其它方式
  6.10  摘要

第7章  使用X的网路设备

  7.1 指定一个远方终端机 -- -display  选项
  7.2 实际使用远方的显示器
  7.3 控制存取你的显示器 -- xhost
  7.4 总结

第8章 终端机模拟器 - 细说 xterm

  8.1 选择 xterm 功能 - 选单与命令列选项
  8.2 卷动 xterm 的萤幕
  8.3 记录你与终端机的交谈过程 - 写记录 (logging)
  8.4 剪与贴本文
  8.5 使用 Tektronix 模拟功能
  8.6 使用不同字型
  8.7 使用色彩 (colour)
  8.8 其他 xterm 选项
  8.9 设定终端机键盘
  8.10 结论

第9章 方便的程式和视窗相关的工具

  9.1 方便的程式
  9.2 储存, 显示与列印萤幕影像
  9.3 结论/摘要

第10章 使用X的应用程式

  10.1 文字编辑器 - Xedit
  10.2 读取指南页 (Manual Pages) - xman
  10.3 邮件/讯息处理系统 - xmh
  10.4 结论/摘要

第11章 示范与游戏程式

  11.1 找出通过随机迷宫的路径 - maze
  11.2 担任指标的大眼睛 - xeyes
  11.3 智慧盘游戏 - puzzle
  11.4 列印一个大X语标 - xlogo
  11.5 跳动的多面体 - ico
  11.6 动态几何图样 - muncher 与 plaid
  11.7 结论


第参部 定制系统

第12章  资讯与状态程式

12.1  列出你的Xserver的特徵 -- xdpyinfo
12.2  获取有关视窗的资讯
12.3  观察X的事件 -- xev
12.4  结论

第13章  使用X的字型和色彩

13.1  字型初步
13.2  字型如何命名
13.3  观察特定字型的内容 -- xfd
13.4  如何储存字型及存在何处
13.5  范例:增加新字型至你的server
13.6  使用X的色彩
13.7  结论

第14章  定义和使用位元映像

14.1  系统位元映像程式馆
14.2  交谈式地编辑一个位元映像 -- bitmap
14.3  编辑位元映像其它的方法
14.4  定制你的根视窗 -- xsetroot
14.5  总结

第15章  定义应用程式的预设选项 -- Resources

15.1  什麽是resources ?
15.2  X Toolkit
15.3  Resources 如何被管理 -- Resource管理器
15.4  Resources 的型态----如何指定值
15.5  结论

第16章  实际的使用Resource

16.1  在何处储存resource的预设值
16.2  在Server上储存预设值 -- xrdb
16.3  一些常见的错误和如何修正它们
16.4  结论

第17章  定制你的键盘和滑鼠 -- 转译

17.1 实际使用转译
17.2 转译 -- 格式和规则
17.3 在转译规格中常见的问题
17.4 结论

第18章  键盘和滑鼠 -- 对应和参数

18.1 键盘和滑鼠对应 -- xmodmap
18.2 键盘和滑鼠参数设定 -- xset
18.3 结论

第19章  进一步介绍 uwm 和如何定制它

19.1 uwm 的新特色
19.2 定制uwm
19.3 结论

第20章  全部放在一起 -- xdm

20.1 我们需要做些什麽
20.2 xdm -- X显示管理器(X Display Manager)的概观
20.3 有关xdm 的更多
20.4  我们自己的uwm 建构
20.5  结论


第肆部 附录

附录A 文件指引

A.1 本发行版所提供手册
A.2 包括在本发行版本内的其它文件
A.3 包括在本发行版本内的其他资讯来源

附录B 安装X

B.1 安装X的提示
B.2 建立本发行版

附录C  本发行版的内容 -- MIT Core Distribution

C.1 核心版

附录D  本发行版的内容 -- 使用者贡献的软体

D.1 使用者贡献的版本

附录E  如何取得X

E.1 在美国
E.2 在欧洲
E.3 如何取得 GNU Emacs

附录F  X网路与电子邮件服务

F.1 xpert 邮件竞技场
F.2 xstuff Server
F.3 FTP 与其他网路 Server

附录G  需要从你的系统管理者得到的资讯



图的目录

图 1 - 1  重叠的视窗
图 2 - 1  X的基础成员
图 2 - 2  xlib函数馆的功能
图 2 - 3  在相同机器上的client和server
图 2 - 4  在不同机器上的client和server
图 2 - 5  使用X网路典型的面貌
图 2 - 6  已存在的显示器可使用在新的 CPU上的client
图 2 - 7  被已存在的client程式使用的新显示器
图 2 - 8  执行远方的一个非X的信件程式
图 3 - 1  在萤幕上重叠的视窗
图 3 - 2  视窗的树状结构阶层
图 3 - 3  受父视窗限制的子视窗
图 3 - 4  选单比用它的应用视窗还大
图 4 - 1  视窗的元素
图 4 - 2  滑鼠拖拽的图形表示法
图 5 - 1  大的 "X" 游标
图 5 - 2  xterm 的本文游标
图 5 - 3  系统启动的画面
图 5 - 4  xclock 启动後的画面
图 5 - 5  xkill的覆盖性的方形游标
图 5 - 6  xcalc 桌上型计算器
图 6 - 1  uwm 的 WindowOps 选单
图 6 - 2  手指形游标
图 6 - 3  十字箭头形游标
图 6 - 4  移动视窗示意图
图 6 - 5  重定视窗大小操作时, 显示视窗大小的长方盒
图 6 - 6  重定视窗大小示意图
图 6 - 7  "左上角" 形游标
图 6 - 8  当建立新视窗时, 出现视窗名称和大小的长方盒
图 6 - 9  相互重叠的视窗
图 6 - 10 正常的xterm 的表徵图
图 6 - 11 一个由twn 视窗管理器所建立含有控制棒的视窗
图 6 - 12 由rtl 视窗管理器控制的萤幕
图 7 - 1  远方的 client 显示器对本地 server 架构图
图 8 - 1 xterm 的三个选单
图 8 - 2 具有卷动棒的 xterm 视窗
图 8 - 3 游标在卷动区的不同形状
图 8 - 4 在一个视窗内卷动本文
图 8 - 5 "剪" 操作中被选择的文字列
图 8 - 6 以字元, 字与列 "剪" 文字
图 8 - 7 xterm 的正常视窗与 Tektronix 视窗
图 8 - 8 被用於 xterm 的 Tektronix 视窗内的闹钟形指标
图 8 - 9 具有粗体与正常字型的xterm 视窗
图 9 - 1 数字型时钟
图 9 - 2 具有钻石形秒针的指针型时钟
图 9 - 3 类比的 xcalc 是一个计算尺
图 9 - 4 反波兰记数法 xcalc 计算器
图 9 - 5 xcalc 表徵图
图 9 - 6 xload 的正常视窗与表徵图视窗
图 9 - 7 xbiff 邮件监视视窗的两种状态
图 9 - 8 十字线形游标
图 9 - 9 一个被重叠视窗的倾印结果
图 10 - 1 xedit 文字编辑器
图 10 - 2 xedit 的插入档案选择视窗
图 10 - 3 xman 的主选择项视窗
图 10 - 4 xman 求助视窗
图 10 - 5 xman 求助与指南页视窗选单
图 10 - 6 xman 的指南书章节选单
图 10 - 7 xman 的指南页进入点目录
图 10 - 8 显示一个指南页的 xman 视窗
图 10 - 9 xman 搜寻视窗
图 10 - 10 xman 的三个不同表徵图
图 10 - 11 同时显示目录与指南页的 xman 视窗
图 10 - 12 xmh 邮件处理视窗
图 11 - 1 迷宫程式
图 11 - 2 xeyes 程式
图 11 - 3 智慧盘游戏
图 11 - 4 xlogo 程式
图 11 - 5 ico 程式
图 11 - 6 muncher 与 plaid 程式
图 12 - 1 典型的xdpyinfo工具程式的输出
图 12 - 2 三个xlswins 的输出
图 12 - 3 典型的xwininfo输出
图 12 - 4 一个应用视窗的性质表列
图 12 - 5 根视窗的性质表列
图 12 - 6 字型的性质表列
图 12 - 7 xev 视窗
图 12 - 8 xev 的输出
图 13 - 1 典型的字型目录列表
图 13 - 2 字型的展示
图 14 - 1 位元映像编辑器
图 14 - 2 一个游标的”热点”
图 14 - 3 字元图格式的位元映像
图 14 - 4 设定 mensetmanus 位元映像为背景图样的根视窗
图 14 - 5 游标及其遮罩的位元映像
图 15 - 1 xedit中物件(widget)的阶层
图 16 - 1 利用前处理器命令的Resource档案
图 17 - 1 xev 显示键名称的输出
图 18 - 1 列出键盘对应的范例
图 18 - 1 列出修饰键对应的范例
图 18 - 1 列出指标对应的范例
图 19 - 1 预设的 .uwmrc 建构档
图 20 - 1 xdm 的 authentication widget
图 20 - 2 程式/usr/lib/X11/xdm/our-session
图 20 - 3 $HOME/.Xsession 程式
图 20 - 4 我们初始化後的萤幕
图 20 - 5 在$HOME/.uwmrc的主机选单
图 20 - 6 在$HOME/.uwmrc中其它的选单
图 20 - 7 在$HOME/.uwmrc中系结和参数的设定

======

X  WINDOWS  系统使用指南

第壹部  系统概观


第1章  使用者对X WINDOWS系统的概观


    X  Window System 是一套在各种位元映像显示器 (bitmapped
dispalys) 上具有极大可携性 (portable) 的视窗系统 (window system),
它是由麻省理工学院 (MIT)所发展出来. X Windows System ( 本书以後部
份简称为X) 可在许多系统上执行. 由於它和生产者无关、具可携性、对彩
色掌握的多样性及对网路之间的操作透通性 (operate transparently), 使
得X成为一个工业的标准. 由於原始程式可自由使用, 所以它也是一个优良
的研究媒介.

    X视窗系统是一个让程式设计师发展可携性图形使用者介面的工业软体
标准, X最重要的特徵之一是它独特的与设备无关结构.任何硬体只要提供
X协定 (Protocol),便可以执行应用程式显示一群包含图文的视窗,而毋需
重新编译和连结.这种与设备无关的特性,使得只要是根据X标准所发展的
应用程式,均可在不同的环境下如大型电脑,工作站,个人电脑上执行,因
而奠定了X成为工业标准的地位.

    X可以在一些 UNIX 系统的电脑上执行, 如 Alliant, Apollo, DEC, IBM,
Hewlett-Packard, Sun等, 也可在 DEC的 VAX/VMS, MS-DOS及一些其它的系
统上执行. 其它的一些厂商如 AT&T, Adobe, Control Data, Data General
, Fujitsu, Prime, Siemens, Silicon Graphics, Sony, Texas Instruments,
Wang, Xerox 均曾表示支援X.



1.1 X有什麽特点?

  以下四个特徵说明了X大部分的能力及其受大众欢迎的原因:

  .X具有网路透通性(Network Transparent): 透过网路,应用程式在
      其他机器输出显示就和在自己机器上一样容易.此种通讯架构和网路
      上另一端的它种机器完全语言无关和机器无关,甚至不需相同的作业
      系统.总结一句,程式可以在另一种不同的显示器型态下执行而毋需
      重新编译(re-compilation)和重新连结(re-linking).

  .可支援许多不同风格的使用者介面,管理视窗的功能例如视窗的摆放
      ,大小及显示顺序等等并不包含於系统中,而是由应用程式来控制,
      因此可轻易的更换.不同风格的介面关系於不同的应用程式,利如卷
      动视窗中的文字和选择视窗中的一个物体,彼此间不会互相限制.

  .X不是电脑作业系统的一部分:对作业系统而言,X只是一个应用程
   式而已,因此,X很容易在不同的系统上装设.

  .视窗是阶层性的 (hierarchical): 应用程式可以直接利用视窗系统
      已有的设施 (facilities) 便可满足大部分的需求,而毋需藉助其他
   的输入或控制结构 (mechanisms). (例如:选单(menu)可利用一个分
      支的子视窗来产生.)

所有的特徵均会在以下的章节中作进一步详述.



1.2 什麽是视窗系统?

    本节讨论一般视窗系统的一些基本概念, X视为其中一个特例, 如果你
已熟悉其它的视窗系统, 本节内容仅需快速浏览即可.

    X是一个在位元映像显示萤幕上建立和管理视窗的系统, 它可以在拥有
位元映像显示器、键盘和一些可以指示萤幕上特定位置或物件的装置的工作
站或他种型式拥有位元映像显示器的终端机上执行. X把指示位置的装置叫
做指标 (pointer), 通常为滑鼠(mouse),X支援现今电脑上常见的视窗使用
者介面.

    使用视窗系统常常拿来和在普通办公桌上的工作比较, 你的桌面上通常
放了一些纸, 信件和手边相关的工作, 一些有用的工具 (如时钟, 日历, 计
算器等),当进行到工作的另一个部份, 你会从新安排桌面上的纸, 你可能把
工具集中放在一起, 也可能不时参考桌上仍然看得到的纸的内容, 过了一阵
子, 你可能把其中的一些资料暂时摆到一边, 或者通通从桌面上移走.

    上述是一个人的工作模式, 把它搬到电脑, 如果能提供相同的功能是很
理想的, 很不幸地, 老式的终端机或 CRT限制了你一次只能在萤幕上做一件
工作, 而且只能看见一小部份的文字资料 (通常为24行),图形的工作就更别
提了, 现在视窗系统试图克服这点, 通常它提供你一个较大的萤幕, 允许你
同时看到几件工作项目, 可以显示图形, 甚至有彩色.

    X便是依照上述视窗的工作模式发展出来的, 在X的环境下、一个视窗
是萤幕上的一块长方形区域, 且平行於萤幕的边, 通常, 每一个视窗 (注1)
被一个独立的应用程式所专用, 数个应用程式可以" 同时" 在它自己所拥有
的视窗上显示输出结果,X允许视窗重叠. 见图 1 - 1

注 1: 严格地说, 应该说成" 一个最高层 (top level)的视窗",因为X允许
      视窗有阶层, 所以, 一个典型的应用视窗可以包含许多子视窗
      (sub-window)分别用来做控制、输入及显示等功能.

               ┌——————————————┐
               │   page 6.  Fig 1.2         │
               │                            │
               │                            │
               │                            │
               │                            │
               │ 图 1 - 1  重叠的视窗       │
               └——————————————┘

    但即使视窗的部份或全部被其它视窗遮盖, 应用程式仍然可以对它自己
所拥有的视窗做输出. 设备程式 (facilities) 提供在萤幕上移动视窗、改
变视窗大小、把视窗放在最上一层或最下一层等功能。即便是视窗可以重叠
, 为了方便而在同一萤幕开了许多视窗仍然非常费时, 因此, 就如同其它的
视窗系统一般,X提供表徵图 (icon), 我们在萤幕上用一个表徵图代表一个
应用视窗, 当我们对应用视窗表徵图化 (iconify)後, 视窗被从视窗上移走
, 代之以表徵图, 而空出了较多的萤幕空间, 相反的动作为解除表徵图化 (
de-iconify),也就是以原先的视窗取代表徵图。

    一些便利的功能, 例如时钟或日历, 并非内建於系统, 而是由许多小的
应用程式所提供.

    对於输出, X提供了许多写文字和画图形到视窗上的功能选择, 许多种
的字型 (FONTS)可以非常容易并且做一致性的处理, 有许多图形的结构和绘
图的基本方法, 例如点, 线, 弧线, 区域 (areas)被提供, 色彩的掌握更是
丰富, 这些复杂的部份对使用者而言是隐藏起来的, 使用者可以简单和方便
的使用它们,例如, 在应用上, 你可以用 "*times-bold-i*"表示要使用加倍
粗的斜体字型 (italic),你需要使用彩色时, 你只要用日常的名称, 例如
"yellow(黄色)" 或 "navy blue (天蓝色)".

    对於输入功能的提供, X也是多样化的, X可以连结不同形式的键盘,
如传统的QWERTY键盘或Dvorak Style键盘, 或者是不同国家的特殊规定. 处
理使用者介面是输入功能很重要的一个部份, 键盘和滑鼠的指令告诉系统如
何架构一个视窗和处理视窗的内容.

    由於X的视窗处理功能并非内建於系统, 而是建在使用者层次, 因此容
易於修改或更换, 所以X能提供不同形态的使用者介面。换个角度来说,使
用者介面所必需具有的弹性几乎完全可由X独立提供.



1.3 X简史

    X於1984年在麻省理工学院 (MIT)电脑科学研究室开始发展, 当时 Bob
Scheifler 正在发展分散式系统 (distributed system),同一时间 DEC公司
的 Jim Gettys 正在麻省理工学院做 Athena 计画的一部份, 两个计画都需
要一个相同的东西 ------ 一套在 UNIX 机器上优良的视窗系统. 因此合作
关系开始展开, 他们从史丹佛 (Stanford) 大学得到了一套叫做W的实验性
视窗系统, 因为是根据W视窗系统的基础开始发展,当发展到了足以和原先
系统有明显区别时,他们把这个新系统叫做X.

    工作持续地进行, 新的版本 (version)不断地产生 (当软体和前一版不
相容时, 新的版本便产生了),在1985年中期, 任何人只要付版权费便可使用
X的基本政策被决定. 以下为一些最近的记事:

    第10版: 1985年底. 直到此时, 在 MIT以外的人和组织, 才开始对X有
        实质的贡献.

    第一套商业化的X产品: DEC 於 1986 年 1月推出 VAXstation-II/GPX.

    第10版第 3次发行: 1986年 2月. 从此时起, X开始流传於世, 人们把
        它移植到许多新的系统上.

    第10版第 4次发行: 1986年11月.

    第一次X技术会议: 1987年 1月於 MIT.

在1986年间, 第10版X无法满足所有的需求已非常明显, MIT 和 DEC便从事於
完整协定 (protocal) 的重新设计, 这就是X第11版.

    第11版第 1次发行: 1987年 9月.

    X协会成立: MIT X协会成立, 目的是为了研究发展及控制标准, 目前有
        30个以上的机构加入.

    第二次X技术会议: 1988年 1月.

    第11版第 2次发行: 1988年 3月.

    第11版第 3次发行: 1988年10月.



1.4 X的成品

    严格地说, X视窗系统并不是一个软体, 而是一个协定 (protocal),这
个协定定义一个系统成品所必需具备的功能 (就如同 TCP/IP, DECnet 或
IBM的 SNA,这些也都是协定, 定义软体所应具备的功能).任何系统能满足此
协定及符合X协会其他的规范, 便可称为X.

    简单地说, 从现在起本书不再区分协定和成品的分别, 我们提到X, 意
指一个完整且适当的系统成品.



1.5 MIT 发行的X

    MIT 所发行的X可以提供许多厂牌的电脑, 目前的版本 (第11版第 3次
发行) 支援以下的系统:

    . Apple A/UX
    . Apollo Domain/IX
    . 4.3 + tahoe
    . Digital Equipment Coporation Ultrix
    . Hewlett Packard HP-UX
    . IBM AOS
    . Sun Mircosystems SunOS

此外尚有更多的商业化产品.

    当系统一直在发展, 而且有更多的人使用它, 由第三集团(third party)
发展的软体逐渐增加, 而使得系统版本一分为二:

    . core版 -- 软体由MIT X协会提供.

    . corelib 版 -- 软体由使用者或第三集团提供.

为了方便, core和corelib 软体储存在不同的磁带上发行.

    本书说明几乎以core版为主, 偶而因core版没有提供的功能或大家较有
兴趣的部份, 会参考到corelib 版本.


1.5.1 MIT 版包含了什麽

    这个版本包含了文件说明, 原始码, 建构档 (configuration file) 和
公用程式 (utilities)和其它一些建立完整工作系统所必需的东面,(没有任
何目的档或二进位档提供, 系统必需由原始码建立),在此我们只讨论从使用
者观点看这个系统, 所以只描述那些视窗系统程式本身或一些使用者所需的
工具程式, 省略装设公用程式、建构工具程式、本版需知等, 这些东西可参
考附录.

    core版的程式可分为以下几类:

    1.  X视窗系统本身的程式.

    2.  使用视窗系统必备的工具和设备程式:

        . 日常的视窗相关功能的工具程式 (例如将视窗内容倾印至列表机)。

        . 一些你常常保持在 "案头" (desktop) 的便利程式 (例如时钟,
          日历).
    3.  从视窗环境获得效益的一般应用程式.

    4.  展示(Demo)程式和游戏程式.

    5.  资讯和状态报告程式.

    6.  定制 (customise)你自己的环境的工具程式.

    我们将在以下的章节讨论它们.


1.5.2 系统程式

    以下的程式包含了所有基本系统的相关程式.

    X -  显示server -- 这个软体控制了你的工作站的键盘、滑鼠和萤幕.
这是X的心脏, 此程式可以建立、去掉视窗, 实际的应其它 client 程式的
Request (需求)做写 (write)和画(draw)的动作.

    这个server程式在各种硬体上有不同的程式提供, 例如:

        Xapollo - 针对Apollo显示器.

        Xhp - 针对Hp 9000/300 的Topcat显示器.

        Xibm -  针对IBM 的APA16 和Megapel 显示器.

        Xmacll -  针对Apple 的Macintosh II.

        Xplx -  针对Parallax图形控制器.

        Xqdss - 针对DEC 的GPX 显示器 (VAXstation II/GPX).

        Xqvss - 针对DEC 的QVSS显示器.

        Xsun -  针对Sun/2, Sun/3, Sun/4 和Sun/386i工作站.


    Xinit - 初始(initialization)程式, 启动系统和设定Server执行.

    Xdm - X显示管理器(display manager),一个提供便利和弹性地启动系统
          , 使系统启动成个别需求的程式, 可以和 Xinit两者择一.

    Uwm - X视窗管理器(Window Manager), 此程式决定如何管理你的 "案头"、
          移动视窗、重定视窗大小等等, 你可以利用选单结合滑鼠的按钮
          或键盘完成视窗操作.

    只有Server程式是绝对必需的, 不需其它的程式, 你就可以在X系统上
跑其它的应用程式 (虽然笨了一点). (Xinit 等程式可由其它相同功能程式
替代.)

    以上程式包含了视窗系统, 但除了在视窗上移动游标外, 什麽事也不能
做. 因此实际上, 你需要更多的公用程式和应用程式.


1.5.3 视窗系统公用程式

    以下的工具程式并不是视窗系统的一部份, 但它们是你要更方便的使用
系统或利用系统做更多的事所不可或缺的, 它们分为以下两个部份:

    1.  视窗系统操作常用工具程式

        只要你用视窗系统代替一般的电脑终端机, 这些程式几乎是天天需
        要的:

        xterm - X终端机模拟器 (terminal emulator), 你的系统内大多
                数的程式并非特别为使用视窗系统设计. 举例来说, 一些
                最普通的系统程式 -- 列出档案目录, 编辑器, 编译器等,
                它们在普通的终端机可以正常的执行, 可是它们如何在连
                视窗系统是什麽都不知道的情况下, 在X下操作? Xterm
                就是建立一个X的视窗, 且允许这些普通的 "笨哑终端机
                (dumb terminal)"程式能够在这个视窗中执行的工具程式.
                这些普通程式会认为它们是在 "真的" 终端机上执行. 当
                然, 你也可以用xterm 去启动其它的X程式而并非一定是
                那些普通程式.

        xhost - 让你控制网路上那些被允许存取你的显示萤幕的其他主机。

        xkill - 一个可杀掉不想要之应用程式的工具程式。

        xwd - 将你视窗内目前的影像倾印 (dump) 到一个档案中,使得你可
              以在稍後重建这个视窗、列印它或做一些你想做的事。

        xpr - 将先前 xwd所抓取 (capture)的视窗影像转换成适合硬拷贝
              (hardcopy)印出的格式.

        xdpr - 结合了 xwd和 xpr,允许你在一个步骤就印出视窗的内容.

        xmag - 将萤幕上被选取的一部份影像加以放大。

        xwud - 将先前 xwd所抓取的视窗影像重新显示於萤幕上。

        x10tox11 - 将能在第10版X执行的程式转换成可在第11版执行。

        xrefresh - 更新 (refresh)显示, 将某些或全部的视窗全部重画
               一遍。

    2.  便利的程式

        xclock - 一个指针或数字型的时钟。

        xclac - 一个计算器,可模拟科学工程型的计算器。

        xload - 用累计图 (histogram)来显示目前机器的负载分布。

        xbiff - X版的 biff,信件到达告知 (barfs if mail arrives) 程
            式,xbiff 会显示一个信箱的表徵图,当信箱上的旗子升起时,
            表示有你的信。


1.5.4 一般应用和工具程式

    这些程式不是直接和视窗系统相关,但视窗系统环境使它们更有效益。

    xedit - 一个文字编辑器,你可以用选单或键盘下命令,也可以用指标指
            定位置或一段文字。

    xman - 一个说明书或系统文件的浏览器。

    xmh - 一个信件管理程式。


1.5.5 示范和游戏程式

    这些程式展示了X图形和彩色的能力, 在你开始使用系统时, 它们是一
个进入状况良好的起点.

    ico - 显示一个二十面体 (或其它多面体) 在视窗内进行弹性碰撞运动.

    maze -  以乱数建立一个迷宫并找出它的解法.

    muncher - 在视窗上描绘大量动态的图样 (patterns).

    plaid - 在视窗上画一些持续变化的花格子图形.

    xlogo - 在视窗上印一个X的字形.

    puzzle -  智慧盘, 在一 4x4方块盘上, 移动编号 1 - 15 的小方块,
              以排成特定型态的游戏.


1.5.6 资讯和状态程式

    以下的程式提供你有关於你的视窗系统的资讯和状态, 你将会常利用它
和你自己的工具程式连结在一起.

    xfd - 在视窗内显示一个被X指定的字型,且可选择性地提供更多有关
          此字型的资讯.

    xlsfonts -  X字型的目录程式, 告诉你一个显示器上有那些字型可供
          使用.

    showsnf - 显示上server上SNF(Server Natural Format,你Server上原
          有的格式) 格式对某一种字型的细节.

    xwininf - 显示某个特定视窗的资讯, 如大小, 位置及其它特徵.

    xlswins - 列出系统内所有的视窗, 并可选择性地列出每个视窗的一些
          细节.

    xprop - 显示视窗的性质 (properties) 和字型.

    xdpyinfo - 提供你的显示器及控制它的 server之细节.

    xev - 印出和视窗相关所有X "事件(event)"的细节, 用来侦错(diagnostic)
          或给有经验的人使用的工具程式.


1.5.7 定制适合你的系统之工具程式

    一开始你可能不会用这些程式, 但过了一段时间, 你可能发现你必需修
改一下系统, 例如想使用较大的预设字型, 视窗边框换成自己喜欢的颜色等,
用以下的程式, 可以使你的工作环境更加适合你.

    xset -- 允许依照你的喜好设定显示特性, 你可以设定一个键使它有效或
            无效, 调整警告铃的音量, 指定字型从何处取得等.

    xsetroot -  你可以选择你显示萤幕背景的外观, 当你滑鼠的指标不在任
            何应用视窗内时, 你可以改变使用的颜色或图样或游标.

    xmodmap - 显示键盘的对应 (mapping), 也就是按什麽键对到什麽字元,
            可以允许你修改成适合你的对应, 通常用来设定一些特殊键 (如
            META, SHIFT-LOCK等) 和函数键, 但你可以视需要设定任何键.

    bitmap -  让你建立和编辑位元映像的程式, 例如用来改变cursor的式样,
            编辑表徵图, 视窗的背景图样等等.

    xrdb -  让你在资料库中显示或改变你喜爱的色彩或字型等等, 稍後可被
            应用程式使用到. 也就是说, 你可以设定一些预设的特性, 让这
            些特性被所有或只有特定的应用程式用来当作预设特性.

    bdftosnf -  将一种字型从BDF("bitmap distribution format"一种可携
            的格式)格式转成你Server 原有的SNF 格式.

=====

第2章  从基本系统模式概观X

    在本章和下一章我们将描述X的基本架构,并介绍许多基础的观念,其目
的在於对你稍後使用系统时能有一个了解,你将会洞悉系统程式做些什麽和如
何做,如此你将更快和更有效率的使用系统,我们也会指出系统外在的利益,
以及使用系统对你的影响。

    本章描述系统的基本元素,以及它们彼此之间如何交谈(interact),下一
章描述系统其它的面貌,特别是使用者介面。此章包含了许多新观念,你不妨
先很快的浏览这两章後,开始实际地使用它,当你对系统比较有感觉之後,再
回头来复习,这样比较容易了解。



2.1 X的基本元素

    X不像早期的视窗系统,把一堆同类软体集中在一起,而是由三个相关的
部份组合起来。

    1.  一个"server"(供应者):是控制实际显示器和输入装置的程式。

    2.  "Client" (顾客) 程式:需藉著server在指定的视窗中完成特定的
        操作。

    3.  一个 "通讯通道(communication channel)":client和server用来作
        为彼此交谈之用。

    基本的"server","client"和 "通讯通道" 的关系图如图2-1 。

            ┌—————————————┐
            │   p16       fig 2.1      │
            │                          │
            │  图 2-1  X的基础成员    │
            └—————————————┘

底下我们描述一下这三个部份。

2.1.1 Server

    Server是控制实际显示器和它的输入装置 (键盘和滑鼠或其它指示装置)
的软体,server可以建立视窗、在视窗中画图形影像和文字、回应client程式
的 "需求" (requests),它不会自己动作,只有在client程式提出需求後才完
成动作。

    每一个显示器只有一个唯一的server。server一般由系统的供应厂商提供
,通常无法被使用者修改。针对作业系统而言,server只是一个普通的使用者
程式而已,因此很容易换一个新的版本,或许甚至是由第三集团提供的原始程
式 (注1) 。

注1:这是Unix系统上的情况,有些供应厂商会选择将server的部份或全部放
      在作业系统核心(kernel)。


2.1.2 Client

    Client是使用系统视窗功能的一些应用程式。把X下的应用程式称作
"client",原因是因为它是server的 "顾客" :它要求server应它的需求
完成特定的动作。

Client无法直接影响视窗或显示,它们只能送一个 "需求" (request) 给
server,让server来完成它们的需求。典型的 "需求" 通常是: "在 XYZ视窗
中写一列 'Hello, world' 的字串" ,或 "在 CDE视窗中用这种颜色从 A点到
B点画一条直线" 。

    当然,对视窗操作提 "需求" 只是client程式的一部份,其它的部份是那
些让使用者执行的程式部份。例如:编辑文字、画一个系统的工程图、执行计
算表的计算等等。一般来说,client程式的这个部份和视窗是独立的,对於视
窗几乎不需要知道什麽,通常 (特别是指大型的标准绘图套装软体,统计套装
软体等) 应用程式对许多的输出装置具有输出的能力。在X视窗上的显示只是
client程式许多输出格式中的一种,所以,client程式中和X相关的部份在整
个程式中,只占了非常小的一部份。

    使用者可由不同的来源来使用client程式:一些是由系统提供的 (例如时
钟) ,一些来自於第三集团,一些是使用者为了特殊应用而撰写他自己的client
程式。


2.1.3 通讯通道

    X的第三个元素为通讯通道,client藉著它送 "需求" 给server,而server
藉著它回送状态 (status) 及一些其它的资讯 (information)。

    只要 client 和 server 都知道如何使用通道,通道的本身并不是很重要
,在系统或网路上支援通讯型态的需求是内建於系统基本的X视窗函数馆(library)
,所有和通讯型态有关的事都从函数馆独立出来,client和server之间的通讯
只要藉著使用这函数馆(在标准X版为xlib)即可,如图2-2 。

            ┌—————————————┐
            │   p17       fig 2.2      │
            │                          │
            │  图 2-2  xlib函数馆的功能│
            └—————————————┘

    总结来说,只要client程式利用函数馆,自然有能力用到所有可用的通讯
方法。

    Client和Server通讯大略分为两类,相对应於二种基本X系统的操作模式:

    1.  server和client在同一部电脑执行,则它们彼此均可使用机器上任何
        可用的方法做交互处理通讯(inter-process communication  
(简称IPC)),             见图2-3  
,在这种模式下,X可以像许多传统的视窗系统一样有效率
        的操作。

            ┌—————————————┐
            │   p18       fig 2.3      │
            │                          │
            │  图 2-3  在相同机器上的  │
            │          client和server  │
            └—————————————┘

    2.  client在一部机器上执行,显示器和server则在另一部机器上,则
        client和server的通讯必需透过网路利用彼此同意的协定(protocol)
        方可。目前,最常见的协定为TCP/IP和DECnet,但其它任何被提供的
        可信赖地协定亦可使用。图2-4 显示一个典型的Ethernet网路的通讯。

            ┌—————————————┐
            │   p18       fig 2.4      │
            │                          │
            │  图 2-4  在不同机器上的  │
            │          client和server  │
            └—————————————┘

        这种透过网路,使得应用程式的操作,如同在本地机器一样的能力称
        为网路透通性(network transparence),几乎是X独一无二的特性
        (注1)。这种特性使得它非常适合建立在有弹性地多目标混合机器
        网路上。

注1:有几种例如Sun Microsystems  的NEWS的视窗系统有使用到网路结构,
但没有一种被广泛地使用,而有超过一家以上的制造厂商使用它们。

    因为client和server完全独立,一种名之为X-terminal 的新型态显示器
被发展出来。简单的说,X-terminal 是一种除了能直接在上面执行X server
程式外,什麽也没有的工作站,它有键盘,滑鼠和萤幕,以及一些和网路互相
通讯的方法(所以在其它主机上的client可在它上面显示),但并没有档案系
统,也不提供一般目的 (general purpose)的程式,一般目的的程式需要在网
路上执行。


2.2 Server和Client如何交谈

    本节描述client和server互相通讯时,双方各传输些什麽。基本上,一个
client要求server去执行输出,输入则藉著 "事件" (event) 的通知由server
来掌握( "事件" :如按下键盘的键或滑鼠的按钮等等)。


2.2.1 Client送达server的东西;Output Handing (输出交予)

    当一个client要求server做一个动作,例如在一个指定的萤幕上建立一个特
殊特徵的视窗,或者在一个视窗中写一列文字串。这时client是藉著送 "需求"
(requests)到server上来达成。一个 "需求" 是一个被封装(package) 的简单
区块(block) ,区块包含一个 "操作码"(opcode) 来指示要执行何种操作,伴
随著一些引数(arguments) 提供更多的需求细节。例如:清除一个视窗内的一
个长方形区域,client会送一个16位元组(byte)的需求区块,来指定是哪一个
视窗,欲清除区域的左上角座标及区域的高和宽。

    这个格式有几个重要的特徵:

    . 需求区块的内容,和client与server在何种型态上的机器上执行完全无
关。一个client可以输出需求给在任何型式显示器上的任何X视窗server。需
求和语言、机器及作业系统均无关。

    . 每一个需求包含了视窗的细节和其它被使用的资源,对一个client送至
特定server的需求超过一种以上的连接方法,所以在网路架构上提供的视窗数
目没有限制。

    . 需求区块通常大小为20位元组左右,算是相当的小,因为需求是设定为
相当高阶的,(例如画一条线是指定两个端点而非记录一串萤幕上的点)通常
萤幕上被影响到的像素的数目往往是区块本身大小的十到一百倍,如此不会使
网路的负荷太重,网路的使用效率会非常的好(一般认为X的server和client
之间的传输是位元影像 (bitmaps)的观念是错误的)。


2.2.2 Server送达Client的东西;Input Handling (输入交予)

    Server也会利用通讯通道送资讯回client,这些资讯包括回应client需求
是否成功和告诉client有兴趣的特殊 "事件" ,这些 "事件" 包含的讯息类似
”视窗XYZ 的滑鼠左按钮被碰触”或”视窗ABC 已被重定大小等”。

    就像从client来的需求一般,server的回应也是一些和语言、机器、作业
系统无关的简单区块。

     "事件" 是X的基本功能,所有的键盘输入,滑鼠按钮输入和滑鼠移动都
是由 "事件" 来控制,尤有进者,client完全依赖 "事件" 才能获得那些一定
在系统发生的而它必需知道的资讯。我们将从一些普通的输入和移动功能著手
,实际了解 "事件" 是如何工作的:

键盘输入

    当你从键盘按下一个键,这个动作会被server查觉到,Server便送出一个
<Key Press> 的 "事件" 通知那些登记对这种情况有兴趣的应用程式。这种通
知有一些限制:不是通知目前被滑鼠指标指到的视窗,便是通知目前被指定接
受所有键盘输入的视窗。这种限制称之为设定键盘焦点(focus) 。

    当键被松开时(通常几乎是立刻),另外一个<Key Release> 的 "事件"
产生了,一般除了那些修饰键(例如SHIFT 或 CONTROL),很少的应用程式会
对松开键这个 "事件" 有兴趣。

    送到client的讯息区块告诉client它们是键盘 "事件" 内容的只是”编号
第几的键已被按下(或松开)”,不包含是不是ASCII 或EBCDIC字元及如何解
释等内容,而把这些留给client程式去处理,这种做法使得client程式看起来
似乎复杂,但是标准的xlib函数馆,有非常简单的副程式可供控制解释键盘 "
事件",而且通常预设成你所希望的键盘型式,换个角度来看,这种”软体”
的键盘字元相关方式允许了很大的弹性:在server这方面,对不同型式的键盘
均可以完全重新对应,在client这方面,每一个单独的键都”可程式化”,例
如按一个键即可以输入一串使用者特定的字串,或者完成一个特殊的功能等。

    稍後我们会再详细讨论,不过直到目前,这些将不会影响你使用系统,事
实上,对於X系统如何处理你按下一个”A ”键,并将它转换成一个ASCII 的
”A ”字元送到你的应用程式的这类事情,你不需要太关心。

关於指标位置的 "事件"

    client可以要求当萤幕上的指标进入或离开它所控制的视窗时被通知,这
种 "事件" ("<EnterWindow>" 和"<LeaveWindow>") 告诉client程式是进入或
离开视窗以及是哪一个视窗。

    当指标进入视窗时通常用类似”高亮度”视窗这一类的方式表式,有些应
用程式是改变视窗的边框(例如从灰到黑),有些则会改变颜色,用以强调你目
前正在处理这个应用程式(视窗)。

当一个视窗未被覆盖时 -- Exposure (曝光 "事件")

    X和大多数其它的视窗系统有一个很大的不同点,那就是client必需负责
保持它的视窗最近的内容,server只是维持视窗在任何时刻均在萤幕上显示,
但它不负责保持视窗的内容。

    当原先被其它的视窗遮住的视窗(或视窗的一部份)变成可见时,server
并不知道应该显示这个视窗的哪个部份。server送一个exposure(曝光)"事件"
给拥有这个视窗的client,告诉它视窗的哪一个部份刚刚已变成可见,client便
会决定该怎麽作,在大多数的情况(一般为简单的应用程式或小视窗),client
只是重画整个视窗,因为只画视窗未被遮盖的部份往往要多花额外计算,并不
值得,在更复杂的应用程式,client才会只重画视窗必需要出现的部份,这是
由应用程式的撰写者决定,他必需在效率(视窗更新的速度)和只重画部份视
窗程式码的复杂程度间作取舍。

    依赖client来重画视窗内容的方式对效率特别重视,尤其是下拉式选单,
你总不希望选下选单之後,选单过了老半天才消失而让下面的视窗显示出来吧
,为了克服这点,有些X的产品包含了被称为save-under(存下层)的便利程
式:

你可以告诉server如果可能的话,尽量在一个视窗被遮盖前将其被遮盖的内容
存下,当遮盖的视窗被移走时便可立即重现而不需要送曝光 "事件" 给client。

    一个类似而更常用,被称为backing store 的方式也被发展出来,你可以
告诉server尽可能在一个视窗被遮盖前将其全部内容存下,同样的,这种方式
可以改进client重画视窗的效率,backing store 和save-under两者的不同处
是前者储存整个视窗的内容,而後者只存被遮盖的部份。

    虽然有了save-under和back store这两种产品,但此种结构不被担保,
client仍然随时保持准备接受曝光 "事件" ,即使server真的维护(maintain)
了一段时间的视窗内容,也可能因为记忆体不足而被迫停止,转而开始重新送
出曝光 "事件"。


2.3 X的网路风貌

    我们曾经提过,client和server只需透过网路便可在不同的机器上执行,
下面几节我们将看看如何利用这种便利、为什麽有用、和它如何因整合了计
算资源而增进了网路的成长。


2.3.1 你如何实际使用X网路

    当server在一个连接了显示器的机器上执行,而client在另一部机器上执
行时,滑鼠和键盘的输入由server所在的机器搜集,可是client却可以在别的
地方使用到这些输入,这是如何办到的?我们以下面的例子解释。

    你在使用一个由Xserver控制显示器的工作站,如果它是独立的,很明显
地,client也在此工作站上执行,即使连接了网路,大部份的时候你还是在你
自己的工作站执行client,可是因为有一些特殊的便利程式,你的机器上并没
有,而你却希望在你的机器上显示程式的输出,这时你便需要网路上的机器了
。利用你的作业系统提供的一些普通的网路设备程式,你便可以让client程式
在远方的机器上执行,而指定输出显示在你自己工作站的显示器上,如图2-5.

            ┌—————————————┐
            │   p23  fig 2.5 (???)     │
            │                          │
            │  图 2-5  使用X网路典型  │
            │          的面貌          │
            └—————————————┘

就如同图上显示的机器名称,假设client程式的名称为xgraph,在Unix系统上
,你所下的命令类似下面:

        rsh neptune xgraph -display venus:0

则xgraph程式在远方名为neptune 的机器上执行,且xgraph的输出会送到你自
己名为venus 的机器上的 0号显示器上,从现在起,我们将参照这种远方显示
(remote display)的模式操作,当client在一部机器上执行时,server在另一
部机器上执行。

    现在总结一下:你使用远方显示的设备程式使得client程式在远方的机器
上被执行,而且告诉它将输出显示在执行Xserver的本地机器上。


2.3.2 X的网路设备有何用途?

    在一部机器上执行client而把输出显示到另一部机器有何用途?这些用途
和便利是极常见的,以下是一小部份的用途:

    . 远方的机器速度比你的快很多(可能是因为加了浮点运算器或它根本就
      是一部超级电脑。)。

    . 在你的区域网路上,远方的机器是一部档案服务器(file server) 提供
      了大量磁碟资源,为了降低网路的负担,你可以把一些类似大量的搜寻
      操作,需要用到大量磁碟动作的程式放在远方机器上执行,如此一来,
      只有执行结果而不是大量操作磁碟的动作会透过网路传送。

    . 远方机器有特殊的结构适合特别的工作,可能是专门的资料库机器,或
      者是为一个单独的应用特别设计的特殊目的机器。

    . 远方的机器有只能在其上执行的特殊软体,在现代的工作站,在网路上
      有些软体执照只有少数的机器拥有已是愈来愈多的趋势,因为软体执照
      只发给那些有付费的工作站CPU 。在这种情况下,可以实际地在远方的
      机器上执行这些有执照的软体,而将显示传回你自己机器上,是相当地
      便利。

    . 你需要同时存取好几部机器,通常系统的管理者有此需求。

    . 你需要同时输出到数部显示器。(下面有一个范例)


一个特别的范例 -- 一个应用程式使用数个显示器

    大部份的情况,数个client应用程式共享一个显示器是常见的,例如一个
萤幕上同时有时钟client和编辑器client,但是一个client也可以连接到数个
server,而且同时输出到server所在的萤幕上。

    这种情形用於教学特别有效率,如果一个班上的学生们有X视窗工作站连
接在网路上,则老师就可以把萤幕当成动态的黑板,同时输出给学生,再发展
下去,学生也可以有一个client程式把显示输出给老师,达成双向的沟通,只
要网路许可,所有的工作站并不需要在同一个房间,因此老师和学生可以分散
在各处。


2.3.3 X网路结构产生的简易性

    就像前面所提过的,所有从client对server发出的 "需求" ,由於它们的
格式和内容是和设备无关的(device-independent),而所有和设备相关的事完
全集中在server,对於任何显示器的硬体,只有对应於此种显示器的server才
需要去关心,只要针对一个显示器的server一旦被提供,所有可执行X client
程式的其它机器立即可使用这个显示器,不需要重新编译或重新连结,甚至连
显示器是什麽型式都不需知道。

    这种把设备的相关性独立出来给server的方式,对许多工作站网路的贩卖
商变得可行且轻松,这种弹性在两方面特别有用:

    . 当一部执行X client 的新机器加入网路,它立即可以使用任何执行X
      的显示器。图2-6 是一个强力的CPU 如何在网路上被当成一个计算服务
      器(compute server)的示意图.

            ┌—————————————┐
            │   p25  fig 2.6 (???)     │
            │                          │
            │  图 2-6  已存在的显示器  │
            │          可使用在新的CPU │
            │          上的client      │
            └—————————————┘

    . 相反的,当一个新的显示器加入,它立即可被任何机器上现存的所有
      X client 应用程式使用,见图2-7 ,这里有两个极端的例子:

       -- 增加一个高效率的显示器:它的高品值和(或)速度可被用来加强
          任何现存的X应用程式。

       -- 增加一个非常低等(low end) 的显示器(例如X显示器),至少这
          是一个使用现在所有软体,并提供图形和视窗的最便宜的方法。

            ┌—————————————┐
            │   p26  fig 2.7 (???)     │
            │                          │
            │  图 2-7  被已存在的client│
            │          程式使用的新显  │
            │          示器            │
            └—————————————┘


2.3.4 在网路上使用非X的应用程式 -- 终端机模拟器

    如果在远方机器上的程式并不是X client 或甚至连X是什麽都不知道,
你仍然可以像远方的机器一样使用它们,这就需要用到X视窗”终端机模拟器”
(terminal emulator) ,一个假装它是终端机的程式。如此一来,你便可以让
任何程式在这个假的终端机执行。这个终端机模拟器利用X显示输出(和得到
键盘输入),当然输出也可以送到本地或远方的显示器。一个这种型式的范例:
利用xterm 终端机显示器去执行信件程式,见图2-8 ,(xterm是MIT 标准版X
的所提供的一部份) ,这种方式对扩展网路的用途是可想像的,但是注意到一
点,它并非万灵丹,一个不是X的应用程式当然还是无法用到X的特性,终端
机显示器并没有什麽魔法让假的终端机可以使用滑鼠输入或图形操作等。

            ┌—————————————┐
            │   p27  fig 2.8 (???)     │
            │                          │
            │  图 2-8  执行远方的一个  │
            │          非X的信件程式  │
            └—————————————┘


2.4 摘要

    本章你可以看到包含在X中的基本构成要素:控制显示器的server,要求
server帮它完成输入输出的client应用程式和介於两者之间的通讯通道,你可
以看到它们彼此间如何交谈,如何实地应用,以及它们对你的好处(不管你是
使用者或系统建立者)。

    下一章,我们继续概观系统,但是在稍高一点的层次,焦点集中在使用者
介面上。

=====

第3章  从使用者介面的面貌概观X

    在本章,我们将观察重点摆到系统控制的使用者介面,例如,系统如何显
示有人使用它,以及包含那些结构等。

    X设计的目标之一就是能支援许多不同型式的使用者介面,一般其它的视
窗系统提供特殊的交谈方法,而X则提供一般性的架构,让系统建立者
(system builder)据以建造所需的交谈的风格。例如,在一个X系统中你可藉
从选单中选一个动作来构建视窗,但其他对视窗的操作则全靠滑鼠来做,这种
弹性允许系统开发者(developers)完全在X的基础上产生全新的介面,也因为
介面并未内建於视窗系统,因此使用者在任何时刻根据他们特别的需求可选用
适当的介面。例如,对於完成一些相同的工作 -- 建立、移动、重定大小萤幕
上的视窗,初学者较老手喜欢简单的系统,而X可分别提供最适合他们的使用
者介面。

    使用者介面分为两个部份:

    管理介面:命令最高层的视窗如何在萤幕上建构或重建构(re-configured),
              也就是说,如何管理你的案头。

    应用介面:决定你和应用程式间交谈的”风格”(style): 你如何利
              用视窗系统的设备程式来控制应用程式及输入资料给它。


3.1 管理介面:视窗管理器

    管理介面(management interface)是系统的一部份,用以控制你萤幕上最
上层的视窗(换句话说:如何重新建构你的案头),这个部份在系统中称之为
视窗管理器(window manager),它的功能有改变视窗的大小或位置、将视窗在
堆叠 (stack)中重新安排位置、或将视窗改变成表徵图 (icon) 等等。

    在X中,视窗管理器只是另一个client程式而已,它以及系统介面的发展,
和server是完全分开的,因此你可以更换它们,这类似於Unix系统中的shell
命令列直译器(interpreter) :shell 只是一个使用者处理程式(process) ,
如果你改变它,你也改变了系统的使用者介面。


3.1.1 手动的和自动的视窗管理器

    有两类的视窗管理器:手动的和自动的。手动的视窗管理器,视窗在萤幕
上的位置和大小完全由使用者控制,手动的视窗管理器只是使用者用来完成工
作的工具,大部份的手动视窗管理器允许应用视窗重叠。

    相对的,自动的视窗管理器尽可能的由它自己来控制案头,对於萤幕的布
置尽可能让使用者少插手。它在新建立一个视窗时自动决定视窗的大小和位置
,和当视窗移动时如何重新安排其馀的视窗,通常自动的视窗管理器将萤幕分
成一块块像磁砖一样(tile)的区域,也就是说安排应用视窗彼此不会重叠,而
且尽量占用最多的萤幕空间。

手动的视窗管理器如何工作 -- 攫取(Grabbing)

    通常当你告诉手动的视窗管理器你要完成什麽动作时,是藉著使用选单或
者结合了按滑鼠的按钮和移动指标,例如,重新摆放一个视窗的位置,你可以
移动指标进入视窗,按住左边的按钮,移动指标然後在新位置松开按钮,视窗
管理器是如何知道这些滑鼠 "事件" 的意图的?或是换个角度,server是如何
知道 "事件" 是来自应用视窗或视窗管理器?

    答案是由视窗管理器告知server有哪些特定的 "事件" (碰触按钮等等)
需要被送达,这和哪一个视窗发生的无关,这种处理称之为攫取(Grabbing),视
窗管理器可以指定哪一个滑鼠按钮希望被攫取,而这攫取发生在滑鼠的按钮被
按下且键盘上一些特定的键(一般称为修饰键(modifer) )也被按住(例如当
CONTROL 和SHIFT 两个键被按住时且滑鼠中间的按钮被按下),当按钮被按下
时,攫取开始动作,server送出所有滑鼠的事件(包括滑鼠的移动事件)到视
窗管理器直到按钮再度松开,视窗管理器把这些 "事件" 的资料解释成来自使
用者的指令来工作。以移动视窗为例,视窗管理器在按钮按下时被告知指标的
位置,而当按钮松开时再度被告知,对指标的位移做一些简单计算便可据以移
动视窗。

    有一件事需要使用者配合,那就是滑鼠和修饰键组合而成的攫取不应该为
应用程式所知道,所以必需确定视窗管理器这种攫取键的组合不会和应用程式
冲突,大多数的视窗管理器可以很容易的定义这些攫取的组合键,而保留给它
自己使用。


3.1.2 视窗管理器额外提供的功能

    视窗管理器除了具有重新建构视窗的基本功能外,也提供额外的功能改进
介面的品质,通常,加入额外功能的目的是为了降低键盘输入的需要,而改成
尽量多用指标。

    一个常见的功能是提供一个你自己可以建构的一般性选单,这样你只要选
取一个选单选项便可启动视窗应用程式。这个启动的命令通常包含了指示应用
视窗在何处出现,大小多少,本文用什麽颜色等等。所以应用程式不需要太多
的使用者输入便能启动。一个常见的选单用法为当你在网路上工作时,你可以
定义一个选单列出所有你在网路上可用的主机,如此你便可藉著在选单上选择
主机名称便能和任一主机建立连接。


3.1.3 视窗管理器和表徵图

    当一个视窗转换成一个表徵图时,表徵图是如何来的?视窗又发生了哪些
事?

    表徵图的结构非常的简单,它只是视窗的代表图案,当系统表徵图化(iconify)
一个应用视窗,视窗管理器只是不对应出(unmap) 这视窗(也就是说,告诉
server不再显示这个视窗到萤幕上)而把表徵图视窗对应出来。解除表徵图化
(deiconify)则把上述的处理反过来。视窗管理器可以办得到的原因是它没有”
存取控制”(access control)或许可限制来防止一个client(例如视窗管理器)
不对应出其它的client的视窗,所有在同一个server上的client都可以对任意
视窗或多或少做一些动作。

    视窗管理器通常提供预设的表徵图,但是client可以提供它自己的表徵图
并建议使用它,有些视窗管理器接受这个要求,有些则忽略不接受仍用自己的
表徵图,只把这个需求当作给视窗管理器的暗示(hint)。

    当应用程式被表徵图化,它的主视窗便不再被对应出来,如果视窗管理器
因任何理由中断了,则这个视窗永远也无法再对应出来了。要避免这点,当视
窗管理器表徵图化一个视窗时,它把这个视窗加入一个名为save set的名单□
,这个名单由server负责维护,如此当视窗管理器被中断时便可重新对应出来。


3.1.4 应用程式传递建构资讯给视窗管理器

    就如同要求显示一个特定的表徵图一般,应用程式也能传递其它的暗示或建
构资讯给视窗管理器,这包括:

    . 应用程式和表徵图视窗的名称。

    . 当应用程式和表徵图视窗被建立时,它们在萤幕上位置的资讯。

    . 对视窗大小的限制(例如,client可以宣告”我所占用的视窗大小绝不
      可小於宽度若干x 长度若干”)。

    . 对视窗重定大小的特别要求(例如,一个显示本文的视窗,可以要求在
      重定大小时按特定的间隔放大或缩小,以使得视窗内的字元永远是完整
      的一个,不致视窗边框的那一行 (列) 有半个字的情况出现。)。

    这种将讯息传递给视窗管理器的结构称之为性质结构(property mechanism),
下一节我们会讨论它。

    我们可以注意到大部份重定大小或表徵图化的事是由视窗管理器做的,这
是因为它是一个公有的client,任何client均可随意重定大小,但如果所有client
都这样做,便会造成混乱,因此要这些应用程式和平共存的原则是:不要自行
重定大小,把它交给视窗管理器,也就是让使用者去决定。

    在第6章中我们会看到一个视窗管理器uwm 如何使用。



3.2 应用程式介面和工具箱

    应用程式介面决定了使用者和应用程式间交谈的风格,举例来说,如何用
指标选一个选项等,X不提供标准的应用程式介面,只提供基本的结构以便建
造它们。

    当那些具有一贯性的应用程式介面被放在一起,便叫做工具箱(toolkit),
它是基础视窗系统软体中最高最有效率的层次,较低层次的细节,被隐藏起来,
因此简化程式和维持介面的一贯风格变得容易执行,当使用者控制应用程式时
好像有一套”虚拟文法(virtul grammer)”一般,需要注意很重要的一点是,
工具箱在编译程式的时候被指定,所以一个client的应用程式介面在编译的时
候就被决定了,如果不重新编译便无法改变。

    MIT 版的X大多数的应用程式均使用标准的工具箱和一套来自MIT 的工具
箱软体构成要素,这造成你可以得到一致性的介面。除此之外,有些结构更提
供了定制的应用程式操作方法和设定它们的预设值。


3.3 其它的系统面貌

    在本节中,我们讨论将应用程式之间传递资讯所用的性质结构(property
mechanism),视窗的树状阶层组织,和X不包含在作业系统中的优点。


3.3.1 client之间的通讯 -- ”性质”

    client和server之间的通讯是藉著送出 "需求" 和接收 "事件" ,但有时
client需要和其它的client传递资讯,例如,正常的应用程式需要告诉视窗管
理器它的位置和大小,这就需要X的性质结构了。

    ”性质”是一小段资料的名称,这一小段资料存在server中且关联到一个
特定的视窗,任何client均可向server查询某一特定视窗”性质”的值。

    让我们看一个client如何把它所喜欢的表徵图名称传递给视窗管理器的范
例:client把表徵图名称存到这个视窗的WIM_ICON_NAME ”性质”去,当视窗
管理器执行表徵图化这个应用视窗时,它会去找这个应用视窗的WIM_ICON_NAME
的”性质”,而後显示”性质”中的表徵图名称。

    应用程式也可以和不是视窗管理器的其它的应用程式通讯,一个常见的例
子是在分属不同应用程式的视窗之间做剪贴(cut-and-paste) 操作,一段本文
从一个应用程式中”切下”(cut) 稍後再”贴”到另一个应用视窗,”性质”
在此被用到,”性质”依序编成”CUT_BUFFER0”,”CUT_BUFFER1”…等等,
所有的应用视窗便可藉此交换资料。

    最後一个例子是称为resources 的”性质”,它被用来定义应用程式的预
设值设定,在根视窗(root window) 中有一个名为RESOURSE_MANAGER的性质存
放著所有设定的名单,它会被所有的应用程式存取,用来做是否要执行任何设
定的依据。


3.3.2 在X中视窗的阶层性

    本节描述视窗在系统中的组织及如何建立,和对应用程式的影响。

    所有在X中的视窗都可视为一个树状结构阶层 (hierarchy)的一部份,树
的根部便是根视窗,涵盖了整个萤幕,应用视窗都是根视窗的子代(children),
上层的视窗可以拥有它自己的子视窗,图3-1 有两个应用视窗。

             ┌———————————————┐
             │   p34  fig 3.1   (???)       │
             │                              │
             │   图3-1 在萤幕上重叠的视窗   │
             └———————————————┘

    ”paint ”程式包含了一个被当做选单用的子视窗,对每一个选择又有一
个子视窗对应,相关的视窗树见图3-2 。

             ┌———————————————┐
             │   p35  fig 3.2               │
             │                              │
             │   图3-2 视窗的树状结构阶层   │
             └———————————————┘

    在X的设计理念下,制造一个视窗非常容易,你可以利用视窗来控制选项
,像选单、卷动棒(scrollbars)、控制钮(control button)等等,即使是大量
也无妨,例如像试算表中的一个cell等。这种观点从程式设计师的角度大於使
用者,但的确对使用者当他”定制”(customising) 特定的程式时有影响,在
本章以後的章节会再度提到。

    为了允许应用程式有子视窗,X提供了大量的设备程式供client程式使用,
如此不但能达成一致性,也避免了相同的需求造成了重复的工作,例如像图3-1
的下拉式选单,可以在应用程式中以一致子视窗完成,这个子视窗有它们自己
的选单选择方框(pane),和用以侦测使用者碰触滑鼠按钮的标准结构,如果没
有子视窗,复杂的程式和输入处理将无可避免。

    子视窗的位置和大小并不受父视窗的限制,子视窗可大可小,可以大过父
视窗或只占父视窗的一部份,但是它会被父视窗剪裁(clipped) ,也就是说,
子视窗所有超出父视窗的部份将会消失不见。见图3-3

             ┌———————————————┐
             │   p36  fig 3.3   (???)       │
             │                              │
             │   图3-3 受父视窗限制的子视窗 │
             └———————————————┘

    在实际的应用上,你可以将上层的视窗定义成几乎占住整个萤幕,就不必
担心子视窗有些部份会看不到了。

    另外一种方式就是把下拉式选单定义成为根视窗的子视窗,如此选单便可
以比应用视窗还大,如图3-4

             ┌————————————————┐
             │   p36  fig 3.4   (???)         │
             │                                │
             │ 图3-4 选单比用它的应用视窗还大 │
             └————————————————┘


3.3.3 X不是深植於作业系统

    不像其它大多数的系统,X并非深植(embedded)於作业系统中,而只是比
使用者层次稍高而已。更精确地说,X不需要深植於系统,虽然有些制造厂商
可能是为了效率(performance) 的理由将server和作业系统结合在一起,但不
深植於作业系统的结构有下列利益:

    .易於安装和改版,或甚至去除。这种工作不需要重新启始系统,也不会
      对其它应用程式造成干扰。

    .第三集团很容易支援加强它的功能。例如你的制造厂商提供的系统不够
      好,你可以向别人买更好或更快的版本。

    .X不会指定作业系统,因此成为一种标准,这也是第三集团发展软体的
      原动力。

    .为了发展者利益。在server上发展工作时,当程式当掉只会当掉视窗系
      统,不会造成机器的损坏或作业系统核心的破坏,没有作业系统核心码
      的程式也较易除错。


3.4 结论

    在本章中我们描述了许多X提供的使用者介面,我们介绍了你用以管理
案头的程式 -- 视窗管理器的概念,也描述了被用来做使用者和client应用程
式间交互作用的设备程式。我们介绍了用来做client间通讯的性质结构,X视
窗的阶层结构对系统的影响,最後对视窗系统不深植於作业系统的好处做一摘
要。

    本章所强调的著眼点,在於针对你每天都用到的视窗系统的部份作一整体
性的概观,了解这些将帮助你学习得更快,更能好好地运用系统。

    本书第一部份 -- 系统概观就此结束,下一个部份将告诉你如何实际使用
系统。

=====

第4章 术语和符号

    本书大部分使用的术语是在第一次碰到时再作解释,但有些术语我们认
为应该先在本章作一个介绍,此外在本章中我们介绍了一些本书使用符号的
习惯,以及本书中所有范例所使用的机器场景 (scenario).



4.1 术语

    在X中,一个视窗 (WINDOW) 是指萤幕上的一块长方形区域,它的边平
行於萤幕的边,大多数的视窗以一种颜色作为背景色 (background),而以另
一种颜色作为前景色 (foreground),例如一个典型的文字视窗,背景色为白
色,前景色 (也就是文字本身) 则为黑色.视窗可以有一个边框 (border),
通常边框的颜色和背景色不同. 有些视窗在视窗上方可能有一个标题棒
(title bar) 或控制棒 (control bar), 在某些情况下用以显示有关这个视
窗的资讯, 你可以对控制棒作某些固定的动作来管理视窗. 系统会显示一个
指标 (pointer,有时也称为游标 (cursor))在萤幕上, 当你移动滑鼠, 整个
萤幕只有一个指标在对应移动. 相对的, 萤幕上许多文字视窗拥有自己专属
的文字游标, 这些游标通常指示你输入文字的位置. 以上的术语可由图 4-1
来解释.

       ┌——————————————————————┐
       │  p. 42  图 4-1   (???)                │
       │                                            │
       │                                            │
       │                                            │
       │ 图 4 - 1 视窗的元素                        │
       └——————————————————————┘


geometry -- 位置和大小

    X用到一些几何学的术语来说明一个视窗的位置和大小, 大部份的X程
式接受一个含有geometry的命令列 (command line) 来启动 (stratup)它们
, 这个命令列说明了这个程式的视窗有多大, 以及在萤幕的哪一个位置显示
. 通常geometry的格式如下:

    宽度 x 高度 + X偏移量 + Y偏移量

    宽度和高度的单位为像素 (pixel,萤幕上的一点) 或字元 (character)
, 视应用的状况而定, 程式的说明通常会告诉你用什麽单位. 上述的式子是
说明建立一个大小为宽 x 高 的视窗, 视窗的位置为左边框距萤幕左边界 X
偏移量个像素, 上边框距萤幕上边界 Y偏移量个像素. 例如假设一个程式以
字元为视窗大小单位, 则格式

    80 x 24 + 600 + 400

的意义为: 建立一个 80 字元宽 24 字元高的视窗, 并且视窗的左边框距萤
幕左边界 600个像素, 上边框距萤幕上边界 400个像素.

    如果需要的话, 也可以只指定大小或只指定位置, 程式对未指定的部份
会使用预设值 (default value), 或给你一些提示, 视实际在系统中执行的
状况而定.


滑鼠和指标的术语:

    有一些输入装置会在执行X时在显示器上指出萤幕上你有兴趣的项目或
区域,通常为一个有数个按钮 (button) 的滑鼠 (一般为三个按钮,分别称为
左按钮, 中按钮, 右按钮).当你移动滑鼠, 系统会对应地移动萤幕上的指标.
接下来, 我们对滑鼠上的三种操作术语作一严谨的定义:

    碰触按钮 (clicking a button): 按下滑鼠的按钮随即松开, 按钮被按
        下的时间, 仅有一瞬间而已.

    按住按钮 (pressing a button): 将滑鼠的按钮按下, 且一直保持按住
        按钮的状态.

    松开按钮 (releasing a button):  将先前按住的按钮松开.

通常碰触按钮被用来指定萤幕上的一个物件, 按住按钮再松开按钮 (一般在
这期间会移动滑鼠) 往往用来移动或描绘一块区域.

    拖拽 (dragging) 一个物件: 利用指标指定一个物件, 按住按钮, 保持
    按住状态移动指标直到某处再松开按钮。做这种操作时, 系统通常有一些
    方式来表示物件被移动, 例如在拖拽一个物件的期间, 系统会将物件周
    围加上一个细线的方框.

    我们常常利用拖拽方式来改变一个物件的大小, 通常系统显示方框, 根
据你的拖拽动作改变大小, 此种方法叫作橡皮筋法 (rubber-banding). (因
为方框好像用橡皮筋做的一样.)

    在本书的图形表示法中, 我们用一个下箭头表示按钮被压住, 虚线表示
滑鼠 (指标) 的移动, 上箭头表示松开按钮, 见图 4 - 2

BBS水木清华站∶精华区

TOP

BBS水木清华站∶精华区


        ┌———————————————————┐
        │      43 页 , 图 4 - 2                │
        │                                      │
        │                                      │
        │                                      │
        │图 4 - 2  滑鼠拖拽的图形表示法        │
        └———————————————————┘

键盘的术语:

    标准的终端机键: SHIFT, DELETE, BACKSPACE, ESC 或 ESCAPE, RETURN,
            CAPSLOCK.

    游标控制键: 采有上下左右箭头的键, 如 UP, DOWN, LEFT, RIGHT.

    特殊键: 压住CTRL或CONTROL 键, 再按其它的键 (例如 A键),用CTRL-A
            表示, 有些终端机有META键, 也同样的用META-A表示.



4.2 符号

连续数列

    在一些情况下, 你输入的命令列或系统输出的文字, 因为太长而无法在
同一列而必需分为数列, 如果它是shell 命令, 或是一段 C语言程式码, 我
们在第一列的最後加上一个倒斜线(backslash"\")後, 在下一列继续, 例如:

    mkfontdir/usr/lib/X11/fonts/misc\
    /usr/lib/X11/fonts/15dpi\
    /usr/lib/X11/fonts/100dpi

然而极少数的情况下, 我们用符号 "(contd.)" 表示本列因排版限制的缘故
在下列继续,如:

    PID TT STAT  TIME COMMAD
    1901 c0 S 0:01 x :0
    1902 c0 S 0:01 xterm -geometry +1+1 (contd.)
         -n login -display unix:0 -c
    1903 p1 S 0:00 -sh (csh)

    当X装设时, 需要定一些目录树 (directory tree). 我们把目录树的
顶端定为$TOP, 在我们的系统中, $TOP对应的目录为 /usr/local/src/X11
,相同地,家目录 (home directory) 参考自 $HOME。



4.3 本书范例的场景

    本书使用大量的范例来说明,这些范例是假设我们在一个拥有下列机器
的网路下工作:

    venus     彩色萤幕,普通解析度
    saturn  单色萤幕,普通解析度,档案工作站(file server)
    mars   彩色萤幕,高解析度
    neptune   非图形萤幕,拥有磁碟储存装置,电脑工作站(computer server)

我们所拥有的工作站是 venus,大部分的时间我们使用它,当我们需要更高
的解析度或在单色萤幕检查某些情况时,我们会使用 mars 或 saturn,当然
,我们会在我们自己的工作站,以远端(remote)的方式使用所有的机器.

    saturn是 venus和 mars 的档案工作站, 三者之间共享相同的档案系统
,( 例如,它们存取档案 $HOME/.login 时,实际上是同一个档案) .neptune
拥有它自己的档案系统,不和其他的工作站共享.



4.4 本书使用的工作站架构

    在本书中,所讨论的一些范例、程式名称、程式码的片段可能和你系统
的有些差异,那是因为系统不同的关系,本书假设使用的系统为:

    .硬体:SUN 3/50  工作站,三个按钮的滑鼠,萤幕大小为 1152x900个
      像素,单色萤幕。

    .作业系统:SunOS 3.4, 以 BSD 4.2 Unix 为基础。

    .视窗软体:X的 MIT标准版,第11版第3 次发行。

=====

第5章 启动和关闭退出X

在本章, 我们将学到:

  .如何在自己的机器上启动X.

  .如何在视窗上做一些基本操作.

  .如何关闭退出X.

    我们在此假设你的系统管理者已经在你的系统上装设好了X, 事实上即
使不曾用过或不熟悉X, 装设X也不会很困难. 因此如果你有必要自己装设
X, 本书的附录将给你一些提示.

    在还未开始前, 我们需要先知道已装设好的X, 它的执行程式在那里,
MIT 版预设的目录为 /usr/bin/X11,但很多地方是用 /usr/local/bin 或
/usr/local/bin/X11, 当你知道了之後, 把它加到你的搜寻路径 (search
path) 里, 如果你使用 C-Shell, 可以在你的.login档 (或者可能是.cshrc
档) 设定路径, 如果你使用Bourne Shell, 则在.profile档中设定. 例如,
在.login档中使用C-Shell 的命令列设定路径:

    set path = (. /usr/local/bin/X11 /usr/ucb /usr/bin /bin)

    如果你不设定路径, X将无法正常启动, 当你设好之後, 为了确定起见,
先logout再login 一次, 检查路径是否设定正确 (用 echo $PATH 指令).


5.1 启动X

    在你的显示器启动X,键入命令:

        xinit

则会依序发生:

    1.  你的整个萤幕会被设定成灰色。

    2.  一个巨大的 "X" 游标出现(见图 5 - 1 )

         ┌————————————————┐
         │         p48   fig 5.1          │
         │                                │
         │                                │
         │                                │
         │图 5 - 1 大的 "X" 游标         │
         └————————————————┘

        你可以用滑鼠将它在萤幕上移动,但按滑鼠按钮或键盘都对它无影响。

    3.  一个xterm 终端机模拟器的视窗出现在萤幕左上角,当游标移到这个
        视窗时,会改变成本文游标,(见图 5 - 2),xterm 准备接受你的
        命令。

         ┌————————————————┐
         │                                │
         │        p48   fig 5.2           │
         │                                │
         │                                │
         │                                │
         │图 5 - 2 xterm 的本文游标       │
         └————————————————┘


    系统启动的画面见图 5 - 3。X现在已被启动,你可以把xterm 这个视
窗当成一个普通的终端机来使用,执行一些普通的指令,不过它最大的价值
在让你可以开始执行其它的X程式,我们将於稍後告诉你,现在先来让你了
解一下X的启始动作做了些什麽。


         ┌————————————————┐
         │                                │
         │        p49   fig 5.3           │
         │                                │
         │                                │
         │                                │
         │图 5 - 3 系统启动的画面         │
         └————————————————┘


5.1.1 xinit 的内部操作:

    首先, xinit 启动Xserver程式在你的显示器上执行, server建立一个
它自己的根视窗, 并把视窗的背景色设定成灰色, 把游标设定成一个大 "X".

    在server执行的期间, server一直控制著键盘及滑鼠, 这就是你能在萤
幕上移动游标的原因, 但是因为目前没有任何client程式要求告知键盘和滑
鼠 "事件",所以server只是追踪滑鼠游标的移动, 而所有其它的键盘或滑鼠
输入虽然都经过server处理但均被放弃, ( 因为没有client程式有兴趣 ),
这就是按键盘或滑鼠按钮没有反应的原因.

    接下来, xinit 启动xterm 程式执行, xterm 对server而言是一个client
程式, xterm 要求server建立一个视窗, 而且保持告知在这个视窗中的滑鼠
和键盘事件, xterm 设定在视窗中执行一个shell , 当指标移至视窗之内便
准备接受输入.

    键盘输入被送至shell 就如同在一部真的终端机上输入一般, 从shell
( 及其副程式 )的输出藉著xterm 显示在视窗上, xterm 也接受滑鼠输入,
使得你能设定不同的程式操作参数和进行本文的剪贴 (cut and paste ) .

    你可以观察到系统执行这些动作的步骤, 例如当在系统启动後, 在xterm
视窗内执行 ps a 命令:

    PID TT STAT TIME COMMAND
    1900 C0 S 0:00 xinit
    1901 C0 S 0:01 X:0
    1902 C0 S 0:01 xterm -geometry +1+1 -n login -display unix:0 -c
    1903 p1 S 0:00 -sh (csh)
    1904 p1 R 0:00 ps

以上的显示说明xinit 在主控台(console )显示器上被启动,它初始化server
,X显示为零。接著xterm 在一个虚拟(pseudo)的终端机上执行,xterm 启
动一个shell 执行,使得它能处理你在xterm 视窗所下的命令。最後,我们执
行ps命令产生上述的列表。

    我们将在第8章讨论更多的xterm 细节, 从现在起, 我们假设xterm 被视
为一个DEC VT102 的终端机, 我们把重点转移到系统启动之後, 我们能做些什
麽.


5.2 如何执行一些X程式

    你目前有一个X server 控制的显示器,一个叫xterm 的client程式,允
许你输入命令,本节告诉你如何执行其它的X程式。

    因为X的client程式和X server 完全独立,所以不需要特别的动作启动
它们,你可以像执行一般的程式一样执行它们。但是这些client程式需要确实
知道它们用的是那一个显示器。实际上因为xterm 一开始设定了DISPLAY 环境
变数,给定了它使用的显示器名称,而其它的client程式用此当作预设显示器
,因此你不需多做其它的事。


5.2.1 如何执行X的时钟,xclock

    我们用X的时钟当作一个简单的范例,先确定指标停在xterm 视窗中,然
後输入命令:

    xclock

一个小的时钟影像出现在萤幕左上角,覆盖了第一个视窗一部份,如图 5 - 4

         ┌————————————————┐
         │                                │
         │        p51   fig 5.4           │
         │                                │
         │                                │
         │                                │
         │图 5 - 4 xclock 启动後的画面    │
         └————————————————┘

现在有三个问题要克服:

    第一个问题:由於xterm 这个 "终端机" 已经有一个程式(xclock)在执
行,所以我们无法再输入其它的命令,该怎麽办?

    唯一的办法就是停掉xclock,但当你按下ctrl-c或DEL 键时,xclock便会
消失,要克服这种状况,你需要非同步(asynchronously)执行xclock,用命令:

        xclock  &

则目前xterm 至少能接受你输入其它的命令。

    第二个问题:如何中止xclock?

    X server 本身没有提供直接的介面中止应用程式,但是有一个叫xkill
的client程式可让你杀掉应用程式,在xterm 视窗内输入xkill 命令便可启动
这个程式,xkill 会显示一个覆盖性的方形游标(draped box cursor ),见
图5-5 ,移动这个游标到任何你想杀掉的应用程式的视窗中,碰触左按钮,应
用程式的视窗会消失且应用程式和xkill 会一起结束,你也会得到如下的讯息:

    xkill:killing creator of resource 0x40004d
    XIO:fatal IO error 32 (Broken pipe) on X server "unix:0.0"
    after 207 requests (178 known processed) with 0 events remain-
    ing.
    The connection was probably broken by a server shutdown or kill-
    client.

         ┌—————————————————┐
         │                                  │
         │        p52   fig 5.5             │
         │                                  │
         │                                  │
         │                                  │
         │图 5 - 5 xkill的覆盖性的方形游标  │
         └—————————————————┘

如果为了某些缘故你无法进到应用程式的视窗内用xkill 中止它,你通常可以用
UNIX的办法:找出process 的ID,然後杀掉它,例如:

    $ps a | grep xclock
    1907 p2 I 0:00 xclock
    1909 p2 S 0:00 grep xclock
    $kill 1907
    [1] Terminated xclock
    $

    第三个问题:如何避免时钟和xterm 视窗重叠?

    这个问题换个问法是:你如何安排应用程式视窗的位置?

    你可以用前一章说明过的 "geometry" 的参数来解决,例如输入命令:

        xclock -geometry 200x300+400+500 &

这个命令告诉xclock建一个宽200 高300 个像素的视窗,位於萤幕左上角右边
400 个像素,下边500 个像素。

    以上的三个问题都解决了,下一章会介绍更巧妙的解决方法。

使用彩色

    如果你拥有彩色显示器,那麽不妨以xclock进行你指定和使用彩色的实验,
xclock有数种选项做彩色识别:

    -bg color   设定背景颜色

    -fg color   设定前景颜色

    -hd color   设定时钟指针的颜色

    -hl color   设定时钟指针边线的颜色

输入指令:

    xclock -bg turquoise -fg red -hd magenta

你可以看到一个彩色的钟,稍後我们会再说明颜色的正确使用名称。

    xclock启动之後,便不再需要和使用者交谈(interaction ),下一节我
们将介绍另一个需要从键盘和滑鼠输入的小程式。


5.2.2 xcalc - 桌上型计算器

    xcalc 是一个X的计算器,移动指标到xterm 视窗,输入命令:

      xcalc - geometry +700+500 &

一个像TI-30 型计算器的视窗出现了(如图 5 - 6),你可以用滑鼠或键盘
来操作它。

         ┌————————————————┐
         │                                │
         │        p54   fig 5.7           │
         │                                │
         │                                │
         │                                │
         │图 5 - 6 xcalc 桌上型计算器     │
         └————————————————┘

    使用滑鼠时,你可以移动指标到你需要的计算器按钮,按滑鼠左按钮表示
按下按钮。如果是用键盘时,键盘上的一些键明显的对应计算器按钮,例如依
序按键盘键1 ,+ ,2 ,+ ,3 和 =键,代表了算1 ,2 ,3 的总和,由於至
少目前你可以用指标指到计算器的任一按钮,因此键盘和计算器那些比较不明
显的对应关系,在此不作进一步说明。

    xcalc 比 xclock 有一个优点,那就是容易中止它。在计算器AC按钮上碰
触滑鼠右按钮即可中止,大部份的X应用程式均有类似的中止设备。


5.3 关闭X

    要关闭X视窗,只要移动指标到最初xterm 的视窗,输入:

        logout

则视窗消失,server终止,X也被关闭。

    详细点说,xterm 查觉到shell 终止时,也终止自己,而xinit 一查觉xterm
已经结束,便杀掉server後离开。


5.4 总结

    你现在已能启动系统、执行程式和关闭系统,所以你可以自行做一些实验
执行xclock一小段时间,给不同的geometry设定,极度放大或缩小时钟,摆在
萤幕的任何位置(甚至萤幕之外!)

    在本章中,我们看到了如何启动程式,如何执行一些视窗应用程式,如何
结束视窗系统。换句话说,你已经能使用系统。

    但是,有许多的功能没有提供,例如:

    . 重定视窗大小

    . 在萤幕任意移动视窗

    . 将一个视窗从另一个视窗之下移出摆在案头上(或者把它堆到下面)

    . 用较方便的方法启动视窗应用程式

    这些以及其它更多的功能并非由基本的X系统提供,而是由下一章我们要
讨论的视窗管理器提供。

=====

第6章  视窗管理器基础  -- uwm

    前一章我们看到了X系统只提供基本的视窗功能,但是实际上系统应该需
要更多更方便及容易使用的功能,在X中,这些由视窗管理器 (Window manager)
提供,本章告诉你什麽是视窗管理器,以及如何使用MIT core版所提供的唯一的
视窗管理器 -- uwm  。


6.1 什麽是视窗管理器

    我们很快的摘要说明以便让你了解视窗管理器的功能。系统最基本的部份
-- 也就是server,它只提供最基本的视窗功能,如建立视窗、在视窗中写入
文字或画图形、控制键盘和滑鼠的输入和去掉视窗等,Server它不提供使用者
介面,它只提供建立介面的基本结构。

    我们把使用者介面分为两个部份 -- 管理介面和应用介面,本章讨论管理
介面,管理介面由视窗管理器控制,提供管理 "案头" 的功能,例如建立应用
视窗,在萤幕上移动它们,重定大小等等。

    你也需要能够:

    . 使一个原来被遮住的视窗重新显现

    . 方便地启动或中止应用程式

    . 更新 (refresh)萤幕

    . 表徵图化 (iconify)和解除表徵图化 (de-iconify)


6.2 启动 uwm

    当X被启动後,你可以在萤幕上的任何shell 视窗启动uwm ,因为视窗管
理器也只是一个普通程式而已,你可以在执行X的任何期间内启动uwm ,但通
常是在一开始时。

    现在你可以先启动X,接著在xterm 视窗内输入下列命令:

        uwm &

uwm 执行後会让终端机的喇叭发出哔声表示它已初始化且准备为你工作,但你
在萤幕上看不到有任何改变,执行一个ps a,你可以看到现在有一个uwm 程式
如下:

     PID TT STAT TIME COMMAND
    1900 co S 0:00 xinit
    1901 co S 0:01 x:0
    1902 co S 0:01 xterm -geometry +1+1 -n login -display unix:0 -c
    1903 p1 S 0:00 -sh (csh)
    1904 p1 I 0:00 uwm
    1905 p1 R 0:00 ps

现在我们有一个视窗管理器了,接下来我们将利用它完成一些基本的操作。


6.3 基本视窗操作 -- uwm 的选单

    uwm 有一个选单的功能,可用来管理选单,其存取的方法如下:

    1.  将指标移到灰色萤幕背景的任何地方。

    2.  按住滑鼠的中按钮且保持按住,一个标头为 "WindowOps" 的下拉式
        选单将会出现,如图 6 - 1

              ┌————————————————┐
              │                                │
              │  p59    fig 6.1                │
              │  ( 合并 p60  fig 6.2)          │
              │                                │
              │                                │
              │                                │
              │图 6 - 1  uwm 的 WindowOps 选单 │
              └————————————————┘

    3.  继续按住按钮,上下移动指标,被指标指到的选项会以高亮度或反白
        表示,当你放松按钮,表示此高亮度的选项被选择。

    如果你不想选择,那就按一下滑鼠其它的钮,或者将指标移到选单的边框
外面,则选单将会消失。

    现在□试选择Refresh Screen (更新萤幕) ,并且放松按钮,则萤幕闪动
一下并完全重画 (re-drawn) 。

    本章剩馀的部份,将让我们了解如何利用其它的选项,满足在上一章总结
中所述我们所需的功能。


6.4 移动视窗

    在萤幕上移动一个视窗步骤如下:

    1.  将指标移至背景,按住滑鼠中按钮,叫出uwm 的下拉式选单。

    2.  选择 "Move" 选项并松开按钮,此时游标改变成 "手指" (pointing hand)
        形,见图 6 - 2

              ┌——————————————┐
              │                            │
              │  p60    fig 6.3            │
              │                            │
              │                            │
              │                            │
              │图 6 - 2 手指形游标         │
              └——————————————┘

    3.  将 "手指" 移动到你打算移动的视窗中,按下任何按钮,保持按住的
        状态,视窗上出现了九宫格,且游标变成十字箭头 (arrow cross)形,
        见图 6 - 3

              ┌——————————————┐
              │                            │
              │  p60    fig 6.4            │
              │                            │
              │                            │
              │                            │
              │图 6 - 3 十字箭头形游标     │
              └——————————————┘

    4.  继续保持按住按钮,移动游标,将九宫格拖拽至你想摆放视窗的新位
        置。

    5.  松开按钮,视窗会跳到新的位置,同时九宫格消失。

    以上步骤的示意图见图6 - 4 ,现在你可以自己□试将视窗移至萤幕右下角。

              ┌——————————————┐
              │                            │
              │  p61    fig 6.5 (???)      │
              │                            │
              │                            │
              │                            │
              │图 6 - 4 移动视窗示意图     │
              └——————————————┘

    注意:你可以移动视窗使其部份因超过萤幕边框而消失,如果纯属意外的
          话,再作一次 "Move" 动作即可。


6.5 重定视窗大小

    你可以在一度空间 (one dimension)或两度空间重定视窗大小,例如:你
可以只把视窗加宽,或同时将视窗变高及变窄。重定视窗大小步骤如下:

    1.  叫出uwm 的下拉式选单,选择 "Resize" 选项,如同移动视窗,你的
        游标变成 "手指" 形。

    2.  移动游标到欲重定大小之视窗的右下角。

    3.  按住滑鼠按钮,保持按住状态,有三种变化发生。

          . 游标变成 "十字箭头" 形
          . 九宫格出现,但不像前节和视窗一样大,它比较小。
          . 出现一个长方盒,显示目前视窗的大小 (见图6 - 5)

              ┌——————————————┐
              │                            │
              │  p62    fig 6.6            │
              │                            │
              │                            │
              │                            │
              │图 6 - 5 重定视窗大小操作时,│
              │       显示视窗大小的长方盒 │
              └——————————————┘

    4.  移动游标,延展或挤压九宫格直到大小合乎需求。

    5.  放松滑鼠按钮,视窗改变大小将和九宫格一致,同时九宫格消失。

    以上步骤的示意图见图 6 - 6,你亦可用xterm 视窗练习重定大小。

              ┌——————————————┐
              │                            │
              │  p63    fig 6.7 (???)      │
              │                            │
              │                            │
              │                            │
              │图 6 - 6 重定视窗大小示意图 │
              └——————————————┘


6.5.1 九宫格的目的

    在重定大小的操作中,九宫格具有让你预先看到重定视窗的大小,而当你
在步骤 3按下按钮时,当时游标在九宫格的位置决定了你的动作:

    . 当你在九宫格的四个角的格子或最中间那一格按下按钮,你可以任意水
      平或垂直改变视窗的大小。

    . 当你在九宫格四边中间那一格按下按钮,你就只能在一度空间改变大小,
      你只能移动视窗最接近你按下按钮的格子的那一边。


6.5.2 大小限制

    那个显示目前视窗大小的长方盒,其大小的单位视情况有所不同,文字视
窗,其意义为若干行乘若干列字元 (例如xterm 通常为80x24 字元大小) ,图
形视窗,其单位则为像素 (例如xclock预设的大小为150x150 像素) 。

    有些视窗会被限制外形或大小,例如xcalc 有最小尺寸的限制:它不允许
你把视窗缩小到连计算器上按钮都无法显示的地步,xterm 虽然可以任意重定
大小,但它以字元为单位,它不会允许视窗最下一行字元只出现一半的情况发
生,相对的;xclock几乎对任意大小或外形均不受限制。


6.6 建立新视窗

    利用视窗管理器uwm 的 "NewWindow"选项,我们可以很容易的建立一个新
视窗,我们在本节内描述如何启动一个新的xterm ,uwm 如何帮助你启动其它
的应用程式,以及你如何控制应用视窗的起始位置和大小。


6.6.1 建立一个新的xterm 视窗

    建立一个新的xterm 视窗步骤如下:

    1.  移动游标到背景视窗,叫出uwm 的下拉式选单,选择 "New Window"
        选项,在松开按钮的一瞬间,有三种变化发生:(不需按住滑鼠按钮)

        . 游标改变成 "左上角" 形 (见图6 - 7)。
        . 一个闪动的新视窗边框出现了,游标在左上角。
        . 一个类似我们前节看过表示视窗大小的长方盒出现,和以前不同的
          是,它比以前多了视窗的名称 (见图6 -

              ┌——————————————┐
              │                            │
              │  p64    fig 6.8            │
              │                            │
              │                            │
              │                            │
              │图6 - 7 "左上角" 形游标     │
              └——————————————┘

              ┌———————————————┐
              │                              │
              │  p65    fig 6.9              │
              │                              │
              │                              │
              │                              │
              │图6 - 8 当建立新视窗时, 出现  │
              │  显示视窗名称和大小的长方盒  │
              └———————————————┘

    2.  移动游标使得新视窗的左上角移到你所需要的位置。

    3.  碰触一下左按钮,一个新的视窗便产生了,显示视窗大小的长方盒和
        闪动的边框同时消失。

    你可以像使用原始xterm 视窗一样地使用这个新视窗来执行普通或X的应
    用程式。

    注意 1:如果你在步骤 3碰触的不是左按钮,则视窗的大小会有所不同,
            特别是你碰触的如果是中按钮,则你的新视窗会小到几乎看不到
            的地步,如果发生这种情况,你可以用前节重定视窗大小的方法
            改善 (细节部份稍後会提及) 。

    注意 2:如果你把视窗的一部份移到萤幕之外,将会使得视窗的一部份无
            法看见,若你并不是故意如此,可以用选项 "Move" 改善。


6.6.2 建一个供任何应用程式使用的视窗

    我们仍然可用以前的方法 -- 在xterm 视窗的shell 中输入一行命令来启
动应用程式,但是现在你有视窗管理器程式在执行,所以你可以用交谈的方式
来控制视窗的起始位置,而不需在命令列中设定geometry参数。 (事实上,uwm
也可控制视窗起始的大小,我们会在下节描述。)

    举一个例子,假设我们要在萤幕的右上角启动xclock:

    1.  在xterm 视窗中,输入命令列:

        xclock &

        就如同 "NewWindow"选项一般,你可以看到一个描述视窗大小的长
        方盒,一个 "左上角" 形游标,一个和时钟同样大小的闪动边框。

    2.  不要按任何钮,只要把边框拖拽到任何你想要摆放的位置。

    3.  碰触左按钮,一个时钟取代了闪动边框出现。

    注意:如果在步骤 3你碰触的不是左按钮,则时钟的大小会不同,但不致
          於像xterm 那麽夸张。


6.6.3 指定新视窗的大小

    前面提到当你建立新视窗时,若你碰触的不是左按钮,会有一些奇怪的情
况发生,事实上三个按钮各有不同的意义,你可以依需要做适当的选择:

    1.  左按钮:碰触左按钮会使得:

          位置:将视窗左上角的位置依目前游标的位置决定。
          大小:应用程式本身原先预设的大小。

    2.  中按钮:你不应该碰触中按钮,但如果你压住不放的话,你可以藉著
                改变视窗的右下角来改变视窗的大小,然後松开按钮:

          位置:视窗左上角的位置依你压下中按钮时游标的位置决定,右下
                角则根据你放松按钮时决定,压住按钮的期间,视窗的边框
                就像橡皮筋般可延展或压缩。
          大小:根据松开按钮时的右下角决定。

        如果应用程式指定了视窗最小的尺寸限制,则橡皮筋边框被压缩到比
        最小视窗还小时会自动消失,确保你无法建立一个比最小视窗限制还
        小的视窗。

    注意:如果你让视窗的面积为零,会有一些奇怪的情况发生,例如你在启
          动xclock时,碰触中按钮,则xclock视窗会跑到萤幕左上角,大小
          为预设的大小。

    3.  右按钮:碰触右按钮会使得:

          位置:视窗左上角依目前游标的位置决定。
          大小:视窗的宽度为预设的宽度,视窗的高度由游标的位置直到萤
                幕的底边,如果大小低於应用程式预设之最小视窗限制的话,
                则用预设的高度来代替。当然,这也意味著会有一部份的视
                窗超出萤幕,所以无法看到。


6.6.4 更多的有关於geometry参数的设定

    关於geometry参数的设定,过去我们都是用视窗左上角的位置相对於萤幕
左上角位置的方式设定,其实,我们可以用视窗的任何一个角来决定视窗位置
,先复习一下geometry的设定方式:

    width x height <xpos> <ypos>
    宽度  x 高度   <x位置><y位置>

     <xpos>   决定了视窗水平的座标,可用下列方式表示:

    +offset :表示视窗的左边位於距离萤幕左边offset个像素的位置。
    -offset :表示视窗的右边位於距离萤幕右边offset个像素的位置。

     <ypos>   决定了视窗垂直的座标,同样地也可用下列方式表示:

    +offset :表示视窗的上边位於距离萤幕上边offset个像素的位置。
    -offset :表示视窗的下边位於距离萤幕下边offset个像素的位置。

以下有几个范例:

    100x100+50+60   :这是我们过去用的方式,视窗的左上角位於距离萤幕
                      左边50个像素,上边60个像素。

    100x100-0-0     :视窗的右下角位於萤幕的右下角。

    100x100-80+160  :视窗的右上角位於距离萤幕右边80个像素,萤幕上边
                      160 个像素。

    100x100+20-40   :视窗的左下角位於距离萤幕左边20个像素,萤幕下边
                      40个像素。

    上述例子的正负号代表了视窗的边和萤幕的边的关系,而不是偏移量的正
负号,事实上偏移量有它自己的正负号,例如:

    100x100+600+-50 :视窗位於萤幕的中上方,且视窗的上半部超出萤幕。

    100x100--50-+20 :视窗位於萤幕的右下角,且视窗的下边距萤幕20个像
                      素,视窗的右半部超出萤幕。


6.7 管理你的萤幕空间

    现在你可以启动许多的应用程式,建立许多的视窗,这些视窗很可能会互
相重叠,但是你有三种方法可以用来管理你的视窗,使你更方便地存取它们:

    . 把视窗缩小,利用前述的 "Resize" 选项。

    . 把视窗 "堆叠(stack)"起来,你现在需要的视窗摆到堆叠最上层,其它
      的放在比较下层,你可以用选单上的 "Raise" "Lower" "CircUp" 和
      "CircDown"来改变堆叠次序。

    . 把视窗换成非常小的视窗,称为 "表徵图(icons)",因此所占的萤幕空
      间极小,但只要需要你随时可还原它们,你可以利用选单上的"NewIconify"
      和"AutoIconify" 选项来办到。


6.7.1 变动堆叠中视窗的次序

    视窗在萤幕上,就如同文件在你桌面上,可以互相重叠,( 如图6 - 9)

              ┌——————————————┐
              │                            │
              │  p69    fig 6.10           │
              │                            │
              │                            │
              │                            │
              │图6 - 9 相互重叠的视窗      │
              └——————————————┘

为了让你容易获得你想要的视窗,uwm 允许你:

     .  将一个视窗移到堆叠最上层,不管它现在在堆叠的哪个位置。

     .  将一个视窗移到堆叠最下层,不管它现在在堆叠的哪个位置。

     .  循环堆叠,将所有在堆叠中的视窗移动一层,将最後一层的视窗移到
        堆叠另一端开头,你可以向上或向下循环。

    1.  将一个视窗移到堆叠最上层 -- Raise

        Raise 选项将一个视窗移到堆叠最上层,所以这个视窗应该变成全部
        可见,你可以Raise 任何视窗而不管它目前在堆叠何处。Raise 一个
        视窗的步骤:

        1). 从选单中选取 "Raise"选项,游标变成手指状。
        2). 将游标移到你想要Raise 的视窗上。
        3). 碰触任意一个滑鼠按钮,视窗保持在原来的位置,但那些原来被
            其它的视窗遮住的部份均会重现,其它的视窗则被盖在下面。

    2.  将一个视窗移到堆叠最下层 -- Lower.

        Lower 选项可将一个视窗移到堆叠的最下层,你可以Lower 任何视窗
        而不管它目前在堆叠何处。Lower 一个视窗的步骤:

        1). 从选单中选取 "Lower"选项,游标变成手指状。
        2). 将游标移到你想要Lower 的视窗上。
        3). 碰触任意一个滑鼠按钮,视窗保持在原来的位置,其它原来被它
            遮住的视窗会显现出来,而它本身的部份则被这些视窗遮住。

    3.  循环堆叠 -- CircUp和CircDown

        CircUp和CircDown选项用来旋转堆叠内的视窗,所差别的只是它的
        "方向" 而已。循环向下(circulate down)的步骤为:

        从选单中选取"CircDown"选项,所有在萤幕上的视窗位置均不变,
        但原来在最上层的视窗被移至最下层,所有原来被它遮住的视窗
        现在变成遮住它。

        CircUp和上述成对比,它把原来最下层的视窗移至最上层,遮住那些
        原来遮住它的视窗。


6.7.2 表徵图化一个视窗

    虽然你可以靠著Raise 或Lower 变动视窗的顺序,但有时视窗实在太多了,
为了给你自己更多的萤幕空间,你可以将那些目前不需要的视窗 "表徵图化"
(iconify) 。 "表徵图化" 的意义是把应用视窗换成一个非常小的视窗後摆在
一边,直到再度需要用它们为止。有些应用程式拥有它们特别的 "表徵图" ,
但是大部份都是让视窗管理器去建一个,uwm 的预设表徵图是一个把应用程式
名称摆在中间的灰色长方形。正常的xterm 的表徵图见图6 - 10

              ┌———————————————┐
              │                              │
              │  p71    fig 6.14             │
              │                              │
              │                              │
              │                              │
              │图6 - 10 正常的xterm 的表徵图 │
              └———————————————┘

    共有两种方法可以表徵图化一个视窗,第一种特别适合尚未表徵图化的视
窗,第二种适合曾经表徵图化的视窗。

    1.  表徵图化一个新视窗 -- NewIconify

        1). 从选单上选取"NewIconify"选项,出现 "手指状"游标。
        2). 将游标移到需要表徵图化的视窗。
        3). 按下滑鼠任意钮,保持按住状态,游标变成 "十字箭头" 形,且
            出现一个小九宫格,这个九宫格代表未来的表徵图。
        4). 保持按住按钮,将九宫格拖拽至你想要的位置。
        5). 松开按钮,九宫格会被表徵图取代,原来的视窗消失。

    因为NewIconify让你选择表徵图的位置,所以它适合新的视窗;当然对任
何应用视窗均可使用,特别是你想改变表徵图位置的时候。

    2.  表徵图化一个 "旧" 的视窗 -- AutoIconify

        AutoIconify 会将表徵图放在上一次出现的位置,如果这个视窗未曾表
        徵图化过,则放在游标所在的位置。

        1). 从选单上选取"AutoIconify"选项,出现 "手指状"游标。
        2). 将游标移到需要表徵图化的视窗。
        3). 碰触任何按钮,原来的视窗消失,表徵图出现在上一次出现的位
            置,若这个视窗是第一次表徵图化,则表徵图出现在目前游标所
            在的位置。


移动一个表徵图

    一个表徵图就像一个视窗,因此你可以利用"Move"选项,像移动视窗一样
移动表徵图。


6.7.3 解除表徵图化 -- 将表徵图还原成一个视窗

    将表徵图还原成一个正常的视窗,它的步骤和表徵图化类似,甚至在选单
上,使用相同的选项,换句话说,"AutoIconify" 和"NewIconify"这两个选项,
如果是在视窗的状况下选择,会变成表徵图,反之如果是表徵图,则会变成视
窗。

    对於位置的处理也是同理可推,使用 "AutoIconify"时,当你在表徵图上
碰触按钮,原来的视窗会在原来的位置出现。如果用"NewIconify"选项,按住
按钮则会出现和原视窗大小相同的九宫格,你可以拖拽九宫格至你要摆放视窗
的位置,松开按钮则在选定的位置上出现原来的视窗。


6.8 中止应用程式视窗

    uwm 选单有一个选项让你杀掉一个应用程式视窗,当你决定不再需要或是
想要去掉一个视窗时,杀掉的步骤如下:

        1.  从选单上选取"KillWindow"选项,游标变成 "手指状" 。

        2.  将游标移到你想要去除的视窗上。

        3.  碰触一下滑鼠任何按钮,视窗消失,内含的应用程式随之中止执
            行。

    当视窗消失後,你可以在原来下命令的xterm 视窗看到和前一章使用xkill
後类似的讯息。

注意 1:如果你杀掉最原始的xterm 视窗,xinit 会查觉到并关闭server( 与
        前一章相同)。

注意 2:如果你杀掉一个表徵图视窗,这样做会中止视窗管理器,所有的小图
        形都会还原成视窗,这是合理的行为,因为只有视窗管理器才能拥有
        表徵图视窗。


6.9 叫用uwm 选单的其它方式

    截至目前为止,我们叫用uwm 选单唯一的方法就是将游标移到萤幕的背景
上且按住滑鼠的中按钮,但是如果一个应用视窗占用了整个萤幕,那该怎麽办?
你会因为找不到萤幕背景而无法叫用选单,以致什麽事都不能做吗?

    答案很简单,有另外的办法叫用选单:

    1.  同时按下META和SHIFT 键,保持按住。

    2.  按住滑鼠的中按钮,uwm 选单即可出现 (你可以现在或稍後放开META
        和SHIFT键)。

    3.  像前几节的方法一样选择选项。

    选单的操作方法和以前一样,只有一点不同:如果你把游标移出选单的边
,选单不仅是消失而已,一个标头为Preferences(喜好) 的选单出现了,你可
以利用这个选单来设定一些参数。例如键盘被按时会不会有声音(keyclick),
喇叭的音量等等。如果你并不需要设定,将游标移出选单,或者碰触滑鼠的任
一按钮即可离开选单。


6.10  摘要

    在本章,你学会如何启动和使用uwm 视窗管理器:利用uwm 的选单,你可
以新建一个应用视窗、移动视窗和重定一个视窗的大小、将视窗转成表徵图或
还原、杀掉一个client应用视窗,这些功能已涵盖了大部份的应用需求。

    uwm 只是许多视窗管理器中的一个而已,你可以换一个别的来使用。MIT
core  版没有提供其它的视窗管理器,但是contrib 版则包含了好几个由第三
集团所提供的视窗管理器,几乎使得MIT 版的视窗管理器成为半荒废的状态,
所以你可以选择各种不同形式的介面程式,甚至对我们前数章所提的介面程式,
一个也不用。

有二个视窗管理器特别值得一提:

    twn 是一个在应用视窗上方有标题棒(title bar) 的视窗管理器,藉著碰
触或拖拽标题棒的一部份来管理视窗,介面的方式非常类似Apple 公司Macintoch
电脑,一个twn 的控制棒如图6 - 11。

              ┌———————————————┐
              │                              │
              │  p74    fig 6.15             │
              │                              │
              │                              │
              │                              │
              │图6 - 11 一个由twn 视窗管理器 │
              │所建立含有控制棒的视窗        │
              └———————————————┘


    rtl 是一个绝不让视窗彼此重叠的视窗管理器,它会让一个视窗尽量占住
最多的萤幕空间;稍後,如果你扩张一个视窗,它会压缩邻近的视窗以挪出空
间。典型的rtl 画面如图6 - 12。

              ┌——————————————┐
              │                            │
              │  p75    fig 6.16           │
              │                            │
              │                            │
              │图6 - 12 由 rtl视窗管理器   │
              │         控制的萤幕         │
              └——————————————┘

    如果有需要,你可以使用时将视窗管理器半途切换到另一个视窗管理器,
也就是杀掉一个,启动另一个,以下的步骤可当作一个练习:建立数个视窗,
将它们表徵图化,利用前章所述PS和kill命令杀掉uwm ,或者利用uwm 选单中
的"Exit"选项也可以,你会发现所有的表徵图都消失且还原成应用视窗,但你
目前全然无法控制;如果你再启动uwm ,你又可以管理它们了,但是你必须将
那些应用视窗重新表徵图化才会变成表徵图。如果你想要换用其它的视窗管理
器程式,同样地,你可以在杀掉前一个视窗管理器後启动它。

    在以後的章节,我们会更深入的讨论uwm ,告诉你那些在本章中未曾讨论
的选项功用,我们也会告诉你如何利用uwm 而不叫用它的选单,更快更方便地
直接管理视窗。

    视窗管理器只决定管理介面,另一半的使用者介面为应用介面 -- 如何和
应用程式交谈和利用滑鼠或键盘控制它们。在第8章我们会以xterm 为例,看
到许多它的应用介面的面貌。但在这之前,我们先岔开来讨论X的网路能力,
以便你能尽快用到大部份的系统功能。

=====

第7章  使用X的网路设备

    X的网路特点在於让你可以在网路上的任何机器执行应用程式,而将其输
出显示在你自己机器的显示器上,这是X最重要的功能之一,但却很容易使用。

    以下将描述你如何指定一个远方终端机,如何实际使用这些功能,最後,
我们再描述如何在网路上从其它的机器上控制或限制存取你的显示器。


7.1 指定一个远方终端机 -- -display  选项

    几乎所有的X程式都接受以一个命令列的选项来指定使用哪一个显示器 (
换个说法,连接到哪一个X server ),这个选项的格式为:

    -display displayname

让我们更进一步讨论显示器名称(displayname)的格式。

    你会告诉程式它的输出是哪一个显示器 (网路上任何你可以选择的显示器)。
明显地,网路上指定机器的名称一定包含在内,但不止於此,因为一些 (大型)
机器可以有好几个I/O 工作站,每一个工作站又拥有自己的键盘,滑鼠等等;
尤有进者,一个工作站还可能控制了好几部终端机。综上所述,显示器名称需
要包含三个元素,hostname,display number和screen number ,我们将详细
解释并举例说明。


7.1.1 Hostname

    hostname是在网路上与显示器直接连接的机器名称,hostname也决定了应
用程式和server是如何连接的。简单地说:

    假使Server在你自己本地的机器上执行,你有两种选择:

    1.  省略掉hostname,系统会选择最有效率的方式和server交谈。

    2.  定hostname为"unix",系统将用Unix domain sockets 作通信。("Unix
        domain" 意指socket用传统Unix档案名称 (例如/dev/urgent)来命名. )
        在命名之後需加一个冒号(, 即使你省略hostname,你仍需要加冒号。

    假使Server在远方的机器上执行,你一样有两种选择,依你网路上用的通
    信系统而定:

    1. TCP/IP :大多数的Unix系统使用此种通信方式, 简单的方法是用在你
       区域网路上已知的normal name (例如"venus" 或"saturn ")。你也可
       以用 full Internet name (例如"expo.lcs.mit.edu"或它的
       Internet address "129.89.12.73")。在 name 後,需要加一个冒号。

    2. DECnet :用你连接到的机器上的DECnet nodename,在hostname加两个
       冒号(:.


7.1.2 display number

    显示器是一组监视器,萤幕,连接一个键盘和滑鼠的逻辑萤幕的组合。换
句话说,即是使用者工作的地方,在一个给定的CPU 上,显示器从 0开始编号,
display number即是指哪个编号的显示器被使用,即使display number为 0,
也不可省略。


7.1.3 screen number

    对於连接到显示器上数个萤幕也被从 0开始编号,screen number 为你使
用萤幕的编号,和display number以一个句点 (.)隔开,screen number 为 0
时可省略,若省略时,其前面的句点一并省略。


7.1.4 范例

    以下为一些显示器格式的范例:

    . 假设为本地的机器,预设萤幕为 0,以下二者均可:

          unix:0
          :0

    . 假设你指定你自己的机器 (通常是venus),但你需要检验TCP/IP网路的
      操作和明显地指定萤幕:

          venus:0.0

    . TCP/IP网路上,远方的机器名为pluto ,仅有一个显示器,指定screen
      number为 0:

          pluto:0.1

    . DECnet网路上,display number为 1,预设screen number 为 0:

          vomvx2::1


7.2 实际上使用远方的显示器

    我们已知如何指定远方的显示器,现在来练习一下:假设你是在venus 工
作,想要在saturn上执行一个例如是xterm 的应用程式。你必须在saturn执
行xterm 且指定venus 的显示器,则命令如下:(为了清楚起见,本节中我们
的命令列包含了命令列前shell 对机器名称的提示)

        venus% xterm -display venus:0.0        (注意:不完整!)

    以上的指令是在本地的机器启动xterm ,并非在远方的机器启动,不符合
需求。

    如果在你的作业系统上,并未支持远方机器的操作,你可以藉著连接到
saturn的终端机输入下面的命令:

        saturn% xterm -display venus:0.0       (注意:不完整!)

则xterm 会在saturn启动,在venus 上建立视窗,视窗会向venus 的滑鼠和键
盘取得输入,这的确是你想要的,现在你可以回到venus 机器开始工作。

    但由於你的作业系统事实上支援远方机器的功能,所以你毋需离开你的机
器便可完成上述的指定,命令如下:

        venus% rsh saturn xterm -display venus:0.0

以上是利用普通的远方 shell的设备程式 -- rsh。

注意 1:命令可能因saturn不被允许存取venus 的显示器而失败,欲克服此种
        状况,输入命令:

        venus% xhost +

        後再试一次。(xhost命令下一节会解释)

注意 2:你可能需要非同步地执行rsh ,在命令列之後加 &,以背景工作方式
        执行, 但可能因为等待永远不会有的输入,shell 和rsh 间的交谈导
        致 rsh "block",为了克服此种情况,需修正命令为:

        venus% rsh saturn xterm\
        -display venus:0.0 < /dev/null &

        远方的机器 (这个例子是saturn) 并不需要有X server 在执行,甚
        至不需要有位元映像显示器,唯一的需求是能执行应用程式和支援网
        路通讯。

    现在总结你的工作模式为:在远方的机器上执行应用程式,连接回自己机
器上的显示器,其架构图见图7 - 1。

             ┌————————————————┐
             │                                │
             │  P81   FIG 7.1   (???)         │
             │                                │
             │                                │
             │                                │
             │图7 - 1 远方的 client显示器对   │
             │        本地 server架构图       │
             └————————————————┘



7.2.1 一个易发生的错误

    如果你搞混了而一开始下了这样的命令:

        venus% xterm -display saturn:0.0           (不正确)

什麽事会发生?假如这命令被接受,xterm 在你本地的机器上执行,而在远方
的机器saturn上建立视窗,你在你的萤幕上只能看到shell 读到的命令列,其
它什麽也没有,系统是正确的工作,但不是你想要的。

    如果你很幸运,你可能因不被允许或saturn上并没有server在执行,以致
无法和saturn上的server连接上,xterm 会传回一个类似下列的讯息而结束:

        X Toolkit Error: Can't open display.

如此你就知道有错了。


7.2.2 设定预设显示器

    如果你不明确地指定显示器名称,程式会以Unix环境变数DISPLAY 来决定
使用哪一个显示器,在启动xterm 时,系统会设定这个变数的内容,所以大部
份情况下,你什麽都不必担心。

    如果你remote-login其它的机器,在其间你执行X的应用程式,并希望回
到你自己的机器上显示,那你必需明确地设定DISPLAY 变数,类似下面:

        venus% rlogin saturn
        Last login: Mon Nov 28 20:01:02 on console
          ...            (在远方机器上的login banner)
        saturn%          (远方机器上的shell 提示)
        saturn%  setenv  DISPLAY  venus:0.0
        saturn%  xcalc  &

换句话说,如果不设定DISPLAY 变数,则在saturn上执行的每一个X程式都必
须包含 -display venus:0.0 选项。


7.3 控制存取你的显示器 -- xhost

    我们前面提到过有时你无法连接到特定的显示器,通常的原因是你没有被
许可,所以X否认你的存取。

    X用很简单的结构控制存取:你指定一份可以存取你的显示器的主机(host)
名单,在这些主机上执行的应用程式均可存取你的显示器,其它不在名单上的
主机则不被允许。你可以用xhost 程式来控制存取:

        允许一或多个机器存取:

            xhost + host1 [+host2...]

        去掉允许一或多个机器存取:

            xhost - host1 [-host2...]

        所有的机器均被允许存取:

            xhost +

        换言之,所有的存取控制均被解除。

        恢复存取控制:(通常因为曾经下了xhost + 的命令)

            xhost -

        再度取得对存取的控制,只有先前明确地被允许的机器可供存取。

    注意:存取控制应用於所有的处理 (process),而不只是针对其他使用者
          所启动的处理,所以如果你透过远方的机器执行应用程式,而将显
          示内容传回自己的机器,则你必需被授与存取权,否则会连接失败。


7.4 总结

    本章中,我们讨论了如何指定X程式的显示器,如何实际在网路上应用,
如何允许或禁止网路使用你的显示器。

    现在,你已经会使用网路,并且知道有一个视窗管理器会控制你的显示器;
我们转而讨论xterm ,并看一看它所提供应用程式介面的细节。

=====

第8章 终端机模拟器 - 细说 xterm

    xterm 是终端机模拟器 - 它是一个可以使X应用程式视窗看起来像普通
终端机一样的程式, 而无需知道有关视窗系统的功能. 我们已经使用过 xterm
的一小部分, 在本章中将更深入地探讨它所提供的特殊额外功能. 并且说明许
多X程式共通的一些应用程式介面的面貌.

    xterm 模拟一个 "哑终端机 (dumb terminal)", 但它也提供许多一般终
端机没有的功能 :

    . 设定终端机模式与特性的突现式 (pop-up) 选单

    . 可以上下移动萤幕影像的卷动棒 (scrollbar) - 当文字列因萤幕卷动
   而消失时, 可以将它拉回.

    . 模拟 Tektronix 4014 终端机.

    . 可选择性地记录萤幕列到一个使用记录档 (log file).

    . "剪"(cut)"贴"(paste)文字区块.

    . 可选择文字颜色, 视窗背景等...

    . 可选择 VT100 与 Tek 视窗字型.

    . 可设定( 程式化(programmable))键盘.

    我们首先描述选择功能的选单结构, 接著描述如何使用选择功能.



8.1 选择 xterm 功能 - 选单与命令列选项

    xterm 有它自己的内建选单结构, 可在使用期间改变设定. 有三个选单可
供利用, 见图 8 - 1 :

               ┌————————————————┐
               │    p84. fig 8 - 1              │
               │                                │
               │                                │
               │                                │
               │ 图 8 - 1 xterm 的三个选单      │
               └————————————————┘

  xterm X11 : 这里的大多数选择项目为程式控制功能, 例如 : continue pro-
              gram (程式继续) 或 kill program (杀掉程式). 欲突现此选单,
              必需同时按住 CONTROL 键与滑鼠左按钮.

  modes     : 设定大多数终端机的特性与选择 Tektronix 模拟功能. 欲突现此
              选单, 须同时按住 CONTROL 键与滑鼠中间按钮 (当处於VT102 视
              窗时).

  Tektronix : 控制 Tektronix 视窗的外表. 当处於 Tektronix 视窗时, 须同时
              按住CONTROL 键与滑鼠中间按钮即可突现此选单.

    选单的操作类似 uwm, 藉著按滑鼠按钮可突现选单, 不放松按钮移动指标至想
选的项目上; 放松按钮後即选定该项. 然而, 有一点不同的地方是, 不能被选择的
选单项目 (因为此时选择将无意义) 是以较淡的型式显示. 例如: 因为尚未开启一
个 Tektronix 视窗, 所以Hide VT Window 项目的颜色较淡.

    许多选单的功能也能以启动 xterm 的命令列选项来设定.(事实上有某些功能仅
能以命令列选项的型式去选择). 下面几节我们将告诉你可以设定不同功能的选单选
择与命令列选项的选择方式.



8.2 卷动 xterm 的萤幕

    突现 xterm X11 选单并选择 Scrollbar 项目, 如图 8 - 2. 高亮度的部分告诉
你两件事:

  1. 萤幕上的列数与储存在卷动棒缓冲区 (scrollbar's buffer) 的列数之比率.

  2. 缓冲区的哪个部份目前显示在萤幕上.

    例如在图 8 - 2 中 : 约有 20 列在萤幕上; 高亮度部分约为总列数的 5 分之 1,
所以缓冲区包含有约 100 列, 且目前显示的部分是缓冲区的最底部 (因为高亮度区
在卷动区的最底部).

               ┌—————————————————┐
               │    p85. fig 8 - 2                │
               │                                  │
               │                                  │
               │                                  │
               │ 图 8 - 2 具有卷动棒的 xterm 视窗 │
               └—————————————————┘

    你可以利用滑鼠按钮移动卷动区的高亮度部分, 以改变显示在萤幕上的文字.
下面的小节将会解释; 为简化说明我们假设卷动缓冲区包含 100 列文字.

注意 : xterm 采用异於其他视窗系统的卷动棒用法, 特别是 Apple Macintosh.



8.2.1 移动卷动棒到指定点

    假如你想移动本文到某一指定位置, 例如 : 想看第 50 列之後的内容 :

    1. 移动指标到卷动棒. 游标变成垂直双箭头. (图 8 - 3a)

    2. 按滑鼠中间按钮 : 游标变成水平箭头 (图 8 - 3b), 且高亮度的顶端跳至游
       标处.(例如 : 假如你想看的部分从 50 列开始, 你应该将游标移到卷动区
       的中央)

    3. 假如视窗显示你所要的部分, 则可以放开按钮. 否则 ...

    4. ... 保持按住按钮, 移动指标 : 高亮度部分跟随著指标移动 (而视窗内的
       本文也随著高亮度区而卷动), 直到放松按钮.

               ┌————————————————┐
               │    p86. fig 8 - 3              │
               │                                │
               │                                │
               │                                │
               │ 图 8 - 3 游标在卷动区的不同形状│
               └————————————————┘


8.2.2 向前卷动本文

    卷动视窗内的本文使文字列往上移出萤幕顶端 : 高亮度区向卷动棒底部移动,
视窗内并显示最近打入的本文. 上卷的步骤如下 :

    1. 移动指标到卷动棒. 和前面一样游标变成垂直双箭头.

    2. 按下滑鼠左按钮 : 游标变成向上箭头. (图 8 - 3c)

    3. 放开按钮 : 与箭头在同一列的文字移到萤幕顶端, 且高亮度区也随著调整.
       ( 以图形来表示,如图 8 - 4. 注意到移动量的多少与你放开按钮时的位置
       有关 : 若接近顶端, 你可以获得的移动量小, 接近底部则当然可以获得较
       大的卷动量).

               ┌————————————————┐
               │    p87. fig 8 - 4              │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 8 - 4 在一个视窗内卷动本文  │
               └————————————————┘


8.2.3 向後卷动本文

    向後卷动视窗本文, 文字列由萤幕底部移出, 使你得以看见先前打入的文字列
. 操作程序类似向前卷动, 但方向相反, 此时使用滑鼠右按钮, 出现向下箭头 (图
8 - 3d).


8.2.4 其他卷动选项

    只要你已经启动卷动功能, 有两个Modes选单的选项可供利用.

    Scroll to bottom on tty output (若有 TTY 输出将输出自动卷到底) :
      若你目前不在卷动区的底部, 稍後某些终端机的输出到达视窗时会自动
      地移动到卷动区的尾端. 此功能为预设的. 若此功能被关闭, 你要看最
      新的输出必须自行卷动视窗.

    Scroll to bottom on key press (按键才卷到底) : 若你不在卷动区的底部,
      稍後你按一个键, 视窗会自动移动至卷动区的尾端. 此功能不预设, 但通常你
      的终端机设定成当你键入时回应一个字元 : 这些字元为TTY 输出, 且将引起
      视窗被卷到底部.


8.2.5 以命令列选项控制卷动

    -sb : 允许使用卷动棒. (预设 : 禁能(disable))

    -sl num : 储存被卷离萤幕的若干列本文. (预设为 64)

    -sk : 致能(enable)当按键才卷到底. (预设 : 禁能)

    -si : 致能当终端机输出时卷到底. (预设 : 致能)



8.3 记录你与终端机的交谈过程 - 写记录 (logging)

    突现 xterm X11 选单, 并选择 logging 选项. (假如你现在是第二次叫同样的
选单,在 logging 选项旁边, 你会看到一个沙漏标志 (tick-mark) , 表示它是启动
的) 从此以後, 所有终端机输出除了被送到萤幕以外, 也会被送至一个档案. 你可
以获得一个使用过程的永久记录. 预设的状况是将输出写到 xtermlog.pid 档案.
其中 pid 为xterm 处理识别码. 此档案被建於启动 xterm 时的目录 (你也可以利用
下面介绍的命令列选项去改变登录档名).

    你可以藉著 xterm X11选单停止或再度logging,反覆的停止和开始logging,你
可以作选择性的记录,logging 的输出永远附加在登录档案(log-file)之後,每一次
都不会覆写(overwrite)登录档。


8.3.1 以命令列选项控制登录使用过程

    -l : 致能登录使用过程

    -lf file : 将登录档写入指定档, 以取代预设档 (指定登录档仅设定登录档
      名而不致能登录功能; 必需另外使用 -l 来致能登录)

使用一个导管 (Pipeline) 作为登录 "档"

   -lf 选择项有一个特殊功能 : 假如 file 引数以导管记号 (|) 开头, 则其馀
     部分视为登录输出的一个管路. 例如 : 假设你的系统 (shell) 提示是 venus%,
     使用下列命令去启动 xterm 并记录於 cmdlog 档, 只需键入

           xterm -l -lf '| grep "^venus% " > cmdlog'



8.4 剪与贴本文

    你可以从 xterm 视窗 "剪" (cutting) 部分本文, 亦即拷贝本文到一个 "剪
缓冲区" (cut buffer), 稍後可被 "贴" (pasting) 回, 亦即取回 (retrieve).
你可以将本文贴回同一个视窗, 或任何提供相同结构的视窗. 你可以现在或稍後
"贴" 回, 但你只有一个缓冲区, 後来所 "剪" 的资料将盖掉先前的. 目前被选择
的部分是以高亮度反白影像显示; 一个有两列文字被选到的xterm视窗显示於
图 8 - 5。

               ┌—————————————————┐
               │    p87. fig 8 - 5                │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │图 8 - 5 "剪" 操作中被选择的文字列│
               └—————————————————┘


8.4.1 剪 (cutting)

"剪" 一段文字 :

    1. 移动游标至你想要 "剪" 的那一段文字的一端.

    2. 按下滑鼠左按钮, 并保持按住.

    3. 拖拽游标至该段文字的另一端 : 在你移动的时候介於启始位置与游标位置
       间的文字会以高亮度显示.

    4. 放开按钮 : 被选到的文字维持高亮度, 任何先前所选择的高亮度本文 (甚
       至在别的视窗中) 变为非高亮度.


8.4.2 贴 (pasting)

"贴" 一段本文 :

    1. 移动游标至你想要插入一段文字的位置.

    2. 碰触滑鼠中间按钮 : 先前被选定的文字被插入. (目前的选择仍保持高亮
       度)

    当你将本文 "贴" 入一个视窗, 它真的就像你用键盘打入的一样 -- 你可以使
    用正常的列编辑键去消除字元, 单字, 或整列 (当然假如 "贴" 了许多列, 你
    只能编辑最後一列, 就像你只能编辑最後敲入的一列一样).

注意 : 假如你试图 "贴" 太多文字到一个 xterm 视窗, xterm 可能永远悬(hang)
       在那里. (我们试"贴" 过多到 4000 个字元没有问题, 但这个值并不保证永
       远不发生问题.)


8.4.3 剪一个字或一列

    假如你想剪一个字或一列, 你可以直接选择它而不需拖拽过它.

    "剪" 一个字 : 指标移到一个字的任何位置, 并碰触两次滑鼠左按钮 : 该字
    即被选择.

    "剪" 一列 : 指标移到一列的任何位置, 并碰触三次滑鼠左按钮 : 该列即被
    选择.

    碰触滑鼠按钮两次与三次是所有以滑鼠基础(mouse-based) 的系统之共同用法,
但在这个例子有特殊的功能: 连续而独立的几次碰触与一个多次碰触是不同的,其
差异取决於介於按下按钮(button-down)与松开按钮(button-up)的期间内有没有其
他的事发生. 所以下列算作碰触三次 :

    DOWN ... pause for a few seconds ... UP DOWN ... another
    pause ... UP DOWN ... pause

这是很有用的 : 因为在碰触後只要你保持按下, 只要更进一步藉著使用 up/down,
你可以改变选择模式 (字元, 字, 列)。


8.4.4 扩大一个选定区块或 "剪"

    只要你有一个选定区块, 你可以扩大它 (或缩减它), 如下 :

    1. 移动指标至你想选择的新端点, 它可以是在已存在的一个区域□面 (当你
       想缩减它时) 或外面 (当你想扩大它时)

    2a. 碰触滑鼠左按钮 : 选择区的端点调整为目前指标位置. 或 ...

    2b. ... 若以按下、拖拽和放开按钮来取代碰触. 在这个状况下, 选择区跟随
        游标变动, 且为高亮度.

    有一个方便的技巧可以选定文字区块, 首先标定你想选定的本文之一端, 碰触
滑鼠左按钮, 然後移至另一端碰触滑鼠右按钮 : 中间的文字即被选定. (这是扩大
选定区的变相方法. 开始时选择区是空的 - 即你已碰触滑鼠左按钮, 但没拖拽通
过任何文字 - 然後你碰触滑鼠右按钮来扩大这个空选定区.)


8.4.5 字或文字列边界的选择

    假如你想选择一些字或文字列, 你可以藉著在碰触按钮之前小心地定位指标来
完成.但这里有一个简捷的方式 - 再次利用多次碰触按钮. 选择文字或文字列 :

    1. 将游标移到你想 "剪" 的文字之一端.

    2. 按下滑鼠左按钮, 并保持按著 ...

    3. ... 拖拽游标至你想要 "剪" 的文字之另一端 : 启始点至游标间的本文为
       高亮度. (如图 8 - 6 上图)

    4. 放开并迅速连续地再按下按钮 : 高亮度区扩展至最接近单字的边界. (图
       8 - 6 中图)

    5. 放开并迅速连续地再按下按钮 : 高亮度区扩展至已选定列的尾端. (图
       8 - 6 下图)

    6. 放开并迅速连续地再按下按钮 : 高亮度区回复至原来的大小, 亦即选定区
       回到字元边界. (图 8 - 6 最上面)

    相同的技巧可应用於以右按钮扩展已选择的区块.

               ┌—————————————————┐
               │    p92. fig 8 - 6                │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 8 - 6 以字元, 字与列 "剪" 文字│
               └—————————————————┘


8.5 使用 Tektronix 模拟功能

    xterm 可以模拟一个 Tektronix 4014 终端机和一个 VT102 终端机, 使你可
以用它来显示图形. 当你在一个远方机器执行 非-X应用程式而想在你的显示器
上看图时, 特别有用.

  xterm 为每一个 "终端机" 使用一个不同的视窗, 所以你可以将所有文字显
示於一个视窗, 而另一个视窗显示图形, 如图 8 - 7. 某个时间只有一个视窗活
动(active)著, 亦即所有的键盘输入或被 "贴" 入的本文 -- 被导引至活动视窗
, 甚至当指标在别的视窗时也一样.

你可以使用终端机的逃脱序码 (escape sequence) 或使用 modes 选单选择你需
要的视窗.你可以使用你的视窗管理器完全分开地处理两个视窗. 例如 : 你可以
表徵图化 VT 视窗,然而保留一个开启的 Tek, 等. 你也可以使用适当的 xterm
选单选项 (Tek Window Showing, Hide VT Window, 等) 去隐藏或显现一个视窗

BBS水木清华站∶精华区

TOP

BBS水木清华站∶精华区
因而显现或隐藏其他视窗.

注意 : 隐藏不是将它送到堆叠的底部, 或表徵图化. 假如你使用选单 "隐藏"一
       个视窗, 当下次你要求再出现时你必须像开启一个新的应用视窗一样地安
       置 (position) 它.

               ┌—————————————————————┐
               │    p93. fig 8 - 7                        │
               │                                          │
               │                                          │
               │                                          │
               │                                          │
               │ 图 8 - 7 xterm 的正常视窗与Tektronix视窗 │
               └—————————————————————┘


8.5.1 Tektronix 的特殊功能

    Tektronix 选单 (同时按下 CONTROL 与滑鼠中间按钮可得到) 提供你一些类
似 Modes控制 xterm 视窗的功能. 但它仅提供用於 Tektronix 视窗的(功能)项目.

    改变字元的大小 : 你可以从四个不同的大小选择, 范围从 Large Characters
        (预设值) 到 Small Characters. 你可以在任何时刻改变它, 甚至在一
        列中间. 在改变之前已出现在萤幕上的字元不受影响.

    清除萤幕 : Tektronix 的一个特性是它的萤幕不卷动. 在萤幕上有两行
        (column) (左与右) 为本文, 当其中之一已写满, 输出切换到另一端, 然
        而, 已显示的字元不清除 (erased), 因此萤幕不久会变混乱, 除非你下
        命令清除它. 想这样做的话需於 Tektronix 选单选择 PAGE : 萤幕会被
        清除, 且游标被移至左上角.

    重置 "终端机" : 於 Tektronix 选单选择 RESET. 字元的大小与线的型式 (
        可能因一个程式输出至视窗而改变) 被设回预设值, 且 PAGE 的萤幕清除
        功能会被执行.

    拷贝视窗内容至一个档案 : 於 Tektronix  选单选择 COPY, 自从最近一次的
        PAGE功能後任何写到萤幕的内容都会被拷贝到名为 COPYyy-mm-dd-hh.mm.ss 的
        档案. yy-mm...... 为当时时刻. 该档被建於启动 xterm 时的目录下.

    重绘 Tek 视窗会花一些时间 : 当它发生时, Tek 视窗内的游标变成一个闹钟
        (见图 8 -

               ┌——————————————————┐
               │    p94. fig 8 - 8                  │
               │                                    │
               │                                    │
               │                                    │
               │ 图 8 - 8 被用於 xterm 的 Tektronix │
               │        视窗内的闹钟形指标          │
               └——————————————————┘


8.6 使用不同字型

    xterm 可以让你从正常的文字与粗体文字选择不同的字型, 字型选择必须有固
定的宽度且彼此大小相同. 你目前尚不知道如何找到可以利用的字型, 但它的应用
范围很广, 下面的例子我们将只用两种, 这两种是 core 版本提供字型的一部分:
8x13 (一个字元大小为 8 像素宽, 13 像素高) 与 8x13b (一个粗体变体)

    欲指定特殊字型必须使用命令列选项 :

    -fn font : 使用 font 的正常字型, 取代预设的 "fixed" 字型.

    -fb font : 使用 font 的粗体字型, 取代预设的 "fixed" 字型; 预设状态下
        xterm 不区分粗体字的本文.

    图 8 - 9 所显示的是执行下列命令

        xterm -fn 8x13 -fb 8x13b

    明确地指定正常与粗体字型的结果. 我们将在 "使用X的字型与色彩" 一章
中 (第13章) 进一步说明视窗字型与颜色.


               ┌—————————————————┐
               │    p94. fig 8 - 9                │
               │                                  │
               │                                  │
               │                                  │
               │ 图 8 - 9 具有粗体与正常字型的    │
               │        xterm 视窗                │
               └—————————————————┘

8.7 使用色彩 (colour)

    假如你有彩色显示器, 你可以用命令列选项设定一组 (些) 视窗元素去指定
  色彩: 

    -fg colour : 以 colour 颜色印出前景, 亦即文字.

    -bg colour : 以 colour 颜色作视窗背景.

    -bd colour : 以 colour 颜色画视窗边界.

    -ms colour : 以 colour 颜色为滑鼠指标颜色.

    -cr colour : 以 colour 颜色为游标颜色.

    参照连接在网路上的机器对视窗设定的色彩码, 你可以发现非常有用. 设定滑
鼠与游标为显眼的颜色也是有帮助的, 使你在纷杂的视窗中较容易看得到它们.


8.8 其他 xterm 选项

    有许多其他的选项可以被 xterm 接受. 有些是设定终端机的特性, 例如 :
-display与 -geometry 前面已经讨论过. 所有的这些都描述於 xterm 指南页
(manpage), 中,但下面是一些有用的杂项 :

    -iconic : xterm 应该以表徵图启动的方式取代由正常方式 "开启" 视窗.(当
         使用uwm 为你的视窗管理器, 表徵图的初始位置将决定於表徵图被产生
         当时的游标位置. 我们将在 "定义应用程式的预设选项 -- Resources"
         这章 (第15章) 里教你如何明确地指定一个表徵图位置)

    -title string : 使用 string 为视窗标头 (抬头), 这个标头就像图 6 - 8 在
         新开启视窗所看到的一样, 且某些视窗管理器可能将它包含在视窗标头棒
         (title bar).

    -C : 这个视窗应该将接收的输出送到系统控制台 (例如 : 磁碟已满讯息, 装
         置错误 (device error), 等) 若你没有一个视窗具有这个选项指定, 控
         制台讯息可能直接出现在你的萤幕 (亦即不在一个固定视窗中) 并扰乱
         显示; 若发生时, 只要使用 uwm 的选单选择 RefreshScreen 去恢复正常
         显示即可.

    -e prog [args] : 在视窗中执行具有选择性引数的 prog 程式, 取代启动一
         个 shell.(此选项必须在命令列的最後, 所有在它後面的视为 args 的
         部分). 你经常需要使用 -e 去 rlogin 到一个不支援X的远方系统, 例
         如 :

         xterm -title saturn -e rlogin saturn -l root



8.9 设定终端机键盘

    X 本身可让你改变键盘对照表, 所以你可以为针对不同的情况改变它以适合一
个国家的使用习惯. 但这个对照表仅决定那个 "字元码" 联结到一个给定的键.
client 程式 (像 xterm 但更进步) 则可指定任意的字串给任何键或键组 (组合
键). 使用这个结构你可以设定一个 xterm 特别适用於邮件程式, 或一个除错器,
你只要指定一般命令给功能键, 或控制字元, 甚至单一字元。这个结构的详细部
分相当的复杂,所以我们将延缓到 "订制你的键盘和滑鼠 -- 转译" 一章(第18
章)中再介绍.

8.10 结论

    xterm 是一个具有许多选项与功能的复杂的程式, 幸运地是大多数的时间你不
需要使用它们, 而当你使用时通常是在你开始启动 xterm 时将它设定成你喜欢的
架构. xterm的指南页 (manpage) 是一个很长的程式功能参考文件. 在详读它之前
, 你尽可能在一般的操作时不使用它, 较专门特别的地方才查考它.

注意 : 指南页提到文件 "Xterm Control Sequence " (控制顺序)这文件目前还在
       准备中, 并不是发行版本的一部份.

    许多介面特性 (功能) 例如 : 卷动棒与如何以指标选择本文等, 是藉由标准软
体 widget (小工具)写在程式里 (在第15章的 toolkit 那节有较多的介绍). 你
将发现许多由其它X应用程式提供的介面都是相同的, 例如: 第10章的 xman 与
xedit. 在继续探讨它们之前我们先在下一章看看一些虽然小但有用的程式.

=====

第9章 方便的程式和视窗相关的工具

    到目前为止我们已经涵盖了使用系统的基本元素, 有了 xterm功能, 你开
始从视窗系统获得看得见的优点. 在本章我们描述一些小程式, 开始去充分使
用系统并使你的工作更方便.

    这章先提出 "案头附属品" (desk accessory) 的方便程式, 接著介绍捕捉
(capturing)、恢复 (restoring) 与列印萤幕影像的一组工具.



9.1 方便的程式

    本节所描述的一些程式功能虽属次要, 但是却可以使你工作得更方便轻松.
有些我们曾经提过 -- xclock 与 xcalc --  但在这里将更有组织地描述, 我
们将看一些可以显示目前机器负载和告诉你有邮件送达等功能的新程式.


9.1.1 一个类比或数位时钟 - xclock

    在第5章中我们用 xclock 为范例程式, 它有下列命令列选项 :

        指定视窗初始大小与位置 : 用 -geometry geomspec.

        设定背景色 : 用 -bg colour.

        设定前景色 : 用 -fg colour.

        设定指针的颜色 : 用 -hd colour.

        指针边缘高亮度 : 用 -hl colour, 以高亮度 colour 颜色为指针的
            边缘.

    其他有用的选项 :

        使用数位时钟 : -digital, 告诉 xclock 使用一个 24 小时的数字型
            时钟, 以取代预设的类比型, 如图 9 - 1.

        设定 "时钟-滴答" 频率 : -update num, 使时钟每 num 秒更新显示一
            次. 处於指针状态下, 若 num 小於 30 秒则以一个钻石形秒针每
            num 秒移动一次, 如图 9 - 2. (预设值为 60 秒)

        设定半小时钟声 : -chime, 每半小时整使终端机铃响一次, 每一个小
            时整铃响两次.

               ┌————————————————┐
               │    p98.  fig 9 - 1             │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 9 - 1 数字型时钟            │
               └————————————————┘


               ┌————————————————┐
               │    p98.  fig 9 - 2             │
               │                                │
               │                                │
               │                                │
               │ 图 9 - 2 具有钻石形秒针的指针型│
               │        时钟                    │
               └————————————————┘


9.1.2 一个桌上型计算器 - xcalc

    这是另一个我们曾经用过的程式. 我们用过的命令列选项如下 :

        指定视窗初始大小与位置 : -geometry geomspec.

        设定背景色 : -bg colour.

        设定前景色 : -fg colour.

    其他选项 :

        指定计算尺 (slide-rule) 模式 : -analog, 执行程式模拟一个计算
            尺 (图 9 - 3) 取代电子式计算器. 这实在很稀奇, 但一些更进一
            步的指令包含於下面, 因为它不包含在指南页内.

        指定 HP-10C 型计算器 : -rpn (代表反波兰记数法 (Reverse Polish
            Notation)), 告诉 xcalc 模拟 HP-10C 型计算器 (如图 9 - 4).

    各种计算器模式的更深入的指令说明包含於指南页. (无论你处於那一个模式
, 当你将它表徵图化时, 其表徵图都是图 9 - 5 的样子.


               ┌——————————————————┐
               │    p99.  fig 9 - 3                 │
               │                                    │
               │                                    │
               │                                    │
               │                                    │
               │ 图 9 - 3 类比的 xcalc 是一个计算尺 │
               └——————————————————┘


               ┌——————————————————┐
               │    p99.  fig 9 - 4                 │
               │                                    │
               │                                    │
               │                                    │
               │                                    │
               │ 图 9 - 4 反波兰记数法 xcalc 计算器 │
               └——————————————————┘
               ┌————————————————┐
               │    p99.  fig 9 - 5             │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 9 - 5 xcalc 表徵图          │
               └————————————————┘


使用计算尺

    使用滑鼠按钮操作计算尺. 当滑鼠指标进入视窗内, 指标变成手型游标.

        定位滑尺 - 左端 : 移动指标进入滑尺区, 定位至你想要的地方,碰
            触左按钮,滑尺左端跳至指标位置.

        定位滑尺 - 右端 : 与设定左端一样, 但碰触右按钮.

        定位计算尺的游标 : 定位指标至你想要的尺体位置, 并碰触左按钮
            : 尺的游标跳至指标位置.

        滑动滑动棒 (slide-bar) : 定位游标至滑尺, 按下中间按钮, 并保
            持按著 ... 拖拽滑尺到你要的位置, 然後放松按钮.

        将尺的长度变为两倍 : 在尺体上碰触中间按钮.

        将尺的长度变为一半 : 在尺体上碰触右按钮.

注意 : 假如你以左或右按钮拖拽, 将会有奇怪的事情发生.


9.1.3 显示机器的负载平均 - xload

    xload 显示系统平均负载 (在执行伫列里的平均工作数目) 的柱状图 ,
它会定期地更新. 典型的输出如图 9 - 6a, xload 的表徵图如 9 - 6b.

               ┌———————————————————┐
               │    p100.  fig 9 - 6                  │
               │                                      │
               │                                      │
               │                                      │
               │                                      │
               │ 图 9 - 6 xload 的正常视窗与表徵图视窗│
               └———————————————————┘


9.1.4 邮件通知程式 - xbiff

    xbiff 是一个监视你的邮件档与让你知道何时有邮件到达的小程式. 它显
示一个邮箱的图案; 当没有新邮件时邮箱的旗子是向下的 (图 9 - 7a). 当有新
邮件进来时, xbiff 响铃, 竖起旗子, 并使图案变成反相显示 (图 9 - 7b).

    你可以在 xbiff 视窗上碰触任何滑鼠按钮, 强迫旗子放下.

    xbiff 接受一般对色彩的命令列选项 (-bg, -fg, -bd) 与对视窗特性的
命令列选项(-display, -geometry, -bw). 其他包括 :

    指定检查邮件频率 : -update num, 告诉 xbiff 每 num 秒检查邮箱一次
, 看是否有新的邮件到达. (预设值为 60 秒)

    指定一个特定邮件档 : -file filename, 使 xbiff 检查在 filename 内
的邮件, 取代预设名称的档. 预设名称为 /usr/spool/mail/username, 其中
username为你的登录名称 (login name)。

    xbiff 特有的 -file 选项, 对网路上的邮件被集中处理和你的邮箱由
另外的机器处理等两方面非常有用. 下面的命令让你执行某个邮件机器(比
如说mars) 上的 xbiff程式, 查看你的邮箱, 并将显示送回你自己的机器venus:

    rsh mars xbiff -file /var/spool/mail/smith\
    -display venus:0 &

               ┌—————————————————┐
               │    p101.  fig 9 - 7              │
               │                                  │
               │                                  │
               │                                  │
               │ 图 9 - 7 xbiff 邮件监视视窗的两种│
               │        状态                      │
               └—————————————————┘



9.2 储存, 显示与列印萤幕影像

    X是一个图形系统, 而你将用它在视窗内显示文字与图形. 经常X视窗的使
用者会想要捕捉萤幕上的某些影像, 以便稍後你可以重新显示它, 或送至硬拷贝
(hard-copy)装置列印. 下面的小节将描述这些功能.


9.2.1 储存一个视窗的影像 - xwd

    xwd 倾印 (dump) 一个视窗的影像到一个档案. 这个档案稍後可以被其他
程式处理 (例如列印一个硬拷贝).

    使用 xwd 有许多种不同方法. 你可以明确地指定一个输出档 (使用命令列
选项-out name), 或者使用 xwd 倾印影像到标准输出. 你也可以明确地指定想
倾印的视窗, 或可以让 xwd "提示" 你一下.

    让我们拿最简单的一个例子 : 於 xterm 下以下列命令启动程式

        xwd > outfile

只要 xwd 启动, 游标便会变成 "十字线" (cross hairs) 状, 见图 9 - 8. 移
动指标进入你想要倾印的视窗, 并碰触任何按钮 : xwd 响一次铃表示它已经开始
记录视窗影像, 且在它完成时响两次铃. 然後游标恢复正常.

               ┌————————————————┐
               │    p102.  fig 9 - 8            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 9 - 8 十字线形游标          │
               └————————————————┘

注意 1 : 假如你试图倾印在萤幕上不完整的视窗, 程式可能失败并在你的控
制台 xterm 视窗内显示出一长串的错误讯息 (假如你有一个控制台的话).

注意 2 : 被捕捉的影像是你真正在萤幕上的视窗边界内所看到的, 特别的是,
假如视窗的某部分被另一个视窗覆盖, 倾印的影像将展现视窗涵盖的可见部分
以及遮蔽视窗重叠的部分. (例如 : 图 9 - 9 展示一个被 xman 覆盖的一个
xterm 视窗的倾印结果) 这似乎是一个不方便的功能, 但有它的优点 :若想要
获得整个萤幕的倾印影像, 只要对根视窗执行 xwd 即可; 就如同你在萤幕上
看到被覆盖的根视窗一样, 用这个方法你可以得到完整萤幕的图片.

               ┌—————————————————┐
               │    p102.  fig 9 - 9              │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 9 - 9 一个被重叠视窗的倾印结果│
               └—————————————————┘

如何指定被倾印的视窗

    有两种方法可以透过命令列选项告诉 xwd 要倾印那一个视窗.

    -root : 倾印根视窗. 例如 : 想得到萤幕的一个完整图片, 使用命令 :

            xwd -root > screenpic

    -id win-id : 倾印视窗识别码为 win-id 的视窗. (每个由 X server 建
            立的视窗皆有一个唯一的视窗识别码 : 它只是一个识别视窗的
            号码. 我们将在 "资讯与状态程式 " (Information and status
            program)那一章 (第12章) 中告诉你如何找到一个指定视窗的
            识别码).

    (这些选项在 xwd 指南页内没有描述)

    使用这些选项的好处是你不必使用滑鼠去指定你感兴趣的视窗. 因为有时
候在倾印的同时,滑鼠必须出现在某个特定的地方执行某项特定的功能,例如:
呼叫一个突现式选单, 或使一个命令按钮出现你想要的状态. 举例来说:欲储存
图 6-1的萤幕影像, 滑鼠必须被使用以突现uwn 选单,因而造成你没有办法同时
使用滑鼠去指定 xwd 的目标. 下面是如何捕捉一个影像的步骤 :

    1. 在一个 xterm 视窗, 键入命令

           sleep 10.xwd -root > uwmfile

       在捕捉影像之前, 给你自己时间使萤幕进入你要的状态.

    2. 移动指标至背景视窗上.

    3. 按下滑鼠中间按钮, 出现 WindoeOps 选单, 并保持按下不松开 ...

    4. ... 等一下, 直到 xwd 响铃一次告诉你开始, 完成则响铃二次. 然後
       放松按钮.

    相同的方法 (技巧) 被用於捕捉第8章所述之 xterm 选单,  请注意必须
使用明确的视窗识别码. (在 "资讯与状态程式" 那一章 (第12章) 中将再一
次提到)


9.2.2 放大萤幕视窗影像 - Xmag

   xmag 容许你快拍 (snapshot) 任何萤幕的影像, 并以任意倍数放大他们. 最
简单的方法为采用交谈方式指定你感兴趣的区域:

    1. 启动程式 (用 xmag 命令) : xmag 显示一个闪动的矩形外框.

    2. 将矩形框安置到你想要的地方上.

    3. 碰触任何按钮 : xmag 快拍矩形框内的区域, 并显示一个清新的视窗
外框, 里面正显示放大的 (enlarged) 快拍影像.

    4. 仿照在第6章启动 xclock 後所采用的方法一样使用指标与按钮放置
       外框. (例如 : 碰触滑鼠左按钮将视窗安置在指标目前所在的位置)

    5. xmag 在你刚安放的视窗内, 重绘放大的影像.

    你现在可以选择底下任一动作:

  . 你可以按 Q 或 q 或 CTRL-C,接著指定 xmag 视窗内的选项, 跳出 xmag.

  . 你可以按滑鼠中间按钮或左按钮以移开目前放大的视窗, xmag 再次显示
    出它的闪烁矩形, 所以你可以放大萤幕上另一个区域.

  . 按下滑鼠左按钮 : xmag 显示出在指标下的像素座标, 即像素的号码 (它
    是一个该像素颜色的内部表示法), 以及像素的 RGB 值, 亦即像素颜色的
    红, 绿, 蓝成分. 当你移动指标, 这些显示随著更新, 直到你放松按钮.

程式记录快拍影像只是为了立即再显示 -- 没有任何方法可以取得它以便倾印
影像至一个档案.

xmag 的命令列选项

    预设的操作方法被一些方式限制住 -- 你必须以交谈方式指定被放大的区
域, 区域的形状与大小被固定, 放大率都是 5. 但事实上你可以使用命令列选
项改变上述所有的特性 :

    指定不同的放大率 : -mag num, 放大影像 num 倍 (num 须为整数). 例
        如 : -mag 2, 将产生一个为原来两倍宽与两倍高的影像.

    指定大小与放大区域的位置 : 使用 -source geomspec. 例如 :

            -source 300x100 + 450 + 762

        xmag 不提示任何讯息, 但将直接跳到它显示放大视窗外框的步骤, 假
        如 geomspec 只有位置部分, 则大小部分预设为 64x64.

    仅指定放大区域的大小 : 使用 -source geomspec, geomspec 仅由大小
        部分组成, 就像

            -source 300x100

        xmag 将显示一个闪烁的 300x100 的矩形外框, 等你定位与碰触按钮.


9.2.3 储存一部分萤幕的影像

    xwd 仅对单一, 完整视窗操作. 假如想补捉一个视窗的某部分, 或某些视
窗一起,你必须采用两阶段处理 :

    1. 使用 xmag 程式选择你要的区域, 并在一个单一视窗 (亦即 xmag 本
身) 显示它.

    2. 用 xwd 倾印 xmag 视窗至一个档案. (假如你想倾印与最初一样大小
       的影像, 别忘了指定 -mag 1 给 xmg.)


9.2.4 显示一个先前倾印的影像 - xwud

    xwud "反倾印" (undumps)一个先前曾经被倾印至一个档案的影像, 也就是
再次将影像显示於萤幕上.预设的作法是它从标准输入读入倾印档, 所以反倾印
一个你想要档案类似:

        xwud < screenpic

    xwud 显示闪烁的视窗外框, 准备让你使用视窗管理器. 当你已安置好它
, 影像即被显示. 当然你可以利用视窗管理器移动视窗, 重定大小, 表徵图化
, ...等, 就如同其他任何视窗一般.

注意 : 在指南页内提到的 -inverse 可能无法正常运作。


9.2.5 列印先前倾印的影像 - xpr

    xpr 能够转译一个先前曾倾印的影像为可送至硬拷贝印表机列印的格式. 它
支援各种不同的印表机 - PostScript, DEC LN03 与 LA100, 以及 IBM PP3812.
由於预设是写到标准输出, 所以典型的用法应该是 :

    xpr -device ln03 < screenpic | lpr

xpr 的命令列选项

    xpr 接受数个选项, 包括控制影像在纸上的位置, 大小与配置, 和指定输
出的印表机型式 :

    指定印表机型式 : 使用 -device type, 这里的 type 是指 ln03, la100,
        ps (PostScript) 或 pp (指 PP3812).

    控制影像的大小 : 由於预设 xpr 以最大的尺寸列印影像, 你可以用
        -width num 或 -height num  指定最大的宽度或高度, num 的单
        位为 inch (不必是整数).

    对影像标刻度 : 你可以使用 -scale num 对影像标刻度, num 为整数.
        作法与 xmag 的 -mag 选项类似, 但大小可能扭曲, 因为印表机可
        能有不同的解析度, 亦即每个 inch 有不同的点 (像素) 数, 例如 :
        -scale 2 表示每个萤幕像素被印表机印成 2x2 点的方形, 所以假
        如你的萤幕为 75 dpi 且你的印表机为 300 dpi, 列印影像仅为萤
        幕影像大小的一半 (75x2/300 = 0.5).

    加影像标题 : 使用 -header string 或 -trailer string 分别将一文字
        字串印在影像的上面或下面.

利用单一操作命令倾印与列印一个视窗 - xdpr

xdpr 是一个使用 xwd 倾印视窗影像, 接著使用 xpr 格式化列印影像, 最後
使用 lpr 印出影像的一个程式. 它接受所有这三种程式的命令列选项 (事实
上 xdpr是一个 shell描述, 它将上述三种程式包装在一起以便使用。它真正
的工作为检查命令列上的各个选项且传送它们给适当的程式)

9.3 结论/摘要

    在本章中你已见过一些可帮助你处理日常的工作小程式, 和一些特殊的工
具以记录和重新 (建立) 产生萤幕影像. 拥有这些工具你开始得到视窗系统的
优点并开始使用它的图形能力.

    下一章我们继续以相同的方向看一些普通的公用程式, 看它们如何利用视
窗系统去简化操作与增强使用介面.

=====

第10章 使用X的应用程式

    本章将介绍一些包含在 core 版本内的公用程式, 它们的主要功能和视窗
系统并无密切关系, 但使用它们却可提供一个相当不错的使用者介面 :

    . Xedit - 一个以视窗为基础的 (window-based) 一般目的文字编辑器.
    . Xman  - 一个指南页 (manpage) 或系统文件的浏览工具.
    . Xmh   - 一个 mh 邮件处理程式的视窗前端 (front-end) .



10.1 文字编辑器 - Xedit

    Xedit 是一个非常简单而具有视窗介面的文字编辑器. 藉著对 Xedit 所
显示的选择盒碰触按钮, 你可以完成某些操作, 但透过使用键盘你可以执行的
更多, 特别是控制字元. 在这个程式内大多数以键盘为基础的功能由一个标准
软体片段提供 -- 假如你喜欢也可以视为一个建筑区块 "building block" --
叫做一个文字小工具 (text widget). (有关小工具 (Widget) 在 "资源
(Resources)" 那一章 (第15章)中我们将谈得更多). 因为这是一个很普通的
结构, 且你将在其他地方遇到相同的编辑功能, 我们在随後的几节将详细描述
它的功能.


10.1.1 启动与结束程式

    假如你想编辑一个名叫 foobar的 档案, 在 xterm 视窗键入命令 :

        xedit foobar &

    (假如你不想编辑已存在的档案, 只要键入 "xedit &")

   xedit 启动与显示它的视窗, 如图 10 - 1 :

               ┌————————————————┐
               │    p108  fig 10 - 1            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 10 - 1 xedit 文字编辑器     │
               └————————————————┘

    视窗被分成三部分 :

    . 上面是命令选单, 具有标著 Quit, Save 等的命令盒.

    . 中间部分是讯息视窗, xedit 在里面显示错误讯息与状态, 你也能把它
      当作一个抓取区 (scratch area) 来使用, 可在里面键入一段你想剪贴
      到其他地方的文字.

    . 下面较大的部分是编辑视窗, 它显示你正在编辑或建立的本文.

    当你想结束程式时, 在 Quit 盒上碰触左按钮, 假如你做了一些改变但未
储存, 则 xedit会在讯息视窗内印出警告讯息 :

      Unsaved changes. Save them, or press Quit again.


10.1.2 插入文字

    首先确定指标在编辑视窗内, 然後键入你要的文字 (键盘上任意的列印字
元),在你键入时,被直接地插入. 当你键入时, 你将会注意到新插入的文字是不
断地推送一个在它前面的一个小脱字符 (^) 游标 : 这个游标是插入点
(insertion point) 或简称为点 (point). 任何你键入的或贴入(paste-in)
的文字都将在这个点的位置被插入. 插入点总是位於两个字元间, 而不在一个
字元上面 (就像一个正常终端机游标的状况).

自动 "列卷绕" (Line-Wrapping) -- xedit 的 "段落" (paragraphs)

    当你在接近一列的尾端插入文字, 假如你键入的字太长以致无法适合目前
这一列时, xedit 将自动移至下一列. 假如接著剪短该字使得可以适合它原来
的列,它将再跳回上一列.

    这个作用与 xedit 的段落定义息息相关 : 一个段落是被新列字元
(newline character)终结的本文. (实际上它意味著连续键入文字而无需插入
新列字元) edit 列卷绕仅作用於一个段落内, 且能正确地处理特殊状况, 例如 :
在移动一个单字 (word)到这列时造成这列必须卷绕到下一列的状况等等.

注意 1 : 这个段落的定义实际上就是被各种其他 Unix 程式视为一列的定
         义, 若你使用 xedit 编辑一个正常的档案, xedit会将读入的每一列
         视为一个段落处理.

注意 2 : 显示器没有明显的标示出萤幕上的一列在尾端有一个新列字元 (无法
         凭肉眼直接辨识) , 亦即xedit 可能视它为一个列尾或一个段落.

注意 3 : 以 xedit 产生的档案, 若用其他程式查看内容时, 可能看到具有非
         常长的一列.

译注:这种方式类似於 PC 上的 Wordstar 文书编辑器。


特殊插入操作

下面有一些插入新列的特殊命令, 各种命令稍为有些不同:

    插入一个新列, 且插入点移至新列 : 按 RETURN. 便可以插入一个新列, 事
        实上就像插入任何列印字元一样. 且假如你不靠 xedit 的列卷绕,
        这是移至新列的正常方法.

    插入新列, 且对齐 : 按 LINEFEED键插入一新列并移动插入点到下一列,
        但任何你键入的列印文字将与上一列的文字对齐. (对键入表格等很有
        用).

    插入一新列, 但不移动插入点 : 按 ctl-O. 可以插入一个新列, 但点仍
        留在同一列. (当你想分开一列并加文字到被分成二列中的第一列尾
        端时使用)


10.1.3 剪 (cutting) 与贴 (pasting)

    就像在 xterm 中一样的, 你可以选择并 "剪" 出一段文字, 但是有一个
讨厌的差异 : 当选择字或列时, 你必须迅速碰触二次或三次按钮 - 你不能在
按钮按下或松开时暂停.

    在插入点的地方贴入文字时, 你可以像以前一样的碰触中间按钮, 或按
meta-Y键.


10.1.4 移动插入点

    移动插入点最简单的方法是使用滑鼠 : 移动视窗文字游标 (在图 5 - 2
所看到的垂直棒)到任何你想要的地方, 并碰触滑鼠左按钮. 插入点的 ^ 标志
即跳到新位置.

    但通常使用键盘移动插入点也很简单 - 当你正在编辑时, 它会打断你的
节奏, 因为必须拿起滑鼠, 移动它, 最後再次将你的手移回键盘. xedit 提供
一次移动一个字元、单字、列或页的方式移动插入点 :

一次一字元移动插入点

    这是移动点的最基本型式 :

        向前一个字元 : 按 ctl-f 或 RIGHTARROW

        向後一个字元 : 按 ctl-b 或 LEFTARROW

        向上一个字元 : 按 ctl-p 或 UPARROW

        向下一个字元 : 按 ctl-n 或 DOWNARROW

    假如你接近一列的开头, 按几次 ctl-b 後,你将回到前一列. 按几次
ctl-f 後可回复至原位. 假如你是在一页的最上面 (最下面) 一列, 类似的
效果会发生 : 移至前 (或下)一列, 将引起文字卷动使你移至的列能被看得
见.

一次移动一个单字、一列或一个段落

    这些是编辑文字时所须的自然移动功能.

        向前一个单字 : 按 meta-F 或 meta-f

        向後一个单字 : 按 meta-B 或 meta-b

        移至列尾     : 按 ctl-E

        移到列的开头 : 按 ctl-A

        向前一个段落 : 按 meta-]

        向後一个段落 : 按 meta-[

    你可以看到一个规律开始浮现 : ctl-char 对单一字元操作. 而 meta-char
对单字作相同的事. e.g. ctl-F 向前一个字元, meta-F 向前一个字.


大量移动 - 以页与档案为单位

    假如你想获得较大的跳越, 就像在 xterm 里面一样, 你可以使用卷动棒
. 然而, 卷动文字并不会移动插入点 : 当你键入或清除任何内容时, 文字将
自动地卷回插入点, 让你可以看到你作了甚麽.

    如果你想卷动显示内容且移动插入点, 使用 :

        往前一页 : 按 ctl-V

        往後一页 : 按 meta-V

        到档案的开头 : 按 meta->

        到档案的尾端 : 按 meta-<


10.1.5 移除不想要的文字 - 删除 (Deleting)  或 杀掉 (Killing)

    有两种移除文字的技巧 - 删除只将文字移除, 杀掉则除了移除文字外,
并将文字储存至 "剪缓冲区" (cut buffer), 以便稍後你可以取回. 杀掉命令
仅对较大单位的文字作用 (最小单位为单字) - 因为假如你删除一个字元, 它
就像没有杀掉它一样很容易再打入.

    在下面的叙述, "下一个" (next) 意思是正好在插入点之後, "前一个"
(previous) 意思是正好在插入点之前.

删除文字

    删除前一个字元 : 按 DELETE 或 BACKSPACE 或 CTL-H.

    删除下一个字元 : 按 CTL-D.

    删除下一个单字 : 按 meta-d.

    删除前一个单字 : 按 meta-h, 或 meta-DELETE 或 meta-BACKSPACE,
        不用 SHIFT 键.

注意 : meta-h 与 meta-H 不同.

    假如你在一列的开头按下 DELETE 键, 它将删除前一列的尾端的新列字
元, 而将两列合并成一列.

杀掉文字

    杀掉下一个单字 : 按 meta-D

    杀掉前一个单字 : 按 meta-H 或 shift-meta-DELETE shift-meta-BACKSPACE.

    从游标位置杀到列尾 : 按 ctl-K

    从游标位置杀到段尾 : 按 meta-k

    杀掉目前选定的文字区块 : 按 ctl-W

救回杀掉的文字; 拷贝与移动文字

    只要你曾经 kill 某些文字, 你就能按 ctl-Y 救回它, 最近被杀掉的文
字在插入点的地方被插入. 但有几点须注意 :

    . 只有最近被杀掉的文字可以被救回 - 你无法将一连串被杀掉的文字取
      回.

    . 救回的文字是被插入到目前插入点的位置 - 不是该段文字原先被移除
      的地方.

    . 若是需要的话你可以救回相同的文字许多次, 亦即按 ctrl-Y 并不影响
      缓冲区之内容.

基於"杀掉"动作的原理, 你可以用它来移动或拷贝文字区域.

      移动文字 : 先 kill 它, 再将点移动到你想重新放置的地方, 最後
          un-kill.

      拷贝文字 : 先 kill 它并 un-kill 它, 使拷贝的来源不变; 再将
          点移动到你想拷贝的地方, 最後 un-kill.


10.1.6 取消改变 (Undoing Changes)

    假如你作了某些改变 - 杀掉或删除或键入或贴入文字 - 但稍後发现并不
是想要的, 你可以复旧 (undo) 它. 在 undo 盒里碰触左键 : 取消最近的改变
. undo本身也是一个改变, 所以假如你再次碰触 undo, 它将取消前一个 undo
的作用; 你可以永远地像这样一直切换下去.

    undo 仅对最近的改变有作用. 假如你想更往回追溯, 你可以利用 more 盒
连续地 undo 更前面的改变.


10.1.7 使用档案

    前面曾提到在启动程式时你可以指定欲编辑的档案,事实上当程式执行时
, 你也能抓取档案. 为达到这个目的你将会使用介於 load  与 undo间的文字
盒,我们称为"档名盒".

    储存文字到一个档案 : 在 save 盒上碰触左按钮; xedit 会将编辑视窗内
        的文字存到档名为档名盒内档名的档案; 若没有名称, xedit会在讯息
        窗内发出

       save : no filename specified -- noting saved

        因此在你再次在 save 上碰触左按钮之前你必须将指标移到档名盒并
        键入档名. 当它已经储存好档案 xedit 会发出确认讯息.

    编辑一个不同档案 : 在档名盒键入档名, 并在 load 上碰触左按钮. 若
        它无法取用档案, xedit 会发出错误讯息.

    插入一个档案到目前的本文 : 按下 meta-I : xedit 突现一个小视窗
        (图 10 - 2). 在上端的文字盒, 键入你想插入的档名, 并在 DoIt
        上碰触左按钮. 该档案的内容即插入目前的插入点位置.

               ┌——————————————————┐
               │    p113  fig 10 - 2                │
               │                                    │
               │                                    │
               │                                    │
               │                                    │
               │ 图 10 - 2 xedit 的插入档案选择视窗 │
               └——————————————————┘

注 : 当你在档名盒内键入文字时, 且文字盒在 "插入档案" (INSERT FILE)视
窗, 你可以使用我们曾经描述过的所有键盘基础命令. 事实上, 你不仅能打字
, 也可以剪贴它们.

注意 : 当你键入档名时, 不须用 RETURN 结尾 - xedit 会将 RETURN 视为档
       名的一部分, 而造成混淆.

10.1.8 搜寻指定的文字字串

    假如你想找出一个指定字串在你编辑本文中出现的地方 :

    1. 在我们称为搜寻字串盒 (searchstring box)的里面, 键入字串於
       Search >> 的右方.

    2. 在 Search >> 上碰触左按钮 : 插入点便会移至本文中下一个出现该
       字串的地方.

搜寻是由插入点开始,并且 xedit 预设的搜寻方向是向前, 而不往後搜寻. 假如
你要从插入点往回搜寻, 你可以在 << 上碰触左按钮.

注意 : 当搜寻字串盒内没有文字时, 假如你在 Search >> 或 << 上碰触按钮,
       xedit 会将最近在你机器上被任何应用程式所选择的文字区块的片段拷
       贝到盒内, 并搜寻它. 假如你不预期会如此, 你可能会感到非常惊讶.


10.1.9 取代一个字串为另一个

    假如你想将出现许多次的一个字串 (旧) 置换成为另一个字串 (新) :

    1. 先搜寻出本文中第一次出现欲取代字串的地方, 如前一小节所诉述.

    2. 在 all 盒右方的取代字串盒内键入新字串.

    3. 在 replace 上碰触左按钮 : 旧字串即被取代成新字串, 且插入点移
       到下一个出现旧字串的地方.

    4. 假如你也要取代它, 再次在 replace 上碰触, 否则 ...

    5. ... 假如你不想取代这个, 但想改变它後面的, 在 search >> 上碰触
       按钮直到你要改变的地方, 即可以再次取代它.

    在你往回移动档案时你无法执行取代, 换言之你无法用简单的方法取代在
插入点之前的字串.

注意 : 假如你目前不在旧字串出现的位置而你试图取代, xedit 会发出下列
       讯息 :

           ReplaceOne : nothing replaced

       但是 replace 本身会完成一个搜寻, 所以你可以继续在 replace 上
       碰触按钮, 再次执行代换.

取代每个出现的字串

    假如你想将出现的每个旧字串取代成新字串, 在 all 上碰触按钮.

注意 : 使用 all 时所有出现的旧字串均会被取代, 不只是从点往前而已, 而
       是整个档案.


10.1.10 杂项功能

    重绘本文显示 : 使用时机例如当视窗内变得混杂扭曲, 按 ctrl-L

    向前卷动一列 : 按 ctrl-Z

    往回卷动一列 : 按 meta-Z

    跳至指定的行数 : 在讯息视窗内, 键入你要跳往的行数, 用滑鼠选择你
        正在打的本文, 并在 jump 上碰触左按钮, 插入点便会跳至指定列
        的开头. (假如在萤幕上有应用程式的文字片段含有你要指定的列数
        数字, 你可以利用它 - 而不必依赖 xedit 编辑讯息视窗)

    到此我们已经完成对 xedit 的描述, 下一节将转移到另一个应用程式,
        我们将会看到类似的使用者操作介面.



10.2 读取指南页 (Manual Pages) - xman

    xman 让你浏览系统上的 Unix 指南页, 从一系列选单中选出你要的项目.

    欲启动程式时,在一个 xterm 视窗中键入命令 "xman &" : xman 启动并
显示它的主功能选择项视窗, 如图 10 - 3. 下面的小节将详细描述这些选择项.

               ┌—————————————————┐
               │    p115  fig 10 - 3              │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 10 - 3 xman 的主选择项视窗    │
               └—————————————————┘

10.2.1 xman 本身的线上求助 (on-line help) 功能

    xman 有它自己的内建求助选择项. 欲使用它, 在选择视窗内的 help 上
碰触按钮.xman 产生一个 "Xman Help" 视窗, 如图 10 - 4. 你可以使用卷
动棒与滑鼠卷动求助本文. 在求助本文视窗内操作方式如下:

    向前移动本文 : 按 f, 或碰触左按钮, 即向前移动一页.

    往回移动本文 : 按 b, 或碰触右按钮, 即往回移动一页.

               ┌—————————————————┐
               │    p116  fig 10 - 4              │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 10 - 4 xman 求助视窗          │
               └—————————————————┘

注意 : 按 b, 或碰触右按钮, 可能无法正确地往回移动一页.

求助视窗内的其他选择项

    移动指标到求助视窗上端的边缘时. 图 10 - 5 的选单突现出来. 其中可
使用的选项有 :

    Remove Help (移开求助) : 移开这个求助视窗, 但保持其他 xman 视窗
        的原样. (在我们的情况是仍得到主选择视窗)

    Open New Manpage (开启新指南页) : 与主选择视窗的 Manual Page 盒
        相同, 描述於後.   

    Quit : 结束整个程式 (停止).

    欲选择某一选项须移动指标到该选单区并碰触左按钮; 假如你甚麽都不想选
, 只要将指标移出选单即可.

               ┌——————————————————┐
               │    p117  fig 10 - 5                │
               │                                    │
               │                                    │
               │                                    │
               │                                    │
               │ 图 10 - 5 xman 求助与指南页视窗选单│
               └——————————————————┘

注意 : 在任何时刻, 只要指标进入顶端边缘区, xman 就会突现它的选单. 假如
       你不是为了这个目的而意外地横过边缘, 这可能会造成困扰.


10.2.2 如何阅读一个指南页

    在主选择视窗的 Manual Page 碰触按钮 : xman 产生一个指南页视窗,
视窗开始时会显示与前面求助视窗相同的文字.

    由此出发, 依照下列三步骤阅读指南页 :

    1. 选择你要看的指南页的特定章节 (section). (section 是参考 unix
       指南页的标准分法. 亦即, section no. 1 包含使用者命令,
       section no. 2 包含系统呼叫)

    2. 视窗会显示你所选择章节的目录, 从目录中选择进入点.

    3. 阅读显示的指南页.

选择指南书 (Manual) 的章节

    当 man启动时, 它预先设定为选择指南书的 section 1. 假如这是你所要
的, 你可以省略下列步骤的程序. 否则需指定一个 section :

    1. 在指南页视窗内, 移动指标到顶端边缘. 我们将得到一个与在指南页
       里相同的突现选单,不过现在所有的选项都可使用.

    2. 在 Change Section 项目上碰触按钮 : 选单被一系列的指南书章节名
       称的列表取代. (如图 10 - 6)

               ┌—————————————————┐
               │    p117  fig 10 - 6              │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 10 - 6 xman 的指南书章节选单  │
               └—————————————————┘

    3. 在你要的章节上碰触按钮 : xman 在指南页视窗内显示进入点的目录
       (如图 10 - 7).

               ┌—————————————————┐
               │    p118  fig 10 - 7              │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 10 - 7 xman 的指南页进入点目录│
               └—————————————————┘

显示目录和选择指南页

    假如你依照上面的描述明白地指定一个指南页章节, xman便会显示一个
指南页目录.否则, 从顶端边缘突现出选单, 并在 Display Directory 上碰触
按钮, 你会得到像上面一样的指南页目录.

    从目录中选择一个指南页 : 只要在你要的名称上碰触按钮, xman 即在视
        窗内显示指南页 (图 10 - . (假如目录列表太长以致视窗无法一次
        显示, 它旁边会有卷动棒. 假如你要的名称看不到, 则必须先将它卷动
        出现後才可以选择你要的名称)

               ┌———————————————————┐
               │    p119  fig 10 - 8                  │
               │                                      │
               │                                      │
               │                                      │
               │                                      │
               │ 图 10 - 8 显示一个指南页的 xman 视窗 │
               └———————————————————┘

察看一个指南页

    只要指南页在视窗内, 你有许多选择 :

      卷动指南页本文 : 卷动指南页本文就像卷动求助本文一样, 亦即,
          按 f, 或碰触左按钮, 即可向前移动, 按 b, 或碰触右按钮, 则可
          往回移动.

      本文/目录间之切换 : 在指南页视窗碰触中间按钮, 本文即被切换成目
          录列表. (在目录内碰触按钮, 则回到上一个指南页本文显示).

      搜寻一个指定的指南页 :

         1. 从顶端边缘突现出选单并选择 Search. xman 突现出一个搜寻视窗
            (图 10 - 9).

         2. 在顶端的本文盒内, 键入你想要的指南页名称 (不用任何 section
            接尾词, 例如你只要键入 diff, 不用键入 diff(1) 或 diff.1)

         3. 在 Manual Page 上碰触按钮,xman 便会显示你所要的指南页. (假
            如它找不到, 它会在指南页的视窗顶端边印出一个讯息)

注意 : 你键入的名称必须完全 (di 不能代表 diff), 名称的大小写也必须配
       合 (xaddhost 不等於 XAddHost).

               ┌—————————————————┐
               │    p120  fig 10 - 9              │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 10 - 9 xman 搜寻视窗          │
               └—————————————————┘

许多项目一起显示

    在任何时刻, 你都可以视需要开启额外的 xman 视窗, 只需从顶端边缘突
现出选单并选择 Open New Manpage 开启一个指南页视窗, 然後选择 Help 开
启一个求助视窗.

    只要你喜欢你可以开启许多不同的 xman 视窗, 且对视窗管理器来说每一
个都可以被独立地管理, 例如 : 你可以将某些重定大小, 其它的表徵图化等等.
为了清楚起见, 主选择视窗、求助视窗及指南页视窗的表徵图均不同 (图 10 - 10
a, b, c). (表徵图内的 "U.P.M." 代表 "Unix Programmer's Manual")

               ┌—————————————————┐
               │    p120  fig 10 - 10             │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 10 - 10 xman 的三个不同表徵图 │
               └—————————————————┘

    在任何一个 xman 视窗, 选择 Show Both Screen, 你可以同时显示目录
及指南页,视窗分成上下两部分, 上面显示目录, 下面显示指南页 (图 10 - 11)
. (当你如此做时, 顶端的边缘变薄 : Display Directory 与 Display 
Manual Page 选择项变成灰色 -- 表示它们目前不可选用, 且选单项目
Show Both Screen 变成 Show One Screen).

               ┌——————————————————————┐
               │    p121  fig 10 - 11                       │
               │                                            │
               │                                            │
               │                                            │
               │                                            │
               │ 图 10 - 11 同时显示目录与指南页的 xman 视窗│
               └——————————————————————┘

    如有需要, 你可以改变视窗中两个分框 (panes) 的相对大小, 注意接近分
隔框线的右手边有一个小的黑方形叫做把手 (柄) (grip)

    1. 将指标指向把手.

    2. 按下任一滑鼠按钮, 并保持按著.

    3. .. 拖拽分隔线至你要的地方.

    4. 放开按钮,两个方框即被适当地重划.

注意 : 我们会在不同的X应用看到许多这种把手, 但大部份的情况均无法让你
       拉动它以重调与相邻视窗的比例. 例如 : 假如你试图拉 xman 顶端
       边缘与本文或目录视窗分隔线上的把手, 它不会有任何反应.



10.3 邮件/讯息处理系统 - xmh

    xmh 是一个架在 mh 邮件/讯息处理系统之上的X介面. 当你启动它时, xmh
会建立一个像图 10 - 12 的视窗. 程式的视窗相关画面如编辑本文, 与管理视
窗方框,均与 xedit 及 xman十分类似, 事实上是由相同的内部结构所提供的.
正因为如此, 且由於大多数描述是与程式的邮件功能有关而较少与X有关, 我
们不进一步讨论. 假如你想知道如何使用程式, 指南页拥有一个简单但内容丰
富的描述.

               ┌—————————————————┐
               │    p123  fig 10 - 12             │
               │                                  │
               │                                  │
               │                                  │
               │                                  │
               │ 图 10 - 12 xmh 邮件处理视窗      │
               └—————————————————┘

10.4 结论/摘要

    在本章中你已经开始看到某些X应用程式在使用者介面上一致性的面貌,
例如:卷动棒的操作, 和一般的本文编辑功能. 这里只归结出包含在 core
发行版本中的一般使用者程式,下一章探讨一些示范程式, 然後我们便进入本
书第三部分,探讨如何订制一个系统.

    但是在许多方面你现在所需的是去获得系统的真正优点. 你目前要的是更
多的应用程式,使你在 X的工作架构下做更广泛的应用, 这就是 MIT 发行版
contrib 部分重要的地方. 它包含了所有阶层的广泛应用程式, 从详细的程式
函数到方便的程式, 一直到完整的应用, 像事先看排版文件的 xdvi 或绘图程
式 xfig.

    制造商与第三集团支持X的程式及套装软体数量不断地增加, 这些软体不
是具有一个完整的X使用者介面, 就是至少可使你输出图形到一个X视窗. 当
然也有其他的软体来源,举例而言, 自由软体基金提供高度弹性与扩展性的
GNU Emacs编辑器, 它曾经被整合到X里面, (事实上, 许多 Xedit 订定编辑
的功能键的确与 Emacs 相同) 如何得到 GNU Emacs 的细节包含在附录E "如何
获得X" 中.

=====

第11章 示范与游戏程式

    MIT 发行的 core 版本提供了少数的示范程式以及仅有的一个游戏程式.
它们展现出某些视窗系统的威力, 且能给人一种强烈的美好印象 -- 特别是在
彩色萤幕上.



11.1 找出通过随机迷宫的路径 - maze

     maze 在视窗中产生一个随机的迷宫 (图 11 - 1), 它会自动找出从入口
通过迷宫到达出口的路径. 它会追踪它走过的轨迹, 当它从一个死巷中退出时
则将轨迹消除. 你可以用滑鼠按钮启动, 暂停, 继续或停止程式, 就如同在手
册页中所描述的. maze不提供颜色.

注意 : 中间按钮对暂停与重新启动的作用并不可靠.

               ┌————————————————┐
               │    p125. fig 11 - 1            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 11 - 1 迷宫程式             │
               └————————————————┘



11.2 担任指标的大眼睛 - xeyes

    xeyes 在视窗中绘出两个大眼睛, 且它们永远保持看著指标 (图 11 - 2).
当指标移动时眼睛也随著调整 (且若你移动指标到它自己的眼睛之间, 它们会
变成斗鸡眼! (cross eyed!)

    你可以明确地给视窗的每个元素设定颜色 - 瞳孔, 背景, 外框等.

注意 :  xeyes 会使你的系统执行速度变慢.

               ┌————————————————┐
               │    p126. fig 11 - 2            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 11 - 2 xeyes 程式           │
               └————————————————┘



11.3 智慧盘游戏 - puzzle

    puzzle 是一种古老的游戏, 有 15 个编号的小方块被一个 4x4 框架围住.
你必须移动小方块使它们按照数字顺序排列. (图 11 - 3)

               ┌————————————————┐
               │    p127. fig 11 - 3            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 11 - 3 智慧盘游戏           │
               └————————————————┘

    你可以使用滑鼠控制游戏 :

    启动游戏 : 藉著在控制棒的左上边盒子内碰触按钮可以重新搅和小方块.

    移动小方块 : 将指标移到与空白位置相同的行或列的小方块上,碰触按
        钮以移动该小方块与所有它之前的所有小方块进入空的位置. (所以
        移动後, 空位置在你碰触按钮的地方)

    由 puzzle 自己去解 : 在控制棒的右手边盒子上碰触按钮.

    离开 (跳出) : 在控制棒的中间碰触中间按钮.


11.3.1 puzzle 的命令列选项

    使用一个大小不是 4x4 的框架 : 使用选项 - size width x height,
        其中尺寸是以小方块为单位.

    改变小方块被移动的速率 : 使用选项 -speed num. 此处 num 是每秒移动
        的数目 (预设值为 5).



11.4 列印一个大X语标 - xlogo

     xlogo 建立一个视窗并在它里面显示一个X语标(logo),如图 11 - 4. 假
如你重定视窗大小,语标再次被绘出, 且尽可能地将视窗填满.

               ┌————————————————┐
               │    p127. fig 11 - 4            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 11 - 4 xlogo 程式           │
               └————————————————┘



11.5 跳动的多面体 - ico

    ico 产生一个视窗且在它里面有一个 12 面体 - 一个具有 12 面的实心
体 - 如图11 - 5 所示. 这个多面体是会动的, 它在视窗内不断地碰撞跳跃.
在单色显示器上你可能只有一个直线构成的图 (使用选项 -i 可以反白显示),
但是在彩色显示萤幕上, 你可以看到实心的彩色面.

试下面的例子 :

    ico -nodeges -faces -colors red blue yellow green

    你可以设定一个跳跃的12面体在一个根视窗内 (背景视窗),而不必靠它自
己使用 -r 选项指定特定视窗. 另外, ico 可指定多面体的面数, 不是只有12
面体 : 如果你想得到一个完整的列表可以键入下列命令 :

    ico -objhelp

               ┌————————————————┐
               │    p128. fig 11 - 5            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 11 - 5 ico 程式             │
               └————————————————┘



11.6 动态几何图样 - muncher 与 plaid

    muncher 与 plaid 重覆地绘出变化多端而有趣的几何图样 (图 11 - 6a
与 b).

               ┌————————————————┐
               │    p129. fig 11 - 6            │
               │                                │
               │                                │
               │                                │
               │                                │
               │ 图 11 - 6 muncher 与 plaid 程式│
               └————————————————┘



11.7 结论

    core版本中没有非常广泛的示范程式. 假如你曾读取 contrib 的磁带, 你
可能会发现下列有趣的程式 :

    paint : 简单的绘图程式. (像一个画图程式, 但你可以对区域涂上纹理
        或颜色, 不只是线.)

    xcolors : 一个可展示你的系统上所有颜色名称的好程式.

    xfish : 设定鱼在你的整个背景视窗内游动. 有趣的部分是你可以用滑鼠
        射击它们.

    qix : 一个 qix 射击游戏的程式.

    xmille : 和你玩一个 Mille Bournes 的牌戏.

    xsol : 和你玩一个单人玩的牌戏.

    xtrek : 一个令人著迷的太空游戏.

=====

第参部  定制系统

第12章  资讯与状态程式

    在本章,我们将讨论一些提供视窗系统本身资讯和目前状态的程式。
这包括了检查系统上视窗各种性质 (property) 的工具,和一个观察X
事件结构是如何工作的程式。

    这些程式有下列用途:

    .当你使用系统时,这些工具程式所提供有关系统内部组织和操作的资讯,
      可以帮助你了解发生了什麽事。

    .当你要做某种处理时,可以藉著所给的资讯来确认系统的组件。(例如
      你必须知道一个视窗的window-id,才可以用xwd 来倾印它。)

    .你将经常把从这些工具获得的资讯,当成定制系统工具程式的输入(稍
      後几章会讨论)。



12.1  列出你的Xserver的特徵 -- xdpyinfo

    xdpyinfo列出有关你的Xserver和server所控制萤幕之各种项目的资讯,
一个典型的输出见图12-1(一个server在Sun 3/50单色工作站上执行的结果)。

           ┌———————————————————┐
           │  p134     fig 12.1                   │
           │                                      │
           │ 图12-1  典型的xdpyinfo工具程式的输出 │
           └———————————————————┘



12.2  获取有关视窗的资讯

    有三个程式可以提供目前在你显示器上视窗的资讯。它们是从不同的角度
看系统:

    1.  列印视窗的阶层 -- xlswins

    2.  对单一视窗详细的资讯 -- xwininfo

    3.  列出视窗的性质 -- xprop



12.2.1  列印视窗的阶层 -- xlswins

    在第一部曾经提过,所有在系统上的视窗被安排成树状的阶层,根视窗
(也叫背景(background)视窗)在最上层,在其下才是应用视窗,每一个应用
视窗可以拥有它自己的子视窗阶层。

    xlswins 列印出这个树状结构,从根视窗或所指定的视窗起至其下所有的
树状结构,对每一个视窗,xlswins 列出视窗的window-id 并用括弧括住它的
名称(如果有的话),子视窗则在下面的几行依序以缩入(indent)两格的方式
列出。下面的图对xman应用程式列出三个不同子树的输出,藉以展示xlswins
如何剖析系统的结构。

    图12-2a 是xman主选单的树。你可以看到在应用视窗(0X600011)中含有另一
个视窗(0X600012),而(0X600012)又包含了四个视窗,不需要知道原始程式,
你也可以猜得到是一种视窗包含著视窗,而对子视窗做某种管理的情况。

    图12-2b 是xman手册页(manpage) 视窗的树。比上一个例子复杂一些,而且
也无法在确定是否在这一页手册页中总共就只有这麽多视窗和子视窗。所以 ...

    图12-2c 这是xlswins 更详细的输出,比上一个例子需要在命令列中多加
一个 -l 的选项,多出来的讯息为巢状的深度(第几层树)、相对於父视窗的
几何座标和大小、和视窗左上角距离根视窗的座标(也就是萤幕上的绝对座标)
,有了这些视窗的座标,你就能了解它们在萤幕上的位置,如果你还是搞不太
清楚,可以执行xwd ,指定xlswins 所输出的window-id ,在本图,我们发觉
视窗(0X60005d)是高而窄的,所以可能是一个卷动棒。我们可以试著用命令:

        xwd -id 0x60005d | xwud

结果的确 xman 卷动棒的图形出现了,这个命令我们在9.2.1 节有提过(只不
过这一次我们不把输出送到档案,而利用导管 (pipe) 的技巧直接当成另一程
式的输入。)你可以用这种方法分析任何视窗。

           ┌——————————————————┐
           │  p136     fig 12.2                 │
           │                                    │
           │ 图12-2  三个xlswins 的输出         │
           └——————————————————┘

注意:并非所有的视窗都可列印出资讯,如果你碰到这种无资讯可供列印视窗
,你将获得类似下面的讯息:

        x Protocol error: BadMatch, invalid parameter
        attributes
        Major opcode of failed request: 73 (X_GetImage)

    为了篇幅的关系,我们只列出了完整xlswins 输出的三个小部份。如果在
你自己已经有好几个应用程式的系统上,你将可以看到uwm 和xterm 选单所相
关的子树,或者是与 xmh和 xedit 的命令按钮相关的子树。


12.2.2  关於单一视窗的详细资讯 -- xwininfo

    xwininfo能够针对特定的视窗给你大量的资讯,你可以藉著命令列的选项
告诉xwininfo你要哪一部份的资讯。图12-3包含完整的列印输出(用选项-all)

           ┌——————————————————┐
           │  p138     fig 12.3                 │
           │                                    │
           │ 图12-3  典型的xwininfo输出         │
           └——————————————————┘

    你可以用和xwd 相同的方法来指定你感兴趣的视窗:

      .交谈式(预设):开始时,xwininfo给你一个十字线游标,你可以将
        它移到你所需的视窗再碰触滑鼠按钮。

      .使用命令列选项:你可以用选项-root 指定根视窗,或用选项-id
        window-id 指定其它的视窗。

    你所看到的资讯可分为以下几类:

    视窗的window-id :window-id 是视窗系统识别每一个视窗的参考,就如
        同先前所看到的,几个程式(包含xwininfo它本身)给你一个数字代
        表window-id 。例如你要倾印一个视窗,你可以先执行xwininfo得到

BBS水木清华站∶精华区

TOP

BBS水木清华站∶精华区
        它的window-id,然後将此window-id 做为xwd 的id选项之引数。

    阶层的资讯:你可以看到这个视窗的父视窗的id,几个子视窗的id,以及
        根视窗的id,在xlswins 中可得到相同的资讯,但在这里只能得到最
        近一层子视窗的id,并非整个子树。

    几何细节:视窗的大小和位置,以及它的四个角的位置。

    和server有关的重建构参数:像”gravity ”和”backing store ”这
        些状态(state) ,当视窗改变大小或从被遮盖的状态下重新显
        露出来时,server需要用到这些参数,这些参数你自己不会用到,
        但可藉它了解系统如何运作。

    事件参数:这些参数也是给server而非给使用者用的。

    视窗管理器资讯:在系统概观中,我们曾经提过应用程式藉著给视窗管理
        器一些提示”hints ”来达成通讯(这些提示包括应用程式所希望视
        窗的大小,以及重定大小时的限制等。),xwininfo在这个部份的输
        出便是告诉你这些”提示”的资料。Program supplied location 为
        应用程式建议它自己应该摆哪里。如果你曾给过位置,不论是在命令
        列或resource file ,都会在 User supplied location 出现,在视
        窗大小方面同理可推,resize increments 解释了为什麽有些视窗(
        例如xterm 和xfd )不能把大小定为任意数目的像素,因为应用程式
        已经告诉了视窗管理器在重定大小时按多少个像素的倍数放大或缩小
        (xterm 和xfd 它们的大小和所使用的字型有关),你也可以由这个
        参数知道目前视窗的位置,所以稍後你可以在同一位置上重建它。


12.2.3  列出视窗的性质 -- xprop

    如同我们在系统概观所提及的,一个”性质”(property)是指一小段有关
视窗的资料,xprop 让你列出一个特定视窗的所有”性质”,你也可以列印
一个字型的性质。

  你可以经由常用的方式来选择视窗(碰触滑鼠按钮或使用-root 或-id 选项)
,如果是指定字型,则用选项-font fontname。

    显示出来的格式为:对每一个性质,均有一个性质名称,在其後用小括弧
括住的为性质的型态或格式,最後则为性质的值。大部份你所看到的性质型态
为STRING,性质的值用” ”括起来,其它的性质型态的格式是专属的,从
性质的值很容易了解它的意义,对字型显示的格式稍有不同,它没有性质型态,
但性质的值意义也很明显。

注意:xprop 的输出相当的复杂,我们并不需要了解其所有的内容,端视需要而
      定。

    以下让我们看看从应用视窗、根视窗、字型所获得不同的输出:

应用视窗的性质

    图12-4为xprop 对一个应用视窗的输出,有些资讯你已经在xwininfo中看
到过,在此处你可以在名为WM_NORMAL_HINTS 和WM_HINTS的性质中看到。

           ┌——————————————————┐
           │  p140     fig 12.4                 │
           │                                    │
           │ 图12-4  一个应用视窗的性质表列     │
           └——————————————————┘

其它的性质如下:

WM_COMMAND:执行启动这个应用程式的命令列,被切成一个个用双引号括起来的
      单字。

WM_CLIENT_MACHINE :执行这个client应用程式的机器名称(这个例子应用程
            式和server在同一部机器上执行,所以机器名称为venus 。)。

WM_CLASS:显示应用程式的instant name和class name,instant name是命令
            列中-name 选项的值。

WM_ICON_NAME:应用程式的表徵图所要显示出来的名称(你的视窗管理器必须
            能够支援方可)。

WM_NAME :很奇怪的,这不是应用程式的名称,而是由-title选项指定的视窗
            标题名称,有些视窗管理器会把标题名称显示在应用视窗的标题
            棒上。

注意:上述命令列中-name 和-title两个选项使用得很广,但它并非通用
      (universal) 的选项,应用程式在撰写时必需要使用到X Toolkit(工
      具箱)才能把这两个选项当成标准选项来用。(参见第15章)


根视窗的性质

    图12-5是xprop 对根视窗的输出,显而易见的是,它不会含有任何视窗管
理器的性质,因为视窗管理器绝不可能重新建构根视窗。

           ┌——————————————————┐
           │  p141     fig 12.5                 │
           │                                    │
           │ 图12-5  根视窗的性质表列           │
           └——————————————————┘

有趣的选项如下:

RESOURCE_MANAGER:这个根视窗性质是resource结构的输入源之一,我们将在
            第11章详细地讨论它。

几个CUT_BUFFER:当你切取一段本文(做剪贴动作常用),这段被切取的本文
            被放在一个切取缓冲器(cut buffer)中,这些缓冲器被当作是根
            视窗的性质来储存,对於切取,缓冲器是循环使用的,例如上次
            用5 号缓冲器,则下次用6 号,接下来7 号、0 号、1 号等等,
            但是黏贴则一定使用上次切取动作所用的缓冲器。

字型性质

    图12-6列出当我们指定*times*bold*-i-*-180-*的字型性质,大部份的资
讯我们都不需关心,你可能只对FULL_NAME 和POINT_SIZE有兴趣。

           ┌——————————————————┐
           │  p142     fig 12.6                 │
           │                                    │
           │ 图12-6  字型的性质表列             │
           └——————————————————┘



12.3  观察X的事件 -- xev

    ”事件”或多或少驱动著整个视窗系统,所有的输入,不论是滑鼠或键盘,
均由”事件”来掌握,”事件”也被用来驱动视窗的重新建构和展现。xev 程
式让你看到当不同的动作发生时,会产生什麽”事件”,以及和”事件”有关
的资讯。

    当xev 启动,它会建一个类似图12-7的视窗,而在这视窗中,会开始列出
类似图12-8的有关事件的细节部份。

           ┌——————————————————┐
           │  p143     fig 12.7                 │
           │                                    │
           │ 图12-7  xev 视窗                   │
           └——————————————————┘

           ┌——————————————————┐
           │  p143     fig 12.8                 │
           │                                    │
           │ 图12-8  xev 的输出                 │
           └——————————————————┘

    由於 xev提供大量的系统内部操作细节,你如果想要”实验”系统,这是一个
很有用的程式,有两个说明手册上未提到的选项可以影响到xev 的行为:

-bs option:此选项改变xev 对server是否使用backing store (见第2章),
            使用backing store 将减少曝光”事件”的次数(也就是减少应
      用程式重新更新它自己视窗的次数),正确的选项内容为always,
      whenmapped和notuseful 。

-s:使用save-unders (见第2章),也就是说,要求server保存那些被xev
            的视窗遮盖之视窗的内容。


12.3.1  xev 和键盘

    如果你将指标移入xev 视窗且按下你的键盘上的某一个键,则一个(或多
个)键盘”事件”会发生,”事件”的资讯包含了keycode 和keysym,这是最
容易观察你的机器上某一个键是什麽键码(keycode) 的方法:执行xev ,按一
个键,xev 便会给你资讯,这对定制你的键盘非常有用,见18章。



12.4  结论

    本章所述的这些程式,让你观察系统的内部;获得它的操作细节;和它的
视窗及其它成员特定的资讯.对这些程式本身而言,它们能帮助你了解系统,
但它们最大的用途可能是用来连接那些定制系统的程式。以下的几章在说明如
何定制和设定你的系统,好让系统更适合你工作的习惯。

    下一章讨论处理字型和颜色,及如何使用它们。

=====

第13章  使用X的字型和色彩

    X支援多种的字型及几乎无限多种变化的色彩,大多数的应用程式允许你指
定应用视窗中各个不同部份的颜色,而几乎所有的X程式均允许你指定你想要使
用的字型。

在X中的字型(fonts):

    .有固定的宽度(像哑终端机的字元)或成比例的间隙。

    .由本文字元(text characters) 或符号组成,或以上两者均有。

    .具有多种的点尺寸(point size)。

    .可以修改以适应特定的萤幕解析度(例如对於同一点尺寸的某一种字型,
      你可能对75 dpi (dots-per-inch 每寸若干点) 的萤幕有一种版本,对
      100 dpi 的萤幕有另一种版本)。

    .有一种标准命名的传统。

    .可以以全名存取,也可以用通用字元(wildcard)。

    .储存在特定建构的目录树中,只要server在执行时,字型便可以加入或
      移出。

    在系统间进行字型的交换有一套标准的格式,并且有工具程式可以将这个
格式转换成你的server能了解的格式,工具程式也包含了列出可用字型的目录
、观察某一特定字型内容等功能。

    本章先对字型作一简短的介绍,让你能尽快的使用它们,然後才转而详细
地解释字型的结构、格式、工具程式等,最後一节讨论色彩:如何设定和使用
它们。


13.1  字型初步

    本节的目的是让你尽快地能使用字型,我们将告诉你如何找出有哪些字型
可用、指定你欲使用的字型名称、看字型的外观、如何在X应用程式中使用字型。


13.1.1  列出可用的字型

    xlsfonts程式一行行的列出server上可用的字型,图13-1显示部份的
xlsfonts的输出,内容为MIT 版标准的字型。

         ┌——————————————————┐
         │      p146     fig  13.1            │
         │                                    │
         │     图13-1  典型的字型目录列表     │
         └——————————————————┘


13.1.2  字型命名

    有些字型的名称太长以致使用不便,但很幸运的,它们也不常被使用,并
且,X支援字型名称可使用通字元(wildcard):

    ?  对应任何一个字元
    *  对应从(字元)长度为零至长度若干的字串

    这和Unix shell传统的通用字元档案名称相同,使用通用字元可使你更容
易指定字型名称。

注意:如果你在shell 的命令列指定一个通用字元的字型名称,需要在名称前
      後加上双引号 。


13.1.3  观察一个特定的字型

    xfd (X font displayer 的缩写) 程式由引数(argument)得到字型的名
称之後,建立一个视窗并且在视窗中显示此名称之字元字型,例如:

        xfd -fn "*symbol*-180-*"

将显示如图13-2的视窗。

         ┌——————————————————┐
         │      p147     fig  13.2            │
         │                                    │
         │     图13-2  字型的展示             │
         └——————————————————┘


13.1.4  以X程式使用字型

    大多数的X程式使用文字,并且允许你指定使用的字型,如何使用的详细
细节可能因不同的程式而异,如果有问题的话可以看指南页。但是几乎都是以
命令列中选项 -fn fontname 或 -font fontname 来指定字型名称,bitmap、
xclock、xterm、xload、xmb 和 xedit都是这样操作的。例如假设你是为了展
示的缘故,以很大的字型执行xterm ,你可以用下列命令列:

        xterm -fn "*courier-bold-r-*-240-*"

注意:如果你给程式的指定对应到一种以上的字型,则server会随便在其中选
      取一个,例如:如果你省略了上例中的 -r 的指定,则你会使用到意大
      利斜体(italic)字型或反斜体(reverse oblique) 字型,和原来所指定
      的罗马(roman) 字型的机会是一样的。

    现在你应该有一些概念了,我们将从不同的观点详细地讨论。


13.2  字型如何命名

    在X中,字型可以取成任何名称,但几乎所有的字型均依照它们的本质来
命名,这样的命名方式,名字是由几个不相关的部份组合而成,而我们在使用
应用程式时,光凭著字型名称便可以大略了解字型的内涵。

    我们以一个字型名称为范例,逐一解释它的组件,组件之间是由短横线(-)
所分开的,而且可以包含空白,字型名称对字元大小写并不会区别,范例如下:

    -adobe-times-bold-normal--12-120-75-75-p-67-iso8859-1

    adobe :字型的制造厂商。

    times :型态家族(type family) ,其它尚包含courier ,helvetica 和
            new century schoolbook。

    bold  :粗体字,其它包含light (细)和medium(中等)。

    r     :字体倾斜的型态,r 是roman (罗马体),其它是 i(italic意
            大利体),o (oblique 倾斜体)。

    12    :字元的高度,单位为像素。

    120   :字型的点尺寸(point-size),为点的10倍(120 意为12点,一点
            约为1/72英□宽)。

    75-75 :字型被设计在显示装置上的水平和垂直的解析度(每□若干点)。

    p     :字和字之间的间隙,p 是proportional(成比例的),相对的是
            m (monospaced固定宽度)。

    如果你对某一栏有特别的兴趣,在本版的说明文件档

        $TOP/doc/fontnames/fname.txt

中,有对每一个组件完整的说明。

    你通常比较有兴趣的项目为家族型态、字体粗细、何种斜体字以及字型大
小,除了指定这几项的值外,其它的项目不妨藉著通用字元的方式去指定。


13.2.1  通用字元和字型名称

    在第13.1节中,我们曾经解释过通用字元的规则:星号(*)表示对应到
零或多个字元,问号(?)对应到一个任意的单一字元。

    你可以随意的使用通用字元,当你的设定对应到一种以上的可用字型时,
server会随便挑一种字型来用,如果你的设定什麽字型也没对应到,通常你会
获得一行讯息,而server将会使用预设字型。

    你可以对字型的点尺寸使用通用字元,而不是像素尺寸,因为在显示器上
一个给定点尺寸的字型对不同的解析度有不同的像素尺寸,所以用通用字元指
定点尺寸可以造成与装备无关的效果,上述的范例你可以如此设定:

        *-times-bold-r-*-120-*

也就是说以-120-取代-12-


13.2.2  列出可用的字型 -- xlsfonts

    xlsfonts列出在你server上可用的字型(如果你使用用命令列中-display
选项,便可列出其它server上可用的字型)。预设是列出所有的字型,但是就
如同Unix的ls命令一样,如果你加上限制,便只会列出合乎限制的项目,例如:

        xlsfonts  "*-times-*-180-*"

列出所有18点Times的字型。

    原则上,xlsfonts试图在每行列印出尽量多的字型名称,但实际上,大部
份的字型名称都很长以致一次只能印一个名称,但是要小心,当字型名称含有
空白时,一行有数个字型名称常常容易混淆。

注意:许多的字型名称开头为一短横线(-) ,所以xlsfonts会误把此种状况当
      成命令列的选项来解释以致发生错误,例如:

        xlsfonts  "-adobe-*"

会失败,你可以用选项-fn 加以区分,或者只要在设定之前加一个星号(*)
即可:

        xlsfonts  "*-adobe-*"
        xlsfonts  -fn "-adobe-*"



13.3  观察特定字型的内容 -- xfd

    xfd 是一个”字型显示”的程式,它建立一个视窗,而後在视窗中将字型
的元素显示在长方格子中。视窗可能没有大到一次将字型中所有的字元显示出
来(尤其是你可能对它重定过大小),但你仍然可以存取它们:

    向前移动:在xfd 视窗中碰触滑鼠右按钮,视窗的下一页将会出现。

    向後移动:碰触滑鼠左按钮。

    获取字元的资讯:在字元上碰触滑鼠中按钮,xfd 会给你字元号码,如果
    你在程式一开始设定命令列选项-verbose,你将获得一些更多的资讯,例
    如字元的大小以及它在字元”cell”中的位置。



13.4  如何储存字型及存在何处

    在本节中,我们描述字型不同的格式,以及转换两种不同格式的工具,然
後讨论server是如何存取字型和你如何更改对字型的选择。最後,我们会给一
个完整的范例来说明如何加入一种新的字型到你的系统。


13.4.1  字型的格式 -- Server Natural Format (SNF)

    字型在server上是以Server Natural Format (SNF) 方式储存,这种格式
并不是一种标准,而且为server所专用,所以你不能将字型移到不同型态的
server。

    showsnf 程式印出储存在SNF 档中字型的资讯,对字型本身执行xprop 可
获得更多类似的资讯。(showsnf的引数为档案名称,xprop 则为字型的名称,
字型名称和档案名称并不相关。)

Bitmap Distribution Format(位元映像分布格式)-- BDF

    为了克服字型流传的问题,X协会对字型交换指定了一种格式,就是Bitmap
Distribution Format (BDF) ,BDF 以ASCII 的方式表示字元的位元映像,并
且只包含可印出的字元,所以它具有完整的可携性(portable)。

    在”Bitmap Distribution Format”文件中包含了对BDF 完整的描述。

从BDF 转换成SNF - bdftosnf

    为了让BDF 能够有用,你必需能将BDF 字型档转换成SNF 档,目前X协会
放弃让这个需求成为X的成品。

    在MIT 版,你可以用bdftosnf来完成转换。

由其它的格式转换

    许多的绘图机器拥有它们制造商自己发展的字型,通常特别适合它们的显
示器。如果这些字型能在X使用那是再好也不过了,但是因为格式的问题,你
不能使用它们。

    MIT core版并不管这个问题,但是core版则有许多的工具程式将制造商特
制的字型转换成BDF 格式,从BDF 你又可以用bdftosnf转换成你自己的SNF ,
本章稍後我们会有一个这样的范例。


13.4.2  字型储存在何处 -- 字型目录

    字型被储存在server上某一个或多个字型目录(font directory)中,字型
目录由三个部份组成:

    1.  一个普通的目录,为包含著字型的SNF 档案之所在。

    2.  一个被X使用,将SNF 档案名称对应到字型名称的资料库。

    3.  一个可选择性的别名档(aliase file) ,可以让你用一个以上的名称
        参考到同一字型(不论你使用了多少个目录,你只需要一个别名档)。

维护字型目录 -- mkfontdir

    mkfontdir 设定新的字型目录并且可以修改它:

   1. 在档案目录中搜集了所有你要使用字型的档案,档案可以是BDF 档(通
常档名结尾为.bdf),SNF 档案(.snf)或被压缩的SNF 档(.snf.Z),mkfontdir
会自动将非SNF 档案转换为SNF 档案。(被压缩的档案是被BSD 压缩程式执行
过用以节省档案空间。)

   2. 如果你要使用别名,需要在字型目录中建立(或编辑)一个名为
fonts.aliase的档案。有关此档案格式的细节部份在指南页中有说明,简单地
说,它的格式为每行以空白间隔出两个栏位,第一栏是别名的名称,第二栏则
是字型的名称(可包含通用字元),例如:

        tbi12  *-times-bold-i*-120*

注意:你对字型定义的第一个别名将造成该字型真正的名称无法使用,以上例
      而言,你只能以tbi12 来存取字型,这种情形也许下一版会改进,但目
      前你可以在第二行将第一行反过来即可(但不可使用通用字元)。

        tbi12  *-times-bold-i*-120*
        -adobe-times-bold-i-normal--12-120-75-755-p-68-iso8859-1 tbi12

   3. 执行mkfontdir ,需把档案名称当成引数输入,以你使用预设的X建构
为例 :

        mkfontdir /usr/lib/x11/fonts/misc\
                  /usr/lib/x11/fonts/75dpi\
                  /usr/lib/x11/fonts/100dpi

(如果档案目录中没有包含字型资料库,mkfontdir 会忽略它。)

注意:建立一个字型目录并不会导致server”注意”它,你必需重新启动server
      或重设字型搜寻路径(search path) (下面描述):

字型搜寻路径 -- xset

    你可以使用任何数目的字型目录,但如果它们有任何和预设建构不同的地
方,你需明确的告诉server,这些字型目录的列表称之为字型搜寻路径(font
search path)或字型路径(font path) ,你可以设定这个一连串以逗点为区隔
的档案目录。

    查看你目前的字型路径:使用命令xset q,如此会印出一大堆资讯,其中有
一行包含著你的字型路径类似下面:

        Font Path : /usr/lib/x11/fonts/misc/,(cond.)
                    /usr/lib/x11/fonts/75dpi/,/usr/lib/x11/fonts/100dpi/

    设定不同的字型路径:使用命令xset fp new-path,例如,如果你有大量
的本地字型且不欲使用多数的标准字型:

        xset fp /usr/local/xfonts, /usr/lib/x11/fonts/75dpi

注意:fp之前并无一短横线(-) ,是fp而非 -fp(-fp 的意义不同,见下述)。

    当你想重新设定server对字型路径的预设值时,使用命令:

        xset fp default

    告诉server重新读入字型的目录,使用命令:

        xset fp rehash

    它告诉server你可能已经改变了字型目录的内容而和它必须重读字型资料
库,现在新加入的字型可以开始存取了。

    在现存的路径加入新的字型目录,使用命令:

        xset +fp dirlist

加入一列由逗号分隔的目录列(dirlist) 在现存路径之左,而

        xset fp+ dirlist

则将目录列加到路径之右。

    将字型目录自路径移去:下两个命令列

        xset -fp dirlist
        xset fp- dirlist

均可将在dirlist 中的目录自现有路径移去。

注意:字型路径由server所掌握,而被所有使用该server的client所应用。

    字型路径的次序是重要的,我们曾经提过字型设定可以对应至一或多个字型,
server会自行选择,但如果对应的字型是在不同的目录中,则server会选择在
路径中较早出现者。

    你可以利用这个原则来安排最适合你的显示器解析度的字型。假设你的显
示器解析度为100dpi,则将100dpi字型设在75dpi 之前,例如:

        xset fp /usr/lib/x11/fonts/100dpi/,\
                /usr/lib/x11/fonts/75dpi/

    如果你指定字型为:

        * -times-bold-r-*-120-*

虽然字型有75dpi 和100dpi两种版本,但你会用到100dpi的字型,这正是你所
需要的。


13.5  范例:增加新字型至你的server

    现在我们将说明如何增加一个新的字型到你的server的完整范例,为了
真实起见,我们以Sun所提供的字型为例,将它转换至BDF ,然後装设(install)
它,字型开始时在:

        /usr/lib/fonts/fixedwidthfonts/screen.r.7

    欲将Sun 的字型转换成BDF ,我们需使用contrib 版的软体程式vtobdf(
其它系统也有类似的工具)。vtobdf有两个引数,分别是输入档档名和欲建立
之BDF 档档名,我们可以事先自contrib 磁带取得此程式,编译它,而後加入
我们可执行的目录中,我们就可以使用它了,我们将或多或少依据X的标准来
命名这个新的字型,我们喜欢把输出档的档尾名用.bdf,但由於vtobdf会在字
型名称後自动产生.bdf,所以可以省略它,但在稍後之重定名称则不可省略。

        venus% cd/tmp
        venus% vtobdf /usr/lib/fonts/fixedwidthfonts/screen.r.7\
              -sun-screen--r-normal---70-75-75-m---

现在重新命名档案,并将其搬入字型目录:

        venus% mv- -sun-screen--r-normal---70-75-75-m---\
        /usr/lib/x11/fonts/misc/-sun-screen--r-normal---70-75-75-m---.bdf

最後,执行mkfontdir 和告诉server重新读入字型目录以便能使用此字型:

        venus% mkfontdir
        venus% xset fp rehash

检查一下此字型是否真的可用:

        venus% xlsfonts "*-sun_screen*"\
        -sun-screen--r-normal---70-75-75-m---

注意:你的字型可能可以取代其它的预设字型,但这些字型档案可能因有保护
而无法更改,必须问一下你的系统管理者。


13.6  使用X的色彩

    我们已经用过一些色彩,但并未细述它们,原因是X允许你用日常常用的
彩色名,在本节我们描述一些其它指定颜色的方法,解释命令结构如何工作和
你如何设定一些你自己拥有的色彩名称。


13.6.1  RGB 色彩设定

    换一种指定色彩的方式,你可以用RGB (Red (红)、Green (绿)、Blue (蓝))
三元素来指定,设定之形式为:

        #<r><g><b>

必须合乎以下的原则:

    .设定必需以井字号(#) 开头。

    .元素需依照红、绿、蓝的次序依序设定。

    .三元素均必须指定。

    .每一个元素为十六进位,共占一到四个位数,因此ffff代表色彩的最大
      强度,0000代表没有该色彩,例如:

        #0000ffff0000

      是最亮的绿色,红色和蓝色一点都没有,同样的:

        #000000000000 黑色(什麽色彩都没有)
        #ffff0000ffff 紫色(全部的红色加蓝色)
        #ffffffffffff 白色(全部的色彩)

      注意#rgb和#rrrgggbbb代表的色彩强度是相同的,但後者较亮一些。

    .每一个元素可由一到四个位数代表,但每个元素的位数则相同(例如你
      不可以用#rrbbbbgg )。

    你可以在设定色彩时直接使用色彩名称,例如:

        xclock -fg #3d7585 -background pink

    色彩设定的形式往往和你的显示器非常相关,通常没有什麽可携性。


13.6.2  X色彩资料库

    为了克服#rgb色彩设定不可携的缺点,而且使系统更易於使用,X使用一
个储存色彩名称及其相关之rgb 值的资料库。

    除非你的系统在装设之後作了明显地改变,应该会有一个/usr/lib/x11/rgb.txt
的文字档说明资料库的内容。这个档的前数行类似於:

        112 219 147 aquamarine            (绿玉色、碧绿色)
        50  204 153 medium aquamarine     (中度碧绿色)
        50  204 153 Medium Aquamarine     (中度碧绿色)
        0   0   0   black                 (黑色)
        0   0   255 blue                  (蓝色)
        95  159 159 cadet blue            (学生蓝)

    每一行前三个数字表示rgb 的元素值,但在此数值是10进位的,且只从0
到255 ,255 代表色彩最大强度,第四个部份为色彩名称,允许名称中间有空
格。

    你可以用程式$TOP/rgb/rgb将此文字档转换为内部的形式,(当你的X系
统建立时,它并不会被装设)。所以,要在你的资料库中加入一个新的色彩,
先用文字编辑器将色彩输入rgb.txt 档,然後:

        venus% cd usr/lib/x11
        venus% $TOP/rgb/rgb < rgb.txt

事实上,rgb 并不需要每次均重建内部资料库,只需加入新增(或修改)的项
目即可,所以你可以用标准输入来输入色彩:

        venus% $TOP/rgb/rgb
        255  50  50  mypink
        …

因为没有任何标准的工具程式可以查询内部资料库的内容,因此上面的作法会
造成rgb.txt 和内部的资料库不一致,所以还是以修改rgb.txt 的方式为佳。


13.7  结论

    本章你已经看到如何命名和储存字型,你如何找到可用的字型及字型的内
容,在X应用程式中如何使用字型,和如何在你的系统中加入新的字型。

    最後一节则描述了X的色彩命名原则,色彩资料库和如何加入你自己的色
彩。

    这里所描述的公用程式只包含core版,contrib 版包含更多的软体,例如
有一个叫做xcolors 的程式,它可以建立一个视窗,并在其中显示在你系统上
已命名的色彩。

    多种的字型和色彩在你的萤幕上出现是一种冲击,接下来你会看到更多的
视窗系统的功能,并□试调整使其适合你工作的习惯及品味。

    下一章我们将继续定制这个系统,告诉你如何利用X的位元映像公用程式
来建立、编辑和使用影像。

=====

第14章  定义和使用位元映像

    一个位元映像是一个小图,说得更清楚一点,一个图的显现是由像素组成,
而像素又是由一个位元来对应,当位元为”1 ”时,像素为”黑色”,而当位
元为”0 ”时,像素为”白色”。X有许多的公用程式来管理位元映像,你可
以用不同的方法来建立、编辑和储存它们。有一些使用者程式允许你直接使用
它们。(其它大部份的程式则以内部的形式使用它们,这些公用程式大都放在
X程式库中,使得使用者撰写程式时很容易便可加以运用。)

    本章开始先描述位元映像的工具,接下来实际使用xsetroot程式,它可以
让你定制你的萤幕,设定一个位元映像的背景,选择你的色彩和指定一个位元
映像当作游标来使用。


14.1  系统位元映像程式馆

    位元映像档案的程式馆被当作系统的一部份提供给你,预设储存在这个目
录:

        /usr/include/x11/bitmaps

但在你的工作站上或许不同,问一下你的系统的装置者,我们将以此目录为准,
并用其中的一些档案作为本章的范例。


14.2  交谈式地编辑一个位元映像 -- bitmap

    bitmap程式是一个让你以交谈式建立或编辑位元映像的工具,它将位元映
像以方格子来表示,每一个格子代表一个像素,你可以用滑鼠设定或清除像素。


14.2.1  启动bitmap

    透过bitmap你可以编辑一个包含有一个位元映像的档案,或从头开始建立
一个位元映像并将它储存为档案。不论是何者,当你启动bitmap时,你需要给
一个档案名称,不论是现存的档案或是新建的档案。

    当建立一个新的位元映像时,你可以选择性地指定大小(宽度X 长度个像
素),如果你未指定,预设大小为16X16 。举例来说,假如我们想要建立一个
比较大一点的十字型数位映像,我们可以用下面的命令列:

        bitmap big-cross 40X50 &


14.2.2  使用bitmap

    假如我们要编辑一个现存的档案,可以用下面的命令列启动程式:

        bitmap /usr/include/x11/bitmaps/cntr-ptr

则一个像图14-1的视窗出现在萤幕上,右下角以实际大小显示出目前位元映像
的状态,另一个则为反相(reverse) 的位元映像,其它在右边的”盒”你可以
用碰触滑鼠按钮的方式来操作它们。

用三钮滑鼠编辑图形最简单的方法:

    设定像素:在一个像素上碰触滑鼠左按钮,或者是按住左按钮并拖拽它,
              每一个经过的像素方格均会被设定,直到松开按钮为止。

    清除像素:和上述相同的方法,但是以滑鼠右按钮代替。

  反转(invert)像素:在一个像素上碰触滑鼠中按钮(也就是黑的像素被清
              除而白的像素被设定),当你按住中按钮并拖拽,所经过的像
              素格均会反转。


        ┌————————————————————┐
        │      p160  fig 14.1                    │
        │                                        │
        │    图14-1  位元映像编辑器              │
        └————————————————————┘

    bitmap还有其它的面貌:如果你观察接近箭头的上端部份(见图14-2的
放大图),你可以在其中的一个方格中看到有一个小菱形,这代表了热点(hotspot)
,当bitmap被用来建造一个游标时会应用到:热点是游标真正动作的点。指向
型的游标,热点通常在顶端,而圆形或方形的游标,热点则在中心。(你可以
用Set Hot Spot和Clear Hot Spot两个命令来更改热点的位置或消去它)

    当你结束了你的更改动作,可以用碰触Write Output将位元映像储存至档
案,但不会离开bitmap程式。

        ┌————————————————————┐
        │      p161  fig 14.2                    │
        │                                        │
        │    图14-2  一个游标的”热点”          │
        └————————————————————┘

    离开程式,碰触Quit,如果你编辑了位元映像却试图在未储存前离开程式,
你将会得到提示以确定你是否真要如此做。


14.2.3  画形状(shapes)

    bitmap有数个功能使得画图更容易:

    画一条线:碰触Line,游标会变成一个大黑点,在所欲画的线的一端碰触
              一下按钮,而後在另一端也碰触一下,bitmap会画出这条线。

    画一个中空的圆:碰触Circle,同样地,游标变成一个大黑点,在你所欲
              画圆的圆心碰触一下,而後在所欲画圆之圆周上的任一点碰触
              一下,bitmap将画出这个圆的圆周。

    画一个填满的圆:碰触Filled Circle ,其馀同上。


14.2.4  在长方形的区域内工作

    命令Clear Area、Set Area和Invert Area 必须在长方形区域下操作,长
方形区域的决定方式是你在它的左上角以按住滑鼠任意按钮的方式指定,然後
拖拽到右下角,当你拖拽时,目前被指定的区域会以高亮度显示。

    你可以拷贝、移动或重叠(overlay) 一个区域,你以拖拽的方式指定原始
区域,而後在目标区域上的左上角碰触按钮,各种命令的动作如下:

        拷贝(Copy):目标区域会被消除,而所有对应於原始区域为黑像素的
                    均会被设定。

        移动(Move):原始区域和目标区域均被清除,目标区域对应於原始区
                    域为黑像素的均会被设定。

        重叠(Overlay) :在目标区域中对应於原始区域被设定的像素均会被
                    设定,其它没有改变。


14.2.5  一个位元映像的档案格式

    一个位元映像会如同ASCII 文字一样储存到档案中,其格式类似C 语言程
式片段。

    例如:档案  /usr/include/X11/bitmaps/cntr_ptr   的内容:

          #define cntr_ptr_width  16
          #define cntr_ptr_height 16
          #define cntr_ptr_x_hot   7
          #define cntr_ptr_y_hot   1
          static char cntr_ptr_bits[]=
          0x00, 0x00, 0x80, 0x01, 0x80, 0x01,\
          0xc0, 0x03, 0xc0, 0x03, 0xe0, 0x07,
          0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f,\
          0x98, 0x19, 0x88, 0x11, 0x80, 0x01,
          0x80, 0x01, 0x80, 0x01, 0x80, 0x01,\
          0x00, 0x00;

    带有_x_hot和_y_hot的变数仅在热点被指定後才会包含进来。

    更多的细节包含在bitmap(1) 的指南页中,不过无论如何,你毋需直接以
此种格式处理位元映像,任何你想要做的事均有工具程式来处理。


14.3  编辑位元映像其它的方法

    bitmap程式对於一个小的图形工作起来算是相当方便,但它有一些缺点:

    .它不接受较简单格式的输入档,例如像一些由扫描现存图形所产生的档案。

    .它必需以交谈式执行,对一些程序性的编辑动作并不方便。

    .你可能希望用它产生一些位元映像来显示,但它无法在非X系统上执行。

    要克服上述的问题,需要以字元图(character picture) 的形式来建立位
元映像,并提供这个格式和bitmap的格式相互转换的程式。字元图格式是非常
明显的:每一行的像素用一行的字元来表示,黑的像素用一个指定的字元(预
设为# )而白的像素用另一个字元(预设为 -)表示,以cntr_ptr为例,字元
图的格式如图14-3

        ┌————————————————————┐
        │      p164  fig 14.3                    │
        │                                        │
        │    图14-3  字元图格式的位元映像        │
        └————————————————————┘

    你能以本文编辑器或其它任何系统上任何其它合适的程式编辑这些图形,
也可以由扫描器(scanner) 或其它影像设备产生。


14.3.1 字元图和X位元映像间的转换

    X提供了两个程式作字元图格式和位元映像格式间的转换:

    atobm : 转换一个字元图为标准的位元映像。

    bmtoa : 转换一个标准的位元映像为字元图。

    两个程式均允许你指定以何字元来代表黑和白像素。


14.4  定制你的根视窗 -- xsetroot

xsetroot 让你设定你的根视窗的特徵,你可以改变视窗背景的颜色和图样(
pattern) ,以及视窗所使用的游标。

14.4.1 设定一个背景的位元图样

   你可以指定任何位元映像来当作你萤幕的背景(只要它是X的标准格式)
, 在 xsetroot 的命令列上,-bitmap 选项跟随著位元映像的档案名称。例如:

    xsetroot -bitmap /usr/include/X11/bitmaps/mensetmanus

会出现一个精致的背景(见图14-4)(拉丁语 Mens et Manus (mensetmanus)
是 MIT的箴言,两个人物的图形简单表现出 MIT的精神。)

             ┌————————————————┐
             │                                │
             │  P165   Fig 14.4               │
             │                                │
             │图14 - 4 设定 mensetmanus位元   │
             │         映像为背景图样的根视窗 │
             └————————————————┘


14.4.2 设定一个背景游标

如果你不要使用预设的 "大的 X "游标,你可以用选项 -CURSOR 加上
cursorbitmap 和 maskbitmap两个引数来改变它,两个引数均为位元映像
档案的名称。例如:设定游标为前节所示的位元映像,使用命令:

    xsetroot -cursor /usr/include/X11/bitmaps/cntr_ptr\
    /usr/include/X11/bitmaps/cntr_ptrmsk

位元映像的对照图见图14-5.

             ┌————————————————┐
             │                                │
             │  P166   Fig 14.5               │
             │                                │
             │图14 - 5 游标及其遮罩的位元映像 │
             └————————————————┘

maskbitmap决定了cursorbitmap的哪些像素真正被显示出来:游标像素
中只有对应到遮罩像素(mask)为黑的部份才会用到,游标其它的像素不会
被显示出来。总结来说,遮罩决定了游标的外形,反之,游标位元映像则
决定了外形的颜色。遮罩和游标的位元映像必须大小相同。

这种遮罩结构在两种情况下非常有用:

1.  它允许 "乾净地" 显示出非长方形游标,而不需显示出多馀的空白。例如
如果没有遮罩,cntr_ptr会显示成一个 16 x 16白方形中有一个箭头,当你用
它指物件时,物件的一部份会被矩形外框遮盖住。

2.  适当地设定遮罩,你可以保证不论背景的颜色为何均能看得到游标。例如
cntr_ptrmsk 比 cntr_ptr 的边均大一个元素,所以游标周围围绕著一圈白边
。如果遮罩和游标大小相同的话,当游标在黑色的区域将会消失不见。

    你可以让遮罩和游标使用相同的位元映像:游标的外形会如你所期望(因
为遮罩决定外形,而这外形正是你想要的),它们可以工作,但是当游标进入
和它相同颜色的区域时,你就很难看到游标了。实际上,并非所有在
/usr/include/X11/bitmaps中的位元映像均有相对应的遮罩,如果你使用它们
当作游标,你必须使用游标位元映像当作遮罩。

    有兴趣的话,试一试把mensetmanus 当作游标和遮罩(热点是在左上角)。


14.4.3  其它的背景设定选项

    你可以用命令列选项 -solid colour设定背景为单一颜色(在单色显示
器上只有黑色和白色)。你可以用 -grey或 -gray设定颜色的灰度,你也可以
用 -mod x y 设定格子图样,x 和 y为 1到16的整数。


14.4.4  重定预设的背景和游标

    如果你不喜欢你既有的设定,你可以用下列两者之一恢复预设的游标和背
景:

        xsetroot -def
        xsetroot


14.5  总结

    本章中,我们看到如何以交谈的方式编辑位元映像,如何储存它们,和如
何把它们与其它格式之间作转换以使它们能被那些非视窗系统程式处理。你可
以把位元映像和xsetroot连接在一起,以定制适合你自己口味的系统:用不同
的方法设定你根视窗的背景和变更游标。

    下一章,我们继续来定制系统,并且来看一下你用以设定X程式预设选项
的结构。

=====

第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*Backgroundrange


如何发现成员和类别名称

    这很困难,因为没有简单和一致的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属性,所以在此范例中可以看出
;星号具有通用字元的效果,甚至可以再一般化一点:

TOP

BBS水木清华站∶精华区

          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*Foregroundrange



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来定制你的键盘。

=====

第16章  实际的使用Resource

    前一章解释X resources的规则----为什麽需要它们,结构如何工作和
resource规格的格式。本章中继续讨论resources ,但较强调实用性:我们告
诉你如何及何处设定resources 预设值,来影响你的系统的一部份或全部。在
本章结束前,我们将完成一些范例,点出你可能常见的错误,并告诉你如何克
服它们。

    在这些范例中,我们假设你自己的工作站叫做venus ,并且大部份时间你
是使用它。从venus 的显示器,你可在远方的机器saturn和mars上执行client
应用程式且和venus 共享档案系统;neptune 则不可,我们曾在第4章描述过。

    当你在本章中时,记得resource结构是:传递资讯给应用程式,通常这些
资讯是用来传递一些比较感兴趣的预设值(例如色彩和字型),但只要应用程
式取得协调你就能使用这种设施传递任何资讯。所以我们一般状况下倾向於把
”resource规格””预设值”(defaults)”resource”这三个名词视为同一含
意。


16.1  在何处储存resource的预设值

    在上一章我们只告诉你输入resource规格到”一个资料库”,但未告诉你
如何做。事实上有几个不同的地方可以储存预设值:这些”地方”通常是一个
你可以用任何编辑器修改的简单的文字档案,但有一个特殊的位置需要特殊的
工具来设定它,我们先很快的给你一个概念,再讨论细节部份。

    首先它的架构非常的复杂:包含命令列选项总共有八种设定resource方法,
但有两个重点需要注意:

    1 .你最好只使用其中的一或二种设置,只要你做完启始设定,你将只
        须改变预设的设定。

    2 .系统是被设计来掌握许多不同模式的工作,和满足那些在许多显示器
        上工作或在一台显示器上工作而存取远方机器的使用者的。

    总结来说,这些设置是提供来让系统尽可能富於弹性,但任何时刻你将只
须存取其中的子集合而已。


16.1.1  设定Resource的八种方法

    总共有八种方法设定resource,但它们可分为下面几类:

    .应用程式专属的(Application-specific)resource:resource的表列,
      限定档案只能被特定的应用程式读取。

    .Server专属的resource:应用设定,不管应用程式在那一种主机上执行。

    .主机专属的设定(Host-specific-setting) :对应用程式在主机上执行
      有关的设定,和显示器无关。

    .命令列选项:在执行时期做一次关闭(one-off) 设定。

应用程式专属的resource -- 方法1 和方法2

    Toolkit 程式初始时在和应用程式直接相关的两个档案中寻找resource,
这些档案只能被特定的应用程式读取:

    1 .应用程式--类别(Application-class) resource档案:这个档案包含
        了机器一般性(site-wide) 对应用程式的类别之预设值,通常为系统
        管理者所设定。它的名称就是应用程式类别的名称,在标准安装的系
        统中它是储存在目录/usr/lib/X11/app-defaults 中,例如xterm 的
        相关档案为:

          /usr/lib/X11/app-defaults/XTerm

        在core版中,有一个相关於Xmh 的此种档案,观察此档案可以看所使
        用之设定的型态。

    2 .你自己拥有的应用程式专属的resource档案:这个档案的名称和上述
        相同,但它存放在不同的地方----由shell 变数$XAPPLRESDIR所指定
        的目录,如果未定义,则放在home目录。例如对Xmh 类别的程式,它
        的档案放在下列二者之一:

          $XAPPLRESDIR/Xmh
          $HOME/Xmh

        你可以使用此种档案,处理方法1 中你不喜欢的 site-wide档案使其无
        效。

Server专属的Resource -- 方法3 和方法4

    这是对你目前工作的Server(显示器)做有关的设定。键盘的设定通常是
server专属的(因为不同的显示器有不同的键盘)。另一个server专属的特徵
为显示器是彩色或单色。

    Resource和这些有关的项目会被所有与这个终端机相关的应用程式应用到,
并且不论应用程式在何主机上执行。(例如,如果你使用的显示器为单色,则
不管你的应用程式在何处执行,你还是不会要它使用彩色。)

储存server专属设定的方法是:

    3 .server的RESOURCE_MANAGER性质(property):(你可在12章中xprop
        的输出看到),使用下述的xrdb程式,你可以在server的根视窗的
        RESOURCE_MANAGER性质中储存resource设定。它的优点如下:

        (a) 你不需编辑任何档案即可设定预设值。(当你为了了解系统而实
            验系统时特别有用)

        (b) resource被server掌握,所以不论应用程式在那一部主机上执行,
            均能被所有的应用程式应用。在我们的范例中,在neptune 的
            情况下特别有用,甚至在不和我们的显示机器venus 共享档案系
            统时,它仍然自动地选出为了使用此显示器所必需的resource设定。

    4 .你的$HOME/.Xdefaults档案:(只有在根视窗没有RESOURCE_MANAGER
        性质定义的情况下使用)。如果你对xrdb尚不熟悉,你便可以此档取
        代,但你必须在每一部你执行client应用程式的机器上均设定一个。

主机专属设定 -- 方法5 和方法6

    主机专属预设值和server专属相反,不管应用程式所使用机器的终端机为
何,只要应用程式在此主机上执行,均使用主机专属预设值,你可以用它们来:

    .让应用程式在不同的机器上对不同的档案系统作计算,例如:被一个应
      用程式读取的资料档案可能在不同的主机上保持不同的位置。

    .区分显示在同一个萤幕上不同的主机的视窗(这些视窗可能由同一个应
      用程式执行),例如:你可以要所有在mars机器上执行的xterm 的视窗
      为红色的边框,而在saturn上执行的视窗为黄边。

    .调高一个相同的应用程式在不同的client机器上版本的差异,例如:
      xterm 在venus 是标准的MIT 版,但在neptune 机器上是由第三集团修
      改过以适应机器结构的产品,这两版的xterm 可能并不完全相容。

主机专属Resource储存在:

    5 .由$XENVIRONMENT 来的档案名称:如果shell 变数$ENVIRONMENT有被
        定义,它会被解释为一个含有resource设定的档案之完整的路径名称。

    6 .你的$HOME/.Xdefaults-thishost 档案:(当$XENVIRONMENT 未被定
        义时使用)。注意它和我们先前的档案有所不同,它必须附加上主机
        名称,例如,如果你在neptune 执行应用程式而在venus 显示(假设
        RESOURCE MANAGER性质未定义),则server专属 resource 读取自:

          .Xdefaults

        而主机专属resource则是:

          .Xdefaults-neptune

        两者均在neptune 的家目录(home directory)中。

    注意:在不同的小节中,我们曾说过类似”server专属resource读取自...”
这可能造成误导:”如果你实际需要,你可以放置任何型态的resource设定到
任何的档案或资料库。”我们真正的意思是你应该放置机器特性或不论甚麽的
resource到任何地方,如果你这样做,你将获得你需要的动作。

命令列选项 -- 方法7 和方法8

    最後,你可以藉著命令列选项设定应用程式的值。通常当你设定预设值时
,为的是你不需要使用选项为你的程式作X相关的设定。但你实际上可以用它
们来:

    .一次关闭(one-off) ,例如:你暂时性地在萤幕上需要一个极小的xedit。

    .为了区别在相同应用程式中各自的成员,你已看过一个这样的例子,当
      我们使用命令

          xterm -name demo

      来设定应用程式的成员名称给demo,将造成以应用程式名称为demo的
resource取代xterm 的resource。

命令列选项分为下列两种:

    7 .应用程式专属选项:例如xclock的-chime的xpr 或-scale。

    8 .Toolkit 标准选项:所有用到Toolkit 的应用程式均接受一些标准的
        命令列选项,我们看过其中的大部份,包括-fg, -bg, -display,
        -geometry 等等,标准选项的清单在”X Toolkit Intrinsics ”手
        册的2.3 节中。

    在其中有一个选项-xrm,重要的足以用一个小节来描述。

Toolkit 标准选项-xrm

    大多数一般的resource均能被命令列选项明确地设定,例如你可以用
-bg colour设定视窗背景颜色。但无论如何,有一些resource并没有符合的选
项。为了克服这点,Toolkit 提供一个 "捕捉遗漏" (catch all) 的选项-xrm
(X Resource Manager 缩写)。

    -xrm以一个引数当做resource规格,就如同你在预设值档案中输入的相同,
例如:你可以输入:

          xclock -xrm "*update:30"



          xclock -update 30

是相等的。

    在同一命令列你可以使用数次-xrm,但每一次只能包含一个resource规格,
例如:

          xclock -xrm "*update:30" -xrm "*chimen"

    -xrm的好处在於你可以用它来设定任何resource供应用程式使用,尤其是
那些和命令列选项不符合的resource。其中一些非常有用的像:

    iconX, iconY:视窗表徵图左上角x,y 座标的位置。

    iconPixmap:被用来当作视窗表徵图的位元映像的名称,你可以用它
                来指定任何的位元映像当作应用程式表徵图。(位元映像
                为已有或利用bitmap程式建立。)例如:命令

                xedit -iconic -xrm "*IconPixmap:cntr_ptr"\
                              -xrm "*iconX:500"\
                              -xrm "*iconY:400"

                的意义为将xedit 设定以表徵图开始启始,表徵图的左上角
                座标为(500,400) (在大多数的显示器会在萤幕中央),使
                用名为cntr_ptr的位元映像来当作表徵图。

    backgroundPixmap:设定用一个位元映像当作背景。

    borderPixmap:设定以一个位元映像当作视窗的边,例如:

                xclock -bw 20 -xrm "*backgroundPixmap: scales"\
                       -xrm "*borderPixmap: cntr_ptr"

    执行xclock,用一个宽达20个像素的边框,视窗的背景为鱼鳞
(fish-scales) 图案,边框则用cntr_ptr的位元映像。

    所有的这些resource当然也可用类别指定。(如IconX ,BorderPixmap等等。)

    注意:请记住,-xrm只有在程式有用到Toolkit 才可应用。


16.1.2  设定Resource不同方法的摘要

    现在我们将如何对一个指定应用程式resource设定的八种方法作一摘要:

    应用程式专属resource:它们被两个档案掌握,且仅能被Toolkit 使用,
              其中一个档案通常由系统管理者设定,另一个由你自己设定。

    server专属的resource:不是存在根视窗的RESOURCE_MANAGER性质中,便
              是在你的$HOME/.Xdefaults档案中。

    主机专属resource:如果shell 变数$XENVIRONMENT 有定义的话,存在其
              所定义的档案中,否则在你的$HOME/.Xdefaults-host 档案。

    一次关闭设定:用应用程式的本身命令列选项来设定,和用Toolkit 标准
              命令列选项,包含”捕捉遗漏”-xrm.

    它们以下列顺序处理:

        if  (程式使用Toolkit )
              读取 /usr/lib/X11/app-defaults/class档案  (1)
              读取你的 $HOME/class档案  (2)
        if  (RESOURCE_MANAGER性质被定义)
              处理内含的指定   (3)
        else
              读取你的$HOME/.Xdefaults档案   (4)
        if  (shell 变数XENVIRONMENT被定义)
              读取所定义名称的档案   (5)
        else
              读取你的$HOME/.Xdefaults-host 档案   (6)
        if  (程式使用Toolkit )
              处理标准的resource选项,包含-xrm  (7)
        处理应用程式本身的选项  (

    现在我们将更详细的看一个较不熟悉的方法 -- 用来储存server本身
resource的方法。


16.2  在Server上储存预设值 -- xrdb

    大部份预设值的结构均和档案有关,当应用程式启始时,不同的档案被读
取且其内容被处理,这种方式的缺点为你希望所有的client在一个特定的
server上使用同一组的预设值,但client所执行的机器上如果没有一个共同的
档案系统,你该怎麽办?

    答案是在server本身储存预设值。X的性质设施是一个具有一般性目的的
结构。(记住,一个”性质(property)”是一小段已知格式资料的名称,被储
存在server),指定由server根视窗的RESOURCE_MANAGER性质载入,且当应用
程式启始时系统会注意此事。当视窗系统启始时,RESOURCE_MANAGER性质未定
义:如果你要使用这个设施,你必须明确地设定它。

    并没有一个一般性的工具来操作一个性质,所以X提供了一个特殊的程式
来处理resource性质,它就是xrdb(the X Resource DataBase 公用程式)。


16.2.1  xrdb能为你做什麽

    为了方便起见,本章剩馀的部份,我们只把RESOURCE_MANAGER性质和它的
内容当成”资料库”。

    xrdb的功能非常简单,它让你能:

    .设定一个新的资料库。

    .看目前有那些resource在资料库中。

    .在现存的资料库加入一个新的resource。

    .完全去除资料库。

    这些是基本操作,且很容易完成。当然也有一些更进一步的功能可以很精
确地让你控制resource,但我们先来讨论基本操作。


16.2.2  使用xrdb的基本功能

    xrdb的操作类似大多数Unix的程式:它从一个档案或标准输入读取输入资
料,并且你可以用命令列选项来控制它的操作模式,它所读取的输入是我们曾经看
过的一系列resource设定,不过比较特别的是它把这些设定载入资料库,让我们看
一看它主要的功能:

    设定一个新的资料库:输入下面命令两者之一:

          xrdb filename
          xrdb < filename

用以将一个档案中的设定载入到一个资料库中,如果只键入xrdb,表示你将由
标准输入(通常为键盘)直接输入设定,稍後我们将说明xrdb所接受的档案格
式,但现在先把输入resource设定当作和.Xdefaults档案或-xrm引数相同的方
法,例如,你可以用下列的方式定义xclock设定:

          venus% xrdb
          xclocks*Background: pink
          xclock*update: 30
          xclock*backgroundPixmap: cntr_ptr
          <end-of-file>

    通常你用一个档案当作xrdb的输入,也就是说,xrdb从一个档案载入预设
值作为你的视窗系统初始化的一部份。如果你很有经验,直接输入它的设定也
许容易些。

    查看现存资料库中的内容,输入命令:

          xrdb -query

则xrdb将以明白本文格式(plain text format) 印出资料库的内容(-query可
以缩写为 -q )。

    (你可能记得也可以在根视窗用xprop 来看资料库的内容,但xprop 的输
出格式不太灵巧,它给你其它一大堆你不需要的资讯。)

    如果需要,你可以抓取xrdb的输出到一个档案,编辑它,更改设定後可再
用它当作xrdb的输入。(下一项功能告诉你一个更好的方法)

    注意:查看资料库,你必须使用选项-query。如果你忽略这个选项而只输
          入xrdb,将造成会清除资料库,且xrdb在等待你自标准输入键入你
          新的设定。

    在现存资料库加入新的设定:加入新的设定到资料库且不要破坏原有的设
定,使用命令:

          xrdb -merge filename

    (-merge可缩写为-m,如果你省略档案名称,xrdb会自标准输入读取。)
xrdb自指定的档案中读取resource设定,并加入现存的资料库中;对於资料库
中已存在的resource,如果有新的设定,旧值会为新值取代,否则则不会变动。

    完全移去资料库:如同先前所述,当系统结束时资料库会自动消失,但如
果你在系统仍在执行时移去资料库,使用命令:

          xrdb -remove

    本节介绍xrdb基本的功能,下一节我们介绍当你熟悉系统时,你可能需要
的更进一步的功能。

16.2.3  xrdb的档案格式

    你已知道大多数的格式细节 -- 你可以用标准的resource规格的形式

          characteristic: value

    上述的格式你已看过多次,但xrdb有两个额外的规则:

    1 .注解(comments):每一行的开头如果是惊叹号(!)会被忽略,所以
        你可以此当作注解。

    2 .xrdb预设将它的输入列传到C 前处理器。

    让我们进一步看一看前处理器的过程。

xrdb前处理它的输入列

    让我们看一看一个你可能碰到的典型问题。假设在一般的场景,你使用下
列显示器:

        venus   彩色萤幕,正常解析度
        saturn  单色萤幕,正常解析度
        mars    彩色萤幕,高解析度

    以上三者共享一个共同网路档案系统,当你在一个显示器上启动X,你需
要定义预设值来反应显示器的特徵。例如:在高解析度萤幕你可能需要较大的
预设字型,或是你不需要在单色系统上定义彩色预设值。

    如何做呢?让我们看一看,如果你能使用.Xdefaults-host 档案:在
.Xdefaults-venus我们包含了彩色指定,而在.Xdefaults-saturn 我们只放入
单色型态的参数。行得通吗?当然,但是是有限度的:它只能掌握应用程式在
和server相同的机器上执行,如果应用程式在其它的机器上执行会得到它们主
机上的预设档案。所以如果你使用venus 且在saturn启始远方的client,将会
用到.Xdefault-saturn而错失所有的彩色指定。

    你能够只使用.Xdefault 档案来区分机器吗?不能,因为三台主机共享相
同的档案系统,所以$HOME/.Xdefaults会被venus 获得也会被其它的机器获得。

    答案是在resource处理程序的某些地方,有一个结构可以分辨出所使用
server的某些特徵。xrdb可以用相当简单的办法做到这点,它先定义一些说明
server特徵的C 前处理器符号,而後将它所有的输入传递到前处理器,最後将
处理过的资料载入资料库。指南页列出所有的xrdb定义的前处理器的符号,但
在此处我们需要用到的是:

    X_RESOLUTION=n:n是每公尺长萤幕有多少像素。(根据我们的server,我
们正常解析度的萤幕为每□90个像素,相当於每公尺3454个像素。)

    COLOR :只有萤幕支援彩色才被定义。

    WIDTH,HEIGHT:萤幕的宽度和高度,单位为像素。

    图16-1显示我们如何在xrdb的输入档案使用这些。(我们命名为
$HOME/.Xresources ,稍後我们仍将再度用到。)它可以正确地做到我们所想
要的 -- 它正确掌握了所有我们的显示器,不论是彩色或高解析度或两者都有。

    一些要点值得注意:

          ┌—————————————————————┐
          │    P197   FIG 16.1                       │
          │                                          │
          │  图16-1  利用前处理器命令的Resource档案  │
          └—————————————————————┘

    .你可以使用所有前处理器的功能。例如,我们使用它的表示掌握
      (expression-handling) 能力:

          #if X_RESOLUTION > 3600

    .你可以在档案中任何地方使用前处理器符号,并不只是前面有# 号的列,
      例如,当

          xload*Width: WIDTH

      在venus 上xrdb执行到时,它将会读取成:

          xload:Width: 1152

    所以由预设值可知,xload 视窗宽度将和萤幕宽度相同,高为80个像素,
且在萤幕的正上方。

    注意:大多数Unix前处理器定义了一些和它们机器结构与作业系统相关的
          符号,这些可能会干扰到你,特别是Unix通常定义的符号,现在
          xrdb定义HOST为显示器名称中主机名称的部份,所以你可能认为你
          可以像这样使用一个resource规格:

              demo*title: X demo using display HOST

          比方在venus 上,预期它相当於:

              demo*title: X demo using display venus

          事实上,在我们的机器上会得到

              demo*title: X demo using display 1

          原因为显示器名称是unix:0.0,所以主机名称部份为unix,但前处
          理器已定义了unix,所以整个解释的顺序为:

              HOST -> unix -> 1

          你可以用xrdb的-u选项来解除符号的定义,用以克服这点,也就是

              xrdb -Unix < filename

          但即使如此,主机名称仍为unix,除非你明确地指定显示器:

              xrdb -display venus:0 < filename

          另一个会产生干扰的范例,如何你输入规格

              xedit*Font: *-sun-screen-*

          使用xrdb,现在用一个xrdb -query ,你可以看到在资料库中实际
          地设定:

              xedit*Font: *-1-screen-*

    在我们sun 的机器上,前处理器定义成另一个符号。如果你使用和你的机
器相关的名称,你可能也会得到相同的效应。(如果你决定不需要前处理器的
功能,你可以用xrdb的-nocpp选项停止它的功能。)


16.2.4  如何将资料库设定和你的xrdb输入档连接在一起

    藉著像前述在一个含有大量前处理器命令的档案执行xrdb,你初始化了资
料库,在稍後的期间,交谈式的使用xrdb,你将对资料库做大量的更动,现在
你需要记录这些设定,且将之与原来的输入档连接,以备将来之用。

    如果你只使用xrdb -query ,你只能获得目前的设定:所有在输入档中的
条件指令列若和现在的server不符则不会被包含。例如在saturn上执行前述的
档案,则所有色彩和高解析度的设定,均被忽略(当然以 #开头的也不例外),
为了克服这点,xrdb提供-edit 选项,例如命令:

          xrdb -edit myresf

连接目前在资料库中的值到档案myresf内存在的内容,它藉著比对resource指
定特徵值的部份做到这点:如果在档案中某一行和资料库中某一项特徵相同,
则档案中值的部份会被在资料库中的值取代,用此方法,所有的以 #开头的列
和条件设定均会保留在档案中。

    注意:前处理器完全不可以使用-edit 选项,那会导致问题,我们看一
          下当我们使用venus ,且以前述档案初始化资料库时,会发生什麽
          情况,假设我们做了更动:

              venus% xrdb -merge
              XTerm*font: *-courier-medium-r-*-140-*
              <end-of-file>

          然後用命令:

              xrdb -edit myresf

          将设定更改的部份放回档案,我们看到两件事:

          1 .前处理器符号在规格中值的部份会被字面(literal)值取代,
              例如:

                xload*Width: 1152 会被

                xload*Width: WIDTH  取代

          2 .在规格中只要特性符合,值均会被取代,甚至那些在条件段中
              目前尚未应用到的也不例外。例如,在前述档案,设定
              XTerm*font的那两行(一行在高解析度那段,一行在正常显示
              器那段)都会被更改,即使我们只需要改变正常显示器也不例
              外。


16.3  一些常见的错误和如何修正它们

    特别是当你对系统是新手的时候,resource看起来相当的复杂。当有些状
况不能正常执行,而系统无法帮助你查觉是什麽错误,或你在何处犯了错误,
这里列出一些常见错误的明细,并提出如何修正它们。

    .如果你未设定一个应用程式的名称和类别,确定在你的resource规格之
      前加一个星号,(如果你省略这个星号,将没有任何东西会对应这个规
      格)这个错误在你使用-xrm时特别常见,例如:

          xclock -xrm "update:3"  (错误)
          xclock -xrm "*update:3" (正确)

    .并非所有的应用程式均使用Toolkit ,非Toolkit 的程式不使用类别,
      且它们的属性名称也可能不同。例如,规格

          *geometry: 300*400+500+600

      对xclock,xlogo 有效,但对xcalc 无效,因它不使用Toolkit ,xcalc
      使用属性名称Geometry(开头为大写的G ),因为在这种情况,Toolkit
      类别名称和xcalc 的属性名称相同,所以单独一个规格

          *Geometry: 300*400+500+600

      可以对所有这类的应用程式有效。

    .你可能在规格中用了错误的属性或Widget的名称,特别是容易把类别名
      称和成员名称搞混,例如:以下两者均错:

          xclock*Update: 10
          xclock*interval: 10

      其它常见的错误如:

          xterm*Text*background:blue

      它不能执行的原因为xterm 并未使用Text widget ,xterm 正常的视窗
      和Tektronix 的视窗分别使用widget类别 VT100和Tek 。最後,当你
      知道一个widget是什麽类别,你可能对成员名称假设错误,不是widget
      本身便是其中之一的属性。试著更换类别名称来修正这个问题。

    .即使你已设定实际的widget和属性名称或类别,应用程式可能以不是你
      预期的方式使用它们。例如:你可能设定如下:

          xterm*Width: 40
          xterm*Height: 10

      意图用比平常较小的视窗启动xterm ,但它不能执行,xterm 只能在
      Tektronix window应用这些值,无法在正常的视窗。

    .你可能所有的设定完全正确,但仍然什麽也没发生,例如:

          xmh -xrm "*inc.Label: Include"

      是一个正确的方式,执行xmh 并指定label 为inc 盒的必须被"Include"。
      但在标准系统的发行版,是没有任何动作发生的,原因是xmh 有一个应
      用程式设定预设值档案/usr/lib/X11/app-defaults/Xmh ,其中有一行:

          xmh*inc.label:Incorporate New Mail

      这个规格较我们的设定有较高优先。

    .将规格

          *Width: 200

      单独包含在资料库将导致大多数的Toolkit 程式启始失败,且有一个
      讯息说它的"shell widget has zero height or width" 。如果你设定
      height和width 二者之一,你必须也设定另外一个。

    .如果你用编辑器建立一个resource档案,你可能省略了最後一个new line
      这将导致当你试图用xrdb载入它时整个档案均被忽略。为了避免如此,
      当载入resource时,用一个命令列像:

          xrdb resfile; xrdb -query

      如果xrdb无法列印出resfile 中的内容,就是有问题了。

    .你可能忘了用-xrm选项的引数来获得resource规格,有时有人会把
      resource规格放入一个档案,而以档案名称为-xrm的引数,预期它自此
      档案中读取resources。

    .最後,一个非常人性的错误,当你发生问题,你通常会循环动作:编辑
      resource档案... 储存它... 载入resource到资料库... 执行应用程式
      和看一看发生什麽状况。”其中载入resource到资料库”常常会被忽略
      以致你更为困惑。

16.4  结论

    本章中,你已看过了所有你能设定resource的地方,为何有这麽多种的方
法,如何决定设定放置在何处。你看到如何使用xrdb程式在server实际地储存
预设值,它们在何处被server所有的client存取,甚至它们可以在远方的机器
上执行。最後,有一些关於常见错误的实际提示,告诉你什麽需要注意。

    你现在处於实际使用resources ,和剪裁你的系统适合你的口味,resource
结构功能非常强大且有无限的弹性,所以它可让你定制任何你需要的事。刚开
始不妨试一些像字型或色彩之类简单的设定,当你熟於基本的结构时,再转到
更高水准的例子。

    下一章将告诉你如何使用特别形式的resource规格 -- Translations(转
译),来剪裁你的键盘以适於特别的应用程式。

=====

第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 <newline>

利用Toolkit 达到此目的方法为:指定一个值给使用转译的widget中的resources
。此值设定应用程式中所必需的定制 (customisation),且被Toolkit 的 Trans-
lation Manager (转译管理器) 所处理。此 resources属於类别Translation,
且其成员名称几乎一定是translations。

    在下一节我们将看到设定到resources 中的值的格式。

17.1.1 如何对一个应用程式指定转译

    对前述xterm 的例子,我们定义 (在即将被应用程式读入的resource资料
库中或一些resource档案中) 一个规格类似:

    xterm*VT100*Translations: (contd.)
    <key>F1: string("rm core *.tmp")            注意:不完整!!

    其意为在任何类别 VT100的 xterm widget 中,当键 F1 被按下时,插入
字串 "rm core *.tmp")。

    不幸的是,并没有这麽简单,转译管理器会把上面的规格解释为 "去掉所
有现存的转译,且加入... " ,所以所有正常的像 " A键是插入一个 A" 这种
系结 (binding)都会消失。为了克服这点,你必需使用一些被称为 directive
(指引)的语法插入在 resource 值之前:

      xterm*VT100*Translations: #override(contd.)
      <key>F1: string("rm core *.tmp")

    通常你会希望保持大部份现存的系结,而只是把你明确指定的值覆盖上去
,所以你一般都是在你的转译表中,指定 #override。

    现在这个规格可以开始工作了,藉著启始一个 xterm且把此规格 (在两个
单引号 (')中间的部份) 当成选项 -xrm 的引数来测试它:

    xterm -xrm 'xterm*VT100*Translations: ... 等等'

    按下特殊功能键 F1,你将看到指定的字串成功的插入,但并未包含新列字元
(newline) ,你可以用一点语法的技巧来克服它,像:

      xterm*VT100*Translations: #override(contd.)
      <key>F1: string("rm core *.tmp")string(0xd)

这解释了以下两点:

  1.  string()的作用和它的引数相关。你可以直接输入本文 (例如 string(lpq))
      ,但如果本文包含空白或非字母字元,则必需在本文前後加上双引号。
      如果引数是以 "0X" 开头,则将其後解释为十六进位,并插入相对的
      ASCII 字元。(例如,0xd是RETURN)

  2.  在你指定此功能时可结合一个以上的作用,在上例,我们用到 string()
      作用两次,如果我们知道其它的作用,我们也一样可以系结起来。

定义许多的转译在一起

你可以根据需求在一个表中定义许多的转译。假设,我们在前面的转译中增加
系结:

      当我按下这个键时...           我希望这个字串被输入

          F2                          lpq-Plpa3 <newline>

对此的转译为:

    <Key>F2: string("lpq-Plpa3")string(0xd)

所以可以将本列加入前面的表中。但是转译管理器的格式规则告诉我们必需将
两个转译以 "\n" 分开且独立成为一列:

      xterm*VT100*Translations: #override(contd.)
      <key>F1: string("rm core *.tmp")sting(0xd) \n(cond.)
      <Key>F2: string("lpq-Plpa3")string(0xd)

以上的形式将造成管理上的困难,你可以藉著包含 "隐藏的新列字元" 来使它
具可读性一些: (新列字元以倒斜线 "\"处理)

      xterm*VT100*Translations: #override\n\
      <key>F1: string("rm core *.tmp")sting(0xd)\n\
      <Key>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\
      <key>F3: insert-selection(CUT_BUFFER0)

到目前为止,这只是一点小小的便利。然而,假定说你花了许多时间在本文文
件上工作,你用 tbl格式化,你用 nroff在萤幕上预视 (preview)它们,用
troff 排版,且将输出送到你的一个用过滤器 (filter) 为tr2printer的印表
机上。设定转译为:

  xterm*VT100*Translations: #override\n\
  <key>F3: string("ed") insert-selection(CUT_BUFFER0)\
  string(0xd)\n\
  <key>F4: string("tbl") insert-selection(CUT_BUFFER0)\
  string("| nroff -man") string(0xd)\n\
  <key>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\
    <Key>?: check()\n\
    <Key>Down: unset()\n\
    <Key>Up: set()

以此测试之:用xrdb从你的resource资料库载入这些设定,然後启动xbiff ,
将指标移到视窗内。重复地按下Up和Down游标控制键以升起和降下信件旗
帜。

找出有哪些作用被提供

你对widget作用将和widget名称遭遇相同的问题:如何找出某个widget到底提
供哪些作用以及它们能做些什麽?同样地,没有一个完美的解答,但有一个合
理的方法来处理:

  1.  查看应用程式的指南页。大多数的应用程式有它们自己专门的作用文件
      。例如:xbiff 有一节叫做ACTION,而xterm 有两节关於转译和作用的
      文件 -- KEY TRANSLATIONS 和 KEY/BUTTON BINDING。

  2.  最初的指南页可能给你提示,或甚至直接告诉你它用到何种widget的类
      别,所以你可以查看它的widget set文件中的特定的widget。(在 core
      版中惟一的widget set为Athena,所以你在此不易出错)。即使指南页未
      告诉你widget的类别,当你对系统熟悉之後,你将对一个widget是否为
      标准型态较具有概念,如果还是不行 ...

  3.  查看程式的原始码,看看用到什麽widget的类别,以及widget提供了哪
      些作用。

17.1.3 转译系结作用到一序列事件,不只是单一键

我们已经看到转译让你设定插入,转译结构也能让你系结这些作用:它可以是
单一的键,或是一序列的键,或者是事实上一序列任何的X事件。

    让我们继续以xbiff 为例,看看如何转译一序列的键盘字元。例如我们定
    义字元字串的转译如下:

        look   check()
       raise   set()
       lower   unset()

以下为相关的转译表:

    xbiff*Mailbox*Translation: #override\n\
    <Key>l,<Key>o,<Key>o,<Key>k: check()\n\
    <Key>r,<Key>a,<Key>i,<Key>s,<Key>e: set()
    <Key>l,<Key>o,<Key>w,<Key>e,<Key>r: unset()

以此测试之 -- 载入设定和启动xbiff ,将指标移到视窗内。现在你可藉
著输入完整的字串来升起和降下旗帜。例如键入五个字元 r, a, i, s, e以升
起旗帜。对xbiff 的两个表有几点值得说明:

    . 键的名称可以用不同的方式指定。正常的印出字元直接指定 (如"<Key>w")
      , 其它的字元则拼出全名(如"<Key>Down").附录A "文件指引" 告诉你
      在何处可查到键的名称,但在本节下面有更简单的方法。

    . 对字元字串,你必需一一指定,并以逗点分开
      (如"<Key>l,<Key>o,<Key>o,<Key>k").

    . 转译可允许相同开头的键,例如 "look" 和 "lower" 均拥有相同的开头
      "lo",对转译管理器不会形成问题。

找出键的名称

找出转译所需的键的名称,最简单的方法为执行xev ,将指标移到视窗内,按
下你所需的键,则键的名称会出现在括弧内字串keysym和一个十六进位数之後
。例如在xev 的视窗内按下游标控制键DOWN,它的输出如图17 - 1,在其中你
会看到

    (keysym 0xff54, Down)

也就是说,键的名称为Down。

               ┌————————————————┐
               │  P209.  fig 17 - 1             │
               │                                │
               │                                │
               │                                │
               │ 图 17 - 1 xev 显示键名称的输出 │
               └————————————————┘

你可以在转译中使用任何型态的事件

到目前为止,我们所写的转译都是系结作用到一个按下的键盘字元。但我们曾
说过,转译结构可系结作用到任何事件,而不只於按下键盘而已。可能的事件
型态非常的多,在此我们只提及一小部份:

      型态               意义

      <Key>          按下一个键
      <KeyDown>      按下一个键 (只是另一个名称)
      <KeyUp>        放松一个键
      <BtnDown>      按下一个滑鼠按钮
      <BtnUp>        放松一个滑鼠按钮
      <Enter>        指标进入视窗内
      <Leave>        指标移出视窗外

我们已经使用过按下一个键的事件,让我们系结xbiff 作用到滑鼠按钮以取代之:

    xbiff*Mailbox*Translations: #override\n\
    <BtnDown>Button1: unset()\n\
    <BtnDown>Button2: check()\n\
    <BtnDown>Button3: set()

你可以看到语法和前面相似:你先给定一般性的事件型态 (例如 <Key> 或
<BtnDown>),其後跟著你所需事件的事件细节部份 (例如s 和Button3) (
Button 1, 2, 3分别对应到左、中、右按钮)

对一序列的事件的转译

就如同我们定义了一序列按下键事件的转译(set,unset和check),我们当然
也可以定义一序列的滑鼠事件。事实上你转译的一序列的事件可以任意组合在
一起,你可以在一个转译的左边随意混合事件的型态。所以你可以定义如下的
转译表:

    xbiff*Mailbox*Translations: #override\n\
    <BtnDown>Button1, <Key>?, <BtnDown>Button3: check()\n\
    <BtnDown>Button1: <Key>u, <BtnDown>Button3: unset()\n\
    <BtnDown>Button1: <Key>s, <BtnDown>Button3: set()

也就是说,用到check(),你必需依序先按下按钮1 (左按钮),然後按下"?"
键 ,最後按下按钮3 (右按钮)。 这个范例并不是很好,但对於一些危险或不
可取消 (irreversible) 的作用 (例如删除一个档案,或是覆写一个缓冲区的
内容) ,你可以依照这种方式来使用转译。你需要使用一个非常谨慎的命令序
列,才能用到此作用,这样使得使用者不可能因意外而输入此命令。

使用非键盘和非滑鼠事件的转译

通常你是对按下或放松滑鼠按钮或键盘的键定义转译。但我们曾经说过,你可
以对任何事件设定转译,例如指标移入或移出一个widget的视窗。让我们以
xman的主选项视窗 (图10 - 3) 为范例来解释它。这是一个相当人为的范例,
因为它没有任何用途。但无论如何,它很容易被看出在做些什麽操作。

查看xman的指南页,在X DEFAULTS标题下,你将看到概括的xman所用到的widget
的名称和类别:主选择项视窗widget的名称叫topBox,类别名为Command。这
是一个好的猜测,因为在选单操作盒的方法。我们可用第15章所提过的技巧
来确认它,使用以下的命令:

    xman -xrm "*Command*backgroundPixmap: scales"

且所有的Command widget将会有鱼鳞状的背景)。

这和我们先前的范例有一个重要的不同:我们所用到的作用不是由特定的应用
程式指定,而是由标准的widget提供 (本例中为Command widget,在 "X
Toolkit Athena Widget"使用手册中有描述)。

    在我们定义任何东西之前,先来看一看此widget预设的功用,以便我们能
够了解有些什麽事发生和有哪些widget的作用会做。启动xman,移动指标进入
Help 盒,你会看到盒的外框变成高亮度 -- 这是highlight() 在作用。将指
标移出,盒的外框恢复正常 -- 这是unhighlight() 作用。将指标再度移入
Help 盒,按下一个滑鼠按钮,保持按住不放。则盒内的色彩反转 (盒内的文
字变成预设的背景色,而原来视窗的背景变成视窗的前景色)。-- 这是set()
在作用。继续保持按住滑鼠按钮,将指标移出视窗外,盒内色彩恢复正常 --
这是reset() 在作用。一个正常 "碰触一下" (clicking on) Help盒的次序为:

    1.  移动指标进入盒中:highlight()将外框变为高亮度。

    2.  按下按钮:set() 反转盒中的色彩。

    3.  松开按钮:notify()开始作用,造成程式建立求助视窗(help window)
        。在进行中时,盒的色彩保持反相。当视窗建立完成之後,reset()反
        转盒内的色彩为正常,但外框仍保持高亮度。

    4. 将指标移出视窗:unhighlight()将外框恢复正常。

    现在你了解了有哪些作用,我们将定义一些转译来改变原先进出视窗的作
用:

    *Command*translations: #override\n\
    <EnterWindow>: reset()\n\
    <LeaveWindow>: set()

用这个奇怪的转译表,当你一开始移动指标进入盒中,什麽事也不会发生,但
当你移出指标时,色彩会反转。如果你再度移动指标进入盒中,色彩会变回正
常。其它的作用和前述相同。

使用修饰键来修饰事件规格

有时你指定的转译希望能同时按下一或多个修饰键 (modifiers) ,例如你要系
结一个作用到和META键同时按下的一个键,或是当CTRL和SHIFT 同时按下的滑
鼠按钮。到目前为止我们还没有任何办法可指定如此。我们不能用事件序列达
成这点,因为它是依序定义的,而我们需要的是指定同时,例如 "按下X 键且
CTRL键同时被按下"。

    欲在转译中指定修饰键,你只需在事件名称之前加上你所需的修饰键名。
例如在xterm 中,定义meta-i为 "贴" 上一次 "剪" 的本文,使用:

    *VT100*Translations: #override\
    Meta <Key>i: insert-selection(PRIMARY, CUT_BUFFER0)

因为这种修饰键/事件型态的组合十分常见,转译管理器允许使用一种缩写的
形式。相等於上面第二列的写法为:

    <Meta>i: insert-selection(PRIMARY, CUT_BUFFER0)

    我们可以对滑鼠事件做同样的处理。让我们对xedit 定义转译,使得使用
滑鼠可以在本文上方便地移动,我们首先的尝试如下:

    *Text*Translation: #override\
    Shift <Btn1Down>: forward-character()\n\
    Shift <Btn2Down>: forward-word()\n\
    Shift <Btn3Down>: next-line()\n\
    Ctrl <Btn1Down>: backward-character()\n\
    Ctrl <Btn2Down>: backward-word()\n\
    Ctrl <Btn3Down>: previous-line()

如果你测试它,奇怪的现象会发生 -- 游标好像会自行其是,而且本文的片段
会一下子被选择,一下子又取消选择。发生这种现象的原因是Text widget 的
预设系结仍然会作用,它包含的转译像:

    <Btn1Up>: extend-end(PRIMARY, CUT_BUFFER0)

你可能认为这不会影响你,因为当你松开按钮时你总是按著SHIFT 键或CTRL键
。但事实上会作用:转译管理器对於你未定义的修饰键解释为你不在乎它们的
影响,所以松开Button1 时会对应到上述的规格。为了克服这点,我们对那些
可能不小心便会发生的按钮松开事件定义转译,并系结到一个空 (null) 作用
。这些转译当被对应到时会盖掉预设的转译。对使用Text widget 我们需再增
加两列,才是一个完整的转译表:

    *Text*Translation: #override\
    Shift <Btn1Down>: forward-character()\n\
    Shift <Btn2Down>: forward-word()\n\
    Shift <Btn3Down>: next-line()\n\
    Ctrl <Btn1Down>: backward-character()\n\
    Ctrl <Btn2Down>: backward-word()\n\
    Ctrl <Btn3Down>: previous-line()\n\
    Shift <BtnUp>: do-nothing()\n\
    Ctrl <BtnUp>: do-nothing()

这解释了下列几点:

    .我们对滑鼠事件使用了缩写的语法,也就是先前的语法像<BtnDown>Button1
      以<Btn1Down>取代。转译管理器容许一些缩写的语法存在。 (我们在前
      面看到的 <Meta> 也是一例)。

    .我们用 do-nothing() 当作一个哑 (dummy)作用,就好像它是列在Text
      widget的文件中一般。事实上这个作用是不存在的,因此会导致错误的
      讯息出现,但因为我们本来就是要用它来什麽事也不做的,所以无需介
      意。

    .对於我们方才指定的哑作用,我们用了一个事件 <BtnUp>便代表了三个
      按钮。相同地,转译管理器把从缺的修饰规格的解释为 "对任何",在一
      个事件中缺少细节部份 (例如在规格"<BtnUp>Button1"中"Button1"的部
      份) 解释为 "对任何所有的细节部份"。

      这点在转译中有一个非常常用的形式为:

          <Key>: ...

      因为缺少细节部份,所以可被用於所有按下键 (key-press)事件,也就
      是对所有的键。事实上在Text widget 上有一个预设的转译为:

          <Key>: insert-char()

      insert-char()作用的功能为当一个键被按下时,插入相对应的ASCII字
      元。

17.1.4 复合的转译表及范例

到目前为止,我们把所有的转译均应用於整体的widget类别。但你能对个别的
widget指定转译,就如同resource一般。在此我们将对xman定义更多的转译。
我们将对Help盒widget (对应作用到助忆(mnemonic)字元)只用到键盘事件,对
Quit盒只用到视窗事件。为了达到此点,我们将对转译应用到的widget 给予明
确的名称。我们的转译表如下:

    *Help*translations: \
    <Key>h: highlight()\n\
    <Key>u: unhighlight()\n\
    <Key>n: notify()\n\
    <Key>s: set()\n\
    <Key>r: reset()\n\
    <Key>LineFeed: set() notify()

    Quit*translations: #override\n\
    <EnterWindow>: reset()\n\
    <LeaveWindaw>: set()

有几点特别的语法需要注意:

    .在此我们对相同类别中不同的widget指定不同的转译,所以我们需要知
      道成员 (instance) 名称。不幸的是,这些成员名称 (Help,Quit,
      Manual Page)并不明显。如果它们在文件中找不到 (本例即找不到),那
      你只能用猜的或是去查看原始程式了。

    .对於Help,我们省略了常用的#override,因为我们对此widget不需要考
      虑任何预设的系结。特别的是,当指标进入视窗时,我们不要此widget
      呈现高亮度,如此我们才能看出这个转译的效用。

    .由於省略 #override,我们将这个转译规格移至第一列。(如果不这麽作
      ,而且对第一列仍以\n\ 作结束,我们将得到错误:

          X Toolkit Warning: translation table syntax er-
          ror: Missing ':' after event sequence.
          X Toolkit Warning: ... found while parsing ''

      因为\n是用来区隔转译规格或类似像 #override 指令的)。而将此列和
      第一个规格以隐藏的新列字元区隔,就如同:

          *Help*translations: \
          <Key>h: highlight()\n\
          ...

    .对LineFeed那一列的转译,包含了复合的作用,和前面xterm 中复合的
      string()作用类似。

    我们已大致涵盖了你所常用的转译。基本的概念很简单,生成它们的结构
也不复杂,但它们非常的令人迷惑。原因是它是一个发展中的糸统,随著发行
版本所附的文件并不是很多。下一节重复本节所述的,本节均以例子来介绍观
念,下一节我们将对转译的规则,作比较正式的描述。

17.2 转译 -- 格式和规则

转译是一个由Toolkit 提供的一般性结构,它让使用者指定当某些特定的事件
由widget接收到时,一个widget应完成何种作用。Toolkit 中处理转译的部份
被称之为转译管理器。

    转译由widget指定,它的确是一个widget的每一个成员。一个转译的集合
称之为一个转译表,而这个表藉著标准的resource结构传递给应用程式。widget
(对转译而言意味深长) 会有一个Translation 类别的resource属性,通常的
成员名称为translation。这个转译resource期待的一个值即为一个转译表。就
像所有其它的resource一般,你可以在同一个应用程式对不同的widget指定不同
的resource,而且你能以类别名称或成员名称或二者混合来指定它们。

    每一个widget定义了它所提供的作用,不论是在数量或型态上,它们都是
极富变化的。

    转译可被各种不同型态的事件指定,不仅只於键盘和滑鼠事件而已。任何
序列的事件均能被处理,就如同单一事件一般。

    转译和转译表在 " X Toolkit Intrinsics " 使用手册附录B一节中,有
简洁地描述。它不是初学者查看转译的好地方,但它含有完整的事件型态、修
饰名称等等的表列,在此不再赘述。

17.2.1 转译表的格式

一个转译表大体上的格式如下:

    [optional-directive\n] list-of-translations

每一个 list-of-translations 由一或多个转译组成,格式如下:

    event-sequence : list-of-actions

当event-sequence发生时,规格中的list-of-actions 会由widget所完成。如
果在一个表中,有多於一个的转译,每一个需以 "\n" 区隔开。

    我们首先来看一下选项的指令,然後看一下list-of-translations的细节
部份。

17.2.2 转译指引 -- #override 等等

选项指引 (directive) 告诉转译管理器,它应对任何已设定之相关widget在此
转译集合中应如何处理。

    #replace : 清除所有现存的对应,只采用在转译表中所含有的。(只使用新
        的)。

    #override : 强制留下现有的对应,加入转译表中。如果在表中有任何项
        目设定,旧有的即被覆写。也就是说,旧有的被新有的取代。 (结合
        旧有的和新的,但新的比较重要)。

    #augment : 强制留下现有的对应,加入转译表中。如果在表中有任何项
        目设定在现有的设定存在,使用旧的而忽略新的。 (结合旧有的和新的
        ,但旧的比较重要)。

如果未设定指引,预设为 #replace 。

17.2.3 个别的转译规格格式

每一个转译的格式为:

    event-sequence : list-of-actions

让我们来看一看此规格的两个部份。

事件和事件序列(event-sequence)的格式

一个事件序列包含一或多个事件规格(event-specs), 其格式为:

    [modifiers] <event-type> [repeat-count] [detail]

除了事件型态(event type)外,均为可选择。(<>中为必需)。

    modifiers : 这是基本设计中比较精巧的部份,我们在下一段说明。

    event-type : 指定我们有兴趣的事件的型态,例如按键(<KeyDown>)、
        松开按钮(<BtnUp>)或指标离开视窗(<Leave>)等等。

    detail : 指定我们有兴趣的特定型态。如果你省略细节栏(detail field
        ),事件规格将对应到任何detail,如此,<Key>将对应到所有的按键
        事件。此格式指定到每一个事件型态。对指定事件型态的细节栏为:

        .对<Key>、<KeyUp>和<KeyDown>事件,细节如果不是键的名称(例如
          "<Key>s"),便是 keysym (keysym是按键以开头为"0x"的十六进位
          数表示,将於下一章详细解释)。

        .对於按钮事件,细节就是按钮的名称,也就是 Button1 ... Button5
          中的一个。例如我们先前使用过的"<BtnDown>Button1"。

    型态/细节的缩写:常用於转译管理器的一些事件型态和细节的组合,允许
        你对它们使用缩写:

          缩写               相等的全名

          <Btn1Down>         <BtnDown>Button1
          ...
          <Btn5Down>         <BtnDown>Button5
          <Btn1Up>           <BtnUp>Button1
          ...
          <Btn5Up>           <BtnUp>Button5

    repeat-count : 这指定了事件需要的次数。如果被指定,它们被包含在
        括弧之中。例如:

        <Btn1Down>(2)

        指定需对一号按钮(button-1)碰触两次。如果你在後面再加上加号(+)
        ,其意为碰触的数目需大於或等於指定。例如:

        <Btn1Down>(3+)

        意为需碰触三或更多次。预设的重复次数为一次。

    一个事件序列以一或多个事件规格组成,以逗点分开。当这个事件的序列
在其widget发生时,相关的作用便会运作。

    当序列发生时,转译管理器会根据一些规则决定它自己是否被满足。我们
用一个例子以便仔细地观察,假设你对两个字元序列set 和unset定义了转译:

    .概略地说,如果个别的事件依序发生,转译管理器会被满足,其它的事
      件 (那些你未指定的事件) 如果在指定的序列中间发生,不会妨碍序列
      被满足。例如,set 可被sweat 和serpent 对应。

    .如果介於其间的未指定事件,启动了转译表中的另一个事件序列,转译
      管理器会放弃原先的序列,而尝试著去满足新的序列。例如,set 不会
      被sauerkraut对应,因为u 会使得转译管理器对应到unset。

    .如果在一个事件的集合中有超过一个的事件序列发生,转译管理器只会
      应用到一个转译:

      - 如果一个序列对应到结束 (右端),较短的那个序列只有在不包含於
        较长的序列才会发生。所以如果unset 被对应到,对set 转译将不会
        作用。

      - 如果一个序列是在另一个序列的中间发生,例如,如果你定义序列
        at和rate,则较长的那个永远不会被对应到。

事件修饰键

修饰键 (modifiers)是一些键或按钮,系指当主要事件发生时,那些必需被按
下才会让转译管理器满足的键或按钮。你可以对键、按钮、移动、进出视窗等
事件指定修饰键。常见的修饰键为:

    Button1   ...        Button5
    Ctrl      Shift      Meta
    Lock

    如果你未指定任何的修饰键,转译管理器会解释为: "当事件发生时,不
论修饰键是否被按下,均会被接受"。例如,<BtnDown>会被满足,不论当时
SHIFT 或META键是否有被按下。

    如果你真的需要指定 "只有在没有修饰键被按下时才接受此事件"。则需使
用虚拟修饰键 (pseudo-modifier) None。例如,None <BtnDown> 会使得当按
钮按下时若META键也被按下则不会满足。

    对一个事件指定一些修饰键意为 "只要符合转译中指定的修饰键,其它的
修饰键不需介意"。它并没有 "一定要完全恰好符合才可以"的意思。例如,
Ctrl <Key>a 在你按下 meta-ctl-shift-a 时仍会被满足。

    如果你真的要指定 "只有刚好符合修饰键的才要",在修饰键之前加一个惊
叹号 (!)。例如,!Ctrl <Key>a 在你按下 meta-ctl-shift-a 时不会被满足。

    对一个修饰键的集合 (可能是空集合) 作限制,意为 "除了这些修饰键不
不接受",需要在不接受的修饰键之前加一个(~)号。例如,Shift~Meta <Key>t
会被ctl-shift-t满足,不会被meta-shift-t满足。

    键事件通常忽略大小写,如果你要区分,需在之前加一个冒号(。例如,
不论 H或 h均可符合<Key>H,但只有H 才符合 :<Key>H。

    就如同对常用的事件型态/细节配对有缩写一般,转译管理器对常用的修
饰键/事件型态配对同样地提供缩写:

          缩写               相等的全名

          <Ctrl>             Ctrl <KeyDown>
          <Shift>            Shift <KeyDown>
          <Meta>             Meta <KeyDown>
          <Btn1Motion>       Button1 <Motion>

BBS水木清华站∶精华区

TOP

BBS水木清华站∶精华区
          ...
          <Btn5Motion>       Button5 <Motion>
          <BtnMotion>        任何按钮的 <Motion>

作用的格式和作用的表列

每一个转译在一或多个作用之上系结一个序列的一或多个事件。在表列中的个
别作用是以空白分开的。 (不可用逗点分开,那将会导致错误)。

    个别的作用格式如下:

      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水木清华站∶精华区

TOP

BBS水木清华站∶精华区
附录A 文件指引

A.1 本发行版所提供手册

    下面所列有关X的手册被以硬拷贝形式提供, 视为完整 MIT 发行版的一
部分.

    这些手册的文件来源包含於软体磁带中, 且所对应的档案名称注明於括弧
内. 想列印硬拷贝版本, 可以使用 nroff 或 troff, 加上选项 -man表示指南
页 (manpage), -ms选项代表教学 (tutorial) 或其它手册.  对於某些较长的
手册, 被转换成 PostScript 型式的格式化的档案 也包含在其中; 因为它们
长度较长, 所以被压缩, 必须使用 uncompress 解压缩. (假如你尚未解压缩
, 它们应包含在发行版磁带的 $TOP/util/compress, 可按照指示去使用它).

  1. 发行版注意事项, 包括安装指示与本发行版内容的描述. 几乎这里所有的
     内容均被再制作成本书附录B,C与D. ($TOP/doc/releasenotes/*;
     PostScript 在 $TOP/hardcopy/releasenotes.PS).

  2. 程式指南页, 或 "指南页(1)". 来源不只储存在一个地方, 但有其代表
     的程式来源. 在预设安装程序, 它们被安装於系统指南页目录内, 所以
     它们可以用 man 去读取. ($TOP/.../*.man; PostScript 在
     $TOP/hardcopy/man/*.PS.Z)

  3. Xlib 功能的指南页; "指南页(3X11). ($TOP/doc/Xlib/Xman/*).

  4. Toolkit Intrinsics 功能的指南页; "指南页(3Xt). ($TOP/doc/Xt/Xman/*;
     PostScript 在 $TOP/hardcopy/Xt/man.PS.Z).

  5. 由 Scheifler, Getty 与 Newman 所写的一本书 "X WINDOW SYSTEM, C
     Library and Protocol Reference" (Digital Press, 198, 内容包括 :

     . "Xlib - C language Interface" 手册. ($TOP/doc/Xlib/*; PostScript
       在 $TOP/hardcopy/Xlib).
     . "X Window System Protocol, X Version 11, Release 3" 手册.
       ($TOP/doc/Protocol/).

  6. "X Toolkit Intrinsics" 手册. ($TOP/doc/Xt/*; PostScript 在
      $TOP/hardcopy/Xt/intrin.PS.Z).

  7. "X Toolkit Athena Widgets" 手册. ($TOP/doc/Xaw/; PostScript 在
     $TOP/hardcopy/Xaw/widget.PS.Z).

  8. "Bitmap Distribution Format" 手册. (文件来源是 Scribe 格式, 但
     具有 PostScript 说明, 在 $TOP/doc/bdf/; 完整的 PostScript 在
     $TOP/hardcopy/bdf/bdf.PS.Z).

A.2 包括在本发行版本内的其它文件

  1. 字型命名惯例的描述. ($TOP/doc/fontnames/fnames.txt).

  2. 对不同X功能的小教学程式 :

    . 在你撰写的X程式里使用颜色. ($TOP/doc/tutorials/color.tbl.ms).

    . 转换 X11 第 2 次发行版的widget 为第 3 次发行版.
      ($TOP/doc/tutorials/x10equiv.txt).

    . 使用资源. ($TOP/doc/tutorials/resources.ms).

    . Xlib 函数的 X 版本 10 与版本 11 之对照.
      ($TOP/doc/tutorials/x10equiv.txt).

  3. 安装 MIT server 至不同系统的注意事项.

    . 安装 X V11 Sample Server 的 godzilla 指南 ($top/doc/server/ddx.tbl.ms).

    . X V11 Sample Server 的安装层(Porting Layer)定义
      ($top/doc/server/ddx.tbl.ms).

    . X V11 Sample Server 的安装策略 ($top/doc/server/start.ms).

    . X V11 Server 扩充 ($top/doc/server/ext.doc).

  4. "client 间的通讯惯例手册" (Inter-Client Communication Conventions
      Manual)" 通常以缩写为 ICCCM 来参用. 它应该包含在发行版中的
      $top/doc/conventions/, 但在发行版中有被修订时才会存在否则常被
      省略, 所以你可以透过电子邮件取得一个拷贝 -- 见附录F "X 网路与
      电子邮件服务" 的 xstuff 一节.

  5. 撰写X程式的教学程式, 先教你使用基本的 Xlib 函数, 然後使用 Toolkit.
     ($top/doc/helloworld).

A.3 包括在本发行版本内的其他资讯来源

    对某些项目, 像 widget 的名称, resources 与动作 (action), 你必须
看原始码 :

     . Widget提供给Intrinsics 的部分. ($TOP/lib/Xt/).

     . 在 Athena Set 里的 Widget ($TOP/lib/Xaw/).

     . client 程式的原始程式. 每个 client 的原始程式储存於不同的目录,
       $Top/Clients/Program-name/ 或 $Top/Demos/Program-name/.

=====

附录B 安装X

B.1 安装X的提示

    .尽快地获得所有文件的拷贝,理想的状况是在开始安装系统之前(你可
      以自行将磁带上所包含的档案列印出来,或是由附录E所列的供应商订
      购一份。)

    .首先,对已有的建构档案尽量少做更动,如果你是第一次安装X,我们
      强力推荐你使用预设的目录来安装那些系统的各个不同的部份,只有在
      有确实需要更动目录名称时,才考虑重新安装。(如果你不如此做,当
      有些问题发生时,你将无法知道,它真的是一个问题或你只是安装时犯
      了一个小错误而已)

    .如果你是用这次发行的版本建立一个标准的系统,你几乎不需要做任何
      更动便可完成安装 -- 建构档已正确地被设定。(本版发行的备忘录对
      此有一点误导,你可能会得到一个错误的印象,以为不论你使用什麽系
      统,均需作大量的更动。)

    .当你开始安装,对大多数的系统而言,你不需明确指定系统的型态,它
      的建立是根据C语言的前处理器(preprocessor)来定义系统名称而自动
      找到。

    .在你熟悉core版之前不要安装contrib 软体,因为它安装费时,且易产
      生问题,当你熟悉系统之後,你可能总会修改一些建构参数。

    .如果你真的需要使用不同预设值的建构,阅读文件
      $TOP/util/imake.includes/README 可得到关於如何更动的资讯。(它
      也对工具程式imake 给了一个概观,imake 是一般Unix系统中make的前
      端(front_end) ,用以建立系统)。


B.2 建立本发行版

    在本次发行的软体分为两类:一部份核心软体由X协会标准所提供,另一
部份则任何人都有可能提供,要使得核心软体这一部份能在大多数的地方重新
建构、建立和安装需极大的努力,而那些使用者贡献的部份,也就是说,未经
X协会标准编译和测试的部份只能自行逐一建立,在util/scripts中的ximake.sh
可能对从Imakefiles到建立Makefiles 非常有用。

    几乎所有在核心软体中的makefiles 均自动地由名叫imake 的公用程式所
产生,所有的Makefiles 初始版本均包含了在哪些地方不能使用imake (无疑
地,在特定的机器上需要修正)。在许多系统,X必需以正确的磁带方能建立。
无论如何,它可以藉简单的设定目录util/imake.includes/中的档案site.def
和*.macros中之参数,来重新建构。


B.2.1 安装摘要

    欲载入(load)和安装此次发行的X Window System你将需要:

    1. 读完本次发行的备忘录。

    2. 建一个你读入磁带的目录(通常名称类似/usr/local/src/X或/src/R31)
        你将需要大约30 megabytes给核心软体,和超过80 megabytes给使用
        者贡献软体。

    3. 从步骤2 卸下核心软体磁带,既然使用者贡献软体必须自行建立,你
        可以等到以後载入,每一卷磁带含有一个非常大的Unix的tar 档案,
        以每英□1600位元方式储存。

    4. 阅读档案util/imake.includes/README以了解如何建构你的特定X系
        统。同样地,确定你依照目录server/ddx/ 中README档案来计画建造
        你的server。

    5. 如果你计画在一部以上的机器编译这个版本并且要有一个分类档案系
        统,你可能希望依照util/scripts/lndir.sh 的说明来建立符号连接
        树在每一个目的机器,它允许所有的机器如你所希望的使用X而分享
        一组原始程式,在这种情况下,build tree这个名词被用来当作你编
        译目录树的参考(和含有实际档案的source tree 有所区别)。

    6. 如果你是在A/UX 1.0下建立在 Macintosh之上,确定你是自目录
        server/ddx/macII执行R3 setup.sh 。它从util/cpp中的公益(public
        domain) 原始码建立一个C的前处理器,和修正一些放错位置的系统
        档案。如果你是在一部SUN 上,确定你在档案
        util/imake.includes/Sun.macros的顶端设定了四个OS的参数。如此
        作可防止在不同的SunOS 编译器下的错误。如果你是在Apollo上建立,
        确定你是使用9.7.1 或更後面版本的C编译器,否则,server将无法
        正确地编译。

    7. 确定你已遵循所有和机器特性有关的指示,且imake 也是依你的机器
        而建构。(看source tree 中util/imake.includes/Imake.tmpl顶端
        的#ifdefs 区段(blocks))。

    8. 当你完成了建构,你可以准备建立core版,注意那些在
        util/imake.includes/应用到你的系统的.macros 档案。它们在接近
        顶端有一行设定一个make的变数名称为BOOTSTRAPCFLAGS 。如果这个
        变数值是空白,你可以用下列的命令开始建立:

            % make World > & make.world &

        如果不是空白,你必须将此定义附加到命令列上。这可用imake 对所
        有的编译器设定特定的cpp 符号。(如果你在不同的系统安装,见
        util/imake/imake.c)在所有的core版提供的macro 档案中,只有
        A/UX需要这个旗标:

            % make BOOTSTRAPCFLAGS=-DmacII World >& make.world &

        不要用输出档make.log当作make clean藉著make World移去此名称的
        所有档。这将导致重建所有的Makefiles 和执行make -k all 来编译
        core版中所有的东西。这将依你的机器不同,花掉2 至12小时。

    9. 当make完成後,检讨log 是否有任何问题。必须要没有严重的问题,
        A/UX的使用者可以忽略有关列举型态不调和(enumeration type
        clashes)的编译警告,Applo 的使用者可以忽略最佳化的警告。

    10.如果你对一切均感到满足且建立正确程序,测试一些不同的程式(如
        server, xterm, xinit, etc)。你也许需要在根目录执行 server或
        xterm ,如果你执行上有问题,第二部的工作站或终端机将很有用。

    11.对你旧版的Xheader file, binaries, fonts, libraries 等作备份。

    12.到build tree顶端并键入

            % make install >& make.install

        你将不是在根目录做便是在熟悉的目录写入存取(看Imakefile 最上
        阶层和util/imake.includes/Imake.tmpl)。xterm 程式在大多数的
        系统必需安装setuid到根目录,xload 程式必需安装setguid 到那些
        属於/dev/kmem 的档案。

    13.如果你要安装指南页,在build tree顶端键入

            % make install.man

    14.如果你要建立和安装lint libraries,在build tree的顶端输入:

            % make install.ln

        如果你是第一次安装X,你可能也需要作以下的步骤。检查一下在
        server/ddx目录中不同的README档案中附加的指示。

    15.加入装置驱动器或重新建构你的核心(kernel)。

    16.建立附加的虚拟终端机(pseudo terminals)。查看你的操作系统说明
        /dev/MAKEDEV和问你的系统管理者细节部份。

    17.阅读有关新的显示管理器xdm 的指南页,这个程式提供了一个可携的
        自动执行X的方法,和许多为了初学者所建立非常好的介面符号。这
        取代了原先自/etc/init 执行的终端机模拟器xterm 。

    18.确定所有的X11 的使用者在他们的搜寻路径中均为BINDIR的目录(通
        常为/usr/bin/X11)。


B.2.2 操作系统需求

    X受欢迎的理由之一为和操作系统无关。虽然我们讨论的范例均为在Unix
系统下,但有许多非Unix操作系统的制造厂商也提供X。本次发行的Server已
在下列系统建立:

          4.3+tahoe
          Ultrix 3.0 FT2(Ultrix 2.0)
          SunOS 3.4
          HP-UX 6.01
          Apollo Domain/IX 9.7
          IBM AOS 4.3
          A/UX 1.0

    如果你使用较早的版本,你可能招致一些麻烦,特别是,server将无法在
IBM 4.2A第二次发行版执行。在server/ddx/ 中不同的README档案描述了对编
译器、函数馆、前处理器等等的特定需求。例如前述的A/UX 1.0的使用者将需
要建立一个新版的C前处理器,而Apollo的使用者将需要9.7.1版的C编译器。

    你应在使用X前先确定你的网路系统和相互通讯公用程式作用正常。如果
像talk和rlogin这样的程式无法工作,X大概也不行。


B.2.3 读取本发行版的磁带

    本发行版可以用电子媒体的方式从DARPA 交换网路、UUNET 计画、一些谘
询公司和不同的UUCP的档案库。尤有进者,MIT 软体发行中心提供了一组2400
□的1600BPI 密度的磁带。(该中心不提供卡带或磁碟片)

    每一卷MIT 的磁带包含有一个大的tar 目录结构,内含发行版一部份的软
体的原始码和文件。如果你受限於磁碟机的空间,你可以只下载core磁带,删
除任何你不需要的server,和产生一份使用者贡献磁带的目录以供以後查询,
所有的档案名称均以相对路径方式给定(在开头以一个点替代斜线),所以这
个发行版可放在你的档案系统的任何地方。

    在读取磁带之前,确定你有足够的磁碟空间,以下为你对每卷磁带所需的
空间。

    版名        内容                        megabytes     情况
    core        servers,函数馆,公用程式       35         必需
    contrib-1   程式,示范程式,字型           36         推荐使用
    contrib-2   使用者贡献的工具               34         推荐使用

    编译过的程式估计需要二分之一到三分之二原始码所占的空间,所以,光
是core版你便需要大约60 megabytes的磁碟空间。

    建立一个目录用以放置所有的原始码,在此目录中,执行适当的作业系统
命令来读取core版磁带。如果你的机器预设tar 为读取1600 BPI的磁带,则你
键入的指令将类似:

        % mkdir /usr/local/scr/X
        % cd    /usr/local/scr/X
        % tar x

必要时可向你的系统管理者取得协助。


B.2.4 使用符号连结(Symbolic Link)

    本发行版在处理使用连结(Symbolic由机器所支援)避免档案重覆(大多
的header file ),如果你在未提供建构档案情况下建立本发行版,你必须在
适当的util/imake.includes/*.macros档案检查LN建构参数。如果你的作业系
统不提供软体连结,LN需被设定为建立硬体连结(hard link) 或拷贝原始档。

    如果你需要在建立後将本发行版移动到其它的机器,用tar 替代CP或rcp
以保留日期和连结,通常可用下列的命令达成:

        % (chdir/usr/local/src/X;tar cf - .) | \
          rsh othermachine "(chdir/moredisk/X; tar xpBf -)"

    可向你的系统管理者获得协助。


B.2.5 建构本发行版

    这个发行版广□使用 imake 公用程式, 它可从机器相关的 (machine-
independent)Imakefiles 产生机器特有的 (machine-specific) Makefiles.
另一个叫做 makedepend 的公用程式,  是用於产生C语言档案的 Makefile 相
关性 (dependencies). 假如你不在乎可携性 (portability), 虽然我们强烈地
鼓励你去使用imake 与 makedepend, 但是仍提供有样本 makefiles.

    imake 的建构档被置於 util/imake.includes 目录. makefiles 是由一个
称做imake.tmpl 的模板 (template)档、一个机器特有的 .macros 档与一个
site 特有的 site.def 档所产生. 只有极少例外, 建构参数为 cpp 符号, 它可
以被定义於一个 per-server 基础上或在一个给定 site 里的所有 server.  模
板档案不应该被修改.

    util/imale.includes/README 档案每一个建构参数以及它可以设定的值.
预设值的选择是考量可适用於多种机器且易於维护. site 特有的建构应在
sit.def 档案内使用下列语法描述 :

        #ifndef BuildParameter
        #define BuildParameter site-specific-value
        #endif


B.2.6 编译本发行版

    建构参数设定後, 你应该可以在构造树 (build tree) 的最上层利用下列
命令以编译core 软体 :

        % make World > &make.world &

    若在建立过程, 将 make.log 这个特殊档案删除, 则请不要将输出重导
(redirect) 到make.log。依照使用机器的不同, 这个步骤将花费 2 - 12 小
时, 且在大多数的机器上皆能顺利完成。

    在所有 Makefiles 与相关性都建好之後, 你必须重新启动以便使你的构
造 (build) 发生作用, 请在构造树的最上层输入下列命令:

        %make -k > &make.out &

假如你以後决定改变任何建构参数, 你将需要作另一个完整的 make World.


B.2.7 安装发行版

    假如每一个编译皆成功, 你可以输入下列命令, 从建造树最上层安装软体:

        # make install

    假如你不想安装在根目录, 你必须建一些可写入的目录并从你的帐号
(account) 安装它们, 然後检查在 BINDIR 目录 (通常是 /USR/BIN/X11) 内
的 xterm 与 xload 的所有权(ownership) 与保护模式 (protection). xterm
必须安装 setuid 至根目录以便它能设定虚拟终端机与更新/etc/utmp. xload
需被 setuid 至根目录, 或 setgid 至拥有档案 /dev/kmem 的目录以使它们
可以取得系统的平均负载.

    假如你的 /etc/termcap 与 /user/lib/terminfo 资料库没有 xterm 的
入口 (entry),可参考在 client/xterm 目录内的样本入口. System V 的使用
者将需要用 tic公用程式编译 terminfo 入口.

    假如你计划使用 xinit 程式去执行X, 你可能会想产生一个将指名的X
指到适当server 程式的连结 (link) (通常的名称像 /usr/bin/x11/ 目录里
的 Xmachine). 然而,xinit 不打算给初学者使用; 取而代之, site 管理者被
期望能使用 xdm 或提供友善的使用介面.

    假如你想安装指南页, 请检查在 util/imake.includes/ 里的
MamDirectoryRoot、ManDir 与 LibManDir 三个建构参数, 并在构造树的最上
层输入:

        # make install.man

    假如你喜欢建立与安装 lint 程式库, 在构造树的最上层输入下列命令:

        # make install.ln

    最後, 确定所有使用者在它们的 PATH 环境变数都有 BINDIR (通常是
/usr/bin/x11/).


B.2.8 kernel 与特殊档案的注意事项

    在某些机器上, 如果有一个新的装置驱动器则必须重建 kernel 或至少经
过重新建构, 假如你以前从未执行X且使用一个没有列在这些注意事项内的系
统, 你可能需要确定在你的 kernel 建构档案里的 csr位址能与你的硬体相匹
配. 另外, 你应该确定在系统启动时 kernel 会自动建构显示器.

    你可能需要为你的显示器、滑鼠或键盘建立特殊的装置. 例如:

        # /etc/mknod/dev/bell c 12 2     # for bell on Sun
        # MAKEDEV displays               # for displays on the RT/PC

    在显示器装置档上的保护模式应该被设定成只有 server 可以开启它. 假
如 server是以 /etc/init启动, 这个保护可以被根读/写, 任何其他的人不能
存取.

    在一个 Digital QVSS (VAXstation II) 上, 你应该使用 adb 去确定
kernel 变数qv-def-scrn 被设定为 2, 以便使用 VR-260 监视器的整个宽度.
这可以藉著直接地改变/vmunix 或 /sys/vaxuba/qv.o 并重新连结与安装
kernel 来达成. 你将需要 reboot 使新值发生作用.

    更详细的资料请看 Server/ddx/ 目录里对应的 README 档与指南页.


B.2.9 测试本发行版

    即使你计划在所有时间都使用 xdm 执行X, 你也应该要从另一个终端机执
行它, 以便检查每个你所安装部份的是否已被安装且正常工作.

    来自 server 的错误讯息将会显示在你的终端机, 而不是被写到
xdm-errors 或/usr/adm/X?msgs ('?' 是显示器的号码).

    测试 server 最简单的方法是先进入 /usr/bin/x11 (或任何你已安装 X
程式的地方)然後执行 xinit, 如下:

        % cd/usr/bin/X11
        % xinit

    你应该可以看到一个灰色的带状图样覆盖萤幕、一个形状像 "X" 的游标追
踪著指标以及一个终端机模拟视窗. 否则请按下列方式检查 :

1. 假如没有显示出灰色萤幕背景, 检查是否有在 server/ddx/ 子目录内的
   README 里描述的任何特殊装置档案的许可 (通常是储存在 /dev/).

2. 假如背景出现, 但游标仍是白色方形. 请确定字型是否已安装 (特别是
   usr/lib/X11/fonts/misc/ 里的字型 cursor.snf; 见建构参数
   DefaultFontPath). 并确定在你的每一个字型目录都有一个档案叫做font.dir.
   这个档案是由 mkfontdir 程式产生的, 被 server 用於找出一个目录里的字型.

3. 假如游标出现但不追踪指标, 请确定任何特定装置档案 (它的名称像
   /dev/mouse) 已被安装 (见 server 的 README 档).

4. 假如 SERVER 启动且不久之後变成黑色, 表示启始的 client (xterm 或
   xdm) 当掉了.请确定 xterm 安装於根目录并建立足够的虚拟终端机. 假
   如你正执行 xinit, 且在你的home 目录一个有叫做 .xinitrc 的档案,
   确定它是可执行的而且上一个它所启动的程式在前景执行 (亦即命令列尾
   端没有一个 & 符号). 否则, .xinitrc 将立刻完成, 这也是 xinit 所
   假设的以及你所想要的. 只要你有正确工作的初始视窗, 试著从 xterm 执
   行其他的程式. 若想用 uwm 视窗管理器定位一个新视窗, 可在闪动的方框
   出现时按下按钮 1 (通常在指标器的最左边按钮) :

        % xlock -g 200x200-0+0 &
        % uwm &
        % xlogo &
        % xeyes &
        ...

    X现在可以被使用了, 研读一个新程式的指南页, 看看新字型, 你会从中
得到乐趣.


B.2.10 建立额外的虚拟终端机

    因为每个 xterm 需要一个不同的虚拟终端机, 所以你应该建很多给它们
(在一个小型多使用者系统你可能至少要 32 个). 每个 ptr 有两个装置, 一
个主控 (master) 与一个从属(slave), 它们通常叫做 /dev/tty/[pqrstu][0-f]
与 /dev/pty[pqrstu][0-f]. 假如你没有最少的 "p" 与 "q" 列建构, 你应该
要求你的系统管理者加上它们. 这通常是以 /dev里执行的 MAKEDEV script来
完成:

        # cd/dev
        # ./MAKEDEV pty0
        # ./MAKEDEV pty1


B.2.11 从 /etc/rc 启动X

    本发行版提供一个可以从系统启动档 /etc/rc 执行X server 的新公用
程式叫做 xdm,它提供一个不同於从 /etc/init 执行X 的可携式与吸引人的
方式. 设计时考虑到可以很容易地裁剪以应不同工作站的需求, xdm 小心地
保持 server 的执行, 提示输入使用者名字与密码并管理使用者的session.
样本建构目前使用 shell script, 以提供相当简单的环境. 这也将是未来发
行版继续研究的地方.

    xdm 弹性的关键是它广泛使用resource, 允许 site 管理者快速与容易地
测试不同的设定(setup). 当 xdm 启动, 它读入一个建构档 (预设是
/usr/lib/X11/xdm/xdm-config 但可以用命令列旗标指定-config) 列出不同的
资料档、预设参数以及启动与关机时会被执行的程式. 因为它使用标准的
Toolkit resource档案格式, 任何可以在 xdm-config 档设定的参数也可以在命
令列使用 -xrm 选项指定.

    预设建构包含下面所列:

        DisplayManager.servers:         /use/lib/X11/Xservers
        DisplayManager.errorLogFile:    /use/lib/X11/Xdm-errors
        DisplayManager*resources:       /use/lib/X11/Xresources
        DisplayManager*startup:         /use/lib/X11/Xstartup
        DisplayManager*session:         /use/lib/X11/Xsession
        DisplayManager*reset:           /use/lib/X11/Xreset

    server 档包含要启动的 server 列表. errorLogFile 是 xdm 输出被重
导的档案.resources 档包含 xdm Login 视窗预设的resource. 特别的地方是
特殊键的顺序可以被指定 (在 xlogin*login.translation resource), startup
档应该是一个程式或可执行的 script, 它可以在使用者打入合理的密码之後执行
. 它是一个作 site 特有的初始化, logging 等的圈套 (hook). session 入口是
用於启动使用环境的一个 session 管理程式或可执行script 的名称. 假如使用者
在他的 home 目录内没有一个可执行的 .xsession 档, 有一个简单的版本可提
供一个简单的 xterm 视窗与 uwm 视窗管理器. 最後, 在使用者 logout之後一
个 reset 程式或可执行的 script 会被执行. 使用预设建构执行 xdm, 加入下列
一行到你的 boot 档 (通常叫做 /etc/rc 或 /etc/rc.local) :

        /usr/bin/X11/xdm &

毫无疑问地, 大多数的 site 想建立它们自己的建构. 我们建议你们将 site
特有的xdm-config 档与其它的 xdm 档放在不同的目录, 这样才不会被某些作
了一个 makeinstall 的人盖掉. 假如你将档案储存在 /usr/local/lib/xdm,
下面的命令可用於以启动xdm :

     /usr/bin/X11/xdm -config /usr/local/lib/xdm-config &

    许多 server 在假设它们是尝试读取键盘的唯一程式下, 将键盘设定成非
阻断式 I/O(non-blocking I/O). 不幸地, 某些 /etc/getty 的版本 (特别是
A/UX) 将立刻看到一个零长度读取的连续 stream, 因为将它解释成 EOF 档尾
指示. 最後 /etc/init 将取消login, 一直到某人打入下列命令:

        # kill -HUP 1

在 A/UX 下, 一个变通的方法是禁止从控制台 login 且从 /etc/inittab 去
执行 xdm.然而, 请确定你存有一个旧的 /etc/inittab 拷贝以备你在出错状
况以及你必须从网路上或单使用者模式恢复 login 的时候使用.

    另一个较少为人彻底研究的是如何设定一个帐号 (account), 它的 shell
是在client/xdm/里的 xdmshell 程式. 预设状况下这个程式不会被安装, 所以
site 管理者需要特别查看它是否符合需求. xdmshell 公用程式确定它执行於
适当的终端机型式、启动 xdm、等待它完成与重置控制台 (如果需要的话).假
如 xdm resource档包含一个终止-显示器 (abort-display) 动作的系结, 就像
下列命令 :

        xlogin*login.translations: #override Ctrl<Key>R: abort-display()

然後在 xdm login 视窗按下指定键 (上例是 <Ctrl-R>) 控制台即可以被恢复.

    xdmshell 程式通常安装在根目录, 但仅能被特殊群体的一份子执行, 如
此以 xdmshell作为 shell 的帐号 (account) 的人是唯一的一份子:

        % grep xdm  /etc/passwd
        X:aB9i7vhDVa82z:101:51:Acount for starting up X: (contd.)
        /tmp:/etc/xdmshell
        % grep 51 /etc/group
        xdmgrp:*:51:
        % ls -g /etc/xdmshell
        -rws--x--- 1 root xdmgrp 20338 Nov 1 01:32 /etc/xdmshell

    假如 xdm resource不曾有一个键系结至 abort-display() 动作的建构,
一般使用者将没有方法可直接 login 到控制台. 至於是否需要则视个别的
site 而定.


B.2.12 支援老旧系统 -- 从 /etc/init 启动X

警告 : 下面所提供的适合较老的系统且在未来的发行版将不提供.

    Ultrix 与 4.3bsd 使用 /etc/ttys 建构档的一个新的扩充格式, 它允许
你指定一个视窗系统与初始时被执行的程式. 虽然一般人比较喜欢使用 xdm,
但系统仍然提供可在 xterm里启动X与一个从 /etc/ttys 初始的 xterm 视窗.

建立 ttyv 终端机

    因为大多数的 /etc/init 版本需要给每个 /etc/ttys 的入口一个真实终
端列, 所以你必须给每一个显示器指定一个虚拟终端机. 虽然正常状态下xterm
动态地配置一个 pty, 但是 -L 选项可以强迫它使用从 /etc/init 传过来的虚
拟终端机.

    依照协议, 具有最高的 "小装置 (minor device) 号码" 被改名成
[pt]tyv0, 次高的被改为 [pt]tyv1, 依此类推. 最高的被改为最低的, 可使
他们不以正常从低至高的搜寻方法 (大多数程式配置一个 pty 的方法) 取得
. 在仅有 "p" 与 "q" 的小系统, 下面的命令可用以将两个显示器设定成"v"
终端机.

     # cd /dev
     # mv ttyqf ttyv0; mv ptyqf ptyv0
     # mv ttyqe ttyv1; mv ptyqf ptyv1

见你的系统管理者可以获得帮助.

增加视窗进入口到 /etc/ttys

    只要你已经改变虚拟终端机的名称, 你就能为它们在 /etc/ttys 增加入口
. 再次提醒这个仅对具有以新的 4.3bsd 格式启动视窗系统的系统, 不能用在
使用 4.2bsd 小进入口格式与 /etc/ttytype 的较老系统上. 假如你的系统没
有新的格式, 将 ttyv 的与 ptyv 的改为原名并跳到下一部分.

    xserver 指南页里包含关於设定 /etc/ttys 进入口的更详细叙述. 通常
, ttyv 被置於档案的底部且类似下列:

        ttyv0"/usr/bin/X11/xterm -L -grometry 80x24+0+0 -display :0" (contd.)
        xterm off window="/usr/bin/X11/X :0"

    注意, 它不像 X10, 给 X server 命令的 server 号码之引数必须在前面
置一个冒号. 额外的命令列选项可以在 xterm 命令列或X命令列指定. 然而,
许多 init 的版本具有相当小的程式名称缓冲区, 限制了入口的长度. 也有某
些版本不允许在入口里有 pound记号, 意谓著不能给任意数目的颜色指定, 这
也是为什麽会写 xdm 的原因.

    只要你曾经增加或改变任何入口, 你必须送信号给 init, 告诉它重读 /etc/ttys
与重新启动. 在根目录下打入下列命令即可以达到这个目的:

        # kill -HUP 1

这将会中止在重新启动前任何改变列上的任何存在的处理 (process), 所以它
应该仅能由系统管理者去执行.

=====

附录C  本发行版的内容 -- MIT Core Distribution

    本文件是从 MIT 发行版内的原始资料再制作而来的.

    本发行版含有大约 100 Mbytes 的原始码与文件. 因为没有人会对它的全
部内容都感兴趣, 所以本发行版被分为大致相等的三个部分: Core 软体(核心
软体)、不同使用者贡献的工具集和使用者贡献的其他软体.

C.1 核心版

    这核心版, 包含大约 30 Mbytes 由X协会成员所支援的软体, 它是由下
面所列的目录所架构起来的. 假如你发现该版中某个部分有错误 (bug), 请填
妥位於doc/bugs/bug-report 的表格, 并邮递至 xbugs@expo.lcs.mit.edu.

  ./ 包含重要通知、一般的X指南页与所有构成该发行版子目录的最上层目录.

  X11/ 所有公用的引头档 (header file) 不是储存於此就是在建立系统的各
      阶段时被连结. 本目录与其下的位元图像 (bitmaps) 在安装阶段被拷
      贝至 incdir架构参考所指定的目录 (预设为 /usr/include/x11).  注
      意最後的目录名称应该是 X11, 否则所有X程式在编译时将会出错.

  X11/Bitmaps/ 本目录内包含一些以 Bitmaps 格式储存 (可用 Xlib 的常式
      XReadBitmapFile, XmuReadBitmapDataFromFile 与 XWrite BitmapFile
      处理者) 的一些单平面影像. 在 C 程式中它们通常被以 #include 引入
      且使用 xsetroot 公用程式被当作背景磁砖 (background tiles) ,而且
      X工具集 (toolkit) 允许使用者指定目录内的档名作为游标与表徵图.
      详细资讯请参考 bitmap 的指南页与util/bm-convert/bm-convert.doc.

  clients/ 本目录是使用者程式来源树 (source tree) 的最上层. 其他一些
      程式则存於 domos/ 与 examples/ 树,原因为它们只是为了示范目的而
      已. 其他一些非常有用的使用者贡献程式可在 coutrib/clients/ 下找
      到.

  clients/bitmap/ 本目录包含建立与修改单平面位元映成影像 (就像储存於
      X11/bitmaps/ 的一样) 的编辑器. 可用於定义双色磁砖 (为了用stipple
      填满区域) 与遮罩 (为剪除与指定游标影像). 所有resource皆可以
      用命令列与预设方式指定. 两个新的程式bmtoa 与 atoma 已经被加入,
      它们用於转换位元影像档案成为简单的字串及简单字串转换成映像档案.

  clients/uwm/ 本目录包含一个较老的X视窗管理器. 一些错误已更正且增加
      了一些新功能.

  clients/x10tox11/ 本目录包含一个重写过的 X10 至 X11 的通讯协定转译
      器. 它充当X10 Server, 转换 X10 的 request 为 X11 的 request 以
      及 X11 的 event 为 X10 event. X10toX11 程式允许 X10 程式不经修
      改即可在 X11 server 上执行, 使得从 X10 转换成 X11 非常容易, 新
      版本实质上会比旧版本有更快更精确的结果.

  clients/xbiff/ 本目录包含一个简单的小程式, 它会在你有新邮件送达时,
      在邮箱上显示一个竖起的旗帜, 它使用 athena widget set 里的 Mailbox
      (邮箱) Widget.

  clients/xcale/ 本目录内包含一个可以模拟 TI-30、HP-10 与计算尺的桌上
      型计算器程式. 这个程式需要被重新改写.

  clients/xcliphoard/ 本目录内包含两个程式用以处理段落. xclipboard 搜
      集来自其他 client (见 xterm 与 Athena Text widget) 的文字将它们
      送至 CLIP-BOARD, xcutsel 提供介於只能处理剪一缓冲区的旧 client
      与使用段落的新 client 之间的桥梁.

  clients/xclock/ 本目录内含有一个可显示时钟的简单小程式. 它可以显示
      指针或数字型时间, 它使用 Athena Widget Set 里的 Clock Widget.

  clients/xdm/ 本目录内包含新的显示管理器 (Display Mamager). 它企图取
      代 xterm-L与大多数使用 xinit 的场合. 位置管理者应该研读文件与样
      本架构以裁剪 xdm 配合它们的特殊环境. 一些样本架构提供於 config
      子目录下面.

  clients/xdpyinfo/ 本目录包含一个可以列印有关显示器的视觉影像与
      萤幕的资讯的公用程式.

  clients/xedit/ 本目录包含一个建立於 Athena Text widget 与 X Toolkit
      之上的文字编辑器.

  clients/xev/ 本目录包含一个可以检查 event 内容以及它们如何产生的程式.

  clients/xfd/ 本目录包含一个可显示指定字型的字元之公用程式.

  clients/xhost/ 本目录包含一个以主机为基础 (host-basis) 控制存取主机
      显示器的公用程式.

  clients/xinit/ 本目录包含一个可以在无法从 /etc/init 启动一个X server
      与初始化一个 client 的系统上, 启动X server 与初始化 client (通
      常是一个终端机模拟器) 的公用程式.

  clients/xkill/ 本目录包含一个公用程式可除去不要的视窗.

  clients/xload/ 本目录包含一个可监视机器平均负载状况的程式. 它可以显
      示最近一段期间平均负载的柱状图, 通常用於监视网路上的机器. 它使
      用 Athena widget set 里的 Load widget, 假如你将X转移至一个新
      的作业系统时, 它须要作些修改.

  clients/xlogo/ 本目录包含一个使用 Athena widget set 里的 Logo widget
      显示 X视窗系统语标 (Logo) 的程式.

  clients/xlsfonts/ 本目录包含一个可以列印目前 server 可供使用的字型
      之公用程式.假如你要求从具有许多压缩字型的 server 作较长的列印,
      你的显示可能会暂停一段较长的时间.

  clients/xlswins/ 本目录包含一个可列印出显示器上的视窗的公用程式.
      在找出一个因某种原因而忽然在萤幕上消失之视窗时非常有用.

  clients/xmag/ 本目录包含一个当你在侦错图形时, 可以放大部分显示的公
      用程式. 如果萤幕上同时有超过一种型式的视像, 可能无法达成目的.

  clients/xman/ 本目录包含一个可以显示指南页的公用程式. 加上少量的修
      改可以模拟本地作业系统的 man 程式.

  clients/xmh/ 本目录包含一个与 MH 邮件处理系统的视像介面. 它扩展X
      Toolkit 与Athena widget set 的使用.

  clients/xmodmap/ 本目录包含一个可以显示更改的键盘、修正器或指标图
      . 它会读取一个包含命令的 script 档且通常在你登录或第一次启动X
      时执行.

  clients/xpr/ 本目录包含一个可列印由 xwd 所获得的萤幕倾印影像的公用
      程式.

  clients/xprop/ 本目录包含一个可检查一个特定视窗特性的公用程式.

  clients/xpseudoroot/ 本目录包含一个在 Inter-Client 通讯惯例手册
      (ICCCM) 的前一版本所描述的原型程式. 它只供实验用且承诺在最终的
      ICCCM 规格被发展时予以修正.

  clients/xrdb/ 本目录包含一个可载入使用者指定的预设resource定义给
      server 的公用程式, 它通常是在 login 或第一次启动 X 时被执行.

  clients/xrefresh/ 本目录包含一个可刷新全部萤幕的一个简便公用程式.

  clients/xset/ 本目录包含一个可设定按键声音、指标加速度等个人喜好特
      性之公用程式.它现在提供从字型路径增加与删除进入点的功能.

  clients/xsetroot/ 本目录包含一个可设定根视窗背景的公用程式.

  clients/xterm/ 本目录包含一个 VT102 与 Tektronix 4014 终端机模拟器
      程式. 先前版本的许许多多错误都已修正. VT102 模式现在可以使用X
      Toolkit 转换管理器(使任意重系结按键成为可能)、选择区 (selection)
      (见 xclipboard 与 xcutsel)与正确地设定它的处理群 (process group).

  clients/xwd/ 本目录包含一个可以倾印视窗影像的公用程式. 它通常是将
      一个视窗快拍以便列印或稍後使用 xwud 程式显示, 对某些使用 XY 格
      式影像的 server 仍有问题, 且执行时大都相当慢.

  clients/xwininfo/ 本目录包含一个可以检查各种不同的视窗属性 (像大小
      、位置、视窗管理器资讯等) 的公用程式. 它常与 xprop 合用, 用以
      检查视窗的阶层架构.

  clients/xwud/ 本目录包含一个可以显示先前用 xwd 建立的影像之公用程式.

  demos/ 本目录包含许多看来非常有趣, 但不常用的程式.

  demos/ico/ 本目录包含一个可以让一个多边型物体绕著萤幕滚动的精巧程式.

  demos/maze/ 本目录包含一个相当吸引人的解迷宫示范程式.

  demos/muncher, demos/plaid/ 目录包含一个可以画可爱图画的程式.

  demos/puzzle/ 本目录包含一个为 X11 设计的 "重排磁砖" 的益智游戏. 假
      如你有彩色显示器, 试著在它建立时的目录执行 puzzle -picture mandrill.cm.

  demos/xeyes/ 本目录包含一个在 SIGGRAPH'88 看到的一个 NEWs demo 所
      启发出的吸引人的程式.

  doc/ 本目录包含描述标准版本的所有文件. 不同 client 的指南页可以在
      个别的原始程式目录里找到.

  doc/HelloWorld/ 本目录包含 DavidRosenthal's USENIX'88 Hello, World
      关於使用toolkit 的文章.

  doc/Protocol/ 本目录包含X通讯协定的正式公认规格, 里面说明了甚麽是
      与甚麽不是X的通讯协定部分以及那一部分是X标准的最後根据.

  doc/Server/ 本目录包含将XServer 植入新工作台的许多指南.

  doc/Xaw/ 本目录包含对 Athena Widget Set 的一个指南.

  doc/Xlib/ 本目录包含 Xlib 程式规划指南与指南页的原始资料. 其中有一
      个未测试过的命令列程序叫做 doc/Xlib/Xman/ expand.names, 它会将
      指南页更改名称使其与它所描述的常式 (routines) 名称匹配.

  doc/Xt/ 本目录包含X Toolkit Intrinsics 的规格说明. Inrinsics 现在
      已经是X标准的一部分; 任何供应 Xlib 的供应商也大都会供应 Xt.

  doc/bdf/ 本目录包含一个描述字型的位元映像分布格式 (Bitmap
      Distribution Format). BDF 已是 X 标准的一部分; 所有的 server 供
      应商也大都会提供一个程式, 可以转换该格式至任何他们所喜欢的内部
      格式.

  doc/bugs/ 本目录包含一个可提供错误报告的模板(见 doc/bugs/bug-report).
      当使用xbug@expo.lcs.mit.edu 报告错误时时请使用这个格式.

  doc/extensions/ 本目录包含 core 通讯协定基础程式库可能扩充的文件.
      它目前包含已提出的 PEX 3D 图形扩充与一个输入综合 (INPUT
      SYNTHESIS) 扩充.

  doc/fontnames/ 本目录包含一个经过X协会评估的字型命名草案的规格.
      这是对 AdobeSystem Inc.、Digital Equipment Corporation 与
      Bitstream Inc. 所赠送的字型命名时所使用的格式.

  doc/releasnotes/ 本目录内包含目前你看的这份文件的原始资料.

  doc/tutorials/ 本目录内包含评论如何使用X视窗系统的特别麻烦的部分.
      且欢迎使用者多提供.

  examples/ 本目录内包含不属於任何其他地方的不同例子.

  examples/CLX 本目录内包含如何使用 CLX (Common Lisp X) 介面的一些样
      本例子.

  examples/Xaw 本目录内包含可以测出不同 Athena widget 的一些小程式.

  extensions/ 本目录树内包含一些 SERVER 扩充样本的原始码: 一个绘出
      request(bezier) 的云形规、一个在X里使用生动视像的程式集 (
      plxvideo)、为了作输入记录与综合的一个扩充的开始 (xtest) 与一
      个梯形绘出要求 (zoid).

  extensions/include/ 本目录包含扩充样本的标头档.

  extensions/lib/ 本目录包含 client 程式库常式用以和扩充程式集通讯.

  extensions/server/ 本目录包含用以撰写扩充功能 server 的常式.

  extensions/test/ 本目录包含一些用以测试扩充功能的范例.

  fonts/ 本目录树内包含可以给不同的公用程式产生与处理字型档的原始资料
      . 使用者贡献的版本有一个不同的转换器用以转换不同格式的字型成为
      BDF 格式.

  fonts/bdf/ 本目录内包含经过仔细选择的字型之原始资料. 从这个发行版开
      始, 给定字型名称的长度与具有别名与通用字型名称的能力, 对组织字
      型到目录是相当重要的. 就像 BDF 格式现在已是X标准的部分, 所有
      server 的供应商被期待提供可以转换 BDF 档成他们的 server 可以接
      受的适当包装字型格式的编译器. 预设状况是 sample server 将具有
      在这里介绍的所有三个字型目录. 假如主显示器的解析度小於每英□
      88 点, 75 dpi 字型将较 100 dpi 字型在路径上优先. 否则 100 dpi
      字型出现在字型路径的最前面.

  fonts/dbf/misc/ 本目录包含前一发行版本的游标与固定宽度字型.

  fonts/bdf/75bpi/ 本目录内包含由 Adobe System Inc. 与 DEC 以及
      Bitstream, inc.为每英□ 75 点的监视器所设计提供的字型. 这些字
      型遵照新的字型命名惯例; 多数使用者将想要去学习如何适当地使用通
      用字元 (wildcard).

  fonts/bdf/100bpi/ 本目录内包含为每英□ 100 点的监视器所设计的 75
      dpi 字型版本.某些家族在这种解析度下无法及时备妥.

  fonts/bdftosnf/ 本目录内包含用以编译 BDF 格式的字型成为由 sample
      server 所使用的已被压缩的 Server Natural Format 的格式.

  fonts/mkfontdir/ 本目录内包含在建立字型资料库时 server 用以映成字
      型名称至对应档案的新公用程式. 无论何时字型被增加或移出目录, 这
      个程式必须在该目录内执行以便重建资料库.

  lib/ 本目录包含标准版本内所有主要的程式库.

  lib/CLX/ 本目录包含 CLX common Lisp X程式集. 这是一个本国的 Common
      Lisp 与X通讯协定的介面 (也就是说,它不使用 Xlib), 它将会被X
      协会审核, 因为考虑它将纳入X标准中.

  lib/X/ 本目录内包含 Xlib C 语言程式的程式库. 这个程式集所提供的介
      面是X标准的一部分 (亦即任何供应商提供任何 C 介面为了叫用它的
      产品X也必须提供 Xlib).供应商可以自由的去改变它的内部, 但介面
      必须保持相同. 自从上一个发行版发行以来一些新的常式已被加入以提
      供存取不透明的资料结构元素.

  lib/X/sysV/ 本目录内包含一个使 Xlib 可工作於 System V-based 机
      器的常式.

  lib/X/mips/ 本目录内包含一个使 Xlib 可工作於由 Mips Computer
      System 制造的工作台的常式.

  lib/Xaw/ 本目录内包含 Athena widget set. 它是一个逐渐搜集使用者介
      面实体的开始,建於 X Toolkit Intrinsics 的顶端. Widget 是用於建
      立高阶应用 (higher level), 且理想地应该尽可能地提供较多的机构
      与较少的政策. (使用者介面工具集、使用者介面管理系统与从应用至
      撰写). 一个由 HP 发展的较完整集合可以在使用者贡献版本中找到,
      (不幸的, 它还无法植入 R3 标准的 X Toolkit Intrinsics).

  lib/Xmu/ 本目录内包含一个搜集有支援 MIT 应用的杂项常式. 它不是X
      标准的一部分; 供应商可以不提供这个程式库. Xmu 使用外面介面连
      结所有程式库且可被植入不同的系统. 它目前被部分 Athena widget
      set 与不同的 client 所使用.  lib/Xt/ 本目录内包含一个 X
      Toolkit Intrinsics 撰写样品、一个resource、事件与物件的管理器
      , 此管理器机制用以建立使用者介面物件, 称为 widgets. Intrinsics
      已被发展成为X标准的一部分. 任何供应 Xlib 的供应商也被期望能提
      供 Xt.  lib/oldX/ 本目录内包含 X11 重新改写的 X10 Xdraw 与
      Assoc Table.

  rgb/ 本目录包含一个 RGB 彩色资料库样品与一个编译它的程式. 一个好的
      资料库是非常有需要的, 但是还没一个有人志愿去做. 灰度阶与一些新
      色彩已被加入.

  server/ 本目录包含一个 Core 通讯协定的 sample Server. 它应该与 X
      Protocol Specification 相当匹配, 但规格是最後的根据. 在试图做
      任何改变之前请读取在dos/Server 目录内的文件与任何在 Server/ddx
      目录内的 README 档案, 并认真地研究它的码.

  server/ddx/ 本目录包含一些不同工作台的设备相关程式库. 在建立或安装
      任何 Server之前请研究每个 README 档案.

  server/ddx/apollo/ 本目录包含一些建立一个 server 的完整原始程式,
      它们须在单色与彩色 Apollo 显示器上执行, README 档内建立有这种
      Server 的提示与必要条件.

  server/ddx/cfb/ 本目录包含一个非现场获取色彩Ports的色彩架构缓冲器
      (color frame buffer)函数馆之范例。在 server执行之後,它被用来
      在所有可用之硬体支援选择最佳之使用。

  server/ddx/dec/ 本目录包含在 VAXstation II、2000 及 300 系列的单色
      (qvss) 与彩色 (qdss) 显示器上建立 server 的完整原始码. 它也包
      含控制与解译 LK201键盘的常式.

  server/ddx/hp/ 本目录包含一个建立可执行於 HP 9000/300 系列,具有
      Topcat 显示器的 server 之完整原始码.

  server/ddx/ibm/ 本目录包含一个建立可执行於 IBM AOS (不是 AIX) 下的
      APA16 与Magaple 显示器的 server 之完整原始码.

  server/ddx/macII/ 本目录包含一个建立可执行於 A/UX 下的 Apple
      Macintosh II 的Server 之原始码.

  server/ddx/mfb/ 本目录包含一个单色架构缓冲显示器的可携式驱动器. 它
      的主要目的是为了没有特殊图形硬体的工作台作为一个初始植入基础.
      假如硬体可以支援,它也可以用在任何可能的地方.

  server/ddx/mi/ 本目录包含与机器无关的不同图形操作的程式. 在将 server
      植入新工作台与处理在记忆体里的 (in-memory) 影片影像 (pixmap) 时
      通常与 mfb 以及 cfb程式库合用.

  server/ddx/ndx/ 本目录包含建立一个不具有输入或输出装置的 server 的
      原始码. 它使用一般性的单色与彩色框架缓冲码, 使得它对於测试 server
      与机器无关的部分很有用.

  server/ddx/plx/ 本目录包含在 Sun 或 VAX 的 parallax 视讯图形控制器
      上建立一个server 的原始程式. 它也使用到在 extensions/server/
      目录里的 Parallax VideoExtension.

  server/ddx/snf/ 本目录包含处理 SNF 字型的常式. 大多数的 server 使
      用不方便的SNF, 但它们并没有需要如此作.

  server/ddx/sun/ 本目录包含一个建立可执行於 Sun bw2 与 cg 显示器的
      server 的完整原始程式. 它使用 cfb 程式库取代一些指定设备的常式
      , 也因此在支援分散处理的某些时候较其他彩色 server 慢. 在建立与
      安装 Sun server 之前请阅读目录里的README 档.

  server/dix/ 本目录包含 sample X server 与设备无关的部分. 它强烈地
      建议你不要改变任何码, 就好像阻碍你更新至新版本一样. 假如你发现
      问题或建议作一个改变使植入一个新工作台更容易, 请依照附录E所描
      述的方式发出一个错误报告.

  server/include/ 本目录包含整个 server 所需用到的前置档.

  server/os/ 本目录包含 server 与不同作业系统相关的部分.

  server/os/4.2bsd/ 本目录包含可以使 sample server 执行於支援 4.2bsd
      插座介面的作业系统常式.

  server/os/bsdemul 本目录包含可模拟一般使用的 BSD 的常式. 它是 System
      V 基础的server 典型的用法.

  util/ 本目录包含本发行版建立与建构的不同程式与 script. 当你想将X
      带上新工作台时, 应该最先将本部分的程式植入.

  util/bm-convert/ 本目录包含一个可以将 X10 格式的位元影像档转换成
      X11 格式的过滤器.

  util/checkfn/ 本目录包含一个可以检查不合法档案名称的公用程式. 它通
      常在准备发布之前使用.

  util/compress/ 本目录包含 BSD 压缩程式的原始码.

  util/cpp/ 本目录包含一个由 Martin Minow's DECUS cpp 所发展的公开领
      域的 C 前置处理器的原始程式. 它提供那些 cpp 无法处理复杂的
      server 或 X Toolkit的系统. A/UX 1.0 的使用者在尝试建立本发行版
      之前必须建立与安装它 (参考 ser-ver/ddx/macII/R3setup.sh).

  util/imake/ 本目录内包含建立系统时大多数重要的公用程式. imake 程式
      用於从机器无关的叙述称作 Imakefile 的档案产生适当的机器相关
      Makefile 档. 它使用 C前置处理器所以记号名称与巨集函式也可以被
      定义. 它有它自己的手工做的Makefile, 且有一个可决定初始编译旗标
      的特殊程式. 假如你将本发行版植入新机器, 你可能需要去编辑
      util/imake/ccflags.c 以加入当你的机器在编译 imake 时所需要的任
      何编译旗标. Imake 会被自动地建立, 就好像 make World 的一部分.

  util/imake.includes/ 本目录包含用於产生不同 Makefile 的架构档.
      README 档里有哪些参数能被设定与在那里设定的描述. server-specific
      值在适当的 macros 档内给定, 与预设值不同的 site-wide 值在 site.def
      档给定. Imake.tmpl 不应该被更改. 假如改变任何这些参数, 你将需
      要完全重新建立 (rebuild) 使其能发生作用.假如你正想将 X 植入新
      机器, 必须非常小心地研读本目录的档案.  util/makedepend/ 本目
      录包含一个可以自动产生 Makefile 的关联性的程式. 它作用於程式建
      立过程, 在有任何原始程式改变的时候会正确地将应该重新编译的档案
      重新编译. 假如架构参数 CppSourcesPresent 设为 Yes, makedepend
      会有一份 C 前置处理器的拷贝, 以便加快速度. 这不是必要的且本发
      行版也未完成该功能. makedepend 被自动地建立, 作为 "make World"
      阶段的一部分.

  util/patch/ 本目录包含 Larry Wall's patch 程式, 它是一个要将修补差
      异转换成原始码时非常有用的程式. 本程式在本发行版不会自动建立;
      它提供无法存取 comp.sources.unix 压缩档的人一个简易与方便性.

  util/scripts/ 本目录包含不同安装软体与产生连结树等工作的有用说明。

  util/soelim/ 本目录包含某些系统需要的一个 soelim 程式版本.

=====

附录D  本发行版的内容 -- 使用者贡献的软体

D.1 使用者贡献的版本

    本文件是从 MIT 发行版内的原始资料再制作而来的. 这个使用者贡献的
版本包括下列的目录. 本发行版这个部分的错误应该报告给个别的作者而不是
送至 Xbugs.contrib/ 本目录是使用者贡献版本的最上层. 这个安排是有意将
它与 core 版本视为平行的地位.

contrib/clients/ 本目录内包含各种一般性的有用程式.

contrib/clients/alertyorngs/ 本目录内包含一些可用以告诉或询问使用者
    不同资讯的突现式对话视窗的公用程式.

contrib/clients/gsh/ 本目录内包含给初学者使用的图形 shell.

contrib/clients/hpxpr/ 本目录内包含一个 xpr 的版本, 它可以在 HP Laserjet
    印表机上列印.

contrib/clients/kterm/ 本目录内包含一个 xterm 的版本, 它可以使用
    Kanji 字型.

contrib/clients/magic/ 本目录内包含可用於 magic VLSI 设计系统的 X 驱
    动器.

contrib/clients/pbm/ 本目录内包含 Jet Poskanzer 的 Portable Bitmap
    Toolkit 与可转换不同位元影像型式的公用程式.

contrib/clients/splot/ 本目录内包含一个描绘图形的程式集.

contrib/clients/spy/ 本目录内包含另一种放大影像的公用程式.

contrib/clients/texx/ 本目录内包含一个 DVI 试播的程式 (previewer).

contrib/clients/x11stsrtup/ 本目录内搜录有用以提供比普通的 xinit 更
    好的介面的script 与预设建构档案.

contrib/clients/xbgsun/ 本目录内包含一个可用以载入一个 Sun raster 影
    像到根视窗背景的公用程式.

contrib/clients/xcalendar/ 本目录内包含一个可以管理行事历的程式.

contrib/clients/xdvi/ 本目录内包含另一个 DVI 试播的程式.

contrib/clients/xdvorak/ 本目录内包含一个公用程式, 它可采用 Dvorak-style
    连结(binding) 方式将键盘重新映射 (remapping).

contrib/clients/xfig/ 本目录内包含一个绘画程式集.

contrib/clients/xim/ 本目录内包含一个可以在 8 plane 显示器上显示 8
    与 24 位元影像的程式.

contrib/clients/xipr/ 本目录内包含一个针对 Imagen printer 的 xpr 程
    式.

contrib/clients/xlock/ 本目录内包含一个可以对不使用的显示器上锁的程
    式.

contrib/clients/xmessage/ 本目录内包含另一个显示讯息的程式. 它主要是
    用於显示X启动 script 时的错误讯息与在其他人的显示器上留言.

contrib/clients/xmore/ 本目录内包含一个针对 X 的 more 标页数的公用程
    式.

contrib/clients/xperfmon/ 本目录内包含一个搜集与显示系统统计资料的公
    用程式. 它必须指定作业系统以及不同的的工作台.

contrib/clients/xpic/ 本目录内包含一个 pic 试播器 (previewer).

contrib/clients/xplaces/ 本目录内包含一个展开与记录一个使用者初始交谈
    (session)的工具.

contrib/clients/xpref/ 本目录内包含一个与一些 xset 函式的视像介面.

contrib/clients/xshell/ 本目录内包含一个可以将命令嵌入单一键的古老程
    式.

contrib/clients/xshowcmap/ 本目录内包含一个可以使 colormap 显示彩色
    的公用程式.

contrib/clients/xstring/ 本目录内包含一个可以在另一个使用者的显示器
    上显示字串的程式.

contrib/clients/xtools/ 本目录内包含另一个可以展开一个使用者交谈的程
    式.

contrib/clients/xtroff/ 本目录内包含一个 troff 试播器.

contrib/clients/xwebster/ 本目录内包含一个 SRINIC webster 字典资料库.

contrib/demos/ 本目录内包含一些好玩的示范程式.

contrib/demos/paint/ 本目录内包含一个非常简单的画图程式.

contrib/demos/psycho/ 本目录内包含一个 ico 的多重显示器版本.

contrib/demos/spaceout/ 本目录内包含另一个可以设定根视窗背景的程式.

contrib/demos/worm/ 本目录内包含一个可以研究随机滑行图样 (slither
    patterns) 的程式.

contrib/demos/xcolors/ 本目录内包含一个可以显示色彩名称的程式.

contrib/demos/xfish/ 本目录内包含另一个可以设定根视窗背景的程式.

contrib/demos/xgranite/ 本目录内包含的仍然是另一个可以设定根视窗背景
    的程式.

contrib/demos/xphoon/ 本目录内包含一个可以显示月亮目前相位的可爱程式.

contrib/demos/xrotmap/ 本目录内包含可以旋转彩色图形的一个难缠程式.

contrib/doc/ 本目录树内包含附加的文件.

doc/SharedLibs/ 本目录内包含 AT&T 所提出的如何撰写主要 C 语言程式库
    共用版之规格. 它是由 AT&T 提出的并不是X的标准.

contrib/extensions/ 本目录树内包含 core 通讯协定的扩充程式集.

contrib/extensions/pex/ 本目录内包含可以让 PEX 将 3d 图形扩充至X的
    现有文件与前置档.

contrib/fonts/ 本目录树内包含编辑以及建立可供取舍的字型之公用程式.

contrib/fonts/bdf/ 本目录树内包含一些随机字型的集合.

contrib/fonts/bdf/bmug/ 本目录内包含转换自 Berkeley Mac User Group
    公益软体压缩档的字型.

contrib/fonts/bdf/info-mac/ 本目录内包含转换自 INFO-MAC 软体压缩档的
    字型.

contrib/fonts/bdf/oldx10/ 本目录内包含许多 X10 字型的 BDF 版.

contrib/fonts/bdf/oldx11/ 本目录内包含发行 X11 之前所给出的字型. 它
    们大多数都很难看.

contrib/fonts/utils/ 本目录树内包含一些可以转换各种不同字型格式为 BDF
    的公用程式,以及可用以分离字型档使它们可以被编辑的两版基本的工具
    程式.

contrib/games/ 本目录树包含一些有趣的游戏, 它对於熟悉X是有帮助的.

contrib/games/mazewar/ 本目录内包含一个光荣的古老迷宫大战 (mazewar)
    的程式, 它是大多数网路计算机游戏的鼻祖.

contrib/games/qix/ 本目录内包含一个与X版 viedo arcade 游戏同名的视
    讯游戏.

contrib/games/xhanoi/ 本目录内包含一个可以解汉诺塔 (Tower of Hanoi)
    问题的程式.

contrib/games/xmille/ 本目录内包含 Milles Bournes 牌戏的一个漂亮的计
    算机版本.

contrib/games/xpuzzle/ 本目录内包含另一个 puzzle 程式.

contrib/games/xsol/ 本目录内包含一个 solitaire 牌戏的X版本.

contrib/games/xtrek/ 本目录内包含恶名昭彰的 xtrek. 它需要 System V
    共用记忆体介面才能工作.

contrib/hacks/ 本目录树内包含一些令人怀疑其有用性的程式.

contrib/hacks/arctest/ 本目录内包含一个可以测试 arcs 的简单程式.

contrib/hacks/reborder/ 本目录内包含一个当 anti-social 视窗当掉後可
    用来重新设定视窗边界的小公用程式.

contrib/hacks/xbounce/ 本目录内包含一个可以在萤幕上带著视窗前进的
    (dribbling window) 程式.

contrib/hacks/xchcursor/ 本目录内包含一个可循环变化不同游标图样的程
    式.

contrib/hacks/xsetsize/ 本目录内包含一个可以由命令列下达移动, 重定大
    小以及表徵图化视窗的公用程式. 它是一个违反 Inter-Client 通讯惯例
    程式的主要范例且可能无法在大多数的视窗管理器上工作.

contrib/server/ 本目录内包含未被整合进 sample server 项目的文件与程式
    码.

contrib/server/sgi/ 本目录树内包含修补 sample server 和可以使 R3 server
    在Silicon Graphics 工作站上执行的机器指定的驱动器.

contrib/server/speedups/ 本目录内包含最佳化样本 server 的建议方法.
    它所强调的是精确度而不是性能. 它可以使许多地方有实质地改进.

contrib/server/veryoldxpc/ 本目录内包含过去尝试将非常早期的 X11 server
植入MS-DOS 下的 IBM PC 的结果. 要使它们有用还需要实质的努力. 这个程
式集将不包含在未来发行的版本, 除非有实质的进展使它可以发表.

contrib/toolkits/ 本目录树内包含一些现有的工具集.

contrib/toolkits/InterViews/ 本目录内包含一个 Standford 大学 InterView
    C++ toolkit 的新版本.

contrib/toolkits/Xr11/ 本目录内包含一个 HP X-Ray toolkit 的新版本.

contrib/toolkits/andrew/ 本目录内包含一个 Carnegie-Mellon 大学 Andrew
    toolkit的新版本.

contrib/toolkits/clue/ 本目录内包含一个 TI 公司的 Common Lisp 使用者
    环境的样本程式.

contrib/widgets/ 本目录树内包含不同的 widget. 某些是立基於 R2 Intrisics
    , 其他则立基於目前的 Intrinsics.

contrib/widgets/Dclock/ 本目录内包含一个立基於 R2 Intrisics 的数字时
    钟 widget.

contrib/widgets/Mailwatch/ 本目录内包含一个立基於 R3 Intrisics 的较
    佳邮箱 widget.

contrib/widgets/MenuBox/ 本目录内包含一个选单 widget 的原型, 它终将
    变成 Athena widget 集的一部分. 它是立基於 R3 Intrinsics.

contrib/widgets/Xhp/ 本目录内包含一个 HP 的大型整合性 widget 集以及
    一个 R2 X Toolkit Intrinsics 的版本, 依赖它这些 widget 可暂时被
    立基.

contrib/widgets/Xsw/ 本目录内包含搜集自 Sony 的 widget, 它也是立基於
    R2 Intrinsics.

contrib/widgets/cpicker/ 本目录内包含一个立基於 R2 Intrinsics, 用於
    选择与修改色彩的 widget.

contrib/widgets/tblwidget/ 本目录内包含一个几何管理器, 它使用 tbl-style
    格式的命令并立基於 R2 Intrinsics 安排子视窗.

contrib/widgets/widgeteditor/ 本目录内包含一个立基於 R2 Intrinsics 的简
    单 widget编辑器.

contrib/widgets/widgetwrap/ 本目录内包含一个可用於建立 widget 与设定
    他们的引数的公用常式.

contrib/widgets/xpalette/ 本目录内包含可用於显立基於 R2 Intrinsics
    彩色的 widget.

contrib/windowmgrs/ 本目录树内包含一些较流行的视窗管理器.

contrib/windowmgrs/awm/ 本目录内包含 awm 视窗管理器.

contrib/windowmgrs/rtl/ 本目录内包含 rtl tiling 视窗管理器. 

contrib/windowmgrs/twm/ 本目录内包含 twm 视窗管理器.

contrib/windowmgrs/wm/ 本目录内包含旧的 wm 视窗管理器. 它主要是因历
    史的理由而提供的.

=====

附录E  如何取得X

E.1 在美国

    仅要完整的手册或手册与全部 MIT 发行版磁带两者都要, 可以从下列地
方取得 :

          MIT Software Center
          Technology Licensing Office
          room E32-300
          77 Massachusetts Avenue
          Cambridge, MA 02139
          USA

E.2 在欧洲

    仅要完整的手册、或手册与磁带、或仅要全部 MIT 发行版磁带, 可以从
下列地方取得 :

          Unipalm Limited
          147 St. Neots Road
          Hardwick
          Cambridge CB3 7QJ
          England

          Phone:+44 954 211797 international, (0954) 211797 in UK.
          Fax:+44 954 211244 international, (0954) 211244 in UK.

E.3 如何取得 GNU Emacs

    GNU Emacs 的生产、开发与出版在 :

        Free Software Foundation
        1000 Mass Avenue
        Cambridge, MA 02138
        USA

    在执照期限内任何拥有系统拷贝的人被允许 (鼓励) 可以自由地将原始码
和文件拷贝给任何其他的人.

    假如你无从得知谁有一份拷贝, 只要付媒体价钱以及手续费你就可以获得
一个系统的完整版本, 你可以从自由软体基金会, 或者在欧洲, 从 Unipalm取
得.

=====

附录F X网路与电子邮件服务

    透过电子邮件与其他网路可取得一些与X相关的服务. 这些包括公布栏
(bulletin board)、"资讯服务 (information servers)", 与获得X软体 (包
括 MIT 发行版以及其他程式与软体) 的设备.

F.1 xpert 邮件竞技场

    xpert 邮件竞技场 (Mailing List) 是一个用於讨论X面貌的论坛. 包括
已存在软体的问题、设计的变更、可能的改进与其他一般资讯. 它发源於 MIT
的X 研究人员, 是许多有用资讯的来源.

    要加入该竞技场, 可以送一个邮件讯息至 :

        xpert-request@athena.mit.edu

要求加入各分布区域的竞技场.

F.2 xstuff Server

    xstuff Server 是一个透过邮件网路发送你的程式与(或)文件档案的服务
程式, 用以反应一个你以电子邮件送出的要求. 它主要包含来自X协会 "认定
的" 资讯, 包括新发行的文件与确定 MIT所发行的软体.

    本节剩於的部分是当你发送一个 "求助 (help)" request 至 server 时,
你从 server 所得到的讯息所组成.

       ┌—————————┐
       │见 p307-310 原文  │
       └—————————┘

F.2.1 注意事项

       ┌———————┐
       │见 p310 原文  │
       └———————┘

F.2.2 明朗性

       ┌———————┐
       │见 p310 原文  │
       └———————┘

F.3 FTP 与其他网路 Server

    对那些可以接取 Internet (Arpanet) 者, 有许多站可以提供 FTP 处理,
允许你直接由网路上获得软体. 也有其他站允许你以用 uucp 或其他通讯协定
存取. 详细的这些内容有时候会印在 xpert 邮件竞技场上.

=====

附录G  需要从你的系统管理者得到的资讯

    如果你自行安装X,我们强力推荐你使用预设的建构(configuration) ,
因而所有的档案将储存在标准的目录中。

    如果系统是以一种非标准建构来安装的话,你需要从你的系统管理者,至
少获得下列的资讯:

    1. X可执行程式的目录
        (预设值:/usr/bin/x11).

    2. 位元映像馆的目录
        (预设值:/usr/include/x11/bitmaps/).

    3. 指南页的目录
        (预设值:/usr/man/mann/).

    4. 字型的目录
        (预设值:/usr/lib/x11/fonts/misc/, /usr/lib/x11/fonts/75dpi
                  和/usr/lib/x11/fonts/100dpi/).

    5. RGB 色彩资料库的位置
        (预设值:/usr/lib/x11).

    6. 应用程式特性resource名称的目录
        (预设值:/usr/lib/x11/app-defaults/).



BBS水木清华站∶精华区

TOP