summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorblastmaster <blastmaster@tuxcode.org>2016-07-16 01:53:42 +0200
committerThomas Graf <tgraf@suug.ch>2016-07-19 22:57:37 +0200
commit828b5b5368bc5054b16a2504fcbb7a7e77087598 (patch)
treeff274a541dd3184bcc879d6d26a434a21c6c1bff
parent1c25eacc95d209716084d9fb28db4c7340b74471 (diff)
enabling colors for bmon
This commit enables colors in bmon. It adds configuration options to let the user decide, which colors should be used. Therefor the graph_rx and graph_tx layouts are introduced and applied respectively. * Add graph_rx, graph_tx and layout_cfg fields. * Setting default colors if colorized output is enabled. * draw_table accept additional layout parameter and apply the given layout for the table graph. * Apply layouts for rx, tx graph and header and statusbar. * Add include/layout.h, which provides functions to parse, color and attribute strings and set the layout. * Adding a default layout-config example in examples/bmon.conf. [Edit: Based on original work by eri!, #PR23]
-rw-r--r--examples/bmon.conf24
-rw-r--r--include/bmon/conf.h2
-rw-r--r--include/bmon/layout.h128
-rw-r--r--src/conf.c100
-rw-r--r--src/out_curses.c17
5 files changed, 253 insertions, 18 deletions
diff --git a/examples/bmon.conf b/examples/bmon.conf
index 389b054..93d64c3 100644
--- a/examples/bmon.conf
+++ b/examples/bmon.conf
@@ -86,3 +86,27 @@ history day {
interval = 86400.
size = 60
}
+
+layout colors {
+ color default {
+ color_pair = {"white", "black"}
+ }
+ color statusbar {
+ color_pair = {"blue", "white", "reverse"}
+ }
+ color header {
+ color_pair = {"yellow", "black"}
+ }
+ color list {
+ color_pair = {"white", "black"}
+ }
+ color selected {
+ color_pair = {"white", "black", "reverse"}
+ }
+ color RX_graph {
+ color_pair = {"green", "black"}
+ }
+ color TX_graph {
+ color_pair = {"red", "black"}
+ }
+}
diff --git a/include/bmon/conf.h b/include/bmon/conf.h
index f95d48f..6f248af 100644
--- a/include/bmon/conf.h
+++ b/include/bmon/conf.h
@@ -74,6 +74,8 @@ enum {
LAYOUT_HEADER,
LAYOUT_LIST,
LAYOUT_SELECTED,
+ LAYOUT_RX_GRAPH,
+ LAYOUT_TX_GRAPH,
__LAYOUT_MAX
};
diff --git a/include/bmon/layout.h b/include/bmon/layout.h
new file mode 100644
index 0000000..cca2a4c
--- /dev/null
+++ b/include/bmon/layout.h
@@ -0,0 +1,128 @@
+
+#ifndef __BMON_LAYOUT_H_
+#define __BMON_LAYOUT_H_
+
+#include <bmon/bmon.h>
+#include <bmon/conf.h>
+#include <bmon/unit.h>
+#include <bmon/utils.h>
+
+
+static int parse_color(const char* color)
+{
+ int color_code = -1;
+
+ if ((strcasestr(color, "red") != NULL))
+ color_code = COLOR_RED;
+ else if ((strcasestr(color, "green") != NULL))
+ color_code = COLOR_GREEN;
+ else if ((strcasestr(color, "white") != NULL))
+ color_code = COLOR_WHITE;
+ else if ((strcasestr(color, "black") != NULL))
+ color_code = COLOR_BLACK;
+ else if ((strcasestr(color, "blue") != NULL))
+ color_code = COLOR_BLUE;
+ else if ((strcasestr(color, "yellow") != NULL))
+ color_code = COLOR_YELLOW;
+ else if ((strcasestr(color, "magenta") != NULL))
+ color_code = COLOR_MAGENTA;
+ else if ((strcasestr(color, "cyan") != NULL))
+ color_code = COLOR_CYAN;
+
+ return color_code;
+}
+
+/*
+ A_NORMAL Normal display (no highlight)
+ A_STANDOUT Best highlighting mode of the terminal.
+ A_UNDERLINE Underlining
+ A_REVERSE Reverse video
+ A_BLINK Blinking
+ A_DIM Half bright
+ A_BOLD Extra bright or bold
+ A_PROTECT Protected mode
+ A_INVIS Invisible or blank mode
+ A_ALTCHARSET Alternate character set
+ A_CHARTEXT Bit-mask to extract a character
+*/
+
+static int parse_attribute(const char* attr)
+{
+ /* no attribute is valid, so we have nothing to do */
+ if (attr == NULL)
+ return 0;
+
+ if ((strcasestr(attr, "normal") != NULL))
+ return A_NORMAL;
+ else if ((strcasestr(attr, "standout") != NULL))
+ return A_STANDOUT;
+ else if ((strcasestr(attr, "underline") != NULL))
+ return A_UNDERLINE;
+ else if ((strcasestr(attr, "reverse") != NULL))
+ return A_REVERSE;
+ else if ((strcasestr(attr, "blink") != NULL))
+ return A_BLINK;
+ else if ((strcasestr(attr, "dim") != NULL))
+ return A_DIM;
+ else if ((strcasestr(attr, "bold") != NULL))
+ return A_BOLD;
+ else if ((strcasestr(attr, "protect") != NULL))
+ return A_PROTECT;
+ else if ((strcasestr(attr, "invis") != NULL))
+ return A_INVIS;
+ else if ((strcasestr(attr, "altcharset") != NULL))
+ return A_ALTCHARSET;
+ else if ((strcasestr(attr, "chartext") != NULL))
+ return A_CHARTEXT;
+
+ return -1;
+}
+
+
+static void add_layout(const char *layout_name, cfg_t *color_cfg)
+{
+ const char *fg, *bg, *attr_str = NULL;
+ int size = -1, fg_code, bg_code, attr_mask, layout_idx = 0;
+
+ size = cfg_size(color_cfg, "color_pair");
+ fg = cfg_getnstr(color_cfg, "color_pair", 0);
+ bg = cfg_getnstr(color_cfg, "color_pair", 1);
+ if (size > 2)
+ attr_str = cfg_getnstr(color_cfg, "color_pair", 2);
+
+ fg_code = parse_color(fg);
+ bg_code = parse_color(bg);
+ if (fg_code == -1 || bg_code == -1) {
+ quit("Unknown color [%s]: %s\n", (fg_code == -1) ? "fg" : "bg",
+ (fg_code == -1) ? fg : bg);
+ }
+ attr_mask = parse_attribute(attr_str);
+ if (attr_mask == -1) {
+ quit("Unknown attribute: '%s'\n", attr_str);
+ }
+
+ DBG("%s:\tfg: %s bg: %s attr: %s\n", layout_name, fg, bg, attr_str);
+
+ if ((strcasecmp(layout_name, "default") == 0))
+ layout_idx = LAYOUT_DEFAULT;
+ else if ((strcasecmp(layout_name, "statusbar") == 0))
+ layout_idx = LAYOUT_STATUSBAR;
+ else if ((strcasecmp(layout_name, "header") == 0))
+ layout_idx = LAYOUT_HEADER;
+ else if ((strcasecmp(layout_name, "list") == 0))
+ layout_idx = LAYOUT_LIST;
+ else if ((strcasecmp(layout_name, "selected") == 0))
+ layout_idx = LAYOUT_SELECTED;
+ else if ((strcasecmp(layout_name, "rx_graph") == 0))
+ layout_idx = LAYOUT_RX_GRAPH;
+ else if ((strcasecmp(layout_name, "tx_graph") == 0))
+ layout_idx = LAYOUT_TX_GRAPH;
+ else {
+ quit("Unknown layout name: '%s'\n", layout_name);
+ }
+
+ struct layout l = { fg_code, bg_code, attr_mask};
+ cfg_layout[layout_idx] = l;
+}
+
+#endif /* __BMON_LAYOUT_H_ */
diff --git a/src/conf.c b/src/conf.c
index d85e9f6..c61fcf8 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -30,6 +30,7 @@
#include <bmon/element.h>
#include <bmon/element_cfg.h>
#include <bmon/history.h>
+#include <bmon/layout.h>
#include <bmon/utils.h>
cfg_t *cfg;
@@ -69,6 +70,16 @@ static cfg_opt_t unit_opts[] = {
CFG_END()
};
+static cfg_opt_t color_opts[] = {
+ CFG_STR_LIST("color_pair", "", CFGF_NONE),
+ CFG_END()
+};
+
+static cfg_opt_t layout_opts[] = {
+ CFG_SEC("color", color_opts, CFGF_MULTI | CFGF_TITLE),
+ CFG_END()
+};
+
static cfg_opt_t global_opts[] = {
CFG_FLOAT("read_interval", 1.0f, CFGF_NONE),
CFG_FLOAT("rate_interval", 1.0f, CFGF_NONE),
@@ -87,6 +98,7 @@ static cfg_opt_t global_opts[] = {
CFG_SEC("attr", attr_opts, CFGF_MULTI | CFGF_TITLE),
CFG_SEC("history", history_opts, CFGF_MULTI | CFGF_TITLE),
CFG_SEC("element", element_opts, CFGF_MULTI | CFGF_TITLE),
+ CFG_SEC("layout", layout_opts, CFGF_MULTI | CFGF_TITLE),
CFG_END()
};
@@ -103,22 +115,26 @@ static char * configfile = NULL;
#if defined HAVE_USE_DEFAULT_COLORS
struct layout cfg_layout[] =
{
- {-1, -1, 0}, /* dummy, not used */
- {-1, -1, 0}, /* default */
- {-1, -1, A_REVERSE}, /* statusbar */
- {-1, -1, 0}, /* header */
- {-1, -1, 0}, /* list */
- {-1, -1, A_REVERSE}, /* selected */
+ {-1, -1, 0}, /* dummy, not used */
+ {-1, -1, 0}, /* default */
+ {-1, -1, A_REVERSE}, /* statusbar */
+ {-1, -1, 0}, /* header */
+ {-1, -1, 0}, /* list */
+ {-1, -1, A_REVERSE}, /* selected */
+ {-1, -1, 0}, /* RX graph */
+ {-1, -1, 0}, /* TX graph */
};
#else
struct layout cfg_layout[] =
{
- {0, 0, 0}, /* dummy, not used */
- {COLOR_BLACK, COLOR_WHITE, 0}, /* default */
- {COLOR_BLACK, COLOR_WHITE, A_REVERSE}, /* statusbar */
- {COLOR_BLACK, COLOR_WHITE, 0}, /* header */
- {COLOR_BLACK, COLOR_WHITE, 0}, /* list */
- {COLOR_BLACK, COLOR_WHITE, A_REVERSE}, /* selected */
+ {0, 0, 0}, /* dummy, not used */
+ {COLOR_WHITE, COLOR_BLACK, 0}, /* default */
+ {COLOR_BLUE, COLOR_GREEN, A_REVERSE}, /* statusbar */
+ {COLOR_GREEN, COLOR_BLACK, 0}, /* header */
+ {COLOR_WHITE, COLOR_BLACK, 0}, /* list */
+ {COLOR_YELLOW, COLOR_BLACK, A_REVERSE}, /* selected */
+ {COLOR_GREEN, COLOR_BLACK, 0}, /* RX graph */
+ {COLOR_RED, COLOR_BLACK, 0}, /* TX graph */
};
#endif
#endif
@@ -423,6 +439,41 @@ static void configfile_read_attrs(void)
}
}
+static void configfile_read_layout_cfg(void)
+{
+ int i, nlayouts;
+ cfg_t *lout;
+ nlayouts = cfg_size(cfg, "layout");
+ for (i = 0; i < nlayouts; i++)
+ {
+ int c, ncolors;
+ const char *name;
+ if (!(lout = cfg_getnsec(cfg, "layout", i)))
+ BUG();
+
+ if (!(name = cfg_title(lout)))
+ BUG();
+
+ ncolors = cfg_size(lout, "color");
+ if (ncolors > LAYOUT_MAX) {
+ fprintf(stderr, "Warning excceeded maximum number of layouts\n");
+ ncolors = LAYOUT_MAX;
+ }
+
+ for (c = 0; c < ncolors; c++) {
+ cfg_t *color_pair;
+
+ if (!(color_pair = cfg_getnsec(lout, "color", c)))
+ BUG();
+
+ if (!(name = cfg_title(color_pair)))
+ BUG();
+
+ add_layout(name, color_pair);
+ }
+ }
+}
+
static void conf_read(const char *path, int must)
{
int err;
@@ -450,6 +501,7 @@ static void conf_read(const char *path, int must)
configfile_read_history();
configfile_read_attrs();
configfile_read_element_cfg();
+ configfile_read_layout_cfg();
}
static const char default_config[] = \
@@ -508,6 +560,29 @@ static const char default_config[] = \
"history day {" \
" interval = 86400.0" \
" size = 60" \
+"}"
+"layout colors {" \
+" color default {" \
+" color_pair = { \"white\", \"black\" }" \
+" }" \
+" color statusbar{" \
+" color_pair = { \"blue\", \"white\", \"reverse\" }" \
+" }" \
+" color header {" \
+" color_pair = { \"yellow\", \"black\" }" \
+" }" \
+" color list {" \
+" color_pair = { \"white\", \"black\" }" \
+" }" \
+" color selected {" \
+" color_pair = { \"yellow\", \"black\", \"reverse\" }" \
+" }" \
+" color rx_graph {" \
+" color_pair = { \"green\", \"black\" }" \
+" }" \
+" color tx_graph {" \
+" color_pair = { \"red\", \"black\" }" \
+" }" \
"}";
static void conf_read_default(void)
@@ -524,6 +599,7 @@ static void conf_read_default(void)
configfile_read_history();
configfile_read_attrs();
configfile_read_element_cfg();
+ configfile_read_layout_cfg();
}
void configfile_read(void)
diff --git a/src/out_curses.c b/src/out_curses.c
index 7b8bc7a..5724121 100644
--- a/src/out_curses.c
+++ b/src/out_curses.c
@@ -420,6 +420,7 @@ static void draw_header(void)
move(row, COLS - strlen(PACKAGE_STRING) - 1);
put_line("%s", PACKAGE_STRING);
move(row, 0);
+ apply_layout(LAYOUT_LIST);
}
static int lines_required_for_statusbar(void)
@@ -632,6 +633,7 @@ static void draw_element(struct element_group *g, struct element *e,
static void draw_group(struct element_group *g, void *arg)
{
+ apply_layout(LAYOUT_HEADER);
int *line = arg;
if (line_visible(*line)) {
@@ -684,7 +686,7 @@ static void draw_graph_centered(struct graph *g, int row, int ncol,
static void draw_table(struct graph *g, struct graph_table *tbl,
struct attr *a, struct history *h,
- const char *hdr, int ncol)
+ const char *hdr, int ncol, int layout)
{
int i, save_row;
char buf[32];
@@ -709,11 +711,14 @@ static void draw_table(struct graph *g, struct graph_table *tbl,
//move(row, ncol + g->g_cfg.gc_width - 3);
//put_line("[err %.2f%%]", rtiming.rt_variance.v_error);
+ memset(buf, 0, strlen(buf));
for (i = (g->g_cfg.gc_height - 1); i >= 0; i--) {
move(++row, ncol);
- put_line("%'8.2f %s",
- tbl->gt_scale[i],
- tbl->gt_table + (i * graph_row_size(&g->g_cfg)));
+ sprintf(buf, "%'8.2f ", tbl->gt_scale[i]);
+ addstr(buf);
+ apply_layout(layout);
+ put_line("%s", tbl->gt_table + (i * graph_row_size(&g->g_cfg)));
+ apply_layout(LAYOUT_LIST);
}
move(++row, ncol);
@@ -747,14 +752,14 @@ static void draw_history_graph(struct attr *a, struct history *h)
graph_refill(g, h);
save_row = row;
- draw_table(g, &g->g_rx, a, h, "RX", ncol);
+ draw_table(g, &g->g_rx, a, h, "RX", ncol, LAYOUT_RX_GRAPH);
if (graph_display == GRAPH_DISPLAY_SIDE_BY_SIDE) {
ncol = cols / 2;
row = save_row;
}
- draw_table(g, &g->g_tx, a, h, "TX", ncol);
+ draw_table(g, &g->g_tx, a, h, "TX", ncol, LAYOUT_TX_GRAPH);
graph_free(g);
}