]> git.sur5r.net Git - i3/i3/commitdiff
Be more strict with encapsulation
authorAxel Wagner <mail@merovius.de>
Thu, 5 Aug 2010 03:09:59 +0000 (05:09 +0200)
committerAxel Wagner <mail@merovius.de>
Thu, 5 Aug 2010 03:09:59 +0000 (05:09 +0200)
I.e. move the xcb-event-handling into xcb.c and the
child-process-communications into newly created child.c.
Also change some includes.

12 files changed:
i3bar/include/child.h [new file with mode: 0644]
i3bar/include/common.h
i3bar/include/ipc.h
i3bar/include/outputs.h
i3bar/include/workspaces.h
i3bar/include/xcb.h
i3bar/src/child.c [new file with mode: 0644]
i3bar/src/ipc.c
i3bar/src/main.c
i3bar/src/outputs.c
i3bar/src/workspaces.c
i3bar/src/xcb.c

diff --git a/i3bar/include/child.h b/i3bar/include/child.h
new file mode 100644 (file)
index 0000000..3d3c28c
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef CHILD_H_
+#define CHILD_H_
+
+#define STDIN_CHUNK_SIZE 1024
+
+void start_child(char *command);
+void kill_child();
+
+#endif
index e2bfb40b769528585549723bd1134a67d42d2cb9..3feab6982ebea90ca9c4df28e5d72a553e749475 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef COMMON_H_
 #define COMMON_H_
 
-#include "util.h"
-
 typedef struct rect_t rect;
 typedef int bool;
 
@@ -17,4 +15,12 @@ struct rect_t {
        int     h;
 };
 
+#include "queue.h"
+#include "child.h"
+#include "ipc.h"
+#include "outputs.h"
+#include "util.h"
+#include "workspaces.h"
+#include "xcb.h"
+
 #endif
index 278077e0d105a645645412a81fa9d5daf0bb40b7..b3760d2ab1f863b0c7e862505742c11d503d3d13 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef IPC_H_
 #define IPC_H_
 
-#include <ev.h>
 #include <stdint.h>
 
 int init_connection(const char *socket_path);
index 05383615e69bc26d7d94622aaf8ab38ecea5133b..b00a93b4c100c53fbc235ffc98b86f8c7985f5ed 100644 (file)
@@ -4,7 +4,6 @@
 #include <xcb/xcb.h>
 
 #include "common.h"
-#include "workspaces.h"
 
 typedef struct i3_output i3_output;
 
index 64c1065eddcf0dd22cb29ea1ff97d48647254e99..ae3c130337b1b25e0ff0d069c97ca2264ecd0944 100644 (file)
@@ -2,7 +2,6 @@
 #define WORKSPACES_H_
 
 #include "common.h"
-#include "outputs.h"
 
 typedef struct i3_ws i3_ws;
 
index d97113a988d15da131abe7a3910253c8a8eddd15..a75b715408fa831a1b15d25d4dca0977a9e16a09 100644 (file)
@@ -1,22 +1,7 @@
 #ifndef XCB_H_
 #define XCB_H_
 
-#include <xcb/xcb.h>
-
-#define NUM_ATOMS 3
-
-enum {
-       #define ATOM_DO(name) name,
-       #include "xcb_atoms.def"
-};
-
-xcb_atom_t atoms[NUM_ATOMS];
-
-xcb_connection_t *xcb_connection;
-xcb_screen_t     *xcb_screens;
-xcb_window_t     xcb_root;
-xcb_font_t       xcb_font;
-int              font_height;
+int font_height;
 
 void init_xcb();
 void clean_xcb();
@@ -25,6 +10,5 @@ void destroy_windows();
 void create_windows();
 void draw_bars();
 int get_string_width(char *string);
-void handle_xcb_event(xcb_generic_event_t *event);
 
 #endif
