X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=i3status.c;h=f0767a0555ac959a0f8257b713f0c9dc92584d42;hb=c01e87b2692bac03dffb07f3cf8e263758385910;hp=b7f9b86a6037b1081289849eb713dbde15303cc5;hpb=188e5873be5e9c590988f9299653df5f52d44355;p=i3%2Fi3status diff --git a/i3status.c b/i3status.c index b7f9b86..f0767a0 100644 --- a/i3status.c +++ b/i3status.c @@ -3,7 +3,7 @@ * * i3status – Generates a status line for dzen2 or xmobar * - * Copyright © 2008-2011 Michael Stapelberg and contributors + * Copyright © 2008-2012 Michael Stapelberg and contributors * Copyright © 2009 Thorsten Toepper * Copyright © 2010 Axel Wagner * Copyright © 2010 Fernando Tarlá Cardoso Lemos @@ -28,6 +28,9 @@ #include #include +#include +#include + #include "i3status.h" #define exit_if_null(pointer, ...) { if (pointer == NULL) die(__VA_ARGS__); } @@ -110,14 +113,15 @@ static char *resolve_tilde(const char *path) { head = globbuf.gl_pathv[0]; result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1); strncpy(result, head, strlen(head)); - strncat(result, tail, strlen(tail)); + if (tail) + strncat(result, tail, strlen(tail)); } globfree(&globbuf); return result; } -static char *get_config_path() { +static char *get_config_path(void) { char *xdg_config_home, *xdg_config_dirs, *config_path; /* 1: check the traditional path under the home directory */ @@ -210,6 +214,7 @@ int main(int argc, char *argv[]) { cfg_opt_t battery_opts[] = { CFG_STR("format", "%status %percentage %remaining", CFGF_NONE), CFG_STR("path", "/sys/class/power_supply/BAT%d/uevent", CFGF_NONE), + CFG_INT("low_threshold", 10, CFGF_NONE), CFG_BOOL("last_full_capacity", false, CFGF_NONE), CFG_END() }; @@ -292,11 +297,11 @@ int main(int argc, char *argv[]) { if ((char)o == 'c') configfile = optarg; else if ((char)o == 'h') { - printf("i3status " VERSION " © 2008-2011 Michael Stapelberg and contributors\n" + printf("i3status " VERSION " © 2008-2012 Michael Stapelberg and contributors\n" "Syntax: %s [-c ] [-h] [-v]\n", argv[0]); return 0; } else if ((char)o == 'v') { - printf("i3status " VERSION " © 2008-2011 Michael Stapelberg and contributors\n"); + printf("i3status " VERSION " © 2008-2012 Michael Stapelberg and contributors\n"); return 0; } @@ -343,10 +348,19 @@ int main(int argc, char *argv[]) { || !valid_color(cfg_getstr(cfg_general, "color_separator"))) die("Bad color format"); +#if YAJL_MAJOR >= 2 + yajl_gen json_gen = yajl_gen_alloc(NULL); +#else + yajl_gen json_gen = yajl_gen_alloc(NULL, NULL); +#endif + if (output_format == O_I3BAR) { /* Initialize the i3bar protocol. See i3/docs/i3bar-protocol * for details. */ printf("{\"version\":1}\n[\n"); + fflush(stdout); + yajl_gen_array_open(json_gen); + yajl_gen_clear(json_gen); } if ((general_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) @@ -354,6 +368,14 @@ int main(int argc, char *argv[]) { int interval = cfg_getint(cfg_general, "interval"); + /* One memory page which each plugin can use to buffer output. + * Even though it’s unclean, we just assume that the user will not + * specify a format string which expands to something longer than 4096 + * bytes — given that the output of i3status is used to display + * information on screen, more than 1024 characters for the full line + * (!), not individual plugins, seem very unlikely. */ + char buffer[4096]; + struct tm tm; while (1) { struct timeval tv; @@ -365,54 +387,101 @@ int main(int argc, char *argv[]) { current_tm = &tm; } if (output_format == O_I3BAR) - printf("["); + yajl_gen_array_open(json_gen); for (j = 0; j < cfg_size(cfg, "order"); j++) { if (j > 0) print_seperator(); const char *current = cfg_getnstr(cfg, "order", j); - CASE_SEC("ipv6") - print_ipv6_info(cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down")); - - CASE_SEC_TITLE("wireless") - print_wireless_info(title, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down")); - - CASE_SEC_TITLE("ethernet") - print_eth_info(title, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down")); - - CASE_SEC_TITLE("battery") - print_battery_info(atoi(title), cfg_getstr(sec, "path"), cfg_getstr(sec, "format"), cfg_getbool(sec, "last_full_capacity")); - - CASE_SEC_TITLE("run_watch") - print_run_watch(title, cfg_getstr(sec, "pidfile"), cfg_getstr(sec, "format")); - - CASE_SEC_TITLE("disk") - print_disk_info(title, cfg_getstr(sec, "format")); - - CASE_SEC("load") - print_load(cfg_getstr(sec, "format")); - - CASE_SEC("time") - print_time(cfg_getstr(sec, "format"), current_tm); - - CASE_SEC("ddate") - print_ddate(cfg_getstr(sec, "format"), current_tm); - - CASE_SEC_TITLE("volume") - print_volume(cfg_getstr(sec, "format"), + CASE_SEC("ipv6") { + SEC_OPEN_MAP("ipv6"); + print_ipv6_info(json_gen, buffer, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down")); + SEC_CLOSE_MAP; + } + + CASE_SEC_TITLE("wireless") { + SEC_OPEN_MAP("wireless"); + print_wireless_info(json_gen, buffer, title, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down")); + SEC_CLOSE_MAP; + } + + CASE_SEC_TITLE("ethernet") { + SEC_OPEN_MAP("ethernet"); + print_eth_info(json_gen, buffer, title, cfg_getstr(sec, "format_up"), cfg_getstr(sec, "format_down")); + SEC_CLOSE_MAP; + } + + CASE_SEC_TITLE("battery") { + SEC_OPEN_MAP("battery"); + print_battery_info(json_gen, buffer, atoi(title), cfg_getstr(sec, "path"), cfg_getstr(sec, "format"), cfg_getint(sec, "low_threshold"), cfg_getbool(sec, "last_full_capacity")); + SEC_CLOSE_MAP; + } + + CASE_SEC_TITLE("run_watch") { + SEC_OPEN_MAP("run_watch"); + print_run_watch(json_gen, buffer, title, cfg_getstr(sec, "pidfile"), cfg_getstr(sec, "format")); + SEC_CLOSE_MAP; + } + + CASE_SEC_TITLE("disk") { + SEC_OPEN_MAP("disk_info"); + print_disk_info(json_gen, buffer, title, cfg_getstr(sec, "format")); + SEC_CLOSE_MAP; + } + + CASE_SEC("load") { + SEC_OPEN_MAP("load"); + print_load(json_gen, buffer, cfg_getstr(sec, "format")); + SEC_CLOSE_MAP; + } + + CASE_SEC("time") { + SEC_OPEN_MAP("time"); + print_time(json_gen, buffer, cfg_getstr(sec, "format"), current_tm); + SEC_CLOSE_MAP; + } + + CASE_SEC("ddate") { + SEC_OPEN_MAP("ddate"); + print_ddate(json_gen, buffer, cfg_getstr(sec, "format"), current_tm); + SEC_CLOSE_MAP; + } + + CASE_SEC_TITLE("volume") { + SEC_OPEN_MAP("volume"); + print_volume(json_gen, buffer, cfg_getstr(sec, "format"), cfg_getstr(sec, "device"), cfg_getstr(sec, "mixer"), cfg_getint(sec, "mixer_idx")); - - CASE_SEC_TITLE("cpu_temperature") - print_cpu_temperature_info(atoi(title), cfg_getstr(sec, "path"), cfg_getstr(sec, "format")); - - CASE_SEC("cpu_usage") - print_cpu_usage(cfg_getstr(sec, "format")); + SEC_CLOSE_MAP; + } + + CASE_SEC_TITLE("cpu_temperature") { + SEC_OPEN_MAP("cpu_temperature"); + print_cpu_temperature_info(json_gen, buffer, atoi(title), cfg_getstr(sec, "path"), cfg_getstr(sec, "format")); + SEC_CLOSE_MAP; + } + + CASE_SEC("cpu_usage") { + SEC_OPEN_MAP("cpu_usage"); + print_cpu_usage(json_gen, buffer, cfg_getstr(sec, "format")); + SEC_CLOSE_MAP; + } } - if (output_format == O_I3BAR) - printf("],"); + if (output_format == O_I3BAR) { + yajl_gen_array_close(json_gen); + const unsigned char *buf; +#if YAJL_MAJOR >= 2 + size_t len; +#else + unsigned int len; +#endif + yajl_gen_get_buf(json_gen, &buf, &len); + write(STDOUT_FILENO, buf, len); + yajl_gen_clear(json_gen); + } + printf("\n"); fflush(stdout);