I have the following code:
static Atom _NET_WM_NAME = XInternAtom( display, "_NET_WM_NAME", false );
unsigned char* wm_data = NULL;
Atom wm_type;
int wm_format;
unsigned long wm_nitems, wm_bytes;
std::string title;
int ret = XGetWindowProperty( display, window, _NET_WM_NAME, 0, 512,
false, utf8_string, &wm_type, &wm_format, &wm_nitems, &wm_bytes, &wm_data);
if( ret == Success && wm_nitems != 0 && wm_data != NULL ) {
title = (const char*)wm_data; // [1]
}
The _NET_WM_NAME
property is a UTF8_STRING
, as per the spec
So, in my code above, [1]
assumes that the received data will always be NULL terminated.
The code as it is works, but the returned byte amount (wm_nitems
) does not include the NULL terminator, it is always the same as the actual string length. This is what makes me uncertain.
So my questions are:
UTF8_STRING
property will always return the string INCLUDING the NULL terminator?wm_nitems
count?_NET_WM_NAME
property?"XGetWindowProperty() always allocates one extra byte in prop_return (even if the property is zero length) and sets it to zero so that simple properties consisting of characters do not have to be copied into yet another string before use."
wm_nitems
nitems_return
: Returns the actual number of 8-bit, 16-bit, or 32-bit items stored in the prop_return data
Why should the null terminator count as data. It is the courtesy of XGetWindowProperty
to automagically return a null terminated string (see above), but the nul
character is not part of the actual data (e.g., it is absolutely possible to set the window name without an ending nul
char).
To put it differently: strlen
doesn't count the terminating null character either, right?
Another thing, C strings are null terminated character arrays. The symbol NULL
is the null pointer and has a special meaning in the C environment (see: https://en.cppreference.com/w/c/types/NULL).
'\0'
is of type char
NULL
is of type void*
(implementation-defined, could also be 0
)