我昨天刚开始学习X11,我很难找到有关它的信息。
我希望能够检索X11窗口的UTF-8标题_NET_WM_NAME。问题是您应该使用length参数来调用它。我当前的解决方案包括首先使用长度参数为0的XGetWindowProperty
检索字符串的长度,然后使用XGetWindowProperty
的bytes_after_return
信息再次调用length
。
问题是,这涉及两个分配和释放。我不是一个超高级的程序员,但这可能不好,对吗?在实践中,虽然为小而不常见的事情(例如获得窗口标题)分配了两次分配可能不会有太大的区别,但我到处都听到应该避免不必要的分配和释放。
这是我的代码:
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);
有更好的方法吗?
另一种解决方案是每次设置标题时都存储该标题,但是我不确定保存的标题与实际标题是否可能不同步。
感谢ppl <3
如果不可避免,则多次分配没有错,对于大量数据,您可能仍然需要这样做。请求合理数量的字节,并根据需要使用循环处理传入的数据,利用offset参数指定从何处继续读取。如果4*length
大于要返回的数据量,那么它将仅返回必要的数据量,因此您不必担心使用bytesAfter
参数计算正确的长度:
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;
}
当然,如果需要,您可以请求更多的数据,根据需要根据length
调整bytesAfter
,并且这样做的确确实有效,因为需要的请求/响应周期更少,无需考虑分配。但是,有时要处理的数据太多,这就是为什么您可能仍需要循环的原因。如果您使用XConvertSelection
并需要处理INCR属性,则尤其如此,因为这意味着显示服务器要发送大量数据。