diff --git a/i3bar/src/child.c b/i3bar/src/child.c
new file mode 100644 (file)
index 0000000..5fe9ca8
--- /dev/null
@@ -0,0 +1,135 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <ev.h>
+
+#include "common.h"
+
+ev_io    *child_io;
+ev_child *child_sig;
+
+void cleanup() {
+    ev_io_stop(main_loop, child_io);
+    ev_child_stop(main_loop, child_sig);
+    FREE(child_io);
+    FREE(child_sig);
+    FREE(statusline);
+}
+
+void strip_dzen_formats(char *buffer) {
+    char *src = buffer;
+    char *dest = buffer;
+    while (*src != '\0') {
+        if (*src == '^') {
+            if (!strncmp(src, "^ro", strlen("^ro"))) {
+                *(dest++) = ' ';
+                *(dest++) = '|';
+                *(dest++) = ' ';
+            }
+            while (*src != ')') {
+                src++;
+            }
+            src++;
+        } else {
+            *dest = *src;
+            src++;
+            dest++;
+        }
+    }
+    *(--dest) = '\0';
+}
+
+void child_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
+    int fd = watcher->fd;
+    int n = 0;
+    int rec = 0;
+    int buffer_len = STDIN_CHUNK_SIZE;
+    char *buffer = malloc(buffer_len);
+    memset(buffer, '\0', buffer_len);
+    while(1) {
+        n = read(fd, buffer + rec, buffer_len - rec);
+        if (n == -1) {
+            if (errno == EAGAIN) {
+                break;
+            }
+            printf("ERROR: read() failed!");
+            exit(EXIT_FAILURE);
+        }
+        if (n == 0) {
+            if (rec == buffer_len) {
+                char *tmp = buffer;
+                buffer = malloc(buffer_len + STDIN_CHUNK_SIZE);
+                memset(buffer, '\0', buffer_len);
+                strncpy(buffer, tmp, buffer_len);
+                buffer_len += STDIN_CHUNK_SIZE;
+                FREE(tmp);
+            } else {
+                break;
+            }
+        }
+        rec += n;
+    }
+    if (strlen(buffer) == 0) {
+        FREE(buffer);
+        return;
+    }
+    strip_dzen_formats(buffer);
+    FREE(statusline);
+    statusline = buffer;
+    printf("%s", buffer);
+    draw_bars();
+}
+
+void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) {
+    printf("Child (pid: %d) unexpectedly exited with status %d\n", child_pid, watcher->rstatus);
+    cleanup();
+}
+
+void start_child(char *command) {
+    int fd[2];
+    pipe(fd);
+    child_pid = fork();
+    switch (child_pid) {
+        case -1:
+            printf("ERROR: Couldn't fork()");
+            exit(EXIT_FAILURE);
+        case 0:
+            close(fd[0]);
+
+            dup2(fd[1], STDOUT_FILENO);
+
+            static const char *shell = NULL;
+
+            if ((shell = getenv("SHELL")) == NULL)
+                shell = "/bin/sh";
+
+            execl(shell, shell, "-c", command, (char*) NULL);
+            break;
+        default:
+            close(fd[1]);
+
+            dup2(fd[0], STDIN_FILENO);
+            fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
+
+            child_io = malloc(sizeof(ev_io));
+            ev_io_init(child_io, &child_io_cb, STDIN_FILENO, EV_READ);
+            ev_io_start(main_loop, child_io);
+
+            /* We must cleanup, if the child unexpectedly terminates */
+            child_sig = malloc(sizeof(ev_io));
+            ev_child_init(child_sig, &child_sig_cb, child_pid, 0);
+            ev_child_start(main_loop, child_sig);
+
+            break;
+    }
+}
+
+void kill_child() {
+    kill(child_pid, SIGQUIT);
+    cleanup();
+}
index bf91420e275cada9c55a9fecf1f4991038b56834..4b17a4bcad6901ba915f37017b87bd45e546990e 100644 (file)
@@ -5,12 +5,9 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <i3/ipc.h>
+#include <ev.h>
 
 #include "common.h"
-#include "outputs.h"
-#include "workspaces.h"
-#include "xcb.h"
-#include "ipc.h"
 
 ev_io *i3_connection;
 
index ab362d5cd9cb17cc3588d664275a12d34055f588..6ce7a38ae5e14e6dd4f0fa8d3b9aa5133e6549b1 100644 (file)
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
-#include <fcntl.h>
 #include <errno.h>
 #include <ev.h>
-#include <xcb/xcb.h>
 
-#include "ipc.h"
-#include "outputs.h"
-#include "workspaces.h"
 #include "common.h"
