]> git.sur5r.net Git - i3/i3/commitdiff
i3-msg, i3-input: get the I3_SOCKET_PATH atoms if socket path was not specified
authorMichael Stapelberg <michael@stapelberg.de>
Sat, 19 Mar 2011 20:23:55 +0000 (21:23 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sat, 19 Mar 2011 20:23:55 +0000 (21:23 +0100)
i3-input/main.c
i3-msg/main.c

index ea1e61322cdc2bf2d01292b19f413250fb5dd400..fb2635a274024e1f41199bd3e71dd8a164fd9bb0 100644 (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 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)
index c6862fae0d57646e52056a4badbddcae752a66fe..ee4de0788b6b8928fcf230ee2535d69cf2a95522 100644 (file)
 #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.
@@ -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];