summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2012-02-16 23:29:29 +0000
committerMichael Stapelberg <michael@stapelberg.de>2012-02-16 23:30:54 +0000
commitd5b4c8e368050cf1b84b03c1379bbbc3c817a713 (patch)
tree2f918d4c5b95a05ebec68bceec35f7d4fa9a0c4e
parent7149f6f78e0d105f02d54e1db60db8b191a98acb (diff)
Implement the i3bar JSON protocol
This hardcodes all the JSON parts. Strings are not properly escaped currently. The best/easiest way to fix this is by actually using libyajl.
-rw-r--r--i3status.c12
-rw-r--r--include/i3status.h2
-rw-r--r--src/auto_detect_format.c4
-rw-r--r--src/output.c4
-rw-r--r--src/print_battery_info.c6
-rw-r--r--src/print_cpu_temperature.c7
-rw-r--r--src/print_cpu_usage.c7
-rw-r--r--src/print_ddate.c6
-rw-r--r--src/print_disk_info.c6
-rw-r--r--src/print_eth_info.c9
-rw-r--r--src/print_ipv6_addr.c8
-rw-r--r--src/print_load.c7
-rw-r--r--src/print_run_watch.c9
-rw-r--r--src/print_time.c6
-rw-r--r--src/print_volume.c4
-rw-r--r--src/print_wireless_info.c9
16 files changed, 103 insertions, 3 deletions
diff --git a/i3status.c b/i3status.c
index 9f04850..dd7d1e6 100644
--- a/i3status.c
+++ b/i3status.c
@@ -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);
diff --git a/include/i3status.h b/include/i3status.h
index 24097b0..e40003c 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_NONE } output_format;
+enum { O_DZEN2, O_XMOBAR, O_I3BAR, O_NONE } output_format;
#include <stdbool.h>
#include <confuse.h>
diff --git a/src/auto_detect_format.c b/src/auto_detect_format.c
index 299614a..7c4d65d 100644
--- a/src/auto_detect_format.c
+++ b/src/auto_detect_format.c
@@ -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)
diff --git a/src/output.c b/src/output.c
index c0c1480..96dd3e4 100644
--- a/src/output.c
+++ b/src/output.c
@@ -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(" | ");
}
diff --git a/src/print_battery_info.c b/src/print_battery_info.c
index 6ee8989..10137c2 100644
--- a/src/print_battery_info.c
+++ b/src/print_battery_info.c
@@ -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("\"}");
}
diff --git a/src/print_cpu_temperature.c b/src/print_cpu_temperature.c
index 8c343c2..08fac88 100644
--- a/src/print_cpu_temperature.c
+++ b/src/print_cpu_temperature.c
@@ -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
diff --git a/src/print_cpu_usage.c b/src/print_cpu_usage.c
index 1d3bac8..d97a7fa 100644
--- a/src/print_cpu_usage.c
+++ b/src/print_cpu_usage.c
@@ -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);
diff --git a/src/print_ddate.c b/src/print_ddate.c
index 453e5a2..0401a3f 100644
--- a/src/print_ddate.c
+++ b/src/print_ddate.c
@@ -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("\"}");
}
diff --git a/src/print_disk_info.c b/src/print_disk_info.c
index b2cbd9c..1ac22d0 100644
--- a/src/print_disk_info.c
+++ b/src/print_disk_info.c
@@ -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("\"}");
}
diff --git a/src/print_eth_info.c b/src/print_eth_info.c
index 28ba6c1..4fae191 100644
--- a/src/print_eth_info.c
+++ b/src/print_eth_info.c
@@ -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("\"}");
}
diff --git a/src/print_ipv6_addr.c b/src/print_ipv6_addr.c
index e96c0d3..3ace6a2 100644
--- a/src/print_ipv6_addr.c
+++ b/src/print_ipv6_addr.c
@@ -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("\"}");
}
diff --git a/src/print_load.c b/src/print_load.c
index d47ecea..8c2343b 100644
--- a/src/print_load.c
+++ b/src/print_load.c
@@ -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
diff --git a/src/print_run_watch.c b/src/print_run_watch.c
index 455130e..c806d8e 100644
--- a/src/print_run_watch.c
+++ b/src/print_run_watch.c
@@ -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("\"}");
}
diff --git a/src/print_time.c b/src/print_time.c
index 9c9df90..3c48d3f 100644
--- a/src/print_time.c
+++ b/src/print_time.c
@@ -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("\"}");
}
diff --git a/src/print_volume.c b/src/print_volume.c
index c13cb17..85b6176 100644
--- a/src/print_volume.c
+++ b/src/print_volume.c
@@ -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("\"}");
}
diff --git a/src/print_wireless_info.c b/src/print_wireless_info.c
index 1aca346..530d9cf 100644
--- a/src/print_wireless_info.c
+++ b/src/print_wireless_info.c
@@ -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("\"}");
}