win,tty: add uv_tty_{get,set}_vterm_state

PR-URL: https://github.com/libuv/libuv/pull/2501
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Saúl Ibarra Corretgé <s@saghul.net>
Reviewed-By: Jameson Nash <vtjnash+github@gmail.com>
This commit is contained in:
erw7 2019-10-02 14:14:12 +09:00 committed by Saúl Ibarra Corretgé
parent fdef604a1e
commit fd2ce38dd6
4 changed files with 81 additions and 11 deletions

View File

@ -33,6 +33,23 @@ Data types
UV_TTY_MODE_IO
} uv_tty_mode_t;
.. c:type:: uv_tty_vtermstate_t
Console virtual terminal mode type:
::
typedef enum {
/*
* The console supports handling of virtual terminal sequences
* (Windows10 new console, ConEmu)
*/
UV_TTY_SUPPORTED,
/* The console cannot process virtual terminal sequences. (Legacy
* console)
*/
UV_TTY_UNSUPPORTED
} uv_tty_vtermstate_t
Public members
@ -98,3 +115,25 @@ API
Gets the current Window size. On success it returns 0.
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
.. c:function:: void uv_tty_set_vterm_state(uv_tty_vtermstate_t state)
Controls whether console virtual terminal sequences are processed by libuv
or console.
Useful in particular for enabling ConEmu support of ANSI X3.64 and Xterm
256 colors. Otherwise Windows10 consoles are usually detected automatically.
This function is only meaningful on Windows systems. On Unix it is silently
ignored.
.. versionadded:: 1.33.0
.. c:function:: int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state)
Get the current state of whether console virtual terminal sequences are
handled by libuv or the console.
This function is not implemented on Unix, where it returns ``UV_ENOTSUP``.
.. versionadded:: 1.33.0

View File

@ -706,10 +706,25 @@ typedef enum {
UV_TTY_MODE_IO
} uv_tty_mode_t;
typedef enum {
/*
* The console supports handling of virtual terminal sequences
* (Windows10 new console, ConEmu)
*/
UV_TTY_SUPPORTED,
/* The console cannot process the virtual terminal sequence. (Legacy
* console)
*/
UV_TTY_UNSUPPORTED
} uv_tty_vtermstate_t;
UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode);
UV_EXTERN int uv_tty_reset_mode(void);
UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state);
UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state);
#ifdef __cplusplus
extern "C++" {

View File

@ -365,3 +365,10 @@ int uv_tty_reset_mode(void) {
return err;
}
void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) {
}
int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) {
return UV_ENOTSUP;
}

View File

@ -149,13 +149,9 @@ 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 BOOL uv__need_check_vterm_state = TRUE;
static uv_tty_vtermstate_t uv__vterm_state = UV_TTY_UNSUPPORTED;
static void uv__determine_vterm_state(HANDLE handle);
void uv_console_init(void) {
@ -223,7 +219,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int unused) {
* between all uv_tty_t handles. */
uv_sem_wait(&uv_tty_output_lock);
if (uv__vterm_state == UV_UNCHECKED)
if (uv__need_check_vterm_state)
uv__determine_vterm_state(handle);
/* Remember the original console text attributes. */
@ -1675,7 +1671,7 @@ 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) {
if (uv__vterm_state == UV_TTY_SUPPORTED && buf.len > 0) {
utf16_buf_used = MultiByteToWideChar(CP_UTF8,
0,
buf.base,
@ -2280,18 +2276,17 @@ int uv_tty_reset_mode(void) {
static void uv__determine_vterm_state(HANDLE handle) {
DWORD dwMode = 0;
uv__need_check_vterm_state = FALSE;
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;
uv__vterm_state = UV_TTY_SUPPORTED;
}
static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) {
@ -2383,3 +2378,17 @@ static void uv__tty_console_signal_resize(void) {
uv_mutex_unlock(&uv__tty_console_resize_mutex);
}
}
void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) {
uv_sem_wait(&uv_tty_output_lock);
uv__need_check_vterm_state = FALSE;
uv__vterm_state = state;
uv_sem_post(&uv_tty_output_lock);
}
int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) {
uv_sem_wait(&uv_tty_output_lock);
*state = uv__vterm_state;
uv_sem_post(&uv_tty_output_lock);
return 0;
}