Skip to content

Commit 8be349c

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 5c6ef0a + da21187 commit 8be349c

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

compat/winansi.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,49 @@ static void detect_msys_tty(int fd)
594594

595595
#endif
596596

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

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

0 commit comments

Comments
 (0)