From 517ade8ab219be2cfd24fa3c3e858528a2345769 Mon Sep 17 00:00:00 2001 From: John McNamee Date: Thu, 9 Jul 2015 20:21:04 -0700 Subject: [PATCH] win,tty: support consoles with non-default colors Use the console text color set by the user rather than assuming the Windows default (white foreground on black background). PR-URL: https://github.com/libuv/libuv/pull/431 Reviewed-By: Bert Belder --- src/win/tty.c | 99 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 84 insertions(+), 15 deletions(-) diff --git a/src/win/tty.c b/src/win/tty.c index 63222e36..c3af02f7 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -55,6 +55,7 @@ #define MAX_INPUT_BUFFER_LENGTH 8192 +static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info); static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info); @@ -96,6 +97,15 @@ static CRITICAL_SECTION uv_tty_output_lock; static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE; +static WORD uv_tty_default_text_attributes = + FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + +static char uv_tty_default_fg_color = 7; +static char uv_tty_default_bg_color = 0; +static char uv_tty_default_fg_bright = 0; +static char uv_tty_default_bg_bright = 0; +static char uv_tty_default_inverse = 0; + void uv_console_init() { InitializeCriticalSection(&uv_tty_output_lock); @@ -143,6 +153,9 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { /* is received. */ uv_tty_output_handle = handle; + /* Remember the original console text attributes. */ + uv_tty_capture_initial_style(&screen_buffer_info); + uv_tty_update_virtual_window(&screen_buffer_info); LeaveCriticalSection(&uv_tty_output_lock); @@ -188,6 +201,62 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { } +/* Set the default console text attributes based on how the console was + * configured when libuv started. + */ +static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info) { + static int style_captured = 0; + + /* Only do this once. + /* Assumption: Caller has acquired uv_tty_output_lock. */ + if (style_captured) + return; + + /* Save raw win32 attributes. */ + uv_tty_default_text_attributes = info->wAttributes; + + /* Convert black text on black background to use white text. */ + if (uv_tty_default_text_attributes == 0) + uv_tty_default_text_attributes = 7; + + /* Convert Win32 attributes to ANSI colors. */ + uv_tty_default_fg_color = 0; + uv_tty_default_bg_color = 0; + uv_tty_default_fg_bright = 0; + uv_tty_default_bg_bright = 0; + uv_tty_default_inverse = 0; + + if (uv_tty_default_text_attributes & FOREGROUND_RED) + uv_tty_default_fg_color |= 1; + + if (uv_tty_default_text_attributes & FOREGROUND_GREEN) + uv_tty_default_fg_color |= 2; + + if (uv_tty_default_text_attributes & FOREGROUND_BLUE) + uv_tty_default_fg_color |= 4; + + if (uv_tty_default_text_attributes & BACKGROUND_RED) + uv_tty_default_bg_color |= 1; + + if (uv_tty_default_text_attributes & BACKGROUND_GREEN) + uv_tty_default_bg_color |= 2; + + if (uv_tty_default_text_attributes & BACKGROUND_BLUE) + uv_tty_default_bg_color |= 4; + + if (uv_tty_default_text_attributes & FOREGROUND_INTENSITY) + uv_tty_default_fg_bright = 1; + + if (uv_tty_default_text_attributes & BACKGROUND_INTENSITY) + uv_tty_default_bg_bright = 1; + + if (uv_tty_default_text_attributes & COMMON_LVB_REVERSE_VIDEO) + uv_tty_default_inverse = 1; + + style_captured = 1; +} + + int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { DWORD flags; unsigned char was_reading; @@ -1022,7 +1091,7 @@ static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative, static int uv_tty_reset(uv_tty_t* handle, DWORD* error) { const COORD origin = {0, 0}; - const WORD char_attrs = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + const WORD char_attrs = uv_tty_default_text_attributes; CONSOLE_SCREEN_BUFFER_INFO info; DWORD count, written; @@ -1178,11 +1247,11 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { if (argc == 0) { /* Reset mode */ - fg_color = 7; - bg_color = 0; - fg_bright = 0; - bg_bright = 0; - inverse = 0; + fg_color = uv_tty_default_fg_color; + bg_color = uv_tty_default_bg_color; + fg_bright = uv_tty_default_fg_bright; + bg_bright = uv_tty_default_bg_bright; + inverse = uv_tty_default_inverse; } for (i = 0; i < argc; i++) { @@ -1190,11 +1259,11 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { if (arg == 0) { /* Reset mode */ - fg_color = 7; - bg_color = 0; - fg_bright = 0; - bg_bright = 0; - inverse = 0; + fg_color = uv_tty_default_fg_color; + bg_color = uv_tty_default_bg_color; + fg_bright = uv_tty_default_fg_bright; + bg_bright = uv_tty_default_bg_bright; + inverse = uv_tty_default_inverse; } else if (arg == 1) { /* Foreground bright on */ @@ -1231,8 +1300,8 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { } else if (arg == 39) { /* Default text color */ - fg_color = 7; - fg_bright = 0; + fg_color = uv_tty_default_fg_color; + fg_bright = uv_tty_default_fg_bright; } else if (arg >= 40 && arg <= 47) { /* Set background color */ @@ -1240,8 +1309,8 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { } else if (arg == 49) { /* Default background color */ - bg_color = 0; - bg_bright = 0; + bg_color = uv_tty_default_bg_color; + bg_bright = uv_tty_default_bg_bright; } else if (arg >= 90 && arg <= 97) { /* Set bold foreground color */