Skip to content

Commit

Permalink
win,tty: add uv_tty_{get,set}_vterm_state
Browse files Browse the repository at this point in the history
PR-URL: libuv#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>
  • Loading branch information
erw7 authored and saghul committed Oct 9, 2019
1 parent fdef604 commit fd2ce38
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 11 deletions.
39 changes: 39 additions & 0 deletions docs/src/tty.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
15 changes: 15 additions & 0 deletions include/uv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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++" {
Expand Down
7 changes: 7 additions & 0 deletions src/unix/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
31 changes: 20 additions & 11 deletions src/win/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}

0 comments on commit fd2ce38

Please sign in to comment.