Win32: Switch codepage to UTF8 in Screen constructor

Co-authored-by: Mikael Olenfalk <mikael@olenfalk.se>
Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
This commit is contained in:
Mikael Olenfalk 2020-03-22 11:29:33 +01:00 committed by ArthurSonzogni
parent b6d1f8ebdb
commit f927d3d712
2 changed files with 44 additions and 31 deletions

View File

@ -101,44 +101,41 @@ void ScreenInteractive::EventLoop(Component* component) {
void ScreenInteractive::Loop(Component* component) { void ScreenInteractive::Loop(Component* component) {
// Install a SIGINT handler and restore the old handler on exit. // Install a SIGINT handler and restore the old handler on exit.
install_signal_handler(SIGINT, OnExit); install_signal_handler(SIGINT, OnExit);
// Handle resize.
install_signal_handler(SIGWINCH, OnResize);
// Save the old terminal configuration and restore it on exit. // Save the old terminal configuration and restore it on exit.
#ifdef WIN32 #ifdef WIN32
// some special utf8 dance needed. // Enable VT processing on stdout and stdin
SetConsoleOutputCP(CP_UTF8); auto stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
setvbuf(stdout, nullptr, _IONBF, 0); auto stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD original_mode = 0; DWORD out_mode = 0;
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &original_mode); DWORD in_mode = 0;
on_exit_functions.push([original_mode]() { GetConsoleMode(stdout_handle, &out_mode);
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), original_mode); GetConsoleMode(stdin_handle, &in_mode);
}); on_exit_functions.push([=] { SetConsoleMode(stdout_handle, out_mode); });
on_exit_functions.push([=] { SetConsoleMode(stdin_handle, in_mode); });
DWORD mode = original_mode; out_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
// disable echo out_mode |= DISABLE_NEWLINE_AUTO_RETURN;
mode &= ~ENABLE_ECHO_INPUT;
mode |= ENABLE_VIRTUAL_TERMINAL_INPUT; in_mode &= ~ENABLE_ECHO_INPUT;
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; in_mode &= ~ENABLE_LINE_INPUT;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode); in_mode |= ENABLE_VIRTUAL_TERMINAL_INPUT;
in_mode |= ENABLE_WINDOW_INPUT;
SetConsoleMode(stdin_handle, in_mode);
SetConsoleMode(stdout_handle, out_mode);
#else #else
struct termios terminal_configuration_old; // Handle resize.
tcgetattr(STDIN_FILENO, &terminal_configuration_old); install_signal_handler(SIGWINCH, OnResize);
on_exit_functions.push(
[terminal_configuration_old = terminal_configuration_old]() {
tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_old);
});
// Set the new terminal configuration struct termios terminal;
struct termios terminal_configuration_new; tcgetattr(STDIN_FILENO, &terminal);
terminal_configuration_new = terminal_configuration_old; on_exit_functions.push([=] { tcsetattr(STDIN_FILENO, TCSANOW, &terminal); });
// Non canonique terminal. terminal.c_lflag &= ~ICANON; // Non canonique terminal.
terminal_configuration_new.c_lflag &= ~ICANON; terminal.c_lflag &= ~ECHO; // Do not print after a key press.
// Do not print after a key press. tcsetattr(STDIN_FILENO, TCSANOW, &terminal);
terminal_configuration_new.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &terminal_configuration_new);
#endif #endif
// Hide the cursor and show it at exit. // Hide the cursor and show it at exit.

View File

@ -7,6 +7,12 @@
#include "ftxui/screen/string.hpp" #include "ftxui/screen/string.hpp"
#include "ftxui/screen/terminal.hpp" #include "ftxui/screen/terminal.hpp"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#endif
namespace ftxui { namespace ftxui {
namespace { namespace {
@ -68,7 +74,17 @@ Screen::Screen(int dimx, int dimy)
: stencil({0, dimx - 1, 0, dimy - 1}), : stencil({0, dimx - 1, 0, dimy - 1}),
dimx_(dimx), dimx_(dimx),
dimy_(dimy), dimy_(dimy),
pixels_(dimy, std::vector<Pixel>(dimx)) {} pixels_(dimy, std::vector<Pixel>(dimx)) {
#if defined(WIN32)
// The placement of this call is a bit weird, however we can assume that
// anybody who instantiates a Screen object eventually wants to output
// something to the console.
// As we require UTF8 for all input/output operations we will just switch to
// UTF8 encoding here
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
#endif
}
void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) { void UpdatePixelStyle(std::wstringstream& ss, Pixel& previous, Pixel& next) {
if (next.bold != previous.bold) if (next.bold != previous.bold)