diff options
Diffstat (limited to 'swaybar/status_line.c')
-rw-r--r-- | swaybar/status_line.c | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/swaybar/status_line.c b/swaybar/status_line.c index 3454f207..8afe4707 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c @@ -1,5 +1,6 @@ #define _POSIX_C_SOURCE #include <fcntl.h> +#include <json-c/json.h> #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -9,35 +10,83 @@ #include "swaybar/status_line.h" #include "readline.h" -bool handle_status_readable(struct status_line *status) { - char *line = read_line_buffer(status->read, - status->buffer, status->buffer_size); +void status_error(struct status_line *status, const char *text) { + close(status->read_fd); + close(status->write_fd); + status->protocol = PROTOCOL_ERROR; + status->text = text; +} + +bool status_handle_readable(struct status_line *status) { + char *line; switch (status->protocol) { + case PROTOCOL_ERROR: + return false; case PROTOCOL_I3BAR: - // TODO + if (i3bar_handle_readable(status) > 0) { + return true; + } break; case PROTOCOL_TEXT: - status->text = line; + line = read_line_buffer(status->read, + status->text_state.buffer, status->text_state.buffer_size); + if (!line) { + status_error(status, "[error reading from status command]"); + } else { + status->text = line; + } return true; case PROTOCOL_UNDEF: + line = read_line_buffer(status->read, + status->text_state.buffer, status->text_state.buffer_size); if (!line) { + status_error(status, "[error reading from status command]"); return false; } if (line[0] == '{') { - // TODO: JSON + json_object *proto = json_tokener_parse(line); + if (proto) { + json_object *version; + if (json_object_object_get_ex(proto, "version", &version) + && json_object_get_int(version) == 1) { + wlr_log(L_DEBUG, "Switched to i3bar protocol."); + status->protocol = PROTOCOL_I3BAR; + } + json_object *click_events; + if (json_object_object_get_ex( + proto, "click_events", &click_events) + && json_object_get_boolean(click_events)) { + wlr_log(L_DEBUG, "Enabled click events."); + status->i3bar_state.click_events = true; + const char *events_array = "[\n"; + ssize_t len = strlen(events_array); + if (write(status->write_fd, events_array, len) != len) { + status_error(status, + "[failed to write to status command]"); + } + } + json_object_put(proto); + } + + status->protocol = PROTOCOL_I3BAR; + free(status->text_state.buffer); + wl_list_init(&status->blocks); + status->i3bar_state.buffer_size = 4096; + status->i3bar_state.buffer = + malloc(status->i3bar_state.buffer_size); } else { - status->text = line; status->protocol = PROTOCOL_TEXT; + status->text = line; } - return false; + return true; } return false; } struct status_line *status_line_init(char *cmd) { struct status_line *status = calloc(1, sizeof(struct status_line)); - status->buffer_size = 4096; - status->buffer = malloc(status->buffer_size); + status->text_state.buffer_size = 8192; + status->text_state.buffer = malloc(status->text_state.buffer_size); int pipe_read_fd[2]; int pipe_write_fd[2]; |