_NET_WM_ICON 的图片格式

Picture format for _NET_WM_ICON

环境:Ubuntu16.04

在我的应用程序中,我通过使用 _NET_WM_ICON 原子调用 XGetWindowProperty 来获取应用程序的图标。

unsigned char* data;
XGetWindowProperty(..., &data);
unsigned long* data1 = (unsigned long*) data;
long width = *data1;
long height = *(data1 + 1)
unsigned char* imageData = (unsigned char*) (data1 + 2);

返回数据的规格如下:

https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm140130317554480

根据规范,返回的图像必须是 packed-32 ARGB 格式。但是,我得到的图像似乎不正确。我终于用我自己的图标创建了一个测试应用程序。为实心图标,RGB值分别为0x20、0x40、0x80

当我在调试器中检查我的变量 imageData 时,这是我看到的:

0x80, 0x40, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff (repeat the pattern)

格式似乎是 BGRA,额外填充了四个字节。

如果有人能解释这种差异,我将不胜感激。问候。

我已经确认格式确实是 BGRA,带有四个额外的填充字节。我枚举了所有 运行 应用程序并能够正确提取图标。

来自 CentOS 7 的 XGetWindowProperty(3) 手册页,这是指您为其传递参数的参数 data:

       prop_return
                 Returns the data in the specified format.  If the returned
                 format is 8, the returned data is represented as a char
                 array. If the returned format is 16, the returned data is
                 represented as a array of short int type and should be cast
                 to that type to obtain the elements. If the returned format
                 is 32, the property data will be stored as an array of longs
                 (which in a 64-bit application will be 64-bit values that are
                 padded in the upper 4 bytes).

我假设您会发现 actual_format_return 是 32(因为规范似乎表明这是 _NET_WM_ICON 的唯一有效格式),并且您的应用程序可能是 64 位的,这意味着您的 long 类型是 64 位长,因此填充。

至于为什么padding bits都设置为1而不是0,我不是很清楚。手册页中的函数签名显示 unsigned char **prop_return,但上面引用的文本说它是 "array of longs",而不是 "an array of unsigned longs",所以这可能是为了按字面意思理解(或被理解为字面意思是您正在检索其图标的应用程序的作者),并且在您的应用程序接收数据之前某处发生了一些符号扩展。