Skip to content

Commit 034bcb0

Browse files
dschoGit for Windows Build Agent
authored andcommitted
win32: use native ANSI sequence processing, if possible (git-for-windows#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 git-for-windows#3712.
2 parents 1840eb1 + 90218f8 commit 034bcb0

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

compat/winansi.c

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

568568
#endif
569569

570+
static HANDLE std_console_handle;
571+
static DWORD std_console_mode = ENABLE_VIRTUAL_TERMINAL_PROCESSING;
572+
static UINT std_console_code_page = CP_UTF8;
573+
574+
static void reset_std_console(void)
575+
{
576+
if (std_console_mode != ENABLE_VIRTUAL_TERMINAL_PROCESSING)
577+
SetConsoleMode(std_console_handle, std_console_mode);
578+
if (std_console_code_page != CP_UTF8)
579+
SetConsoleOutputCP(std_console_code_page);
580+
}
581+
582+
static int enable_virtual_processing(void)
583+
{
584+
std_console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
585+
if (std_console_handle == INVALID_HANDLE_VALUE ||
586+
!GetConsoleMode(std_console_handle, &std_console_mode)) {
587+
std_console_handle = GetStdHandle(STD_ERROR_HANDLE);
588+
if (std_console_handle == INVALID_HANDLE_VALUE ||
589+
!GetConsoleMode(std_console_handle, &std_console_mode))
590+
return 0;
591+
}
592+
593+
std_console_code_page = GetConsoleOutputCP();
594+
if (std_console_code_page != CP_UTF8)
595+
SetConsoleOutputCP(CP_UTF8);
596+
if (!std_console_code_page)
597+
std_console_code_page = CP_UTF8;
598+
599+
atexit(reset_std_console);
600+
601+
if (std_console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)
602+
return 1;
603+
604+
if (!SetConsoleMode(std_console_handle,
605+
std_console_mode |
606+
ENABLE_PROCESSED_OUTPUT |
607+
ENABLE_VIRTUAL_TERMINAL_PROCESSING))
608+
return 0;
609+
610+
return 1;
611+
}
612+
570613
/*
571614
* Wrapper for isatty(). Most calls in the main git code
572615
* call isatty(1 or 2) to see if the instance is interactive
@@ -605,6 +648,9 @@ void winansi_init(void)
605648
return;
606649
}
607650

651+
if (enable_virtual_processing())
652+
return;
653+
608654
/* create a named pipe to communicate with the console thread */
609655
if (swprintf(name, ARRAY_SIZE(name) - 1, L"\\\\.\\pipe\\winansi%lu",
610656
GetCurrentProcessId()) < 0)

0 commit comments

Comments
 (0)