]> git.sur5r.net Git - i3/i3/commitdiff
Display statusline (without formats)
authorAxel Wagner <mail@merovius.de>
Wed, 4 Aug 2010 01:34:18 +0000 (03:34 +0200)
committerAxel Wagner <mail@merovius.de>
Wed, 4 Aug 2010 01:34:18 +0000 (03:34 +0200)
i3bar/include/common.h
i3bar/include/outputs.h
i3bar/include/xcb.h
i3bar/src/ipc.c
i3bar/src/main.c
i3bar/src/xcb.c

index 431c46945a9af23139d17dcea89b45c8a77cdfc3..e2bfb40b769528585549723bd1134a67d42d2cb9 100644 (file)
@@ -3,9 +3,12 @@
 
 #include "util.h"
 
+typedef struct rect_t rect;
 typedef int bool;
 
-typedef struct rect_t rect;
+struct ev_loop* main_loop;
+pid_t           child_pid;
+char            *statusline;
 
 struct rect_t {
        int     x;
@@ -14,6 +17,4 @@ struct rect_t {
        int     h;
 };
 
-struct ev_loop* main_loop;
-
 #endif
index 1c6abe3a0dbb58a2ff53fbab86dd9ea5bed9d3e4..05383615e69bc26d7d94622aaf8ab38ecea5133b 100644 (file)
@@ -16,15 +16,15 @@ void        free_outputs();
 i3_output*  get_output_by_name(char* name);
 
 struct i3_output {
-       char*           name;
-       bool            active;
-       int             ws;
-       rect            rect;
+       char*           name;
+       bool            active;
+       int             ws;
+       rect            rect;
 
-       xcb_window_t    bar;
-       xcb_gcontext_t  bargc;
+       xcb_window_t    bar;
+       xcb_gcontext_t  bargc;
 
-       struct ws_head  *workspaces;
+       struct ws_head  *workspaces;
 
        SLIST_ENTRY(i3_output) slist;
 };
index 230ff6e6b6e2a219fa61436d0b7cfe34bd333e7e..d97113a988d15da131abe7a3910253c8a8eddd15 100644 (file)
@@ -23,7 +23,7 @@ void clean_xcb();
 void get_atoms();
 void destroy_windows();
 void create_windows();
-void draw_buttons();
+void draw_bars();
 int get_string_width(char *string);
 void handle_xcb_event(xcb_generic_event_t *event);
 
index 1553fc20d1fc91e05aaec0995b1b634bc87ddf45..80ada5219d8b0369b02c6a9668a2d94369b4023a 100644 (file)
@@ -41,7 +41,7 @@ void got_command_reply(char *reply) {
 void got_workspace_reply(char *reply) {
     printf("Got Workspace-Data!\n");
     parse_workspaces_json(reply);
-    draw_buttons();
+    draw_bars();
 }
 
 void got_subscribe_reply(char *reply) {
index 9465fc12f5af981f996846397810cff4ee1be5ad..3bd2183edc5d22180f1b35d54b8ba7c117f6528d 100644 (file)
@@ -3,6 +3,8 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
 #include <ev.h>
 #include <xcb/xcb.h>
 
@@ -12,6 +14,8 @@
 #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);
 }
@@ -27,6 +31,99 @@ void ev_check_cb(struct ev_loop *loop, ev_check *w, int revents) {
 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);
 
@@ -50,6 +147,13 @@ int main(int argc, char **argv) {
     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);
index 6d7a38b3e3a08319b25b86ffa3bb0f2a8f42e96f..6b16b45f0841d63cef277a46d56e182e8d4bef11 100644 (file)
@@ -7,6 +7,7 @@
 #include "xcb.h"
 #include "outputs.h"
 #include "workspaces.h"
+#include "common.h"
 #include "ipc.h"
 
 xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS];
@@ -88,7 +89,7 @@ void handle_button(xcb_button_press_event_t *event) {
 void handle_xcb_event(xcb_generic_event_t *event) {
     switch (event->response_type & ~0x80) {
         case XCB_EXPOSE:
-            draw_buttons();
+            draw_bars();
             break;
         case XCB_BUTTON_PRESS:
             handle_button((xcb_button_press_event_t*) event);
@@ -232,8 +233,8 @@ void create_windows() {
     xcb_flush(xcb_connection);
 }
 
-void draw_buttons() {
-    printf("Drawing Buttons...\n");
+void draw_bars() {
+    printf("Drawing Bars...\n");
     int i = 0;
     i3_output *outputs_walk;
     SLIST_FOREACH(outputs_walk, outputs, slist) {
@@ -255,6 +256,26 @@ void draw_buttons() {
                                 outputs_walk->bargc,
                                 1,
                                 &rect);
+        if (statusline != NULL) {
+            printf("Printing statusline!\n");
+            xcb_change_gc(xcb_connection,
+                          outputs_walk->bargc,
+                          XCB_GC_BACKGROUND,
+                          &color);
+            color = get_colorpixel("FFFFFF");
+            xcb_change_gc(xcb_connection,
+                          outputs_walk->bargc,
+                          XCB_GC_FOREGROUND,
+                          &color);
+
+            xcb_image_text_8(xcb_connection,
+                             strlen(statusline),
+                             outputs_walk->bar,
+                             outputs_walk->bargc,
+                             outputs_walk->rect.w - get_string_width(statusline) - 4,
+                             font_height + 1,
+                             statusline);
+        }
         i3_ws *ws_walk;
         TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
             printf("Drawing Button for WS %s at x = %d\n", ws_walk->name, i);
@@ -293,6 +314,7 @@ void draw_buttons() {
                              ws_walk->name);
             i += 10 + ws_walk->name_width;
         }
+
         i = 0;
     }
     xcb_flush(xcb_connection);