问题
Environment: Ubuntu 16.04
In my app, I get an application's icon by calling XGetWindowProperty
with _NET_WM_ICON
atom.
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);
Here are the specs for the returned data:
https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm140130317554480
According to the specs, the returned image must be in packed-32 ARGB format. However, the image I was getting did not seem right. I finally created a test application with my own icon. It is a solid icon with RGB value of 0x20, 0x40, and 0x80 respectively.
When I examine my variable imageData
in the debugger, here is what I see:
0x80, 0x40, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff (repeat the pattern)
It appears the format is BGRA with extra four bytes of padding.
I would appreciate it if anyone can explain this discrepancy. Regards.
回答1:
I have confirmed that the format is indeed BGRA with four extra bytes of padding. I enumerated through all the running applications and was able to extract the icons properly.
回答2:
From the XGetWindowProperty(3)
man page on CentOS 7, this refers to the parameter for which you're passing the argument 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).
I assume you'd find that the actual_format_return
is 32 (since the specification seems to indicate that this is the only valid format for _NET_WM_ICON
), and presumably your application is 64-bit, meaning that your long
type is 64 bits long, hence the padding.
As for why the padding bits are all set to 1
instead of 0
, I'm not so sure. The function signature in the man page shows unsigned char **prop_return
, but the text quoted above says that it is an "array of longs", not "an array of unsigned longs", so perhaps this is intended to be taken literally (or was taken literally by the author of the application whose icon you are retrieving), and some sign extension has taken place somewhere prior to your application receiving the data.
来源:https://stackoverflow.com/questions/43237104/picture-format-for-net-wm-icon