]> git.sur5r.net Git - i3/i3status/commitdiff
Implement the i3bar JSON protocol
authorMichael Stapelberg <michael@stapelberg.de>
Thu, 16 Feb 2012 23:29:29 +0000 (23:29 +0000)
committerMichael Stapelberg <michael@stapelberg.de>
Thu, 16 Feb 2012 23:30:54 +0000 (23:30 +0000)
This hardcodes all the JSON parts. Strings are not properly escaped currently.
The best/easiest way to fix this is by actually using libyajl.

16 files changed:
i3status.c
include/i3status.h
src/auto_detect_format.c
src/output.c
src/print_battery_info.c
src/print_cpu_temperature.c
src/print_cpu_usage.c
src/print_ddate.c
src/print_disk_info.c
src/print_eth_info.c
src/print_ipv6_addr.c
src/print_load.c
src/print_run_watch.c
src/print_time.c
src/print_volume.c
src/print_wireless_info.c

index 9f04850513b9a5a3d5420aa811f04de328c413b0..dd7d1e67bba66b00dd3b816a38aec9773e957dd9 100644 (file)
@@ -331,6 +331,8 @@ int main(int argc, char *argv[]) {
                 output_format = O_DZEN2;
         else if (strcasecmp(output_str, "xmobar") == 0)
                 output_format = O_XMOBAR;
+        else if (strcasecmp(output_str, "i3bar") == 0)
+                output_format = O_I3BAR;
         else if (strcasecmp(output_str, "none") == 0)
                 output_format = O_NONE;
         else die("Unknown output format: \"%s\"\n", output_str);
@@ -341,6 +343,12 @@ int main(int argc, char *argv[]) {
                         || !valid_color(cfg_getstr(cfg_general, "color_separator")))
                die("Bad color format");
 
+        if (output_format == O_I3BAR) {
+                /* Initialize the i3bar protocol. See i3/docs/i3bar-protocol
+                 * for details. */
+                printf("{\"version\":1}\n[\n");
+        }
+
         if ((general_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
                 die("Could not create socket\n");
 
@@ -356,6 +364,8 @@ int main(int argc, char *argv[]) {
                         localtime_r(&current_time, &tm);
                         current_tm = &tm;
                 }
+                if (output_format == O_I3BAR)
+                        printf("[");
                 for (j = 0; j < cfg_size(cfg, "order"); j++) {
                         if (j > 0)
                                 print_seperator();
@@ -401,6 +411,8 @@ int main(int argc, char *argv[]) {
                         CASE_SEC("cpu_usage")
                                 print_cpu_usage(cfg_getstr(sec, "format"));
                 }
+                if (output_format == O_I3BAR)
+                        printf("],");
                 printf("\n");
                 fflush(stdout);
 
index 24097b02ca6bf90fd4ac067dab83cef8f09fcc9b..e40003ca7f4987b1b7ac85f5bd04e2a278918e06 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _I3STATUS_H
 #define _I3STATUS_H
 
-enum { O_DZEN2, O_XMOBAR, O_NONE } output_format;
+enum { O_DZEN2, O_XMOBAR, O_I3BAR, O_NONE } output_format;
 
 #include <stdbool.h>
 #include <confuse.h>
index 299614a0ba7ef6c27c57895d81d1630f0c3a4d11..7c4d65d6adee54697a8a752a57fb7554fb104a50 100644 (file)
@@ -78,7 +78,7 @@ char *auto_detect_format() {
      * pipe target the parent process of i3status. If we detect that, we set
      * the format and we are done. */
     if (strcasecmp(parentname, "i3bar") == 0)
-        format = "none";
+        format = "i3bar";
     else if (strcasecmp(parentname, "dzen2") == 0)
         format = "dzen2";
     else if (strcasecmp(parentname, "xmobar") == 0)
@@ -133,7 +133,7 @@ char *auto_detect_format() {
         /* Check for known destination programs and set format */
         char *newfmt = NULL;
         if (strcasecmp(name, "i3bar") == 0)
-            newfmt = "none";
+            newfmt = "i3bar";
         else if (strcasecmp(name, "dzen2") == 0)
             newfmt = "dzen2";
         else if (strcasecmp(name, "xmobar") == 0)
index c0c1480bcbed785bf6f0ee03ac9327379df7b9a4..96dd3e498073ffe6286d5ce4b194ceb6046671b6 100644 (file)
@@ -24,6 +24,8 @@ 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_I3BAR)
+                (void)snprintf(colorbuf, sizeof(colorbuf), "\"color\":\"%s\", ", cfg_getstr(cfg_general, colorstr));
 
         return colorbuf;
 }
@@ -43,6 +45,8 @@ void print_seperator() {
                 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_I3BAR)
+                printf(", ");
         else if (output_format == O_NONE)
                 printf(" | ");
 }
index 6ee89896cfed8c0e226e7a9bb77dcc2e19bc354d..10137c2f4248d5629165734ecd98917b463b5bde 100644 (file)
@@ -36,6 +36,9 @@ void print_battery_info(int number, const char *path, const char *format, bool l
         memset(remainingbuf, '\0', sizeof(remainingbuf));
         memset(emptytimebuf, '\0', sizeof(emptytimebuf));
 
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"battery\", \"instance\": \"%s\", \"full_text\":\"", path);
+
 #if defined(LINUX)
         static char batpath[512];
         sprintf(batpath, path, number);
@@ -185,4 +188,7 @@ void print_battery_info(int number, const char *path, const char *format, bool l
                         walk += strlen("emptytime");
                 }
         }
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index 8c343c26c138c0d77d3716ebd3c1391ddb7dca36..08fac88cd3ade54ddce7c846fbcbb58f8e628ac0 100644 (file)
@@ -31,6 +31,9 @@ void print_cpu_temperature_info(int zone, const char *path, const char *format)
                 path = thermal_zone;
         }
 
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"cpu_temperature\", \"instance\": \"%s\", \"full_text\":\"", path);
+
         for (walk = format; *walk != '\0'; walk++) {
                 if (*walk != '%') {
                         putchar(*walk);
@@ -58,6 +61,10 @@ void print_cpu_temperature_info(int zone, const char *path, const char *format)
                         walk += strlen("degrees");
                 }
         }
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
+
         return;
 error:
 #endif
