在 X11 中获取 window 属性 长度的惯用方法?

Idiomatic way to get the length of a window property in X11?

我昨天才开始学习X11,很难找到有关它的资料。

我希望能够检索 X11 window 的 UTF-8 标题 _NET_WM_NAME。问题是您应该使用长度参数调用它。我目前的解决方案包括首先使用 XGetWindowProperty 和 0 长度参数检索字符串的长度,然后使用 length.[=17 的 bytes_after_return 信息再次调用 XGetWindowProperty =]

问题是这涉及到两次分配和释放。我不是一个超级高级的程序员,但这可能不太好,对吧?虽然在实践中为获得 window 称号这样的小事和不常见的事情进行两次分配可能不会有太大的不同,但我到处都听到仍然应该避免不必要的分配和释放。

这是我的代码:

Atom actualType;
int actualFormat;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char* prop;

XGetWindowProperty(
    display, 
    window,
    _NET_WM_NAME,
    0UL,
    0UL,
    False,
    UTF8_STRING,
    &actualType,
    &actualFormat,
    &nItems,
    &bytesAfter,
    &prop
);

XFree(prop);

XGetWindowProperty(
    display, 
    window,
    _NET_WM_NAME,
    0UL,
    (bytesAfter + 3UL) / 4UL, // Divide by four and round up
    False,
    UTF8_STRING,
    &actualType,
    &actualFormat,
    &nItems,
    &bytesAfter,
    &prop
);

printf("title: %s", prop);

XFree(prop);

有更好的方法吗?

另一种解决方案是每次设置标题时都存储它,但我不确定是否有可能使保存的标题和实际标题不同步。

谢谢大家 <3

如果不可避免,多次分配并没有错,而且对于大量数据,您可能无论如何都需要这样做。请求合理数量的字节并根据需要使用循环处理传入数据,利用偏移参数指定继续读取的位置。如果 4*length 大于 return 的数据量,那么它只会 return 必要的数据量,所以你不需要担心使用 return 来计算正确的长度=12=]参数:

Atom actualType;
int actualFormat;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char* prop;

// specify length as number of bytes divided by 4
#define MB (1048576)
long length = (64 * MB) / 4;

printf("title: ");
for (long offset = 0;; offset += length) {

    XGetWindowProperty(
        display,
        window,
        _NET_WM_NAME,
        offset,
        length,
        False,
        UTF8_STRING,
        &actualType,
        &actualFormat,
        &nItems,
        &bytesAfter,
        &prop
    );

    printf("%s", prop);
    XFree(prop);
    if (bytesAfter == 0)
        break;
}

当然你可以请求更多的数据,如果你愿意的话,根据需要在bytesAfter的基础上调整length,这样做确实更有效,因为需要更少的request/response周期,没关系分配。但是,有时要处理的数据太多,这就是您可能仍需要循环的原因。如果您使用 XConvertSelection 并且需要处理 INCR 属性 则尤其如此,因为这意味着显示服务器要发送大量数据。