]> git.sur5r.net Git - i3/i3status/commitdiff
Implement term-output-format
authorAxel Wagner <mail@merovius.de>
Thu, 16 May 2013 20:49:13 +0000 (22:49 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 19 May 2013 17:51:01 +0000 (19:51 +0200)
i3status.c
include/i3status.h
man/i3status.man
src/auto_detect_format.c
src/output.c

index df233f75911de0fcab6c75fdb6857c961d2a7695..5311ca954581a93168bdaab722a9f4d775b5fb2b 100644 (file)
@@ -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();
index 6b2a688bc01aba1f59cd25b5cfc1eaf8a0fde45f..8185d38e75a16435d6d8fc50175ae5418cf2f1da 100644 (file)
@@ -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 <stdbool.h>
 #include <confuse.h>
@@ -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();
index 9f895680eaf610ff24d19c194048bd609abdf039..fb4ae188d3bc76c92bb79395c2a3bc33dfd87cf6 100644 (file)
@@ -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.
index 6ec5f731d906eb1269c2bdc2b26fd23a39439914..524e2e9d9b40a0737a2c45a5cd5eaca92b12965f 100644 (file)
  *
  */
 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();
 
index c4a2d275cde9864b00561d94e2eaffbb5eab76e6..4473ca505fdf744317d3df3132231d13ee7ec3d7 100644 (file)
@@ -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), "<fc=%s>", cfg_getstr(cfg_general, colorstr));
-
+        else if (output_format == O_TERM) {
+                /* The escape-sequence for color is <CSI><col>;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 "</fc>";
+        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("<fc=%s> | </fc>", 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");
+}