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:
- Is guaranteed that a read of a
UTF8_STRING
property will always return the string INCLUDING the NULL terminator? - If so, why is the NULL terminator not included as part of the
wm_nitems
count? - Can somebody point where this is specified in the spec?
- And in particular, is the above snippet correct for reading the
_NET_WM_NAME
property?
XGetWindowProperty
wm_nitems
Why should the null terminator count as data. It is the courtesy of
XGetWindowProperty
to automagically return a null terminated string (see above), but thenul
character is not part of the actual data (e.g., it is absolutely possible to set the window name without an endingnul
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 typechar
NULL
is of typevoid*
(implementation-defined, could also be0
)