From 27aa9a640e4f7754a0068c0db6c42c05e9867ea5 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Wed, 4 Aug 2010 03:34:18 +0200 Subject: [PATCH] Display statusline (without formats) --- i3bar/include/common.h | 7 +-- i3bar/include/outputs.h | 14 +++--- i3bar/include/xcb.h | 2 +- i3bar/src/ipc.c | 2 +- i3bar/src/main.c | 104 ++++++++++++++++++++++++++++++++++++++++ i3bar/src/xcb.c | 28 +++++++++-- 6 files changed, 142 insertions(+), 15 deletions(-) diff --git a/i3bar/include/common.h b/i3bar/include/common.h index 431c4694..e2bfb40b 100644 --- a/i3bar/include/common.h +++ b/i3bar/include/common.h @@ -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 diff --git a/i3bar/include/outputs.h b/i3bar/include/outputs.h index 1c6abe3a..05383615 100644 --- a/i3bar/include/outputs.h +++ b/i3bar/include/outputs.h @@ -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; }; diff --git a/i3bar/include/xcb.h b/i3bar/include/xcb.h index 230ff6e6..d97113a9 100644 --- a/i3bar/include/xcb.h +++ b/i3bar/include/xcb.h @@ -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); diff --git a/i3bar/src/ipc.c b/i3bar/src/ipc.c index 1553fc20..80ada521 100644 --- a/i3bar/src/ipc.c +++ b/i3bar/src/ipc.c @@ -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) { diff --git a/i3bar/src/main.c b/i3bar/src/main.c index 9465fc12..3bd2183e 100644 --- a/i3bar/src/main.c +++ b/i3bar/src/main.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include @@ -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); diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 6d7a38b3..6b16b45f 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -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);