Xlib应用实用函数详解
1. 重绑定KeySym含义
在处理键盘输入时,有时需要重绑定
KeySym
的含义,这时可以使用
XRebindKeysym
函数。
1.1 函数原型
XRebindKeysym(Display *display, KeySym keysym, KeySym list[], int mod_count, char *string, int num_bytes);
1.2 参数说明
| 参数 | 说明 |
|---|---|
display
| 指定与X服务器的连接 |
keysym
|
指定要重绑定的
KeySym
|
list
|
指定用作修饰符的
KeySym
数组
|
mod_count
| 指定修饰符列表中的修饰符数量 |
string
|
指定要复制并由
XLookupString
返回的字符串
|
num_bytes
|
指定
string
参数中的字节数
|
1.3 功能说明
该函数用于为客户端重绑定
KeySym
的含义,它不会在X服务器中重新定义任何键,只是提供了一种将长字符串与键关联的简便方法。当按下适当的修饰键组合,并且原本会使用该
KeySym
进行转换时,
XLookupString
将返回此字符串。需要注意的是,不会进行文本转换,客户端负责提供适当编码的字符串,并且可以重绑定可能不存在的
KeySym
。
2. 分配永久存储
在某些情况下,需要分配一些在程序生命周期内永远不会释放的内存,这时可以使用
Xpermalloc
函数。
2.1 函数原型
char *Xpermalloc(size_t size);
2.2 功能说明
该函数分配的存储在程序的整个生命周期内都无法释放,内存分配时会按照C类型
double
进行对齐。与标准操作系统内存分配器相比,此函数可能会节省一些性能和空间。
3. 解析窗口几何信息
在X应用程序中,通常使用标准字符串来表示窗口的大小和位置,
XParseGeometry
函数可以帮助我们解析这些标准窗口几何字符串。
3.1 函数原型
int XParseGeometry(const char *parsestring, int *x_return, int *y_return, unsigned int *width_return, unsigned int *height_return);
3.2 参数说明
| 参数 | 说明 |
|---|---|
parsestring
| 指定要解析的字符串 |
x_return
| 返回x偏移量 |
y_return
| 返回y偏移量 |
width_return
| 返回确定的宽度 |
height_return
| 返回确定的高度 |
3.3 支持的字符串格式
该函数可以解析以下形式的字符串:
[=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]
其中,
<>
内的项为整数,
[]
内的项为可选,
{}
表示“选择其中一个”。实际字符串中不应包含括号。
3.4 返回值
函数返回一个位掩码,指示在字符串中实际找到的四个值(宽度、高度、x偏移量和y偏移量),以及x和y值是否为负。对于找到的每个值,相应的参数会被更新;对于未找到的值,参数保持不变。这些位由
XValue
、
YValue
、
WidthValue
、
HeightValue
、
XNegative
或
YNegative
表示,定义在
<X11/Xutil.h>
中。
3.5 示例
graph TD;
A[输入字符串] --> B{是否符合格式};
B -- 是 --> C[解析各值];
B -- 否 --> D[实现依赖结果];
C --> E[更新对应参数];
E --> F[返回位掩码];
4. 构建窗口几何信息
XWMGeometry
函数用于结合用户指定的几何信息和调用程序的默认几何信息,以及大小提示,返回描述窗口的位置、大小和重力信息。
4.1 函数原型
int XWMGeometry(Display *display, int screen, const char *user_geom, const char *def_geom, unsigned int bwidth, XSizeHints *hints, int *x_return, int *y_return, unsigned int *width_return, unsigned int *height_return, int *gravity_return);
4.2 参数说明
| 参数 | 说明 |
|---|---|
display
| 指定与X服务器的连接 |
screen
| 指定屏幕 |
user_geom
|
指定用户指定的几何信息或
NULL
|
def_geom
|
指定应用程序的默认几何信息或
NULL
|
bwidth
| 指定边框宽度 |
hints
| 指定窗口正常状态下的大小提示 |
x_return
| 返回x偏移量 |
y_return
| 返回y偏移量 |
width_return
| 返回确定的宽度 |
height_return
| 返回确定的高度 |
gravity_return
| 返回窗口重力 |
4.3 功能说明
该函数会根据用户和程序指定的几何信息以及大小提示,计算窗口的最终位置、大小和重力。如果
XSizeHints
结构中未设置基本大小,则使用最小大小(如果设置了);否则,假设基本大小为零。如果提示结构中未设置最小大小,则使用基本大小。函数还会返回一个掩码,描述哪些值来自用户指定,以及位置坐标是否相对于右侧或底部边缘。需要注意的是,无效的几何指定可能会导致返回宽度或高度为零。调用者可以将提示的
win_gravity
字段的地址作为
gravity_return
传递,以直接更新提示。
5. 操作区域
区域是任意的像素位置集合,Xlib提供了一系列函数来操作区域。
5.1 创建、复制或销毁区域
5.1.1 创建新的空区域
Region XCreateRegion();
5.1.2 从多边形生成区域
Region XPolygonRegion(XPoint points[], int n, int fill_rule);
参数说明:
| 参数 | 说明 |
| ---- | ---- |
|
points
| 指定点的数组 |
|
n
| 指定多边形中的点数 |
|
fill_rule
| 指定要为指定GC设置的填充规则,可以传递
EvenOddRule
或
WindingRule
|
5.1.3 设置GC的剪辑掩码为区域
XSetRegion(Display *display, GC gc, Region r);
5.1.4 释放指定区域的存储
XDestroyRegion(Region r);
5.2 移动或缩小区域
5.2.1 按指定量移动区域
XOffsetRegion(Region r, int dx, int dy);
5.2.2 按指定量缩小区域
XShrinkRegion(Region r, int dx, int dy);
正数会缩小区域大小,负数会扩大区域。
5.3 区域计算
5.3.1 生成包围区域的最小矩形
XClipBox(Region r, XRectangle *rect_return);
5.3.2 计算两个区域的交集
XIntersectRegion(Region sra, Region srb, Region *dr_return);
5.3.3 计算两个区域的并集
XUnionRegion(Region sra, Region srb, Region *dr_return);
5.3.4 创建源区域和矩形的并集
XUnionRectWithRegion(XRectangle rectangle, Region src_region, Region *dest_region_return);
5.3.5 减去两个区域
XSubtractRegion(Region sra, Region srb, Region *dr_return);
5.3.6 计算两个区域的并集和交集之差
XXorRegion(Region sra, Region srb, Region *dr_return);
5.4 判断区域是否为空或相等
5.4.1 判断指定区域是否为空
Bool XEmptyRegion(Region r);
5.4.2 判断两个区域是否具有相同的偏移、大小和形状
Bool XEqualRegion(Region r1, Region r2);
5.5 在区域中定位点或矩形
5.5.1 判断指定点是否位于指定区域内
Bool XPointInRegion(Region r, int x, int y);
5.5.2 判断指定矩形是否在区域内
int XRectInRegion(Region r, int x, int y, unsigned int width, unsigned int height);
返回值:
-
RectangleIn
:矩形完全在指定区域内
-
RectangleOut
:矩形完全在指定区域外
-
RectanglePart
:矩形部分在指定区域内
6. 使用剪切缓冲区
Xlib提供了操作剪切缓冲区的函数,剪切缓冲区是一种非常简单的客户端间复制粘贴通信形式,但通常建议使用更强大和有用的选择机制来进行客户端间的数据交换。
6.1 存储数据到剪切缓冲区
6.1.1 存储数据到剪切缓冲区0
XStoreBytes(Display *display, const char *bytes, int nbytes);
6.1.2 存储数据到指定剪切缓冲区
XStoreBuffer(Display *display, const char *bytes, int nbytes, int buffer);
6.2 从剪切缓冲区获取数据
6.2.1 从剪切缓冲区0返回数据
char *XFetchBytes(Display *display, int *nbytes_return);
6.2.2 从指定剪切缓冲区返回数据
char *XFetchBuffer(Display *display, int *nbytes_return, int buffer);
6.3 旋转剪切缓冲区
XRotateBuffers(Display *display, int rotate);
该函数会旋转剪切缓冲区,例如缓冲区0变为缓冲区
n
,缓冲区1变为
n + 1 mod 8
等。需要注意的是,如果八个缓冲区中的任何一个未创建,
XRotateBuffers
会生成
BadMatch
错误。
7. 确定合适的视觉类型
一个显示器可以支持多个屏幕,每个屏幕可以在不同深度支持多种不同的视觉类型。可以使用以下函数来确定应用程序应使用的视觉类型。
7.1 视觉信息掩码和
XVisualInfo
结构
视觉信息掩码和
XVisualInfo
结构定义在
<X11/Xutil.h>
中,
XVisualInfo
结构包含以下成员:
/* Visual information mask bits */
#define VisualNoMask 0x0
#define VisualIDMask 0x1
#define VisualScreenMask 0x2
#define VisualDepthMask 0x4
#define VisualClassMask 0x8
#define VisualRedMaskMask 0x10
#define VisualGreenMaskMask 0x20
#define VisualBlueMaskMask 0x40
#define VisualColormapSizeMask 0x80
#define VisualBitsPerRGBMask 0x100
#define VisualAllMask 0x1FF
/* Values */
typedef struct {
Visual *visual;
VisualID visualid;
int screen;
unsigned int depth;
int class;
unsigned long red_mask;
unsigned long green_mask;
unsigned long blue_mask;
int colormap_size;
int bits_per_rgb;
} XVisualInfo;
7.2 获取匹配指定模板的视觉信息结构列表
XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return);
该函数返回具有与
vinfo_template
指定的属性相等的视觉结构列表。如果使用指定的
vinfo_mask
没有视觉结构与模板匹配,则返回
NULL
。使用
XFree
释放该函数返回的数据。
7.3 获取匹配指定屏幕深度和类别的视觉信息
Status XMatchVisualInfo(Display *display, int screen, unsigned int depth, int class, XVisualInfo *vinfo_return);
该函数返回与指定屏幕的深度和类别匹配的视觉信息。由于可能存在多个匹配的视觉,因此选择的确切视觉是未定义的。如果找到视觉,返回非零值并将视觉信息存储在
vinfo_return
中;否则返回零。
8. 操作图像
Xlib提供了几个对图像执行基本操作的函数,所有图像操作都使用
XImage
结构定义,该结构定义在
<X11/Xlib.h>
中。
8.1 创建
XImage
结构
XImage *XCreateImage(Display *display, Visual *visual, unsigned int depth, int format, int offset, char *data, unsigned int width, unsigned int height, int bitmap_pad, int bytes_per_line);
参数说明:
| 参数 | 说明 |
| ---- | ---- |
|
display
| 指定与X服务器的连接 |
|
visual
| 指定
Visual
结构 |
|
depth
| 指定图像的深度 |
|
format
| 指定图像的格式,可以传递
XYBitmap
、
XYPixmap
或
ZPixmap
|
|
offset
| 指定扫描线开始处要忽略的像素数 |
|
data
| 指定图像数据 |
|
width
| 指定图像的宽度(以像素为单位) |
|
height
| 指定图像的高度(以像素为单位) |
|
bitmap_pad
| 指定扫描线的量子(8、16或32) |
|
bytes_per_line
| 指定客户端图像中一条扫描线开始到下一条扫描线开始之间的字节数 |
该函数为指定的显示器分配
XImage
结构所需的内存,但不分配图像本身的空间。它会从显示器初始化结构的字节顺序、位顺序和位图单元值,并返回指向
XImage
结构的指针。对于Z格式图像,红色、绿色和蓝色掩码值是从传入的
Visual
结构派生的。如果
bytes_per_line
传递零值,Xlib假设扫描线在内存中是连续的,并自行计算
bytes_per_line
的值。
8.2 获取和设置像素值
8.2.1 获取图像中的像素值
unsigned long XGetPixel(XImage *ximage, int x, int y);
8.2.2 设置图像中的像素值
XPutPixel(XImage *ximage, int x, int y, unsigned long pixel);
需要注意的是,输入和返回的像素值必须是规范化格式(即长整型的最低有效字节是像素的最低有效字节),并且图像必须包含指定的x和y坐标。
通过以上这些函数,我们可以在Xlib环境中完成各种窗口管理、区域操作、图像操作等任务,为开发X应用程序提供了强大的支持。在实际使用中,需要根据具体需求选择合适的函数,并注意函数的参数和返回值的含义。
9. 图像操作进阶
9.1 图像的获取与放置
基本的获取和放置图像的函数是
XGetImage
和
XPutImage
,不过原文未详细给出它们的函数原型。但我们知道,
XGetImage
用于从服务器获取图像到客户端内存中的
XImage
结构,
XPutImage
则将客户端内存中的
XImage
结构图像发送到服务器进行显示。
9.2 图像结构的特点
XImage
结构描述了客户端内存中的图像。用户可以在图像发送到服务器时请求更改其某些成员,如高度、宽度和x偏移量。
bytes_per_line
与偏移量配合使用,可以提取图像的子集。其他成员(如字节顺序、位图单元等)是图像和服务器的特性,如果图像和服务器的这些成员不同,
XPutImage
会进行适当的转换。
下面是一个简单的操作图像步骤列表:
1. 使用
XCreateImage
创建
XImage
结构。
2. 根据需要使用
XGetPixel
和
XPutPixel
操作像素。
3. 使用
XPutImage
将图像发送到服务器显示。
9.3 图像操作注意事项
目前还没有定义用于从磁盘文件读写图像的函数。当使用
XCreateImage
、
XGetImage
或
XSubImage
创建图像时,
XDestroyImage
函数会释放图像结构和图像结构指向的数据。
10. 区域操作总结
10.1 区域操作流程
可以用以下mermaid流程图来总结区域操作的主要流程:
graph LR;
A[创建区域] --> B{选择操作};
B -- 移动 --> C[XOffsetRegion];
B -- 缩小 --> D[XShrinkRegion];
B -- 计算 --> E{计算类型};
E -- 交集 --> F[XIntersectRegion];
E -- 并集 --> G[XUnionRegion];
E -- 差集 --> H[XSubtractRegion];
E -- 异或 --> I[XXorRegion];
B -- 判断 --> J{判断类型};
J -- 为空 --> K[XEmptyRegion];
J -- 相等 --> L[XEqualRegion];
B -- 定位 --> M{定位类型};
M -- 点 --> N[XPointInRegion];
M -- 矩形 --> O[XRectInRegion];
B -- 销毁 --> P[XDestroyRegion];
10.2 区域操作的用途
区域操作在图形处理中非常有用,例如裁剪、碰撞检测等。通过创建、移动、计算区域等操作,可以精确地控制图形的显示范围和交互。
11. 剪切缓冲区使用要点
11.1 剪切缓冲区的局限性
剪切缓冲区只能包含
STRING
编码的文本,并且文本编码在获取或存储时不会被Xlib更改。虽然它提供了一种简单的客户端间复制粘贴通信方式,但与选择机制相比,功能较弱,一般建议优先使用选择机制进行客户端间的数据交换。
11.2 剪切缓冲区操作示例
以下是一个简单的使用剪切缓冲区存储和获取数据的步骤示例:
1. 存储数据到剪切缓冲区:
- 使用
XStoreBytes
存储数据到剪切缓冲区0。
- 使用
XStoreBuffer
存储数据到指定剪切缓冲区。
2. 从剪切缓冲区获取数据:
- 使用
XFetchBytes
从剪切缓冲区0返回数据。
- 使用
XFetchBuffer
从指定剪切缓冲区返回数据。
3. 旋转剪切缓冲区:使用
XRotateBuffers
旋转剪切缓冲区。
11.3 错误处理
XStoreBytes
和
XStoreBuffer
可能会生成
BadAlloc
错误,
XRotateBuffers
如果八个缓冲区中的任何一个未创建,会生成
BadMatch
错误。在使用这些函数时,需要进行适当的错误处理。
12. 视觉类型选择指南
12.1 选择视觉类型的步骤
选择合适的视觉类型可以按照以下步骤进行:
1. 定义
XVisualInfo
结构和视觉信息掩码。
2. 使用
XGetVisualInfo
获取匹配指定模板的视觉信息结构列表。
3. 如果已知屏幕的深度和类别,使用
XMatchVisualInfo
获取匹配的视觉信息。
12.2 视觉类型选择的重要性
选择合适的视觉类型对于应用程序的显示效果至关重要。不同的视觉类型在颜色深度、颜色模式等方面可能存在差异,选择不当可能会导致显示效果不佳。
13. 总结
13.1 函数总结表格
| 功能分类 | 函数名称 | 作用 |
|---|---|---|
| 重绑定KeySym |
XRebindKeysym
|
为客户端重绑定
KeySym
的含义
|
| 内存分配 |
Xpermalloc
| 分配永久存储的内存 |
| 窗口几何解析 |
XParseGeometry
| 解析标准窗口几何字符串 |
| 窗口几何构建 |
XWMGeometry
| 结合多种信息构建窗口几何信息 |
| 区域操作 |
XCreateRegion
、
XPolygonRegion
等
| 创建、操作和判断区域 |
| 剪切缓冲区操作 |
XStoreBytes
、
XFetchBytes
等
| 存储、获取和旋转剪切缓冲区数据 |
| 视觉类型选择 |
XGetVisualInfo
、
XMatchVisualInfo
| 获取匹配的视觉信息 |
| 图像操作 |
XCreateImage
、
XGetPixel
等
| 创建和操作图像 |
13.2 实际应用建议
在实际开发中,要根据具体需求选择合适的函数。例如,在处理键盘输入时使用
XRebindKeysym
重绑定
KeySym
;在进行图形裁剪时使用区域操作函数;在需要永久存储数据时使用
Xpermalloc
。同时,要注意函数的参数和返回值的含义,以及可能出现的错误情况,进行适当的错误处理。通过合理使用这些函数,可以提高开发效率,实现更强大的X应用程序。
超级会员免费看
3

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



