X 窗口系统并未为选择区数据定义固定的数据类型,也没有限定选择区的固定数量。选择区由 X “原子(atoms)” 标识,原子是 X 服务器为字符串名称分配的唯一 29 位标识符。Emacs 隐藏了这一复杂性:当 Lisp 传入一个符号,其名称对应某个原子名时,Emacs 会自动请求这些标识符,无需额外干预。
在 X 中,当一个程序 “设置(sets)” 选择区时,它实际上成为了该选择区的 “所有者(owner)” —随后 X 服务器会将选择区请求转发给该程序,程序必须向请求客户端返回选择区数据。
同理,程序并非直接从 X 服务器 “获取(get)” 选择区数据,而是将选择区请求发送给最后声明拥有该选择区的窗口所属客户端,由其返回所请求的数据。
每个选择区请求包含三个参数:
gui-get-selection 的 type 参数决定。
选择区所有者会向请求方传输一系列字节、16 位字或 32 位字,并附带另一个标识这些字类型的原子。请求选择区后,Emacs 会按照自身对数据格式和类型的解析规则,将选择区所有者传来的数据转换为 Lisp 表示形式,并由 gui-get-selection 返回。
Emacs 会将任意字节序列的选择区数据转换为保存这些字节的单字节字符串;将单个 16 位或 32 位字转换为无符号数;将多个此类字转换为无符号数向量。这一通用规则存在例外,Emacs 会对以下转换目标的数据做特殊处理:
INTEGER该类型的 16 位或 32 位字按有符号整数处理,而非无符号数。若选择区数据包含多个字,则返回向量;否则直接返回整数。
ATOM该类型的 32 位字被视为 X 原子,并以其名称对应的 Lisp 符号返回(单独返回或作为向量返回)。无效原子替换为 nil。
COMPOUND_TEXTUTF8_STRINGSTRING从这些数据类型请求得到的单字节字符串,会被设置一个名为 foreign-selection 的文本属性,值为选择区数据的类型。
每个选择区所有者必须至少返回两种选择区目标:TARGETS,返回所有者支持的若干原子类型;以及 MULTIPLE,供 X 客户端内部使用。选择区所有者还可支持任意数量的其他目标,部分由 X 协会的
客户端间通信约定手册 标准化,另一些(如 UTF8_STRING)本应由 XFree86 项目标准化,但最终并未完成。
按照惯例,对某个选择区目标的请求可以返回特定类型的数据,也可返回多种类型之一(以选择区所有者最方便为准);后一类选择区目标称为 多态目标(polymorphic target)。对某个目标的请求也可能完全不返回数据,而是由选择区所有者执行某个附带动作,这类目标称为 副作用目标(side-effect targets)。
以下是一些选择区目标,从 CLIPBOARD、PRIMARY 或 SECONDARY 请求时,其行为通常符合标准:
ADOBE_PORTABLE_DOCUMENT_FORMAT该目标以字符串形式返回 Adobe “可移植文档格式(Portable Document Format)” (PDF)数据。
APPLE_PICT该目标以字符串形式返回 Mac 计算机使用的 “PICT” 图像格式数据。
BACKGROUNDBITMAPCOLORMAPFOREGROUND这四个目标共同返回使用 X 服务器上位图图像所需的整数数据:位图背景色像素值、位图的 X 标识符、分配前景与背景色的颜色表、位图前景色像素值。
CHARACTER_POSITION该目标返回两个 SPAN 类型的无符号 32 位整数,以字节为单位表示选择区数据在其文本域中的起始与结束位置。
COMPOUND_TEXT该目标返回 X 协会多字节文本编码系统中的 COMPOUND_TEXT 类型字符串。
DELETE该目标不返回数据,但会附带删除包含选择区内容的文本域中的数据。
DRAWABLEPIXMAP该目标返回无符号 32 位整数列表,每个整数对应一个 X 服务器可绘制对象或像素图。
ENCAPSULATED_POSTSCRIPT_ADOBE_EPS该目标返回包含封装 PostScript 代码的字符串。
FILE_NAME该目标返回包含一个或多个文件名的字符串,以空字符分隔。
HOST_NAME该目标返回运行选择区所有者的机器的完整域名。
USER该目标返回运行选择区所有者的机器的用户名。
LENGTH该目标返回一个无符号 32 位或 16 位整数,表示选择区数据长度。
LINE_NUMBER该目标返回两个 SPAN 类型的无符号 32 位整数,表示选择区数据在其文本域中对应起始与结束行号。
MODULE该目标返回包含选择区数据的函数名称,主要由文本编辑器请求。
STRING该目标以 STRING 类型字符串返回选择区数据,采用 ISO Latin-1 编码与 Unix 换行符。
C_STRING该目标以 “C 字符串” 形式返回选择区数据,通常解释为所有者使用的任意编码原始数据,可能以空字节结尾或无结尾,也可能是 ASCII 字符串。
UTF8_STRING该目标以 UTF8_STRING 类型字符串返回选择区数据,采用 UTF-8 编码,换行格式未指定。
TIMESTAMP该目标以 CARDINAL 类型的 16 位或 32 位字返回选择区所有者获得所有权时的 X 服务器时间。
TEXT这一多态目标以字符串形式返回选择区数据,可为 COMPOUND_TEXT、STRING、C_STRING 或 UTF8_STRING,由选择区所有者自行决定。
当使用 gui-get-selection 请求 STRING、COMPOUND_TEXT 或 UTF8_STRING 目标,且未设置 selection-coding-system 与 next-selection-coding-system 时,结果字符串会分别使用对应编码系统解码:iso-8859-1、compound-text-with-extensions 与 utf-8。
除上述目标(以及各类程序自用的大量目标)外,许多流行程序与工具包未咨询 X 标准组织便自行定义了选择区数据类型。这些目标通常以 MIME 类型命名,如 text/html 或 image/jpeg,它们返回的数据形式如下:
file:// 格式 URI(或换行/空字符分隔的 URI 列表),标识对应格式文件。
这类选择区目标最早由网景浏览器使用,如今各类程序均提供支持,尤其是基于新版 GTK+ 或 Qt 工具包的程序。
Emacs 也可作为选择区所有者。调用 gui-set-selection 时,传入的选择区数据会被内部记录,Emacs 获得对应选择区的所有权。
从选择区目标到 “选择区转换器(selection converter)” 函数的关联列表。收到选择区请求时,Emacs 根据请求的目标查找对应的转换器。
选择区转换器接收三个参数:对应所请求选择区原子的符号、所请求的选择区目标,以及通过 gui-set-selection 设置的值。其返回值必须为以下形式之一:表示数据类型与数值的符号 cons、符号、数值或符号向量,或此类 cons 的 cdr 部分。
若选择区转换器返回特殊符号 NULL,则向请求方返回的数据类型设为 NULL,且不发送任何数据。
若返回字符串,必须为单字节字符串;若未显式指定数据类型,则以 STRING 类型传输。
若返回符号,会获取其对应 “原子(atom)”,并以 32 位值传输;未指定类型时默认为 ATOM。
若返回数值在 -32769 到 32768 之间,以 16 位值传输;未指定类型时默认为 INTEGER。
若为其他数值,按 32 位值处理。即使返回无符号数,请求方仍会将 INTEGER 类型字视为有符号。如需返回无符号值,应指定类型为 CARDINAL。
若返回符号或数值向量,向请求方返回多个原子或数值列表。未显式设置时,返回类型为列表首个元素的类型。
默认情况下,Emacs 为以下选择区目标配置了转换器:
TEXT该选择区转换器按以下规则返回选择区数据:
C_STRING 类型字符串。(see 文本表示方式)。
STRING 类型字符串。
selection-coding-system 或 next-selection-coding-system 设为 :mime-charset 属性为 x-ctext 的编码系统,返回 COMPOUND_TEXT 类型字符串。
UTF8_STRING 类型字符串。
COMPOUND_TEXT该选择区转换器以 COMPOUND_TEXT 类型字符串返回选择区数据。
STRING该选择区转换器以 STRING 类型字符串返回选择区数据,采用 ISO-Latin-1 编码。
UTF8_STRING该选择区转换器以 UTF-8 格式返回选择区数据。
text/plaintext/plain;charset=utf-8text/uri-listtext/x-xdnd-usernameXmTRANSFER_SUCCESSXmTRANSFER_FAILUREFILE_DT_NETFILE这些选择区转换器用于拖放操作内部,仅对 XdndSelection 有效。
TARGETS该选择区转换器返回原子列表,每个原子对应 Emacs 支持的一种选择区目标。
MULTIPLE该选择区转换器由 C 代码实现,用于高效处理同时指定多个目标的选择区请求。
LENGTH该选择区转换器返回选择区数据的字节长度。
DELETE该选择区转换器用于拖放操作内部。
FILE_NAME该选择区转换器返回包含选择区数据的缓冲区文件名。
CHARACTER_POSITION该选择区转换器返回选择区在对应缓冲区中的起止字符位置。
LINE_NUMBERCOLUMN_NUMBER该选择区转换器返回选择区在对应缓冲区中的起止行号与列号。
OWNER_OS该选择区转换器返回 Emacs 运行的操作系统名称。
HOST_NAME该选择区转换器返回 Emacs 运行机器的完整域名。
USER该选择区转换器返回运行 Emacs 的用户账号名。
CLASSNAMEThese selection converters return the resource class and name used by Emacs.
INTEGERThis selection converter returns an integer value verbatim.
SAVE_TARGETS_EMACS_INTERNAL这些选择区转换器返回 Emacs 使用的资源类与资源名。
INTEGER该选择区转换器原样返回整数值。
SAVE_TARGETS_EMACS_INTERNAL这些选择区转换器用于内部用途。
除 INTEGER 外,所有选择区转换器均要求 gui-set-selection 提供的数据为以下形式之一:
(beg end buf) 的列表,其中 beg 与 end 为标记或覆盖区,表示缓冲区 buf 中选择区数据的范围。