i3-msg, i3-input: get the I3_SOCKET_PATH atoms if socket path was not specified

next
Michael Stapelberg 2011-03-19 21:23:55 +01:00
parent 65a3259b3c
commit 307a036d5c
2 changed files with 95 additions and 8 deletions

View File

@ -22,6 +22,7 @@
#include <err.h>
#include <stdint.h>
#include <getopt.h>
#include <limits.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
@ -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 doesnt work.
* As i3-msg is a short-running tool, we dont 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)

View File

@ -27,9 +27,51 @@
#include <err.h>
#include <stdint.h>
#include <getopt.h>
#include <limits.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <i3/ipc.h>
static char *socket_path;
/*
* Try to get the socket path from X11 and return NULL if it doesnt work.
* As i3-msg is a short-running tool, we dont 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];