-#include "xcb.h"
-
-#define STDIN_CHUNK_SIZE 1024
-
-void ev_prepare_cb(struct ev_loop *loop, ev_prepare *w, int revents) {
-    xcb_flush(xcb_connection);
-}
-
-void ev_check_cb(struct ev_loop *loop, ev_check *w, int revents) {
-    xcb_generic_event_t *event;
-    if ((event = xcb_poll_for_event(xcb_connection)) != NULL) {
-        handle_xcb_event(event);
-    }
-    free(event);
-}
-
-void xcb_io_cb(struct ev_loop *loop, ev_io *w, int revents) {
-}
-
-void start_child(char *command) {
-    int fd[2];
-    pipe(fd);
-    child_pid = fork();
-    switch (child_pid) {
-        case -1:
-            printf("ERROR: Couldn't fork()");
-            exit(EXIT_FAILURE);
-        case 0:
-            close(fd[0]);
-
-            dup2(fd[1], STDOUT_FILENO);
-
-            static const char *shell = NULL;
-
-            if ((shell = getenv("SHELL")) == NULL)
-                shell = "/bin/sh";
-
-            execl(shell, shell, "-c", command, (char*) NULL);
-            break;
-        default:
-            close(fd[1]);
-
-            dup2(fd[0], STDIN_FILENO);
-
-            break;
-    }
-}
-
-void strip_dzen_formats(char *buffer) {
-    char *src = buffer;
-    char *dest = buffer;
-    while (*src != '\0') {
-        if (*src == '^') {
-            if (!strncmp(src, "^ro", strlen("^ro"))) {
-                *(dest++) = ' ';
-                *(dest++) = '|';
-                *(dest++) = ' ';
-            }
-            while (*src != ')') {
-                src++;
-            }
-            src++;
-        } else {
-            *dest = *src;
-            src++;
-            dest++;
-        }
-    }
-    *(--dest) = '\0';
-}
-
-void child_io_cb(struct ev_loop *loop, ev_io *w, int revents) {
-    int fd = w->fd;
-    int n = 0;
-    int rec = 0;
-    int buffer_len = STDIN_CHUNK_SIZE;
-    char *buffer = malloc(buffer_len);
-    memset(buffer, '\0', buffer_len);
-    while(1) {
-        n = read(fd, buffer + rec, buffer_len - rec);
-        if (n == -1) {
-            if (errno == EAGAIN) {
-                break;
-            }
-            printf("ERROR: read() failed!");
-            exit(EXIT_FAILURE);
-        }
-        if (n == 0) {
-            if (rec == buffer_len) {
-                char *tmp = buffer;
-                buffer = malloc(buffer_len + STDIN_CHUNK_SIZE);
-                memset(buffer, '\0', buffer_len);
-                strncpy(buffer, tmp, buffer_len);
-                buffer_len += STDIN_CHUNK_SIZE;
-                FREE(tmp);
-            } else {
-                break;
-            }
-        }
-        rec += n;
-    }
-    if (strlen(buffer) == 0) {
-        FREE(buffer);
-        return;
-    }
-    strip_dzen_formats(buffer);
-    FREE(statusline);
-    statusline = buffer;
-    printf("%s", buffer);
-    draw_bars();
-}
 
 int main(int argc, char **argv) {
     main_loop = ev_default_loop(0);
@@ -132,44 +16,19 @@ int main(int argc, char **argv) {
 
     subscribe_events();
 
-    ev_io *xcb_io = malloc(sizeof(ev_io));
-    ev_prepare *ev_prep = malloc(sizeof(ev_prepare));
-    ev_check *ev_chk = malloc(sizeof(ev_check));
-
-    ev_io_init(xcb_io, &xcb_io_cb, xcb_get_file_descriptor(xcb_connection), EV_READ);
-    ev_prepare_init(ev_prep, &ev_prepare_cb);
-    ev_check_init(ev_chk, &ev_check_cb);
-
-    ev_io_start(main_loop, xcb_io);
-    ev_prepare_start(main_loop, ev_prep);
-    ev_check_start(main_loop, ev_chk);
-
     i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
     i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
 
     start_child("i3status");
 
-    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
-    ev_io *child_io = malloc(sizeof(ev_io));
-    ev_io_init(child_io, &child_io_cb, STDIN_FILENO, EV_READ);
-    ev_io_start(main_loop, child_io);
-
     ev_loop(main_loop, 0);
 
-    ev_prepare_stop(main_loop, ev_prep);
-    ev_check_stop(main_loop, ev_chk);
-    ev_io_stop(main_loop, xcb_io);
-    ev_io_stop(main_loop, child_io);
-
-    FREE(xcb_io);
-    FREE(ev_prep);
-    FREE(ev_chk);
-    free(child_io);
+    kill_child();
 
     FREE(statusline);
 
-    ev_default_destroy();
     clean_xcb();
+    ev_default_destroy();
 
     free_workspaces();
     FREE_SLIST(outputs, i3_output);
index 18abff513bb42d063594d88288f7768660853e94..dc61cb47117d0445769702b4464fd051e2eca777 100644 (file)
@@ -2,12 +2,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <i3/ipc.h>
-
 #include <yajl/yajl_parse.h>
 
 #include "common.h"
-#include "outputs.h"
-#include "ipc.h"
 
 struct outputs_json_params {
     struct outputs_head *outputs;
index ee54c8b6d3439d13a6e66e8d34edf57a3201dfe7..abc3a572530a6e5613183fbaf6659e42bd1895ff 100644 (file)
@@ -1,13 +1,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-
 #include <yajl/yajl_parse.h>
 
 #include "common.h"
-#include "workspaces.h"
-#include "xcb.h"
-#include "ipc.h"
 
 struct workspaces_json_params {
     struct ws_head *workspaces;
index eff74ac4f87fa410f2157a8247ba1ebdc57de66b..154af575d6df5fab995094a7f01e1983f5bc9497 100644 (file)
@@ -3,14 +3,28 @@
 #include <stdlib.h>
 #include <string.h>
 #include <i3/ipc.h>
+#include <ev.h>
 
-#include "xcb.h"
-#include "outputs.h"
-#include "workspaces.h"
 #include "common.h"
-#include "ipc.h"
+
+#define NUM_ATOMS 3
+
+enum {
+    #define ATOM_DO(name) name,
+    #include "xcb_atoms.def"
+};
 
 xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS];
+xcb_atom_t               atoms[NUM_ATOMS];
+
+xcb_connection_t *xcb_connection;
+xcb_screen_t     *xcb_screens;
+xcb_window_t     xcb_root;
+xcb_font_t       xcb_font;
+
+ev_prepare *xcb_prep;
+ev_check   *xcb_chk;
+ev_io      *xcb_io;
 
 uint32_t get_colorpixel(const char *s) {
     char strings[3][3] = { { s[0], s[1], '\0'} ,
@@ -97,6 +111,23 @@ void handle_xcb_event(xcb_generic_event_t *event) {
     }
 }
 
+void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revenst) {
+    xcb_flush(xcb_connection);
+}
+
+void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) {
+    xcb_generic_event_t *event;
+    if ((event = xcb_poll_for_event(xcb_connection)) != NULL) {
+        handle_xcb_event(event);
+    }
+    FREE(event);
+}
+
+void xcb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
+    /* Dummy Callback. We only need this, so that xcb-events trigger
+     * Prepare- and Check-Watchers */
+}
+
 int get_string_width(char *string) {
     xcb_query_text_extents_cookie_t cookie;
     xcb_query_text_extents_reply_t *reply;
@@ -150,12 +181,32 @@ void init_xcb() {
     FREE(reply);
     printf("Calculated Font-height: %d\n", font_height);
 
+    xcb_io = malloc(sizeof(ev_io));
+    xcb_prep = malloc(sizeof(ev_prepare));
+    xcb_chk = malloc(sizeof(ev_check));
+
+    ev_io_init(xcb_io, &xcb_io_cb, xcb_get_file_descriptor(xcb_connection), EV_READ);
+    ev_prepare_init(xcb_prep, &xcb_prep_cb);
+    ev_check_init(xcb_chk, &xcb_chk_cb);
+
+    ev_io_start(main_loop, xcb_io);
+    ev_prepare_start(main_loop, xcb_prep);
+    ev_check_start(main_loop, xcb_chk);
+
     /* FIXME: Maybe we can push that further backwards */
     get_atoms();
 }
 
 void clean_xcb() {
     xcb_disconnect(xcb_connection);
+
+    ev_check_stop(main_loop, xcb_chk);
+    ev_prepare_stop(main_loop, xcb_prep);
+    ev_io_stop(main_loop, xcb_io);
+
+    FREE(xcb_chk);
+    FREE(xcb_prep);
+    FREE(xcb_io);
 }
 
 void get_atoms() {