跨客户端通信函数详解
1. 客户端间通信基础
在客户端间通信中,某些属性若足够大以包含基本大小和窗口重力字段,
supplied_return
参数还会包含以下位:
PBaseSize|PWinGravity
。不过,
XGetWMSizeHints
函数在使用时可能会产生
BadAtom
和
BadWindow
错误。
2. 设置和读取 WM_CLASS 属性
Xlib 提供了用于设置和获取给定窗口
WM_CLASS
属性的函数,这些函数使用在
<X11/Xutil.h>
头文件中定义的
XClassHint
结构体。
-
分配
XClassHint
结构体
:使用
XAllocClassHint
函数,代码如下:
XClassHint *XAllocClassHint();
该函数会分配并返回一个指向
XClassHint
结构体的指针。需注意,
XClassHint
结构体中的指针字段初始会被设置为
NULL
。若内存不足,函数将返回
NULL
。使用
XFree
函数可释放为该结构体分配的内存。
-
XClassHint
结构体定义
:
typedef struct {
char *res_name;
char *res_class;
} XClassHint;
其中,
res_name
成员包含应用程序名称,
res_class
成员包含应用程序类。要注意,此属性中设置的名称可能与
WM_NAME
中设置的名称不同。
WM_NAME
指定的是应显示在标题栏中的内容,可能包含临时信息;而
WM_CLASS
部分指定的名称是从资源数据库中检索应用程序资源时应使用的应用程序正式名称。
-
设置
WM_CLASS
属性
:使用
XSetClassHint
函数,代码如下:
XSetClassHint(display, w, class_hints);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `class_hints`:指定要使用的 `XClassHint` 结构体。
若字符串不在主机可移植字符编码中,结果将依赖于具体实现。该函数可能会产生
BadAlloc
和
BadWindow
错误。
-
读取
WM_CLASS
属性
:使用
XGetClassHint
函数,代码如下:
Status XGetClassHint(display, w, class_hints_return);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `class_hints_return`:返回 `XClassHint` 结构体。
若服务器返回的数据采用拉丁可移植字符编码,返回的字符串将采用主机可移植字符编码;否则,结果依赖于具体实现。成功时返回非零状态,否则返回零状态。使用完字符串后,需分别对
res_name
和
res_class
使用
XFree
函数释放内存。该函数可能会产生
BadWindow
错误。
3. 设置和读取 WM_TRANSIENT_FOR 属性
Xlib 提供了设置和读取给定窗口
WM_TRANSIENT_FOR
属性的函数。
-
设置
WM_TRANSIENT_FOR
属性
:使用
XSetTransientForHint
函数,代码如下:
XSetTransientForHint(display, w, prop_window);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `prop_window`:指定要将 `WM_TRANSIENT_FOR` 属性设置为的窗口。
该函数会将指定窗口的
WM_TRANSIENT_FOR
属性设置为指定的
prop_window
,可能会产生
BadAlloc
和
BadWindow
错误。
-
读取
WM_TRANSIENT_FOR
属性
:使用
XGetTransientForHint
函数,代码如下:
Status XGetTransientForHint(display, w, prop_window_return);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `prop_window_return`:返回指定窗口的 `WM_TRANSIENT_FOR` 属性。
成功时返回非零状态,否则返回零状态。该函数可能会产生
BadWindow
错误。
4. 设置和读取 WM_PROTOCOLS 属性
Xlib 提供了设置和读取给定窗口
WM_PROTOCOLS
属性的函数。
-
设置
WM_PROTOCOLS
属性
:使用
XSetWMProtocols
函数,代码如下:
Status XSetWMProtocols(display, w, protocols, count);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `protocols`:指定协议列表。
- `count`:指定列表中的协议数量。
该函数会用
protocols
参数指定的原子列表替换指定窗口上的
WM_PROTOCOLS
属性。若该属性不存在,则会进行设置。属性以
ATOM
类型和 32 位格式存储。若无法插入
WM_PROTOCOLS
原子,函数返回零状态;否则返回非零状态。可能会产生
BadAlloc
和
BadWindow
错误。
-
读取
WM_PROTOCOLS
属性
:使用
XGetWMProtocols
函数,代码如下:
Status XGetWMProtocols(display, w, protocols_return, count_return);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `protocols_return`:返回协议列表。
- `count_return`:返回列表中的协议数量。
若属性存在、类型为
ATOM
、格式为 32 位且能插入
WM_PROTOCOLS
原子,函数会将
protocols_return
参数设置为原子列表,将
count_return
参数设置为列表中的元素数量,并返回非零状态;否则,不设置返回参数并返回零状态。使用
XFree
函数释放原子列表。该函数可能会产生
BadWindow
错误。
5. 设置和读取 WM_COLORMAP_WINDOWS 属性
Xlib 提供了设置和读取给定窗口
WM_COLORMAP_WINDOWS
属性的函数。
-
设置
WM_COLORMAP_WINDOWS
属性
:使用
XSetWMColormapWindows
函数,代码如下:
Status XSetWMColormapWindows(display, w, colormap_windows, count);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `colormap_windows`:指定窗口列表。
- `count`:指定列表中的窗口数量。
该函数会用
colormap_windows
参数指定的窗口列表替换指定窗口上的
WM_COLORMAP_WINDOWS
属性。若属性不存在,则会进行设置。属性以
WINDOW
类型和 32 位格式存储。若无法插入
WM_COLORMAP_WINDOWS
原子,函数返回零状态;否则返回非零状态。可能会产生
BadAlloc
和
BadWindow
错误。
-
读取
WM_COLORMAP_WINDOWS
属性
:使用
XGetWMColormapWindows
函数,代码如下:
Status XGetWMColormapWindows(display, w, colormap_windows_return, count_return);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `colormap_windows_return`:返回窗口列表。
- `count_return`:返回列表中的窗口数量。
若属性存在、类型为
WINDOW
、格式为 32 位且能插入
WM_COLORMAP_WINDOWS
原子,函数会将
windows_return
参数设置为窗口标识符列表,将
count_return
参数设置为列表中的元素数量,并返回非零状态;否则,不设置返回参数并返回零状态。使用
XFree
函数释放窗口标识符列表。该函数可能会产生
BadWindow
错误。
6. 设置和读取 WM_ICON_SIZE 属性
Xlib 提供了设置和读取给定窗口
WM_ICON_SIZE
属性的函数,这些函数使用在
<X11/Xutil.h>
头文件中定义的
XIconSize
结构体。
-
分配
XIconSize
结构体
:使用
XAllocIconSize
函数,代码如下:
XIconSize *XAllocIconSize();
该函数会分配并返回一个指向
XIconSize
结构体的指针。
XIconSize
结构体中的所有字段初始会被设置为零。若内存不足,函数返回
NULL
。使用
XFree
函数可释放为该结构体分配的内存。
-
XIconSize
结构体定义
:
typedef struct {
int min_width, min_height;
int max_width, max_height;
int width_inc, height_inc;
} XIconSize;
width_inc
和
height_inc
成员定义了一个从最小到最大的尺寸等差数列,代表支持的图标尺寸。
-
设置
WM_ICON_SIZE
属性
:使用
XSetIconSizes
函数,代码如下:
XSetIconSizes(display, w, size_list, count);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `size_list`:指定尺寸列表。
- `count`:指定列表中的项目数量。
该函数仅由窗口管理器用于设置支持的图标尺寸。可能会产生
BadAlloc
和
BadWindow
错误。
-
读取
WM_ICON_SIZE
属性
:使用
XGetIconSizes
函数,代码如下:
Status XGetIconSizes(display, w, size_list_return, count_return);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `size_list_return`:返回尺寸列表。
- `count_return`:返回列表中的项目数量。
若窗口管理器未设置图标尺寸,函数返回零;否则返回非零。应用程序若想了解运行所在窗口管理器最认可的图标尺寸,应调用此函数,然后使用
XSetWMHints
为窗口管理器提供支持尺寸之一的图标像素图或窗口。使用
XFree
函数释放
size_list_return
中分配的数据。该函数可能会产生
BadWindow
错误。
7. 使用窗口管理器便利函数
-
XmbSetWMProperties函数 :
void XmbSetWMProperties(display, w, window_name, icon_name, argv[], argc, normal_hints, wm_hints, class_hints);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `window_name`:指定窗口名称,应为以空字符结尾的字符串。
- `icon_name`:指定图标名称,应为以空字符结尾的字符串。
- `argv`:指定应用程序的参数列表。
- `argc`:指定参数数量。
- `normal_hints`:指定窗口正常状态下的尺寸提示。
- `wm_hints`:指定要使用的 `XWMHints` 结构体。
- `class_hints`:指定要使用的 `XClassHint` 结构体。
该函数用于存储标准的窗口管理器属性,文本属性采用标准编码以进行国际化文本通信。若
window_name
参数不为
NULL
,会设置
WM_NAME
属性;若
icon_name
参数不为
NULL
,会设置
WM_ICON_NAME
属性。若参数能完全转换为
STRING
编码,属性以
STRING
类型创建;否则转换为复合文本,属性以
COMPOUND_TEXT
类型创建。若
normal_hints
参数不为
NULL
,会调用
XSetWMNormalHints
设置
WM_NORMAL_HINTS
属性;若
wm_hints
参数不为
NULL
,会调用
XSetWMHints
设置
WM_HINTS
属性。若
argv
参数不为
NULL
,会根据
argv
和
argc
设置
WM_COMMAND
属性。使用
XSetWMClientMachine
存储机器的主机名。若
class_hints
参数不为
NULL
,会设置
WM_CLASS
属性。可能会产生
BadAlloc
和
BadWindow
错误。
-
XSetWMProperties
函数
:
void XSetWMProperties(display, w, window_name, icon_name, argv, argc, normal_hints, wm_hints, class_hints);
该函数提供了一个单一的编程接口,用于设置与其他客户端(特别是窗口和会话管理器)通信时使用的基本窗口属性。其参数含义与
XmbSetWMProperties
类似。若
window_name
参数不为
NULL
,会调用
XSetWMName
设置
WM_NAME
属性;若
icon_name
参数不为
NULL
,会调用
XSetWMIconName
设置
WM_ICON_NAME
属性;若
argv
参数不为
NULL
,会调用
XSetCommand
设置
WM_COMMAND
属性。若
normal_hints
参数不为
NULL
,会调用
XSetWMNormalHints
设置
WM_NORMAL_HINTS
属性;若
wm_hints
参数不为
NULL
,会调用
XSetWMHints
设置
WM_HINTS
属性;若
class_hints
参数不为
NULL
,会调用
XSetClassHint
设置
WM_CLASS
属性。可能会产生
BadAlloc
和
BadWindow
错误。
以下是设置和读取属性的操作流程总结:
|操作|函数|可能产生的错误|
| ---- | ---- | ---- |
|设置
WM_CLASS
属性|
XSetClassHint
|
BadAlloc
、
BadWindow
|
|读取
WM_CLASS
属性|
XGetClassHint
|
BadWindow
|
|设置
WM_TRANSIENT_FOR
属性|
XSetTransientForHint
|
BadAlloc
、
BadWindow
|
|读取
WM_TRANSIENT_FOR
属性|
XGetTransientForHint
|
BadWindow
|
|设置
WM_PROTOCOLS
属性|
XSetWMProtocols
|
BadAlloc
、
BadWindow
|
|读取
WM_PROTOCOLS
属性|
XGetWMProtocols
|
BadWindow
|
|设置
WM_COLORMAP_WINDOWS
属性|
XSetWMColormapWindows
|
BadAlloc
、
BadWindow
|
|读取
WM_COLORMAP_WINDOWS
属性|
XGetWMColormapWindows
|
BadWindow
|
|设置
WM_ICON_SIZE
属性|
XSetIconSizes
|
BadAlloc
、
BadWindow
|
|读取
WM_ICON_SIZE
属性|
XGetIconSizes
|
BadWindow
|
mermaid 流程图展示设置属性的通用流程:
graph LR
A[开始] --> B[指定与 X 服务器的连接]
B --> C[指定窗口]
C --> D{选择属性类型}
D -->|WM_CLASS| E[设置 XClassHint 结构体]
D -->|WM_TRANSIENT_FOR| F[指定目标窗口]
D -->|WM_PROTOCOLS| G[指定协议列表和数量]
D -->|WM_COLORMAP_WINDOWS| H[指定窗口列表和数量]
D -->|WM_ICON_SIZE| I[指定尺寸列表和数量]
E --> J[调用相应设置函数]
F --> J
G --> J
H --> J
I --> J
J --> K{是否成功}
K -->|是| L[结束]
K -->|否| M[处理错误]
M --> L
跨客户端通信函数详解
8. 客户端与会话管理器通信
客户端与会话管理器之间的通信主要涉及设置和读取
WM_COMMAND
与
WM_CLIENT_MACHINE
属性。
8.1 设置和读取 WM_COMMAND 属性
Xlib 提供了用于设置和读取给定窗口
WM_COMMAND
属性的函数。
-
设置
WM_COMMAND
属性
:使用
XSetCommand
函数,代码如下:
XSetCommand(display, w, argv, argc);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `argv`:指定应用程序的参数列表。
- `argc`:指定参数数量。
该函数设置用于调用应用程序的命令和参数(通常
argv
是主程序的
argv
数组)。若字符串不在主机可移植字符编码中,结果将依赖于具体实现。此函数可能会产生
BadAlloc
和
BadWindow
错误。
-
读取
WM_COMMAND
属性
:使用
XGetCommand
函数,代码如下:
Status XGetCommand(display, w, argv_return, argc_return);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `argv_return`:返回应用程序的参数列表。
- `argc_return`:返回返回的参数数量。
该函数从指定窗口读取
WM_COMMAND
属性并返回字符串列表。若
WM_COMMAND
属性存在,其类型为
STRING
且格式为 8 位。若能分配足够的内存来包含字符串列表,函数会填充
argv_return
和
argc_return
参数并返回非零状态;否则返回零状态。若服务器返回的数据采用拉丁可移植字符编码,返回的字符串将采用主机可移植字符编码;否则,结果依赖于具体实现。使用
XFreeStringList
函数释放为字符串列表分配的内存。
8.2 设置和读取 WM_CLIENT_MACHINE 属性
Xlib 提供了用于设置和读取给定窗口
WM_CLIENT_MACHINE
属性的函数。
-
设置
WM_CLIENT_MACHINE
属性
:使用
XSetWMClientMachine
函数,代码如下:
void XSetWMClientMachine(display, w, text_prop);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `text_prop`:指定要使用的 `XTextProperty` 结构体。
该便利函数调用
XSetTextProperty
来设置
WM_CLIENT_MACHINE
属性。
-
读取
WM_CLIENT_MACHINE
属性
:使用
XGetWMClientMachine
函数,代码如下:
Status XGetWMClientMachine(display, w, text_prop_return);
- `display`:指定与 X 服务器的连接。
- `w`:指定窗口。
- `text_prop_return`:返回 `XTextProperty` 结构体。
该便利函数对
WM_CLIENT_MACHINE
属性执行
XGetTextProperty
操作。成功时返回非零状态,否则返回零状态。
以下是客户端与会话管理器通信相关操作的总结表格:
|操作|函数|可能产生的错误|
| ---- | ---- | ---- |
|设置
WM_COMMAND
属性|
XSetCommand
|
BadAlloc
、
BadWindow
|
|读取
WM_COMMAND
属性|
XGetCommand
|无明确错误提及,但可能因内存分配失败等返回零状态|
|设置
WM_CLIENT_MACHINE
属性|
XSetWMClientMachine
|无明确错误提及|
|读取
WM_CLIENT_MACHINE
属性|
XGetWMClientMachine
|无明确错误提及,但可能返回零状态表示失败|
mermaid 流程图展示客户端与会话管理器通信操作流程:
graph LR
A[开始] --> B[指定与 X 服务器的连接]
B --> C[指定窗口]
C --> D{选择操作类型}
D -->|设置 WM_COMMAND| E[指定参数列表和数量]
D -->|读取 WM_COMMAND| F[准备接收参数列表和数量的变量]
D -->|设置 WM_CLIENT_MACHINE| G[准备 XTextProperty 结构体]
D -->|读取 WM_CLIENT_MACHINE| H[准备接收 XTextProperty 结构体的变量]
E --> I[调用 XSetCommand]
F --> J[调用 XGetCommand]
G --> K[调用 XSetWMClientMachine]
H --> L[调用 XGetWMClientMachine]
I --> M{是否成功}
J --> M
K --> M
L --> M
M -->|是| N[结束]
M -->|否| O[处理错误]
O --> N
9. 总结与注意事项
在进行跨客户端通信时,需要注意以下几点:
-
内存管理
:使用
XAllocClassHint
、
XAllocIconSize
等函数分配内存后,记得使用
XFree
或
XFreeStringList
释放内存,避免内存泄漏。
-
字符编码
:许多函数对字符串的字符编码有要求,若字符串不在主机可移植字符编码中,结果可能依赖于具体实现。在使用时,要确保输入的字符串符合要求。
-
错误处理
:各个函数都可能产生不同的错误,如
BadAlloc
、
BadWindow
等。在调用函数后,要检查返回状态,及时处理错误,以保证程序的稳定性。
通过合理使用这些函数和结构体,开发者可以实现客户端之间、客户端与会话管理器之间的有效通信,为应用程序的开发和管理提供有力支持。
总之,掌握这些跨客户端通信函数和相关操作,对于开发基于 X 服务器的应用程序至关重要。开发者可以根据具体需求,灵活运用这些函数来实现各种功能。
超级会员免费看
1877

被折叠的 条评论
为什么被折叠?



