From 307a036d5cdff4c191fd9134be153e4c2d03300e Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 19 Mar 2011 21:23:55 +0100 Subject: [PATCH] i3-msg, i3-input: get the I3_SOCKET_PATH atoms if socket path was not specified --- i3-input/main.c | 49 ++++++++++++++++++++++++++++++++++++++++---- i3-msg/main.c | 54 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/i3-input/main.c b/i3-input/main.c index ea1e6132..fb2635a2 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ #include "i3-input.h" +static char *socket_path; static int sockfd; static xcb_key_symbols_t *symbols; static int modeswitchmask; @@ -52,6 +54,42 @@ static int prompt_len; static int limit; xcb_window_t root; +/* + * Try to get the socket path from X11 and return NULL if it doesn’t work. + * As i3-msg is a short-running tool, we don’t bother with cleaning up the + * connection and leave it up to the operating system on exit. + * + */ +static char *socket_path_from_x11() { + xcb_connection_t *conn; + int screen; + if ((conn = xcb_connect(NULL, &screen)) == NULL || + xcb_connection_has_error(conn)) + return NULL; + xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen); + xcb_window_t root = root_screen->root; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + atom_cookie = xcb_intern_atom(conn, 0, strlen("I3_SOCKET_PATH"), "I3_SOCKET_PATH"); + atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL); + if (atom_reply == NULL) + return NULL; + + 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, PATH_MAX); + prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL); + if (prop_reply == NULL || xcb_get_property_value_length(prop_reply) == 0) + return NULL; + if (asprintf(&socket_path, "%.*s", xcb_get_property_value_length(prop_reply), + (char*)xcb_get_property_value(prop_reply)) == -1) + return NULL; + return socket_path; +} + /* * Concats the glyphs (either UCS-2 or UTF-8) to a single string, suitable for * rendering it (UCS-2) or sending it to i3 (UTF-8). @@ -242,10 +280,7 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press } int main(int argc, char *argv[]) { - char *socket_path; - if ((socket_path = getenv("I3SOCK")) == NULL) { - socket_path = "/tmp/i3-ipc.sock"; - } + socket_path = getenv("I3SOCK"); char *pattern = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1"; int o, option_index = 0; @@ -293,6 +328,12 @@ int main(int argc, char *argv[]) { } } + if (socket_path == NULL) + socket_path = socket_path_from_x11(); + + if (socket_path == NULL) + socket_path = "/tmp/i3-ipc.sock"; + sockfd = connect_ipc(socket_path); if (prompt != NULL) diff --git a/i3-msg/main.c b/i3-msg/main.c index c6862fae..ee4de078 100644 --- a/i3-msg/main.c +++ b/i3-msg/main.c @@ -27,9 +27,51 @@ #include #include #include +#include + +#include +#include #include +static char *socket_path; + +/* + * Try to get the socket path from X11 and return NULL if it doesn’t work. + * As i3-msg is a short-running tool, we don’t bother with cleaning up the + * connection and leave it up to the operating system on exit. + * + */ +static char *socket_path_from_x11() { + xcb_connection_t *conn; + int screen; + if ((conn = xcb_connect(NULL, &screen)) == NULL || + xcb_connection_has_error(conn)) + return NULL; + xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen); + xcb_window_t root = root_screen->root; + + xcb_intern_atom_cookie_t atom_cookie; + xcb_intern_atom_reply_t *atom_reply; + + atom_cookie = xcb_intern_atom(conn, 0, strlen("I3_SOCKET_PATH"), "I3_SOCKET_PATH"); + atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL); + if (atom_reply == NULL) + return NULL; + + 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, PATH_MAX); + prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL); + if (prop_reply == NULL || xcb_get_property_value_length(prop_reply) == 0) + return NULL; + if (asprintf(&socket_path, "%.*s", xcb_get_property_value_length(prop_reply), + (char*)xcb_get_property_value(prop_reply)) == -1) + return NULL; + return socket_path; +} + /* * Formats a message (payload) of the given size and type and sends it to i3 via * the given socket file descriptor. @@ -107,10 +149,7 @@ static void ipc_recv_message(int sockfd, uint32_t message_type, } int main(int argc, char *argv[]) { - char *socket_path; - if ((socket_path = getenv("I3SOCK")) == NULL) { - socket_path = strdup("/tmp/i3-ipc.sock"); - } + socket_path = getenv("I3SOCK"); int o, option_index = 0; int message_type = I3_IPC_MESSAGE_TYPE_COMMAND; char *payload = ""; @@ -158,6 +197,13 @@ int main(int argc, char *argv[]) { } } + if (socket_path == NULL) + socket_path = socket_path_from_x11(); + + /* Fall back to the default socket path */ + if (socket_path == NULL) + socket_path = strdup("/tmp/i3-ipc.sock"); + if (optind < argc) payload = argv[optind];