Files
.github
AnyEvent-I3
contrib
debian
docs
etc
i3-config-wizard
i3-dump-log
i3-input
i3-msg
i3-nagbar
i3bar
include
libi3
README
boolstr.c
create_socket.c
dpi.c
draw_util.c
fake_configure_notify.c
font.c
format_placeholders.c
g_utf8_make_valid.c
get_colorpixel.c
get_config_path.c
get_exe_path.c
get_mod_mask.c
get_process_filename.c
get_visualtype.c
ipc_connect.c
ipc_recv_message.c
ipc_send_message.c
is_background_set.c
is_debug_build.c
mkdirp.c
nonblock.c
path_exists.c
resolve_tilde.c
root_atom_contents.c
safewrappers.c
screenshot_wallpaper.c
string.c
strndup.c
ucs2_conversion.c
man
meson
parser-specs
release-notes
share
src
testcases
travis
.clang-format
.dockerignore
.editorconfig
.gitignore
DEPENDS
I3_VERSION
LICENSE
PACKAGE-MAINTAINER
README.md
RELEASE-NOTES-4.22
generate-command-parser.pl
i3-dmenu-desktop
i3-migrate-config-to-v4
i3-save-tree
i3-sensible-editor
i3-sensible-pager
i3-sensible-terminal
logo.svg
meson.build
meson_options.txt
pseudo-doc.doxygen
release.sh
i3/libi3/root_atom_contents.c
2020-04-20 04:25:06 +02:00

93 lines
3.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
*/
#include "libi3.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
/*
* Try to get the contents of the given atom (for example I3_SOCKET_PATH) from
* the X11 root window and return NULL if it doesnt work.
*
* If the provided XCB connection is NULL, a new connection will be
* established.
*
* The memory for the contents is dynamically allocated and has to be
* free()d by the caller.
*
*/
char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, int screen) {
xcb_intern_atom_cookie_t atom_cookie;
xcb_intern_atom_reply_t *atom_reply;
char *content = NULL;
size_t content_max_words = 256;
xcb_connection_t *conn = provided_conn;
if (provided_conn == NULL &&
((conn = xcb_connect(NULL, &screen)) == NULL ||
xcb_connection_has_error(conn))) {
return NULL;
}
atom_cookie = xcb_intern_atom(conn, 0, strlen(atomname), atomname);
xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen);
xcb_window_t root = root_screen->root;
atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
if (atom_reply == NULL) {
goto out_conn;
}
xcb_get_property_cookie_t prop_cookie;
xcb_get_property_reply_t *prop_reply;
prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
if (prop_reply == NULL) {
goto out_atom;
}
if (xcb_get_property_value_length(prop_reply) > 0 && prop_reply->bytes_after > 0) {
/* We received an incomplete value. Ask again but with a properly
* adjusted size. */
content_max_words += ceil(prop_reply->bytes_after / 4.0);
/* Repeat the request, with adjusted size */
free(prop_reply);
prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
if (prop_reply == NULL) {
goto out_atom;
}
}
if (xcb_get_property_value_length(prop_reply) == 0) {
goto out;
}
if (prop_reply->type == XCB_ATOM_CARDINAL) {
/* We treat a CARDINAL as a >= 32-bit unsigned int. The only CARDINAL
* we query is I3_PID, which is 32-bit. */
sasprintf(&content, "%u", *((unsigned int *)xcb_get_property_value(prop_reply)));
} else {
sasprintf(&content, "%.*s", xcb_get_property_value_length(prop_reply),
(char *)xcb_get_property_value(prop_reply));
}
out:
free(prop_reply);
out_atom:
free(atom_reply);
out_conn:
if (provided_conn == NULL)
xcb_disconnect(conn);
return content;
}