From ac086ed2d55ce9f67e20bb9e96a99ba744c9773c Mon Sep 17 00:00:00 2001 From: Jacob Floyd Date: Tue, 7 Jan 2014 10:30:46 -0500 Subject: [PATCH] [WIP] util: Make colors configurable Add color configuration options to system.conf/user.conf so that users with visual impairment can change colors. This also means that distributions can set colors to match their own color pallete. --- src/core/main.c | 6 ++++++ src/core/system.conf | 8 ++++++++ src/core/user.conf | 8 ++++++++ src/shared/conf-parser.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ src/shared/conf-parser.h | 1 + src/shared/util.c | 34 ++++++++++++++++++++++++++++++++ src/shared/util.h | 29 ++++++++++++++++++++-------- 7 files changed, 128 insertions(+), 8 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index d052c8d..a6ef6d2 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -675,6 +675,12 @@ static int parse_config_file(void) { { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]}, { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]}, { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]}, + { "Manager", "ANSIColorEmphasize", config_parse_ansicolor, 0, NULL }, + { "Manager", "ANSIColorBad", config_parse_ansicolor, 0, NULL }, + { "Manager", "ANSIColorOk", config_parse_ansicolor, 0, NULL }, + { "Manager", "ANSIColorGood", config_parse_ansicolor, 0, NULL }, + { "Manager", "ANSIColorWarn", config_parse_ansicolor, 0, NULL }, + { "Manager", "ANSIColorDeemphasize", config_parse_ansicolor, 0, NULL }, { NULL, NULL, NULL, 0, NULL } }; diff --git a/src/core/system.conf b/src/core/system.conf index 38bbca5..8dc7d64 100644 --- a/src/core/system.conf +++ b/src/core/system.conf @@ -46,3 +46,11 @@ #DefaultLimitNICE= #DefaultLimitRTPRIO= #DefaultLimitRTTIME= + +#These are the SGR parameters ##;##;##... Do not include the Escape code or m. +#ANSIColorEmphasize=1;39 +#ANSIColorBad=1;31 +#ANSIColorOk=32 +#ANSIColorGood=1;32 +#ANSIColorWarn=1;33 +#ANSIColorDeemphasize=1;34 diff --git a/src/core/user.conf b/src/core/user.conf index 923ca66..5845d80 100644 --- a/src/core/user.conf +++ b/src/core/user.conf @@ -19,3 +19,11 @@ #DefaultRestartSec=100ms #DefaultStartLimitInterval=10s #DefaultStartLimitBurst=5 + +#These are the SGR parameters ##;##;##... Do not include the Escape code or m. +#ANSIColorEmphasize=1;39 +#ANSIColorBad=1;31 +#ANSIColorOk=32 +#ANSIColorGood=1;32 +#ANSIColorWarn=1;33 +#ANSIColorDeemphasize=1;34 diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 1e3cee5..e7ddf57 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -913,3 +913,53 @@ int config_parse_set_status(const char *unit, return 0; } + +int config_parse_ansicolor(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char **s = data; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + n = strdup(rvalue); + if (!n) + return log_oom(); + + if (!utf8_is_valid(n)) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "ANSIColor is not UTF-8 clean, ignoring assignment: %s", rvalue); + free(n); + return 0; + } + + if (!in_charset("0123456789;", n)) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, + "ANSIColor is not valid [0-9;], ignoring assignment: %s", rvalue); + free(n); + return 0; + } + + init_ansi_color(lvalue, n); + + free(*s); + if (*n) + *s = n; + else { + free(n); + *s = NULL; + } + + return 0; +} diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 2d5aa31..36c6825 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -110,6 +110,7 @@ int config_parse_mode(const char *unit, const char *filename, unsigned line, con int config_parse_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_set_status(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_ansicolor(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int log_syntax_internal(const char *unit, int level, const char *file, unsigned line, const char *func, diff --git a/src/shared/util.c b/src/shared/util.c index 6c8d348..d7debb2 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -86,9 +86,43 @@ int saved_argc = 0; char **saved_argv = NULL; +//initialize with \x1B[...m +char ansi_color_emphasize = "\x1B[1;39m"; //highlight-normal +char ansi_color_bad = "\x1B[1;31m"; //highlight-red +char ansi_color_ok = "\x1B[32m"; //green +char ansi_color_good = "\x1B[1;32m"; //highlight-green +char ansi_color_warn = "\x1B[1;33m"; //highlight-yellow +char ansi_color_deemphasize = "\x1B[1;34m"; //highlight-blue + static volatile unsigned cached_columns = 0; static volatile unsigned cached_lines = 0; +void init_ansi_color(const char *name, char *color) { + switch( *name[9] ) {/* ASCIColor = 9 characters */ + case E://Emphasize + &ansi_color_emphasize_ = new(char, "\x1B[" color "m") + break; + case B://Bad + &ansi_color_bad_ = new(char, "\x1B[" color "m") + break; + case O://Ok + &ansi_color_ok_ = new(char, "\x1B[" color "m") + break; + case G://Good + &ansi_color_good_ = new(char, "\x1B[" color "m") + break; + case W://Warn + &ansi_color_warn_ = new(char, "\x1B[" color "m") + break; + case D://Deemphasize + &ansi_color_deemphasize_ = new(char, "\x1B[" color "m") + break; + default: + //Unknown color: Silently, and creepily do nothing... + break; + } +} + size_t page_size(void) { static thread_local size_t pgsz = 0; long r; diff --git a/src/shared/util.h b/src/shared/util.h index 8f106ae..cd84b50 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -70,14 +70,26 @@ #define FORMAT_BYTES_MAX 8 -#define ANSI_COLOR_EMPHASIZE "\x1B[1;39m" //highlight-normal -#define ANSI_COLOR_RED "\x1B[31m" //Only for graphics -#define ANSI_COLOR_BAD "\x1B[1;31m" //highlight-red -#define ANSI_COLOR_OK "\x1B[32m" //green -#define ANSI_COLOR_GOOD "\x1B[1;32m" //highlight-green -#define ANSI_COLOR_WARN "\x1B[1;33m" //highlight-yellow -#define ANSI_COLOR_DEEMPHASIZE "\x1B[1;34m" //highlight-blue -#define ANSI_COLOR_OFF "\x1B[0m" //remove coloring +//This feels ugly. Is there any better way to have a global variable in C? +//It's not going to be as efficient as inlining a string via a #define macro. +extern char ansi_color_emphasize_; +extern char ansi_color_bad_; +extern char ansi_color_ok_; +extern char ansi_color_good_; +extern char ansi_color_warn_; +extern char ansi_color_deemphasize_; + +void init_ansi_color(const char *name, char *color); + +#define ANSI_COLOR_EMPHASIZE ansi_color_emphasize_ +#define ANSI_COLOR_BAD ansi_color_bad_ +#define ANSI_COLOR_OK ansi_color_ok_ +#define ANSI_COLOR_GOOD ansi_color_good_ +#define ANSI_COLOR_WARN ansi_color_warn_ +#define ANSI_COLOR_DEEMPHASIZE ansi_color_deemphasize_ + +#define ANSI_COLOR_RED "\x1B[31m" //Only for the Cylon eye graphic +#define ANSI_COLOR_OFF "\x1B[0m" #define ANSI_ERASE_TO_END_OF_LINE "\x1B[K" size_t page_size(void); @@ -411,6 +423,7 @@ void columns_lines_cache_reset(int _unused_ signum); bool on_tty(void); +// I'm not sure how these will have to change if I'm pushing in an extern char instead of #defined string static inline const char *ansi_color_emphasize(void) { return on_tty() ? ANSI_COLOR_EMPHASIZE : ""; } -- 1.8.3.2