环境:Ubuntu 16.04
在我的应用程序中,我通过使用XGetWindowProperty
atom调用_NET_WM_ICON
来获取应用程序的图标。
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
根据规范,返回的图像必须采用打包的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位长,因此填充。
至于为什么填充位都设置为1
而不是0
,我不太确定。手册页中的函数签名显示了unsigned char **prop_return
,但上面引用的文字说它是一个“longs数组”,而不是“unsigned longs数组”,所以这可能是字面意思(或者字面意思是您正在检索其图标的应用程序的作者),并且在您的应用程序接收数据之前的某个位置发生了一些符号扩展。