From 094c26556e06af16aa7ef1a5d6a04930053e4154 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 2 Oct 2011 16:11:30 +0100 Subject: [PATCH] Introduce libi3, an *internal* library to eliminate code duplication --- Makefile | 10 ++++--- common.mk | 1 + libi3/Makefile | 26 ++++++++++++++++++ libi3/README | 16 +++++++++++ libi3/get_socket_path.c | 59 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 libi3/Makefile create mode 100644 libi3/README create mode 100644 libi3/get_socket_path.c diff --git a/Makefile b/Makefile index 0c8227ea4..fedd6ec34 100644 --- 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 \ diff --git a/common.mk b/common.mk index b8ceea3bf..53094fb33 100644 --- 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 index 000000000..e9efcf7bd --- /dev/null +++ b/libi3/Makefile @@ -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 index 000000000..740ef22e1 --- /dev/null +++ b/libi3/README @@ -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 index 000000000..9e02ec51b --- /dev/null +++ b/libi3/get_socket_path.c @@ -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 +#include +#include +#include + +#include +#include + +/* + * 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; +} +