Revert "Revert "win,tty: add support for ANSI codes in win10 v1511""

To bring back support for ANSI codes in win10 v1511.

This reverts commit 8cbabaa817.

PR-URL: https://github.com/libuv/libuv/pull/1143
Refs: https://github.com/libuv/libuv/pull/1138
Refs: https://github.com/libuv/libuv/pull/889
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Imran Iqbal <imran@imraniqbal.org>
This commit is contained in:
Santiago Gimeno 2016-11-16 16:16:54 +01:00
parent c1c55ee1aa
commit 445e3a1f06
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE
3 changed files with 106 additions and 0 deletions

View File

@ -57,6 +57,9 @@
#define MAX_INPUT_BUFFER_LENGTH 8192
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info);
static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
@ -125,6 +128,14 @@ static char uv_tty_default_fg_bright = 0;
static char uv_tty_default_bg_bright = 0;
static char uv_tty_default_inverse = 0;
typedef enum {
UV_SUPPORTED,
UV_UNCHECKED,
UV_UNSUPPORTED
} uv_vtermstate_t;
/* Determine whether or not ANSI support is enabled. */
static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED;
static void uv__determine_vterm_state(HANDLE handle);
void uv_console_init() {
if (uv_sem_init(&uv_tty_output_lock, 1))
@ -168,6 +179,9 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
/* shared between all uv_tty_t handles. */
uv_sem_wait(&uv_tty_output_lock);
if (uv__vterm_state == UV_UNCHECKED)
uv__determine_vterm_state(handle);
/* Store the global tty output handle. This handle is used by TTY read */
/* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */
/* is received. */
@ -1636,6 +1650,33 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
uv_buf_t buf = bufs[i];
unsigned int j;
if (uv__vterm_state == UV_SUPPORTED && buf.len > 0) {
utf16_buf_used = MultiByteToWideChar(CP_UTF8,
0,
buf.base,
buf.len,
NULL,
0);
if (utf16_buf_used == 0) {
*error = GetLastError();
break;
}
if (!MultiByteToWideChar(CP_UTF8,
0,
buf.base,
buf.len,
utf16_buf,
utf16_buf_used)) {
*error = GetLastError();
break;
}
FLUSH_TEXT();
continue;
}
for (j = 0; j < buf.len; j++) {
unsigned char c = buf.base[j];
@ -2193,3 +2234,24 @@ int uv_tty_reset_mode(void) {
/* Not necessary to do anything. */
return 0;
}
/* Determine whether or not this version of windows supports
* proper ANSI color codes. Should be supported as of windows
* 10 version 1511, build number 10.0.10586.
*/
static void uv__determine_vterm_state(HANDLE handle) {
DWORD dwMode = 0;
if (!GetConsoleMode(handle, &dwMode)) {
uv__vterm_state = UV_UNSUPPORTED;
return;
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(handle, dwMode)) {
uv__vterm_state = UV_UNSUPPORTED;
return;
}
uv__vterm_state = UV_SUPPORTED;
}

View File

@ -47,6 +47,7 @@ TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty)
#ifdef _WIN32
TEST_DECLARE (tty_raw)
TEST_DECLARE (tty_empty_write)
#endif
TEST_DECLARE (tty_file)
TEST_DECLARE (tty_pty)
@ -404,6 +405,7 @@ TASK_LIST_START
TEST_ENTRY (tty)
#ifdef _WIN32
TEST_ENTRY (tty_raw)
TEST_ENTRY (tty_empty_write)
#endif
TEST_ENTRY (tty_file)
TEST_ENTRY (tty_pty)

View File

@ -212,6 +212,48 @@ TEST_IMPL(tty_raw) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tty_empty_write) {
int r;
int ttyout_fd;
uv_tty_t tty_out;
uv_loop_t* loop = uv_default_loop();
/* Make sure we have an FD that refers to a tty */
HANDLE handle;
handle = CreateFileA("conout$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
ASSERT(handle != INVALID_HANDLE_VALUE);
ttyout_fd = _open_osfhandle((intptr_t) handle, 0);
ASSERT(ttyout_fd >= 0);
ASSERT(UV_TTY == uv_guess_handle(ttyout_fd));
r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 0); /* Writable. */
ASSERT(r == 0);
char dummy[1];
uv_buf_t bufs[1];
bufs[0].len = 0;
bufs[0].base = &dummy;
r = uv_try_write((uv_stream_t*) &tty_out, bufs, 1);
ASSERT(r == 0);
uv_close((uv_handle_t*) &tty_out, NULL);
uv_run(loop, UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif