]> git.sur5r.net Git - i3/i3/commitdiff
Introduce libi3, an *internal* library to eliminate code duplication
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 2 Oct 2011 15:11:30 +0000 (16:11 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 2 Oct 2011 15:11:30 +0000 (16:11 +0100)
Makefile
common.mk
libi3/Makefile [new file with mode: 0644]
libi3/README [new file with mode: 0644]
libi3/get_socket_path.c [new file with mode: 0644]

index 0c8227ea43d246c02c13da2faf619aa5afa1ef37..fedd6ec34e445da944447fb92b42beeef4291be9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -27,9 +27,12 @@ src/%.o: src/%.c ${HEADERS}
 
 all: i3 subdirs
 
-i3: src/cfgparse.y.o src/cfgparse.yy.o src/cmdparse.y.o src/cmdparse.yy.o ${FILES}
-       echo "LINK i3"
-       $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+i3: libi3/libi3.a src/cfgparse.y.o src/cfgparse.yy.o src/cmdparse.y.o src/cmdparse.yy.o ${FILES}
+       echo "[i3] LINK i3"
+       $(CC) $(LDFLAGS) -o $@ $(filter-out libi3/libi3.a,$^) $(LIBS)
+
+libi3/%.a:
+       $(MAKE) -C libi3
 
 subdirs:
        for dir in $(SUBDIRS); do \
@@ -120,6 +123,7 @@ dist: distclean
 clean:
        rm -f src/*.o src/*.gcno src/cfgparse.tab.{c,h} src/cfgparse.yy.c src/cfgparse.{output,dot} src/cmdparse.tab.{c,h} src/cmdparse.yy.c src/cmdparse.{output,dot} loglevels.tmp include/loglevels.h
        (which lcov >/dev/null 2>&1 && lcov -d . --zerocounters) || true
+       $(MAKE) -C libi3 clean
        $(MAKE) -C docs clean
        $(MAKE) -C man clean
        for dir in $(SUBDIRS); do \
index b8ceea3bfc65475a72f9152db1c5c09e72999576..53094fb33040bbc86901a4b94041e074958d067b 100644 (file)
--- a/common.mk
+++ b/common.mk
@@ -58,6 +58,7 @@ CPPFLAGS += -DPCRE_HAS_UCP=1
 endif
 
 LIBS += -lm
+LIBS += -L $(TOPDIR)/libi3 -li3
 LIBS += $(call ldflags_for_lib, xcb-event, xcb-event)
 LIBS += $(call ldflags_for_lib, xcb-keysyms, xcb-keysyms)
 ifeq ($(shell pkg-config --exists xcb-util || echo 1),1)
diff --git a/libi3/Makefile b/libi3/Makefile
new file mode 100644 (file)
index 0000000..e9efcf7
--- /dev/null
@@ -0,0 +1,26 @@
+# Default value so one can compile i3-msg standalone
+TOPDIR=..
+
+include $(TOPDIR)/common.mk
+
+CFLAGS += -I$(TOPDIR)/include
+
+# Depend on the object files of all source-files in src/*.c and on all header files
+FILES=$(patsubst %.c,%.o,$(wildcard *.c))
+HEADERS=$(wildcard *.h)
+
+# Depend on the specific file (.c for each .o) and on all headers
+%.o: %.c ${HEADERS}
+       echo "[libi3] CC $<"
+       $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
+
+all: libi3.a
+
+libi3.a: ${FILES}
+       echo "[libi3] AR libi3.a"
+       ar rcs libi3.a ${FILES}
+
+clean:
+       rm -f *.o libi3.a
+
+distclean: clean
diff --git a/libi3/README b/libi3/README
new file mode 100644 (file)
index 0000000..740ef22
--- /dev/null
@@ -0,0 +1,16 @@
+Introduction
+============
+
+libi3 is an *INTERNAL* library which contains functions that i3 and related
+tools (i3-msg, i3-input, i3-nagbar, i3-config-wizard, i3bar) use.
+
+It is NOT to be used by other programs.
+
+Structure
+=========
+
+Every function gets its own .c file, which in turn gets compiled into an .o
+object file. Afterwards, all .o files are archived into one static library
+(libi3.a). This library will be linked into all i3 binaries. The linker is able
+to eliminate unused .o files when linking, so only the functions which you
+actually use will be included in the corresponding binary.
diff --git a/libi3/get_socket_path.c b/libi3/get_socket_path.c
new file mode 100644 (file)
index 0000000..9e02ec5
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * vim:ts=4:sw=4:expandtab
+ *
+ * i3 - an improved dynamic tiling window manager
+ *
+ * © 2009-2011 Michael Stapelberg and contributors
+ *
+ * See file LICENSE for license information.
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <limits.h>
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+
+/*
+ * Try to get the socket path from X11 and return NULL if it doesn’t work.
+ *
+ * The memory for the socket path is dynamically allocated and has to be
+ * free()d by the caller.
+ *
+ */
+char *socket_path_from_x11() {
+    xcb_connection_t *conn;
+    xcb_intern_atom_cookie_t atom_cookie;
+    xcb_intern_atom_reply_t *atom_reply;
+    int screen;
+    char *socket_path;
+
+    if ((conn = xcb_connect(NULL, &screen)) == NULL ||
+        xcb_connection_has_error(conn))
+        return NULL;
+
+    atom_cookie = xcb_intern_atom(conn, 0, strlen("I3_SOCKET_PATH"), "I3_SOCKET_PATH");
+
+    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)
+        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;
+    xcb_disconnect(conn);
+    return socket_path;
+}
+