Skip to content

Commit 5d2406e

Browse files
committed
win32: use native ANSI sequence processing, if possible (#4700)
Windows 10 version 1511 (also known as Anniversary Update), according to https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences introduced native support for ANSI sequence processing. This allows using colors from the entire 24-bit color range. All we need to do is test whether the console's "virtual processing support" can be enabled. If it can, we do not even need to start the `console_thread` to handle ANSI sequences. Incidentally, this addresses #3712.
2 parents 61f4638 + ff4dcfe commit 5d2406e

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

compat/winansi.c

+46
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,49 @@ static void detect_msys_tty(int fd)
596596

597597
#endif
598598

599+
static HANDLE std_console_handle;
600+
static DWORD std_console_mode = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
601+
static UINT std_console_code_page = CP_UTF8;
602+
603+
static void reset_std_console(void)
604+
{
605+
if (std_console_mode != ENABLE_VIRTUAL_TERMINAL_PROCESSING)
606+
SetConsoleMode(std_console_handle, std_console_mode);
607+
if (std_console_code_page != CP_UTF8)
608+
SetConsoleOutputCP(std_console_code_page);
609+
}
610+
611+
static int enable_virtual_processing(void)
612+
{
613+
std_console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
614+
if (std_console_handle == INVALID_HANDLE_VALUE ||
615+
!GetConsoleMode(std_console_handle, &std_console_mode)) {
616+
std_console_handle = GetStdHandle(STD_ERROR_HANDLE);
617+
if (std_console_handle == INVALID_HANDLE_VALUE ||
618+
!GetConsoleMode(std_console_handle, &std_console_mode))
619+
return 0;
620+
}
621+
622+
std_console_code_page = GetConsoleOutputCP();
623+
if (std_console_code_page != CP_UTF8)
624+
SetConsoleOutputCP(CP_UTF8);
625+
if (!std_console_code_page)
626+
std_console_code_page = CP_UTF8;
627+
628+
atexit(reset_std_console);
629+
630+
if (std_console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)
631+
return 1;
632+
633+
if (!SetConsoleMode(std_console_handle,
634+
std_console_mode |
635+
ENABLE_PROCESSED_OUTPUT |
636+
ENABLE_VIRTUAL_TERMINAL_PROCESSING))
637+
return 0;
638+
639+
return 1;
640+
}
641+
599642
/*
600643
* Wrapper for isatty(). Most calls in the main git code
601644
* call isatty(1 or 2) to see if the instance is interactive
@@ -634,6 +677,9 @@ void winansi_init(void)
634677
return;
635678
}
636679

680+
if (enable_virtual_processing())
681+
return;
682+
637683
/* create a named pipe to communicate with the console thread */
638684
if (swprintf(name, ARRAY_SIZE(name) - 1, L"\\\\.\\pipe\\winansi%lu",
639685
GetCurrentProcessId()) < 0)

0 commit comments

Comments
 (0)