4

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Peter
  • 11,260
  • 14
  • 78
  • 155

2 Answers2

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.

doshea
  • 1,567
  • 1
  • 11
  • 12
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.

Peter
  • 11,260
  • 14
  • 78
  • 155