#include <err.h>
#include <stdint.h>
#include <getopt.h>
+#include <limits.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include "i3-input.h"
+static char *socket_path;
static int sockfd;
static xcb_key_symbols_t *symbols;
static int modeswitchmask;
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).
}
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;
}
}
+ 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)
#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 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.
}
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 = "";
}
}
+ 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];