#include #include #include "environment.hpp" static HANDLE hStdin = NULL; static HANDLE hStdout = NULL; static int savedConsoleOutputModeIsValid = 0; static DWORD savedConsoleOutputMode = 0; static int savedConsoleInputModeIsValid = 0; static DWORD savedConsoleInputMode = 0; static void disableRawMode(void) { printf("\x1b[0m"); fflush(stdout); if (savedConsoleOutputModeIsValid) SetConsoleMode(hStdout, savedConsoleOutputMode); if (savedConsoleInputModeIsValid) SetConsoleMode(hStdin, savedConsoleInputMode); } int enableRawMode(void) { // Make sure the console state will be returned to its original state // when this program ends atexit(disableRawMode); // Get handles for stdin and stdout hStdin = GetStdHandle(STD_INPUT_HANDLE); if (hStdin == INVALID_HANDLE_VALUE || hStdin == NULL) return 1; hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdout == INVALID_HANDLE_VALUE || hStdout == NULL) return 1; // Set console to "raw" mode if (!GetConsoleMode(hStdout, &savedConsoleOutputMode)) return 1; savedConsoleOutputModeIsValid = 1; DWORD newOutputMode = savedConsoleOutputMode; newOutputMode |= ENABLE_PROCESSED_OUTPUT; newOutputMode &= ~ENABLE_WRAP_AT_EOL_OUTPUT; newOutputMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; if (!SetConsoleMode(hStdout, newOutputMode)) return 1; if (!GetConsoleMode(hStdin, &savedConsoleInputMode)) return 1; savedConsoleInputModeIsValid = 1; DWORD newInputMode = savedConsoleInputMode; newInputMode &= ~ENABLE_ECHO_INPUT; newInputMode &= ~ENABLE_LINE_INPUT; newInputMode &= ~ENABLE_PROCESSED_INPUT; newInputMode |= ENABLE_VIRTUAL_TERMINAL_INPUT; if (!SetConsoleMode(hStdin, newInputMode)) return 1; return 0; } // https://stackoverflow.com/questions/6812224/getting-terminal-size-in-c-for-windows int getWindowSize(int *rows, int *cols) { CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); *cols = csbi.srWindow.Right - csbi.srWindow.Left + 1; *rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; return 0; } int writeTerm(const char *buf, int length) { unsigned long wrote = 0; WriteConsoleA(hStdout, buf, length, &wrote, NULL); return (int)wrote; } int readTerm(char *buf, int length) { unsigned long read = 0; ReadConsoleA(hStdin, buf, length, &read, NULL); return (int)read; }