From 83f1a1f3e1be15619f936741c2681fed6f28d534 Mon Sep 17 00:00:00 2001 From: Herwin Date: Thu, 1 Jul 2021 21:24:06 +0200 Subject: [PATCH] Initial commit --- .gitignore | 5 + AinsiEscapeCode.pbi | 83 ++++++++++++ Console.pbi | 188 ++++++++++++++++++++++++++ Examples/VirtualTerminal/Basic.pb | 68 ++++++++++ LICENSE | 24 ++++ VirtualTerminal.pbi | 215 ++++++++++++++++++++++++++++++ readme.md | 7 + 7 files changed, 590 insertions(+) create mode 100644 .gitignore create mode 100644 AinsiEscapeCode.pbi create mode 100644 Console.pbi create mode 100644 Examples/VirtualTerminal/Basic.pb create mode 100644 LICENSE create mode 100644 VirtualTerminal.pbi create mode 100644 readme.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..595fdae --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.exe +*.pbi.cfg +*.pb.cfg +*.txt +.idea/ diff --git a/AinsiEscapeCode.pbi b/AinsiEscapeCode.pbi new file mode 100644 index 0000000..44158f0 --- /dev/null +++ b/AinsiEscapeCode.pbi @@ -0,0 +1,83 @@ +;{- Code Header +; ==- Basic Info -================================ +; Name: AinsiEscapeCode.pbi +; Version: N/A +; Author: Herwin Bozet +; +; ==- Compatibility -============================= +; Compiler version: PureBasic 5.70 (x86/x64) +; Operating system: Windows 10 21H1 (Previous versions untested) +; +; ==- Links & License -=========================== +; License: Unlicense +;} + +;- Module Declaration + +DeclareModule AinsiEscapeCode + ;-> Documentation + ; * https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences + ; * https://invisible-island.net/xterm/ctlseqs/ctlseqs.html + ; * https://en.wikipedia.org/wiki/ANSI_escape_code + + + ;-> Constants + + ;-> > Control characters + #BEL$ = #BEL$ + #BS$ = #BS$ + #HT$ = #TAB$ + #LF$ = #LF$ + #FF$ = #FF$ + #CR$ = #CR$ + #ESC$ = #ESC$ + + ;-> > Operators + #CSI$ = "[" + #OSC$ = "]" + + ;-> > Cursor + #CUU$ = "A" ; Cursor Up by n + #CUD$ = "B" ; Cursor Down by n + #CUF$ = "C" ; Cursor Forward (Right) by n + #CUB$ = "D" ; Cursor Backward (Left) by n + + #CNL$ = "E" ; Cursor Next Line by n + #CPL$ = "F" ; Cursor Previous Line by n + + + ;-> Buffer ? + #ED$ = "J" ; Erase in Display + #ED_0 = 0 ; 0 from cursor to end of screen + #ED_1 = 1 ; 1 from cursor to beginning of the screen + #ED_2 = 2 ; 2 clear entire screen (May move to 0:0) + #ED_3 = 3 ; 3 clear entire screen and lines saved in the scrollback buffer. (Does not work on Windows as of 21H1 in Windows Terminal) + + + ;-> Queries + #DECXCPR$ = "6n" ; Emit the cursor position as: ESC [ ; R Where = cursor row and = cursor column + + #DECSC$ = "7" ; Save Cursor Position in Memory** + #DECSR$ = "8" ; Restore Cursor Position from Memory** + + #RI$ = "M" ; Reverse Index – Performs the reverse operation of \n, moves cursor up one line, maintains horizontal position, scrolls buffer if necessary* + + + ; https://invisible-island.net/xterm/ctlseqs/ctlseqs.html + + ; https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#cursor-positioning + #CHA$ = "G" ; Cursor Horizontal Absolute Cursor moves to th position horizontally in the current line + #VPA$ = "d" ; Vertical Line Position Absolute Cursor moves to the th position vertically in the current column + #CUP$ = "H" ; Cursor Position *Cursor moves to ; coordinate within the viewport, where is the column of the line + #HVP$ = "f" ; Horizontal Vertical Position *Cursor moves to ; coordinate within the viewport, where is the column of the line + #ANSISYSSC_DECSC$ = "s" ; Save Cursor – Ansi.sys emulation **With no parameters, performs a save cursor operation like DECSC + #ANSISYSSC_DECRC$ = "u" ; Restore Cursor – Ansi.sys emulation **With no parameters, performs a restore cursor operation like DECRC + +EndDeclareModule + + +;- Module Definition + +Module AinsiEscapeCode + ; Nothing... +EndModule diff --git a/Console.pbi b/Console.pbi new file mode 100644 index 0000000..d94dffa --- /dev/null +++ b/Console.pbi @@ -0,0 +1,188 @@ +;{- Code Header +; ==- Basic Info -================================ +; Name: Console.pbi +; Version: N/A +; Author: Herwin Bozet +; +; ==- Compatibility -============================= +; Compiler version: PureBasic 5.70 (x86/x64) +; Operating system: Windows 10 21H1 (Previous versions untested) +; +; ==- Links & License -=========================== +; License: Unlicense +; MSDN: https://docs.microsoft.com/en-us/windows/console/console-functions +;} + +;- Module declaration + +DeclareModule Console + ;-> Structures + + Structure CursorPosition + X.l + Y.l + EndStructure + + + ;-> Constants + + CompilerIf #PB_Compiler_Console + #IsConsoleApp = #True + CompilerElse + #IsConsoleApp = #False + CompilerEndIf + + ; https://docs.microsoft.com/en-us/windows/console/setconsolemode + ; https://docs.microsoft.com/en-us/windows/console/getconsolemode + ; For input handles + #ENABLE_PROCESSED_INPUT = $0001 + #ENABLE_LINE_INPUT = $0002 + #ENABLE_ECHO_INPUT = $0004 + #ENABLE_WINDOW_INPUT = $0008 + #ENABLE_MOUSE_INPUT = $0010 + #ENABLE_INSERT_MODE = $0020 + #ENABLE_QUICK_EDIT_MODE = $0040 + #ENABLE_VIRTUAL_TERMINAL_INPUT = $0200 + + ; For buffer/output? handles + #ENABLE_PROCESSED_OUTPUT = $0001 + #ENABLE_WRAP_AT_EOL_OUTPUT = $0002 + #ENABLE_VIRTUAL_TERMINAL_PROCESSING = $0004 + #DISABLE_NEWLINE_AUTO_RETURN = $0008 + #ENABLE_LVB_GRID_WORLDWIDE = $0010 + + + ;-> Typedefs Macros + + ; DWORD and HANDLE types from MS libraries + Macro DWORD : l : EndMacro + Macro HANDLE : i : EndMacro + + + ;-> Procedure Declaration + + Declare.s GetConsoleTitle(MaxLength.i = 255) + Macro SetConsoleTitle(Title) : ConsoleTitle(Title) : EndMacro + + Declare.b AddConsoleModeFlag(Flags.DWORD = #Null, ConsoleHandle.Console::HANDLE = #Null) + Declare.b RemoveConsoleModeFlag(Flags.DWORD = #Null, ConsoleHandle.Console::HANDLE = #Null) + + ; May fail on Windows if the program's output is piped. + Macro EnableVirtualTerminalProcessing() : Console::AddConsoleModeFlag(Console::#ENABLE_VIRTUAL_TERMINAL_PROCESSING, #Null) : EndMacro + Macro DisableVirtualTerminalProcessing() : Console::RemoveConsoleModeFlag(Console::#ENABLE_VIRTUAL_TERMINAL_PROCESSING, #Null) : EndMacro + + + ;-> Generic Macros + + ; Macro for #IsConsoleApp + Macro IsConsoleApp() : #IsConsoleApp : EndMacro + + ; https://docs.microsoft.com/en-us/windows/console/getstdhandle + Macro GetOutputHandle() : GetStdHandle_( #STD_OUTPUT_HANDLE ) : EndMacro + Macro GetInputHandle() : GetStdHandle_( #STD_INPUT_HANDLE ) : EndMacro + Macro GetErrorHandle() : GetStdHandle_( #STD_ERROR_HANDLE ) : EndMacro +EndDeclareModule + + +;- Module Definition + +Module Console + ;-> Compiler Directives + + EnableExplicit + + + ;-> Procedure Definition + + Procedure.s GetConsoleTitle(MaxLength.i = 255) + Protected *ConsoleTitleBuffer = AllocateMemory(MaxLength) + Protected ConsoleTitle$ = #Null$ + + If *ConsoleTitleBuffer + Protected ConsoleTitleLength.l = GetConsoleTitle_(*ConsoleTitleBuffer, MaxLength) + ConsoleTitle$ = PeekS(*ConsoleTitleBuffer, ConsoleTitleLength) + FreeMemory(*ConsoleTitleBuffer) + EndIf + + ProcedureReturn ConsoleTitle$ + EndProcedure + + Procedure.b AddConsoleModeFlag(Flags.DWORD = #Null, ConsoleHandle.Console::HANDLE = #Null) + Protected ConsoleMode.DWORD = 0 + + If ConsoleHandle = #Null + ConsoleHandle = GetOutputHandle() + EndIf + + If GetConsoleMode_(ConsoleHandle, @ConsoleMode) + ConsoleMode = ConsoleMode | Flags + + If SetConsoleMode_(ConsoleHandle, ConsoleMode) + ProcedureReturn #True + EndIf + EndIf + + Debug GetLastError_() + ProcedureReturn #False + EndProcedure + + Procedure.b RemoveConsoleModeFlag(Flags.DWORD = #Null, ConsoleHandle.Console::HANDLE = #Null) + Protected ConsoleMode.DWORD = 0 + + If ConsoleHandle = #Null + ConsoleHandle = GetOutputHandle() + EndIf + + If GetConsoleMode_(ConsoleHandle, @ConsoleMode) + ConsoleMode = ConsoleMode & ~Flags + + If SetConsoleMode_(ConsoleHandle, ConsoleMode) + ProcedureReturn #True + EndIf + EndIf + + Debug GetLastError_() + ProcedureReturn #False + EndProcedure + + ; ??? +EndModule + + +;- Tests + +CompilerIf #PB_Compiler_IsMainFile + EnableExplicit + + If Not OpenConsole("Console.pbi") + Debug "Can't open console !" + End 1 + EndIf + + ;Debug "Console title: "+Console::GetConsoleTitle() + + If Console::EnableVirtualTerminalProcessing() + PrintN("Virtual terminal processing activated !"+#CRLF$) + Else + PrintN("Virtual terminal processing couldn't be activated !"+#CRLF$) + EndIf + + Console::CursorSave() + PrintN("#####") + PrintN("#####") + PrintN("#####") + Console::CursorUp() + Print("A") + Console::CursorRestore() + Print("B") + + + If Console::DisableVirtualTerminalProcessing() + PrintN("Virtual terminal processing deactivated !"+#CRLF$) + Else + PrintN("Virtual terminal processing couldn't be deactivated !"+#CRLF$) + EndIf + + Print("Press enter key to exit...") + Input() +CompilerEndIf diff --git a/Examples/VirtualTerminal/Basic.pb b/Examples/VirtualTerminal/Basic.pb new file mode 100644 index 0000000..e70dd20 --- /dev/null +++ b/Examples/VirtualTerminal/Basic.pb @@ -0,0 +1,68 @@ +;{- Code Header +; ==- Basic Info -================================ +; Name: VirtualTerminal/Basic.pb +; Author: Herwin Bozet +; +; ==- Links & License -=========================== +; License: Unlicense +;} + +;- Compiler Directives + +EnableExplicit + +XIncludeFile "../../VirtualTerminal.pbi" + +CompilerIf #PB_Compiler_ExecutableFormat <> #PB_Compiler_Console + CompilerWarning "You should preferably compile the example as a console app !" +CompilerEndIf + + +;- Code + +; Safely openning the console +If OpenConsole("My first title") + If Not VirtualTerminal::EnableVirtualTerminalProcessing() + VirtualTerminal::WriteErrorN("Unable to activate virtual terminal processing, output is likely piped !") + CloseConsole() + End 2 + EndIf +Else + Debug "Can't open console !" + End 1 +EndIf + +; Clearing the console +VirtualTerminal::ClearDisplay(AinsiEscapeCode::#ED_2) ; 2 or +ClearDisplayFull() also works just fine +VirtualTerminal::CursorTo(0, 0) + +; Intro +VirtualTerminal::WriteOutputN("-===- Welcome to the 'Basic' demo for 'VirtualTerminal' -===-") +VirtualTerminal::WriteOutputN("Press enter to start...") +Input() + +; Basic info +VirtualTerminal::WriteOutputN("-=- Basic info -=-") +VirtualTerminal::WriteOutputN("Terminal size: "+Str(VirtualTerminal::GetTerminalWidth())+"x"+Str(VirtualTerminal::GetTerminalHeight())) +VirtualTerminal::WriteOutputN("Press enter to continue...") +Input() + +; Title demo +VirtualTerminal::WriteOutputN("-=- Title -=-") +VirtualTerminal::WriteOutputN("Press enter to change the title...") +Input() +VirtualTerminal::SetWindowTitle("My new title") + +; ??? + +; End +VirtualTerminal::WriteOutputN("-=- End of the demo -=-") +Print("Press enter to clear the terminal and exit...") +Input() +VirtualTerminal::ClearDisplayFull() +VirtualTerminal::CursorTo(0, 0) + +; Quitting safely +VirtualTerminal::DisableVirtualTerminalProcessing() +CloseConsole() +End 0 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/VirtualTerminal.pbi b/VirtualTerminal.pbi new file mode 100644 index 0000000..881233d --- /dev/null +++ b/VirtualTerminal.pbi @@ -0,0 +1,215 @@ +;{- Code Header +; ==- Basic Info -================================ +; Name: VirtualTerminal.pbi +; Version: N/A +; Author: Herwin Bozet +; +; ==- Compatibility -============================= +; Compiler version: PureBasic 5.70 (x86/x64) +; Operating system: Windows 10 21H1 (Previous versions untested) +; +; ==- Links & License -=========================== +; License: Unlicense +;} + +;- Compiler directives + +XIncludeFile "./Console.pbi" +XIncludeFile "./AinsiEscapeCode.pbi" + + +;- Module declaration + +DeclareModule VirtualTerminal + ;-> Macros + + ;-> > Console.pbi macros + + Macro IsConsoleApp() : Console::#IsConsoleApp : EndMacro + + Macro GetOutputHandle() : Console::GetOutputHandle() : EndMacro + Macro GetInputHandle() : Console::GetInputHandle() : EndMacro + Macro GetErrorHandle() : Console::GetErrorHandle() : EndMacro + + ;-> > Platform-dependant Macros + + CompilerIf #PB_Compiler_OS = #PB_OS_Windows + Macro EnableVirtualTerminalProcessing() : Console::EnableVirtualTerminalProcessing() : EndMacro + Macro DisableVirtualTerminalProcessing() : Console::DisableVirtualTerminalProcessing() : EndMacro + CompilerElse + Declare.b EnableVirtualTerminalProcessing() + Declare.b DisableVirtualTerminalProcessing() + CompilerEndIf + + ;-> > Generic Macros + + Macro WriteOutput(Message) : Print(Message) : EndMacro + Macro WriteOutputN(Message) : PrintN(Message) : EndMacro + Macro WriteErrorN(Message) : ConsoleError(Message) : EndMacro + + ;-> > Ainsi Escape Code Macros + + ;-> > > Cursor + Macro CursorUp() : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CUU$) : EndMacro + Macro CursorDown() : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CUD$) : EndMacro + Macro CursorRight() : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CUF$) : EndMacro + Macro CursorLeft() : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CUB$) : EndMacro + Macro CursorNextLine(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CNL$) : EndMacro + Macro CursorPreviousLine(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CPL$) : EndMacro + + Macro CursorUpBy(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Amount) + AinsiEscapeCode::#CUU$) : EndMacro + Macro CursorDownBy(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Amount) + AinsiEscapeCode::#CUD$) : EndMacro + Macro CursorRightBy(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Amount) + AinsiEscapeCode::#CUF$) : EndMacro + Macro CursorLeftBy(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Amount) + AinsiEscapeCode::#CUB$) : EndMacro + Macro CursorLineDownBy(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Amount) + AinsiEscapeCode::#CNL$) : EndMacro + Macro CursorLineUpBy(Amount) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Amount) + AinsiEscapeCode::#CPL$) : EndMacro + + Macro CursorToColumn(ColumnNumber) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(ColumnNumber) + AinsiEscapeCode::#CHA$) : EndMacro + Macro CursorToLine(LineNumber) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(LineNumber) + AinsiEscapeCode::#VPA$) : EndMacro + + Macro CursorTo(X, Y) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Y) + ";" + Str(X) + AinsiEscapeCode::#CUP$) : EndMacro + + Macro CursorFlip() : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#RI$) : EndMacro + Macro CursorSave() : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#DECSC$) : EndMacro + Macro CursorRestore() : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#DECSR$) : EndMacro + + ;-> > > Others + Macro ClearDisplay(Mode = AinsiEscapeCode::#ED_0) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + Str(Mode) + AinsiEscapeCode::#ED$) : EndMacro + Macro ClearDisplayToEnd() : VirtualTerminal::ClearDisplay(AinsiEscapeCode::#ED_0) : EndMacro + Macro ClearDisplayToStart() : VirtualTerminal::ClearDisplay(AinsiEscapeCode::#ED_1) : EndMacro + Macro ClearDisplayFull() : VirtualTerminal::ClearDisplay(AinsiEscapeCode::#ED_2) : EndMacro + Macro ClearDisplayAbsolute() : VirtualTerminal::ClearDisplay(AinsiEscapeCode::#ED_3) : EndMacro + + ;-> > > Window + Macro SetWindowTitleAndIcon(Title) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#OSC$ + "0;" + Left(Title, 255) + AinsiEscapeCode::#BEL$) : EndMacro + Macro SetWindowTitle(Title) : VirtualTerminal::WriteOutput(#ESC$ + AinsiEscapeCode::#OSC$ + "2;" + Left(Title, 255) + AinsiEscapeCode::#BEL$) : EndMacro + + + ;-> Procedure Declaration (See the "Platform-dependant Macros" section) + + Declare.b GetCursorPosition(*CursorPosition.Console::CursorPosition, TimeoutMs.i = 1) + + Declare.i GetTerminalWidth(RestorePosition.b = #True) + Declare.i GetTerminalHeight(RestorePosition.b = #True) +EndDeclareModule + + +;- Module Definition + +Module VirtualTerminal + ;-> Compiler Directives + + EnableExplicit + + + ;-> Procedure Definition + + CompilerIf Not #PB_Compiler_OS = #PB_OS_Windows + ; FIXME: May not work if piped, not sure ! + Procedure.b EnableVirtualTerminalProcessing() : ProcedureReturn #True : EndIf + Procedure.b DisableVirtualTerminalProcessing() : ProcedureReturn #True : EndIf + CompilerEndIf + + Procedure.b GetCursorPosition(*CursorPosition.Console::CursorPosition, TimeoutMs.i = 1) + Protected StartTime.q + Protected Input$ = #Null$ + + If *CursorPosition + WriteOutput(#ESC$ + AinsiEscapeCode::#CSI$ + AinsiEscapeCode::#DECXCPR$) + + ; Waiting for stuff to come in... + StartTime = ElapsedMilliseconds() + Repeat + Input$ = Inkey() + Until Input$ <> #Null$ Or ((TimeoutMs <> -1 And (ElapsedMilliseconds() - StartTime > TimeoutMs)) Or (TimeoutMs = -1)) + + Repeat + Protected NewChar$ = Inkey() + If NewChar$ <> #Null$ + Input$ = Input$ + NewChar$ + Else + Break + EndIf + ForEver + + Protected.i ResponseCodeStart = FindString(Input$, "[") + 1 + Input$ = Mid(Input$, ResponseCodeStart, FindString(Input$, "R", ResponseCodeStart) - ResponseCodeStart) + + If FindString(Input$, ";") >= 2 + *CursorPosition\Y = Val(StringField(Input$, 1, ";")) + *CursorPosition\X = Val(StringField(Input$, 2, ";")) + ProcedureReturn #True + EndIf + EndIf + + ProcedureReturn #False + EndProcedure + + Procedure.i GetTerminalWidth(RestorePosition.b = #True) + Define OriginalCursorPosition.Console::CursorPosition + Define MeasuringCursorPosition.Console::CursorPosition + + If RestorePosition + VirtualTerminal::GetCursorPosition(@OriginalCursorPosition) + EndIf + + VirtualTerminal::CursorTo(32767, 0) + VirtualTerminal::GetCursorPosition(@MeasuringCursorPosition) + + If RestorePosition + VirtualTerminal::CursorTo(OriginalCursorPosition\X, OriginalCursorPosition\Y) + EndIf + + ProcedureReturn MeasuringCursorPosition\X + EndProcedure + + Procedure.i GetTerminalHeight(RestorePosition.b = #True) + Define OriginalCursorPosition.Console::CursorPosition + Define MeasuringCursorPosition.Console::CursorPosition + + If RestorePosition + VirtualTerminal::GetCursorPosition(@OriginalCursorPosition) + EndIf + + VirtualTerminal::CursorTo(0, 32767) + VirtualTerminal::GetCursorPosition(@MeasuringCursorPosition) + + If RestorePosition + VirtualTerminal::CursorTo(OriginalCursorPosition\X, OriginalCursorPosition\Y) + EndIf + + ProcedureReturn MeasuringCursorPosition\Y + EndProcedure +EndModule + + +;- Tests + +CompilerIf #PB_Compiler_IsMainFile + EnableExplicit + + If OpenConsole("Console.pbi") + If Not VirtualTerminal::EnableVirtualTerminalProcessing() + VirtualTerminal::WriteErrorN("Unable to activate virtual terminal processing, output is likely piped !") + CloseConsole() + End 2 + EndIf + Else + Debug "Can't open console !" + End 1 + EndIf + + VirtualTerminal::ClearDisplay(AinsiEscapeCode::#ED_2) + VirtualTerminal::CursorTo(0, 0) + PrintN("-==- Title Bar -==-") + + Print("Size: "+VirtualTerminal::GetTerminalWidth()+"x"+VirtualTerminal::GetTerminalHeight()) + + ;Print("Press enter key to exit...") + Debug Input() + ;FreeMemory(*Buffer) + + VirtualTerminal::DisableVirtualTerminalProcessing() + CloseConsole() + End 0 +CompilerEndIf diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..79d8627 --- /dev/null +++ b/readme.md @@ -0,0 +1,7 @@ +# PB-ConsoleHelpers + +A set of includes that should help you develop CLI applications that need to interact with the terminal and its buffers directly. + +## License + +[Unlicense](LICENSE)