[+] Internal TTY double buffeirng under NT
[+] NT: TTYScrollBuffer [*] Move TTY under the ConsoleTTY namespace
This commit is contained in:
parent
de504a3a2d
commit
adcde3b0a3
@ -55,29 +55,11 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM AuSPtr<Loop::ILoopSource> StdInBufferLoopSource();
|
||||
|
||||
AUKN_SYM AuUInt32 TTYWrite(const void *buffer, AuUInt32 length);
|
||||
AUKN_SYM void TTYWrite(const char *string, EAnsiColor fgColor = EAnsiColor::eEnumCount, EAnsiColor bgColor = EAnsiColor::eEnumCount);
|
||||
|
||||
AUKN_SYM void TTYFill(char character, EAnsiColor fgColor = EAnsiColor::eEnumCount, EAnsiColor bgColor = EAnsiColor::eEnumCount);
|
||||
|
||||
AUKN_SYM void TTYClearLine(EAnsiColor bgColor = EAnsiColor::eEnumCount);
|
||||
AUKN_SYM void TTYClearScreen();
|
||||
|
||||
AUKN_SYM AuPair<AuUInt32, AuUInt32> TTYScreenSize();
|
||||
|
||||
AUKN_SYM void TTYSetPos(AuPair<AuUInt32, AuUInt32> position);
|
||||
AUKN_SYM void TTYStorePos();
|
||||
AUKN_SYM void TTYRestorePos();
|
||||
AUKN_SYM void TTYMoveY(AuInt16 lines);
|
||||
AUKN_SYM void TTYMoveX(AuInt16 cols);
|
||||
AUKN_SYM void TTYSetY(AuUInt16 Y);
|
||||
AUKN_SYM void TTYSetX(AuUInt16 X);
|
||||
|
||||
AUKN_SYM void TTYReturnHome();
|
||||
|
||||
AUKN_SYM void OpenLateStd();
|
||||
AUKN_SYM void OpenLateGUI();
|
||||
}
|
||||
|
||||
#include "ConsoleTTY/ConsoleTTY.hpp"
|
||||
|
||||
#include "Commands/Commands.hpp"
|
||||
#include "Hooks/Hooks.hpp"
|
||||
|
33
Include/Aurora/Console/ConsoleTTY/ConsoleTTY.hpp
Normal file
33
Include/Aurora/Console/ConsoleTTY/ConsoleTTY.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ConsoleTTY.hpp
|
||||
Date: 2022-5-11
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Console::ConsoleTTY
|
||||
{
|
||||
AUKN_SYM AuUInt32 TTYWrite(const void *buffer, AuUInt32 length);
|
||||
AUKN_SYM void TTYWrite(const char *string, EAnsiColor fgColor = EAnsiColor::eEnumCount, EAnsiColor bgColor = EAnsiColor::eEnumCount);
|
||||
|
||||
AUKN_SYM void TTYFill(char character, EAnsiColor fgColor = EAnsiColor::eEnumCount, EAnsiColor bgColor = EAnsiColor::eEnumCount);
|
||||
|
||||
AUKN_SYM void TTYClearLine(EAnsiColor bgColor = EAnsiColor::eEnumCount);
|
||||
AUKN_SYM void TTYClearScreen();
|
||||
|
||||
AUKN_SYM AuPair<AuUInt32, AuUInt32> TTYScreenSize();
|
||||
|
||||
AUKN_SYM void TTYScrollBuffer(int Y);
|
||||
|
||||
AUKN_SYM void TTYSetPos(AuPair<AuUInt32, AuUInt32> position);
|
||||
AUKN_SYM void TTYStorePos();
|
||||
AUKN_SYM void TTYRestorePos();
|
||||
AUKN_SYM void TTYMoveY(AuInt16 lines);
|
||||
AUKN_SYM void TTYMoveX(AuInt16 cols);
|
||||
AUKN_SYM void TTYSetY(AuUInt16 Y);
|
||||
AUKN_SYM void TTYSetX(AuUInt16 X);
|
||||
|
||||
AUKN_SYM void TTYReturnHome();
|
||||
}
|
@ -1,38 +1,41 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: ConsoleTTY.NT.cpp
|
||||
Date: 2022-5-2
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "../Console.hpp"
|
||||
#include <Source/Console/Console.hpp>
|
||||
#include "ConsoleTTY.NT.hpp"
|
||||
#include "../ColorConvert.hpp"
|
||||
#include <Source/Console/ColorConvert.hpp>
|
||||
#include <Source/Console/ConsoleStd/ConsoleStd.hpp>
|
||||
|
||||
namespace Aurora::Console
|
||||
namespace Aurora::Console::ConsoleTTY
|
||||
{
|
||||
static HANDLE gConsole {INVALID_HANDLE_VALUE};
|
||||
static COORD gSavedCoord {};
|
||||
|
||||
HANDLE GetTTYHandle()
|
||||
{
|
||||
if (gConsole != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return gConsole;
|
||||
}
|
||||
static bool gIsRecording {};
|
||||
static AuThreadPrimitives::SpinLock gRecordLock;
|
||||
static AuList<AuFunction<void()>> gRecordedActions {};
|
||||
|
||||
return gConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
#define TTY_RECORD_FOR_FLIP(func, ...) \
|
||||
if (gIsRecording) \
|
||||
{ \
|
||||
AU_LOCK_GUARD(gRecordLock); \
|
||||
gRecordedActions.push_back(std::bind(func, ## __VA_ARGS__)); \
|
||||
}
|
||||
|
||||
AUKN_SYM void SuperSecretTTYReplacer(HANDLE console)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(SuperSecretTTYReplacer, console);
|
||||
gConsole = console;
|
||||
}
|
||||
|
||||
AUKN_SYM void TTYClearLine(EAnsiColor bgColor)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYClearLine, bgColor);
|
||||
|
||||
HANDLE hConsole;
|
||||
DWORD cCharsWritten;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
@ -67,6 +70,8 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYClearScreen()
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYClearScreen);
|
||||
|
||||
HANDLE hConsole;
|
||||
DWORD cCharsWritten;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
@ -109,6 +114,8 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYFill(char character, EAnsiColor fgColor, EAnsiColor bgColor)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYFill, character, fgColor, bgColor);
|
||||
|
||||
DWORD attrib {0}, cCharsWritten {};
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
HANDLE hConsole;
|
||||
@ -158,11 +165,14 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM AuUInt32 TTYWrite(const void *buffer, AuUInt32 length)
|
||||
{
|
||||
// no record required
|
||||
return ConsoleStd::WriteStdOutBlocking2(buffer, length);
|
||||
}
|
||||
|
||||
AUKN_SYM void TTYWrite(const char *string, EAnsiColor fgColor, EAnsiColor bgColor)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP((void(*)(const char *, EAnsiColor, EAnsiColor))(TTYWrite), string, fgColor, bgColor);
|
||||
|
||||
DWORD attrib {};
|
||||
HANDLE hConsole;
|
||||
|
||||
@ -200,6 +210,8 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYReturnHome()
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYReturnHome);
|
||||
|
||||
SetConsoleCursorPosition(GetTTYHandle(), {0, 0});
|
||||
}
|
||||
|
||||
@ -218,6 +230,8 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYStorePos()
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYStorePos);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
if (!GetConsoleScreenBufferInfo(GetTTYHandle(), &csbi))
|
||||
@ -230,12 +244,16 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYRestorePos()
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYRestorePos);
|
||||
|
||||
SetConsoleCursorPosition(GetTTYHandle(), gSavedCoord);
|
||||
}
|
||||
|
||||
AUKN_SYM void TTYMoveY(AuInt16 lines)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYMoveY, lines);
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
HANDLE hConsole;
|
||||
|
||||
hConsole = GetTTYHandle();
|
||||
@ -251,6 +269,8 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYMoveX(AuInt16 lines)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYMoveX, lines);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
HANDLE hConsole;
|
||||
|
||||
@ -267,6 +287,8 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYSetY(AuUInt16 Y)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYSetY, Y);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
HANDLE hConsole;
|
||||
|
||||
@ -283,6 +305,8 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYSetX(AuUInt16 X)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYSetX, X);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
HANDLE hConsole;
|
||||
|
||||
@ -299,6 +323,149 @@ namespace Aurora::Console
|
||||
|
||||
AUKN_SYM void TTYSetPos(AuPair<AuUInt32, AuUInt32> position)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYSetPos, position);
|
||||
|
||||
SetConsoleCursorPosition(GetTTYHandle(), COORD {AuStaticCast<short>(position.first), AuStaticCast<short>(position.second)});
|
||||
}
|
||||
|
||||
AUKN_SYM void TTYScrollBuffer(int Y)
|
||||
{
|
||||
TTY_RECORD_FOR_FLIP(TTYScrollBuffer, Y);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
SMALL_RECT srctScrollRect, srctClipRect;
|
||||
HANDLE hConsole;
|
||||
COORD coordDest;
|
||||
|
||||
hConsole = GetTTYHandle();
|
||||
|
||||
if (!GetConsoleScreenBufferInfo(hConsole, &csbi))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto res = AuMakePair(AuStaticCast<AuUInt32>(csbi.srWindow.Right - csbi.srWindow.Left + 1),
|
||||
AuStaticCast<AuUInt32>(csbi.srWindow.Bottom - csbi.srWindow.Top + 1));
|
||||
|
||||
srctScrollRect.Top = 0;
|
||||
srctScrollRect.Bottom = csbi.dwSize.Y - 1;
|
||||
srctScrollRect.Left = 0;
|
||||
srctScrollRect.Right = csbi.dwSize.X - 1;
|
||||
|
||||
coordDest.X = 0;
|
||||
coordDest.Y = -1;
|
||||
|
||||
srctClipRect = srctScrollRect;
|
||||
|
||||
CHAR_INFO chiFill;
|
||||
chiFill.Attributes = BACKGROUND_BLACK | FOREGROUND_WHITE;
|
||||
chiFill.Char.UnicodeChar = ' ';
|
||||
|
||||
ScrollConsoleScreenBufferW(
|
||||
hConsole,
|
||||
&srctScrollRect,
|
||||
&srctClipRect,
|
||||
coordDest,
|
||||
&chiFill);
|
||||
}
|
||||
|
||||
struct Console
|
||||
{
|
||||
HANDLE h {INVALID_HANDLE_VALUE};
|
||||
int width, height;
|
||||
};
|
||||
|
||||
static Console gConsoles[2];
|
||||
static AuUInt32 gConsoleIndex {0};
|
||||
|
||||
HANDLE GetTTYHandle()
|
||||
{
|
||||
if (gConsole != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return gConsole;
|
||||
}
|
||||
|
||||
return gConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
}
|
||||
|
||||
static void AU_NOINLINE InitConsoles()
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
if (!GetConsoleScreenBufferInfo(GetTTYHandle(), &csbi))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto res = AuMakePair(AuStaticCast<AuUInt32>(csbi.srWindow.Right - csbi.srWindow.Left + 1),
|
||||
AuStaticCast<AuUInt32>(csbi.srWindow.Bottom - csbi.srWindow.Top + 1));
|
||||
|
||||
auto &curConsole = gConsoles[gConsoleIndex % 2];
|
||||
|
||||
if (((res.first == curConsole.width &&
|
||||
res.second == curConsole.height)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AuWin32CloseHandle(gConsoles[0].h);
|
||||
AuWin32CloseHandle(gConsoles[1].h);
|
||||
|
||||
auto a = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, 0, nullptr);
|
||||
auto b = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, 0, nullptr);
|
||||
|
||||
SetConsoleScreenBufferSize(a, COORD {(short)res.first, (short)res.second});
|
||||
SetConsoleScreenBufferSize(b, COORD {(short)res.first, (short)res.second});
|
||||
|
||||
SetConsoleWindowInfo(a, true, &csbi.srWindow);
|
||||
SetConsoleWindowInfo(b, true, &csbi.srWindow);
|
||||
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), true, &csbi.srWindow);
|
||||
|
||||
gConsoles[0].width = gConsoles[1].width = res.first;
|
||||
gConsoles[0].height = gConsoles[1].height = res.second;
|
||||
|
||||
gConsoles[0].h = a;
|
||||
gConsoles[1].h = b;
|
||||
}
|
||||
|
||||
void BeginBuffering()
|
||||
{
|
||||
gConsoleIndex++;
|
||||
|
||||
InitConsoles();
|
||||
|
||||
SetConsoleActiveScreenBuffer(gConsoles[(gConsoleIndex + 1) % 2].h);
|
||||
|
||||
gConsole = gConsoles[gConsoleIndex % 2].h;
|
||||
gIsRecording = true;
|
||||
}
|
||||
|
||||
void RecordFunction(const AuFunction<void()> &func)
|
||||
{
|
||||
if (gIsRecording)
|
||||
{
|
||||
AU_LOCK_GUARD(gRecordLock);
|
||||
gRecordedActions.push_back(func);
|
||||
}
|
||||
}
|
||||
|
||||
static void RepeatRecord()
|
||||
{
|
||||
AU_LOCK_GUARD(gRecordLock);
|
||||
|
||||
for (auto action : AuExchange(gRecordedActions, {}))
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
void EndBuffering()
|
||||
{
|
||||
auto &curConsole = gConsoles[gConsoleIndex % 2];
|
||||
SetConsoleActiveScreenBuffer(curConsole.h);
|
||||
|
||||
gConsole = gConsoles[(gConsoleIndex + 1) % 2].h;
|
||||
gIsRecording = false;
|
||||
RepeatRecord();
|
||||
}
|
||||
}
|
@ -6,3 +6,13 @@
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::Console::ConsoleTTY
|
||||
{
|
||||
HANDLE GetTTYHandle();
|
||||
|
||||
void RecordFunction(const AuFunction<void()> &func);
|
||||
|
||||
void BeginBuffering();
|
||||
void EndBuffering();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <Source/Console/ConsoleStd/ConsoleStd.hpp>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
namespace Aurora::Console
|
||||
namespace Aurora::Console::ConsoleTTY
|
||||
{
|
||||
static int gFdTtyHandle {-1};
|
||||
static bool gIsBuffering = false;
|
||||
@ -74,8 +74,8 @@ namespace Aurora::Console
|
||||
kAnsiColorForegroundToVirtualEscape[AuStaticCast<AuUInt>(fgColor)]);
|
||||
|
||||
auto size = TTYScreenSize();
|
||||
AuString line(size.first, character);
|
||||
line += '\n';
|
||||
AuString line(size.first + 1, character);
|
||||
line[line.size() - 1] = '\n';
|
||||
|
||||
if (size.second)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user