From b3e36c552b3321a5e317c012d194034d60e363ec Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Sat, 6 Sep 2014 10:46:27 +0200 Subject: [PATCH 1/7] watch: enhancing ANSI color & style support This commit adds support for background colors and additional ANSI styles (faint, italic, underlined, blinking, inversed). --- watch.1 | 2 +- watch.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 21 deletions(-) diff --git a/watch.1 b/watch.1 index e31f642d..34f604aa 100644 --- a/watch.1 +++ b/watch.1 @@ -53,7 +53,7 @@ Exit when the output of changes. .TP \fB\-c\fR, \fB\-\-color\fR -Interpret ANSI color sequences. +Interpret ANSI color and style sequences. .TP \fB\-x\fR, \fB\-\-exec\fR .I command diff --git a/watch.c b/watch.c index 5bd4d269..e7341659 100644 --- a/watch.c +++ b/watch.c @@ -89,7 +89,7 @@ static void __attribute__ ((__noreturn__)) _(" %s [options] command\n"), program_invocation_short_name); fputs(USAGE_OPTIONS, out); fputs(_(" -b, --beep beep if command has a non-zero exit\n"), out); - fputs(_(" -c, --color interpret ANSI color sequences\n"), out); + fputs(_(" -c, --color interpret ANSI color and style sequences\n"), out); fputs(_(" -d, --differences[=]\n" " highlight changes between updates\n"), out); fputs(_(" -e, --errexit exit if command has a non-zero exit\n"), out); @@ -106,34 +106,90 @@ static void __attribute__ ((__noreturn__)) exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } +static int nr_of_colors; +static int attributes; +static int fg_col; +static int bg_col; + static void init_ansi_colors(void) { - int i; short ncurses_colors[] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; - for (i = 0; i < 8; i++) - init_pair(i + 1, ncurses_colors[i], -1); + nr_of_colors = sizeof(ncurses_colors) / sizeof(short); + + for (bg_col = 0; bg_col < nr_of_colors; bg_col++) + for (fg_col = 0; fg_col < nr_of_colors; fg_col++) + init_pair(bg_col * nr_of_colors + fg_col + 1, ncurses_colors[fg_col], ncurses_colors[bg_col]); + + /* default settings */ + attributes = A_NORMAL; + fg_col = COLOR_WHITE; + bg_col = COLOR_BLACK; } + static void set_ansi_attribute(const int attrib) { switch (attrib) { - case -1: - return; - case 0: - standend(); - return; - case 1: - attrset(A_BOLD); - return; - } - if (attrib >= 30 && attrib <= 37) { - color_set(attrib - 29, NULL); - return; + case -1: /* restore last settings */ + break; + case 0: /* restore default settings */ + attributes = A_NORMAL; + fg_col = COLOR_WHITE; + bg_col = COLOR_BLACK; + break; + case 1: /* set bold / increased intensity */ + attributes |= A_BOLD; + break; + case 2: /* set decreased intensity (if supported) */ + attributes |= A_DIM; + break; +#ifdef A_ITALIC + case 3: /* set italic (if supported) */ + attributes |= A_ITALIC; + break; +#endif + case 4: /* set underline */ + attributes |= A_UNDERLINE; + break; + case 5: /* set blinking */ + attributes |= A_BLINK; + break; + case 7: /* set inversed */ + attributes |= A_REVERSE; + break; + case 21: /* unset bold / increased intensity */ + attributes &= ~A_BOLD; + break; + case 22: /* unset bold / any intensity modifier */ + attributes &= ~(A_BOLD | A_DIM); + break; +#ifdef A_ITALIC + case 23: /* unset italic */ + attributes &= A_ITALIC; + break; +#endif + case 24: /* unset underline */ + attributes &= ~A_UNDERLINE; + break; + case 25: /* unset blinking */ + attributes &= ~A_BLINK; + break; + case 27: /* unset inversed */ + attributes &= ~A_REVERSE; + break; + default: + if (attrib >= 30 && attrib <= 37) { /* set foreground color */ + fg_col = attrib - 30; + } else if (attrib >= 40 && attrib <= 47) { /* set background color */ + bg_col = attrib - 40; + } } + + attrset(attributes | COLOR_PAIR(bg_col * nr_of_colors + fg_col + 1)); } static void process_ansi(FILE * fp) @@ -414,7 +470,8 @@ static int run_command(char *restrict command, char **restrict command_argv) xerr(5, _("fdopen")); for (y = show_title; y < height; y++) { - int eolseen = 0, tabpending = 0; + int eolseen = 0, tabpending = 0, tabwaspending; + set_ansi_attribute(-1); #ifdef WITH_WATCH8BIT wint_t carry = WEOF; #endif @@ -426,6 +483,10 @@ static int run_command(char *restrict command, char **restrict command_argv) #endif int attr = 0; + if (tabwaspending && (flags & WATCH_COLOR)) + set_ansi_attribute(-1); + tabwaspending = 0; + if (!eolseen) { /* if there is a tab pending, just * spit spaces until the next stop @@ -475,16 +536,25 @@ static int run_command(char *restrict command, char **restrict command_argv) carry = c; /* character on the next line */ continue; /* because it won't fit here */ } - if (c == WEOF || c == L'\n' || c == L'\t') + if (c == WEOF || c == L'\n' || c == L'\t') { c = L' '; + if (flags & WATCH_COLOR) + attrset(A_NORMAL); + } #else - if (c == EOF || c == '\n' || c == '\t') + if (c == EOF || c == '\n' || c == '\t') { c = ' '; + if (flags & WATCH_COLOR) + attrset(A_NORMAL); + } #endif - if (tabpending && (((x + 1) % 8) == 0)) + if (tabpending && (((x + 1) % 8) == 0)) { tabpending = 0; + tabwaspending = 1; + } } move(y, x); + if (!first_screen && !exit_early && (flags & WATCH_CHGEXIT)) { #ifdef WITH_WATCH8BIT cchar_t oldc; @@ -538,6 +608,7 @@ static int run_command(char *restrict command, char **restrict command_argv) fclose(p); + /* harvest child process and get status, propagated from command */ if (waitpid(child, &status, 0) < 0) xerr(8, _("waitpid")); @@ -733,6 +804,8 @@ int main(int argc, char *argv[]) if (run_command(command, command_argv)) break; + + if (precise_timekeeping) { watch_usec_t cur_time = get_time_usec(); next_loop += USECS_PER_SEC * interval; From 0160bdb559fc1e79e40f0281811a3e3293b08ea9 Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Sat, 6 Sep 2014 10:54:34 +0200 Subject: [PATCH 2/7] watch: fixing future italic support --- watch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch.c b/watch.c index e7341659..b0c132ff 100644 --- a/watch.c +++ b/watch.c @@ -169,7 +169,7 @@ static void set_ansi_attribute(const int attrib) break; #ifdef A_ITALIC case 23: /* unset italic */ - attributes &= A_ITALIC; + attributes &= ~A_ITALIC; break; #endif case 24: /* unset underline */ From e428a27af95c4b79474452aac8dd5e8fecb85984 Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Mon, 8 Sep 2014 15:50:24 +0200 Subject: [PATCH 3/7] watch: fixing default color handling Previously the default background color was expected to be always black and the default foreground color was expected to be always white. This commit extends the group of color pairs with pairs containing default colors. --- watch.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/watch.c b/watch.c index b0c132ff..84fd58be 100644 --- a/watch.c +++ b/watch.c @@ -111,11 +111,19 @@ static int attributes; static int fg_col; static int bg_col; + +static void reset_ansi(void) +{ + attributes = A_NORMAL; + fg_col = 0; + bg_col = 0; +} + static void init_ansi_colors(void) { short ncurses_colors[] = { - COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, - COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE + -1, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, + COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; nr_of_colors = sizeof(ncurses_colors) / sizeof(short); @@ -123,11 +131,7 @@ static void init_ansi_colors(void) for (bg_col = 0; bg_col < nr_of_colors; bg_col++) for (fg_col = 0; fg_col < nr_of_colors; fg_col++) init_pair(bg_col * nr_of_colors + fg_col + 1, ncurses_colors[fg_col], ncurses_colors[bg_col]); - - /* default settings */ - attributes = A_NORMAL; - fg_col = COLOR_WHITE; - bg_col = COLOR_BLACK; + reset_ansi(); } @@ -137,9 +141,7 @@ static void set_ansi_attribute(const int attrib) case -1: /* restore last settings */ break; case 0: /* restore default settings */ - attributes = A_NORMAL; - fg_col = COLOR_WHITE; - bg_col = COLOR_BLACK; + reset_ansi(); break; case 1: /* set bold / increased intensity */ attributes |= A_BOLD; @@ -183,9 +185,9 @@ static void set_ansi_attribute(const int attrib) break; default: if (attrib >= 30 && attrib <= 37) { /* set foreground color */ - fg_col = attrib - 30; + fg_col = attrib - 30 + 1; } else if (attrib >= 40 && attrib <= 47) { /* set background color */ - bg_col = attrib - 40; + bg_col = attrib - 40 + 1; } } @@ -469,6 +471,7 @@ static int run_command(char *restrict command, char **restrict command_argv) if ((p = fdopen(pipefd[0], "r")) == NULL) xerr(5, _("fdopen")); + reset_ansi(); for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0, tabwaspending; set_ansi_attribute(-1); From 578cce67304cbbb9db923e0c8318f544e6f4f878 Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Mon, 8 Sep 2014 18:24:28 +0200 Subject: [PATCH 4/7] watch: fixing uninitialized variable --- watch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/watch.c b/watch.c index 84fd58be..5c177a28 100644 --- a/watch.c +++ b/watch.c @@ -473,7 +473,7 @@ static int run_command(char *restrict command, char **restrict command_argv) reset_ansi(); for (y = show_title; y < height; y++) { - int eolseen = 0, tabpending = 0, tabwaspending; + int eolseen = 0, tabpending = 0, tabwaspending = 0; set_ansi_attribute(-1); #ifdef WITH_WATCH8BIT wint_t carry = WEOF; From eae9b671c034e3ab112c805f421a12db767e6a86 Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Mon, 8 Sep 2014 18:28:08 +0200 Subject: [PATCH 5/7] watch: avoid ansi manipulations in non-ansi mode --- watch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/watch.c b/watch.c index 5c177a28..c6ef3892 100644 --- a/watch.c +++ b/watch.c @@ -474,7 +474,8 @@ static int run_command(char *restrict command, char **restrict command_argv) reset_ansi(); for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0, tabwaspending = 0; - set_ansi_attribute(-1); + if (flags & WATCH_COLOR) + set_ansi_attribute(-1); #ifdef WITH_WATCH8BIT wint_t carry = WEOF; #endif From 60660219b8d635ed5e97a398a9db9d93f94736ef Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Tue, 9 Sep 2014 18:13:23 +0200 Subject: [PATCH 6/7] NEWS: adding enhanced ANSI support in watch --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 76f61f81..67fbb9c5 100644 --- a/NEWS +++ b/NEWS @@ -19,7 +19,7 @@ procps-ng-3.3.10 * usernames up to 32 characters now accommodated (up from 19), redhat #1112734 * free exploits MemAvailable field and offers improved memory statistics * free considers slabs in displayed totals, debian #565518, ubuntu #126329 - + * watch supports new ANSI styles and background colors procps-ng-3.3.9 --------------- From 34774392785b9daa08b4de68d7b46da5492663bd Mon Sep 17 00:00:00 2001 From: Jaromir Capik Date: Tue, 9 Sep 2014 18:35:44 +0200 Subject: [PATCH 7/7] 3.3.10 API --- proc/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proc/Makefile.am b/proc/Makefile.am index d14ef075..f000dbcb 100644 --- a/proc/Makefile.am +++ b/proc/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = \ # # See http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html -LIBprocps_CURRENT=3 +LIBprocps_CURRENT=4 LIBprocps_REVISION=0 LIBprocps_AGE=0