index 1d3bac878accbee67bfbe43a91acc0a0e15176eb..d97a7fa303a3c50bcf2226633ffaafa5cb4644c8 100644 (file)
@@ -26,6 +26,9 @@ void print_cpu_usage(const char *format) {
         int curr_user = 0, curr_nice = 0, curr_system = 0, curr_idle = 0, curr_total;
         int diff_idle, diff_total, diff_usage;
 
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"cpu_usage\", \"full_text\":\"");
+
 #if defined(LINUX)
         static char statpath[512];
         strcpy(statpath, "/proc/stat");
@@ -70,6 +73,10 @@ void print_cpu_usage(const char *format) {
                         walk += strlen("usage");
                 }
         }
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
+
         return;
 error:
         (void)fputs("Cannot read usage\n", stderr);
index 453e5a270efebfe52f74e056ce1972e37df7e2c4..0401a3f366d22c177fd9daf3ee88d4b1a98877b3 100644 (file)
@@ -4,6 +4,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "i3status.h"
+
 /* define fixed output-Strings */
 char *season_long[5] = {
         "Chaos",
@@ -200,6 +202,10 @@ void print_ddate(const char *format, struct tm *current_tm) {
         if (form == NULL)
                 if ((form = malloc(strlen(format) + 1)) == NULL)
                         return;
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"ddate\", \"full_text\":\"");
         strcpy(form, format);
         format_output(form, dt);
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index b2cbd9c5f066684394ca1cc42b7d5fee455b853d..1ac22d0f3a51d453f9c70f17b1c19a93a3e95197 100644 (file)
@@ -45,6 +45,9 @@ static void print_bytes_human(uint64_t bytes) {
 void print_disk_info(const char *path, const char *format) {
         const char *walk;
 
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"disk_info\", \"instance\": \"%s\", \"full_text\":\"", path);
+
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
         struct statfs buf;
 
@@ -83,4 +86,7 @@ void print_disk_info(const char *path, const char *format) {
                         walk += strlen("avail");
                 }
         }
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index 28ba6c1aef1dd67a319c8bfac298b44ac0faff35..4fae191293994005cc7223fe23c3942d91cb6cfd 100644 (file)
@@ -78,6 +78,9 @@ void print_eth_info(const char *interface, const char *format_up, const char *fo
         const char *walk;
         const char *ip_address = get_ip_addr(interface);
 
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"ethernet\", \"instance\": \"%s\", ", interface);
+
         if (ip_address == NULL) {
                 printf("%s", color("color_bad"));
                 printf("%s", format_down);
@@ -87,6 +90,9 @@ void print_eth_info(const char *interface, const char *format_up, const char *fo
                 printf("%s", color("color_good"));
         }
 
+        if (output_format == O_I3BAR)
+                printf("\"full_text\":\"");
+
         for (walk = format_up; *walk != '\0'; walk++) {
                 if (*walk != '%') {
                         putchar(*walk);
@@ -103,4 +109,7 @@ void print_eth_info(const char *interface, const char *format_up, const char *fo
         }
 
         (void)printf("%s", endcolor());
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index e96c0d3d712b8b04eb2668ab6084ede42fe3b3d9..3ace6a24fe20c0856e22ad7c88802de246a6bbfc 100644 (file)
@@ -9,6 +9,8 @@
 #include <string.h>
 #include <arpa/inet.h>
 
+#include "i3status.h"
+
 static char *get_sockname(struct addrinfo *addr) {
         static char buf[INET6_ADDRSTRLEN+1];
         struct sockaddr_storage local;
@@ -111,6 +113,9 @@ void print_ipv6_info(const char *format_up, const char *format_down) {
         const char *walk;
         char *addr_string = get_ipv6_addr();
 
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"ipv6\", \"full_text\":\"");
+
         if (addr_string == NULL) {
                 printf("%s", format_down);
                 return;
@@ -127,4 +132,7 @@ void print_ipv6_info(const char *format_up, const char *format_down) {
                         walk += strlen("ip");
                 }
         }
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index d47eceacdbf3abee23fcb98f6519c924654fa17b..8c2343bcfe395b3b65666cea8a0d0b7ba3eb2037 100644 (file)
@@ -6,6 +6,9 @@
 
 void print_load(const char *format) {
 /* Get load */
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"load\", \"full_text\":\"");
+
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(sun)
         double loadavg[3];
         const char *walk;
@@ -34,6 +37,10 @@ void print_load(const char *format) {
                         walk += strlen("15min");
                 }
         }
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
+
         return;
 error:
 #endif
index 455130e91bab049ce1c024e42f75f1b061e5a355..c806d8e25c04d74a0e630db400d79ee4b06a16bc 100644 (file)
@@ -6,8 +6,14 @@ void print_run_watch(const char *title, const char *pidfile, const char *format)
        bool running = process_runs(pidfile);
        const char *walk;
 
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"run_watch\", \"instance\": \"%s\", ", pidfile);
+
        printf("%s", (running ? color("color_good") : color("color_bad")));
 
+        if (output_format == O_I3BAR)
+                printf("\"full_text\":\"");
+
         for (walk = format; *walk != '\0'; walk++) {
                 if (*walk != '%') {
                         putchar(*walk);
@@ -24,4 +30,7 @@ void print_run_watch(const char *title, const char *pidfile, const char *format)
         }
 
        printf("%s", endcolor());
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index 9c9df901319ca3e9d69bfc14e69a5c8432d4c522..3c48d3f8e5a1188ffeb20db90aca17c88d32a81a 100644 (file)
@@ -3,12 +3,18 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "i3status.h"
+
 void print_time(const char *format, struct tm *current_tm) {
         static char part[512];
         /* Get date & time */
         if (current_tm == NULL) {
                 return;
         }
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"time\", \"full_text\":\"");
         (void)strftime(part, sizeof(part), format, current_tm);
         printf("%s", part);
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index c13cb1761f4a206e9d2c999cef6c888c9563e153..85b6176de03267b2f0e66df64aa76bf8ab7768ad 100644 (file)
@@ -43,6 +43,8 @@ static void free_hdl(struct mixer_hdl *hdl) {
 
 void print_volume(const char *fmt, const char *device, const char *mixer, int mixer_idx) {
 /* Printing volume only works with ALSA at the moment */
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"volume\", \"instance\": \"%s.%s.%d\", \"full_text\":\"", device, mixer, mixer_idx);
 #ifdef LINUX
        /* Check if we already opened the mixer and get the handle
         * from cache if so */
@@ -180,4 +182,6 @@ void print_volume(const char *fmt, const char *device, const char *mixer, int mi
         }
         close(mixfd);
 #endif
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }
index 1aca346f3bdef1e9597405f1f99b78d45e90be53..530d9cf8eb3c2533e107458cc1d1de5229c63ad1 100644 (file)
@@ -224,6 +224,9 @@ static int get_wireless_info(const char *interface, wireless_info_t *info) {
 void print_wireless_info(const char *interface, const char *format_up, const char *format_down) {
         const char *walk;
         wireless_info_t info;
+        if (output_format == O_I3BAR)
+                printf("{\"name\":\"wireless\", \"instance\": \"%s\", ", interface);
+
         if (get_wireless_info(interface, &info)) {
                 walk = format_up;
                 if (info.flags & WIRELESS_INFO_FLAG_HAS_QUALITY)
@@ -234,6 +237,9 @@ void print_wireless_info(const char *interface, const char *format_up, const cha
                 printf("%s", color("color_bad"));
         }
 
+        if (output_format == O_I3BAR)
+                printf("\"full_text\":\"");
+
         for (; *walk != '\0'; walk++) {
                 if (*walk != '%') {
                         putchar(*walk);
@@ -308,4 +314,7 @@ void print_wireless_info(const char *interface, const char *format_up, const cha
         }
 
         (void)printf("%s", endcolor());
+
+        if (output_format == O_I3BAR)
+                printf("\"}");
 }