Windows/CLog: Support color logging on Win 10

Windows 10 supports V100 on all consoles given
you enable the ENABLE_VIRTUAL_TERMINAL_PROCESSING
flag for the console.

This patch enables color logging only on windows
10 and only if the log is not being redirected
to a file.

Differential Revision: https://developer.blender.org/D10546
This commit is contained in:
Jacob Møller 2021-03-04 18:20:52 -07:00 committed by Ray Molenkamp
parent 6a662ffda8
commit 57812c7e4f

@ -1,4 +1,4 @@
/*
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -38,8 +38,14 @@
#endif
#if defined(_MSC_VER)
// clang-format off
# include <Windows.h>
# include <VersionHelpers.h> /* This needs to be included after Windows.h. */
# include <io.h>
# include <windows.h>
// clang-format on
# if !defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
# endif
#endif
/* For printing timestamp. */
@ -228,6 +234,9 @@ enum eCLogColor {
#define COLOR_LEN (COLOR_RESET + 1)
static const char *clg_color_table[COLOR_LEN] = {NULL};
#ifdef _WIN32
static DWORD clg_previous_console_mode = 0;
#endif
static void clg_color_table_init(bool use_color)
{
@ -548,13 +557,22 @@ static void CLG_ctx_output_set(CLogContext *ctx, void *file_handle)
#if defined(__unix__) || defined(__APPLE__)
ctx->use_color = isatty(ctx->output);
#elif defined(WIN32)
/* Windows Terminal supports color like the Linux terminals do while the standard console does
* not, the way to tell the two apart is to look at the `WT_SESSION` environment variable which
* will only be defined for Windows Terminal. */
/* As of Windows 10 build 18298 all the standard consoles supports color
* like the Linux Terminal do, but it needs to be turned on.
* To turn on colors we need to enable virtual terminal processing by passing the flag
* ENABLE_VIRTUAL_TERMINAL_PROCESSING into SetConsoleMode.
* If the system doesn't support virtual terminal processing it will fail silently and the flag
* will not be set. */
/* #getenv is used here rather than #BLI_getenv since it would be a bad level call
* and there are no benefits for using it in this context. */
ctx->use_color = isatty(ctx->output) && getenv("WT_SESSION");
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &clg_previous_console_mode);
ctx->use_color = 0;
if (IsWindows10OrGreater() && isatty(ctx->output)) {
DWORD mode = clg_previous_console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode)) {
ctx->use_color = 1;
}
}
#endif
}
@ -638,6 +656,9 @@ static CLogContext *CLG_ctx_init(void)
static void CLG_ctx_free(CLogContext *ctx)
{
#if defined(WIN32)
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), clg_previous_console_mode);
#endif
while (ctx->types != NULL) {
CLG_LogType *item = ctx->types;
ctx->types = item->next;