From 7a372b0f4627b9482d1276238348a1432c13fbe3 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Thu, 16 May 2013 22:49:13 +0200 Subject: Implement term-output-format --- i3status.c | 26 +++++++++++++++++++++----- include/i3status.h | 3 ++- man/i3status.man | 6 ++++++ src/auto_detect_format.c | 5 +++++ src/output.c | 25 ++++++++++++++++++++++++- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/i3status.c b/i3status.c index df233f7..5311ca9 100644 --- a/i3status.c +++ b/i3status.c @@ -48,12 +48,15 @@ int general_socket; cfg_t *cfg, *cfg_general, *cfg_section; /* - * Exit upon SIGPIPE because when we have nowhere to write to, gathering - * system information is pointless. + * Exit upon SIGPIPE because when we have nowhere to write to, gathering system + * information is pointless. Also exit explicitly on SIGTERM and SIGINT because + * only this will trigger a reset of the cursor in the terminal output-format. * */ -void sigpipe(int signum) { - fprintf(stderr, "Received SIGPIPE, exiting\n"); +void fatalsig(int signum) { + fprintf(stderr, "Received SIG%s, exiting\n", signum == SIGPIPE ? "PIPE" : + signum == SIGTERM ? "TERM" : + "INT"); exit(1); } @@ -321,8 +324,10 @@ int main(int argc, char *argv[]) { struct sigaction action; memset(&action, 0, sizeof(struct sigaction)); - action.sa_handler = sigpipe; + action.sa_handler = fatalsig; sigaction(SIGPIPE, &action, NULL); + sigaction(SIGTERM, &action, NULL); + sigaction(SIGINT, &action, NULL); memset(&action, 0, sizeof(struct sigaction)); action.sa_handler = sigusr1; @@ -376,6 +381,8 @@ int main(int argc, char *argv[]) { output_format = O_XMOBAR; else if (strcasecmp(output_str, "i3bar") == 0) output_format = O_I3BAR; + else if (strcasecmp(output_str, "term") == 0) + output_format = O_TERM; else if (strcasecmp(output_str, "none") == 0) output_format = O_NONE; else die("Unknown output format: \"%s\"\n", output_str); @@ -400,6 +407,12 @@ int main(int argc, char *argv[]) { yajl_gen_array_open(json_gen); yajl_gen_clear(json_gen); } + if (output_format == O_TERM) { + /* Save the cursor-position and hide the cursor */ + printf("\033[s\033[?25l"); + /* Undo at exit */ + atexit(&reset_cursor); + } if ((general_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) die("Could not create socket\n"); @@ -419,6 +432,9 @@ int main(int argc, char *argv[]) { gettimeofday(&tv, NULL); if (output_format == O_I3BAR) yajl_gen_array_open(json_gen); + else if (output_format == O_TERM) + /* Restore the cursor-position */ + printf("\033[u"); for (j = 0; j < cfg_size(cfg, "order"); j++) { if (j > 0) print_seperator(); diff --git a/include/i3status.h b/include/i3status.h index 6b2a688..8185d38 100644 --- a/include/i3status.h +++ b/include/i3status.h @@ -1,7 +1,7 @@ #ifndef _I3STATUS_H #define _I3STATUS_H -enum { O_DZEN2, O_XMOBAR, O_I3BAR, O_NONE } output_format; +enum { O_DZEN2, O_XMOBAR, O_I3BAR, O_TERM, O_NONE } output_format; #include #include @@ -133,6 +133,7 @@ bool slurp(const char *filename, char *destination, int size); void print_seperator(); char *color(const char *colorstr); char *endcolor() __attribute__ ((pure)); +void reset_cursor(void); /* src/auto_detect_format.c */ char *auto_detect_format(); diff --git a/man/i3status.man b/man/i3status.man index 9f89568..fb4ae18 100644 --- a/man/i3status.man +++ b/man/i3status.man @@ -146,6 +146,12 @@ managers like dwm, wmii and xmonad though it will work with any windowmanger xmobar:: xmobar is a minimalistic, text based, status bar. It was designed to work with the xmonad Window Manager. +term:: +Use ANSI Escape sequences to produce a terminal-output as close as possible to +the graphical outputs. This makes debugging your config file a little bit +easier because the terminal-output of i3status becomes much more readable, but +should only used for such quick glances, because it will only support very +basic output-features (for example you only get 3 bits of color depth). none:: Does not use any color codes. Separates values by the pipe symbol. This should be used with i3bar and can be used for custom scripts. diff --git a/src/auto_detect_format.c b/src/auto_detect_format.c index 6ec5f73..524e2e9 100644 --- a/src/auto_detect_format.c +++ b/src/auto_detect_format.c @@ -30,6 +30,11 @@ * */ char *auto_detect_format(void) { + /* If stdout is a tty, we output directly to a terminal. */ + if (isatty(STDOUT_FILENO)) { + return "term"; + } + pid_t myppid = getppid(); pid_t mypid = getpid(); diff --git a/src/output.c b/src/output.c index c4a2d27..4473ca5 100644 --- a/src/output.c +++ b/src/output.c @@ -24,7 +24,19 @@ char *color(const char *colorstr) { (void)snprintf(colorbuf, sizeof(colorbuf), "^fg(%s)", cfg_getstr(cfg_general, colorstr)); else if (output_format == O_XMOBAR) (void)snprintf(colorbuf, sizeof(colorbuf), "", cfg_getstr(cfg_general, colorstr)); - + else if (output_format == O_TERM) { + /* The escape-sequence for color is ;1m (bright/bold + * output), where col is a 3-bit rgb-value with b in the + * least-significant bit. We round the given color to the + * nearist 3-bit-depth color and output the escape-sequence */ + char *str = cfg_getstr(cfg_general, colorstr); + int col = strtol(str + 1, NULL, 16); + int r = (col & (0xFF << 0)) / 0x80; + int g = (col & (0xFF << 8)) / 0x8000; + int b = (col & (0xFF << 16)) / 0x800000; + col = (r << 2) | (g << 1) | b; + (void)snprintf(colorbuf, sizeof(colorbuf), "\033[3%d;1m", col); + } return colorbuf; } @@ -35,6 +47,8 @@ char *color(const char *colorstr) { char *endcolor(void) { if (output_format == O_XMOBAR) return ""; + else if (output_format == O_TERM) + return "\033[0m"; else return ""; } @@ -43,6 +57,15 @@ void print_seperator(void) { printf("^fg(%s)^p(5;-2)^ro(2)^p()^fg()^p(5)", cfg_getstr(cfg_general, "color_separator")); else if (output_format == O_XMOBAR) printf(" | ", cfg_getstr(cfg_general, "color_separator")); + else if (output_format == O_TERM) + printf(" %s|%s ", color("color_separator"), endcolor()); else if (output_format == O_NONE) printf(" | "); } + +/* + * The term-output hides the cursor. We call this on exit to reset that. + */ +void reset_cursor(void) { + printf("\033[?25h"); +} -- cgit v1.2.3