87 lines
2.4 KiB
C++
87 lines
2.4 KiB
C++
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
|
|
#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;
|
|
} |