From 6f667f48ae109d4291cda1f8d4e977315c0dae8a Mon Sep 17 00:00:00 2001 From: Michael Niksa Date: Thu, 19 Dec 2019 14:12:53 -0800 Subject: [PATCH] =?UTF-8?q?Make=20the=20terminal=20parser/adapter=20and=20?= =?UTF-8?q?related=20classes=20use=20modern=E2=80=A6=20(#3956)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary of the Pull Request Refactors parsing/adapting libraries and consumers to use safer and/or more consistent mechanisms for passing information. ## PR Checklist * [x] I work here * [x] Tests still pass * [x] Am a core contributor. ## Detailed Description of the Pull Request / Additional comments This is in support of hopefully turning audit mode on to more projects. If I turned it on, it would immediately complain about certain classes of issues like pointer and size, pointer math, etc. The changes in this refactoring will eliminate those off the top. Additionally, this has caught a bunch of comments all over the VT classes that weren't updated to match the parameters lists. Additionally, this has caught a handful of member variables on classes that were completely unused (and now gone). Additionally, I'm killing almost all hungarian and shortening variable names. I'm only really leaving 'p' for pointers. Additionally, this is vaguely in support of a future where we can have "infinite scrollback" in that I'm moving things to size_t across the board. I know it's a bit of a memory cost, but all the casting and moving between types is error prone and unfun to save a couple bytes. ## Validation Steps Performed - [x] build it - [x] run all the tests - [x] everyone looked real hard at it --- src/cascadia/TerminalCore/ITerminalApi.hpp | 14 +- src/cascadia/TerminalCore/Terminal.cpp | 7 +- src/cascadia/TerminalCore/Terminal.hpp | 12 +- src/cascadia/TerminalCore/TerminalApi.cpp | 40 +- .../TerminalCore/TerminalDispatch.cpp | 66 +- .../TerminalCore/TerminalDispatch.hpp | 32 +- .../TerminalCore/TerminalDispatchGraphics.cpp | 76 +- src/host/VtInputThread.cpp | 11 +- src/host/_stream.cpp | 2 +- src/host/getset.cpp | 48 +- src/host/getset.h | 12 +- src/host/outputStream.cpp | 462 ++--- src/host/outputStream.hpp | 134 +- src/host/screenInfo.cpp | 13 +- src/host/ut_host/ScreenBufferTests.cpp | 351 ++-- src/host/ut_host/TextBufferTests.cpp | 110 +- src/inc/ITerminalOutputConnection.hpp | 4 +- src/inc/LibraryIncludes.h | 1 + src/renderer/vt/WinTelnetEngine.cpp | 2 +- src/renderer/vt/WinTelnetEngine.hpp | 2 +- src/renderer/vt/XtermEngine.cpp | 2 +- src/renderer/vt/XtermEngine.hpp | 2 +- src/renderer/vt/state.cpp | 6 +- src/renderer/vt/vtrenderer.hpp | 8 +- src/terminal/adapter/DispatchCommon.cpp | 24 +- src/terminal/adapter/DispatchCommon.hpp | 4 +- src/terminal/adapter/IInteractDispatch.hpp | 13 +- src/terminal/adapter/ITermDispatch.hpp | 90 +- src/terminal/adapter/InteractDispatch.cpp | 101 +- src/terminal/adapter/InteractDispatch.hpp | 14 +- src/terminal/adapter/adaptDefaults.hpp | 2 +- src/terminal/adapter/adaptDispatch.cpp | 1003 ++++++----- src/terminal/adapter/adaptDispatch.hpp | 156 +- .../adapter/adaptDispatchGraphics.cpp | 371 ++-- src/terminal/adapter/conGetSet.hpp | 126 +- src/terminal/adapter/termDispatch.hpp | 90 +- .../adapter/ut_adapter/adapterTest.cpp | 1595 +++++++++-------- src/terminal/parser/IStateMachineEngine.hpp | 23 +- .../parser/InputStateMachineEngine.cpp | 773 ++++---- .../parser/InputStateMachineEngine.hpp | 161 +- .../parser/OutputStateMachineEngine.cpp | 1003 +++++------ .../parser/OutputStateMachineEngine.hpp | 170 +- .../parser/ft_fuzzwrapper/echoDispatch.cpp | 5 +- .../parser/ft_fuzzwrapper/echoDispatch.hpp | 2 +- src/terminal/parser/ft_fuzzwrapper/main.cpp | 4 +- src/terminal/parser/stateMachine.cpp | 312 ++-- src/terminal/parser/stateMachine.hpp | 38 +- src/terminal/parser/tracing.cpp | 62 +- src/terminal/parser/tracing.hpp | 13 +- .../parser/ut_parser/InputEngineTest.cpp | 113 +- .../parser/ut_parser/OutputEngineTest.cpp | 815 +++++---- .../parser/ut_parser/StateMachineTest.cpp | 37 +- 52 files changed, 4087 insertions(+), 4450 deletions(-) diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index 2bf09bf7b3..867699ceb8 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -15,7 +15,7 @@ namespace Microsoft::Terminal::Core ITerminalApi& operator=(const ITerminalApi&) = default; ITerminalApi& operator=(ITerminalApi&&) = default; - virtual bool PrintString(std::wstring_view stringView) = 0; + virtual bool PrintString(std::wstring_view string) = 0; virtual bool ExecuteChar(wchar_t wch) = 0; virtual bool SetTextToDefaults(bool foreground, bool background) = 0; @@ -29,20 +29,20 @@ namespace Microsoft::Terminal::Core virtual bool SetCursorPosition(short x, short y) = 0; virtual COORD GetCursorPosition() = 0; - virtual bool DeleteCharacter(const unsigned int uiCount) = 0; - virtual bool InsertCharacter(const unsigned int uiCount) = 0; - virtual bool EraseCharacters(const unsigned int numChars) = 0; + virtual bool DeleteCharacter(const size_t count) = 0; + virtual bool InsertCharacter(const size_t count) = 0; + virtual bool EraseCharacters(const size_t numChars) = 0; virtual bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0; virtual bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) = 0; virtual bool SetWindowTitle(std::wstring_view title) = 0; - virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) = 0; + virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) = 0; - virtual bool SetDefaultForeground(const DWORD dwColor) = 0; - virtual bool SetDefaultBackground(const DWORD dwColor) = 0; + virtual bool SetDefaultForeground(const DWORD color) = 0; + virtual bool SetDefaultBackground(const DWORD color) = 0; protected: ITerminalApi() = default; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index e903607d58..3ae05c0937 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -50,7 +50,10 @@ Terminal::Terminal() : _selectionAnchor{ 0, 0 }, _endSelectionPosition{ 0, 0 } { - _stateMachine = std::make_unique(new OutputStateMachineEngine(new TerminalDispatch(*this))); + auto dispatch = std::make_unique(*this); + auto engine = std::make_unique(std::move(dispatch)); + + _stateMachine = std::make_unique(std::move(engine)); auto passAlongInput = [&](std::deque>& inEventsToWrite) { if (!_pfnWriteInput) @@ -199,7 +202,7 @@ void Terminal::Write(std::wstring_view stringView) { auto lock = LockForWriting(); - _stateMachine->ProcessString(stringView.data(), stringView.size()); + _stateMachine->ProcessString(stringView); } // Method Description: diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 8391f39f8e..6a776f8a59 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -75,16 +75,16 @@ public: bool ReverseText(bool reversed) override; bool SetCursorPosition(short x, short y) override; COORD GetCursorPosition() override; - bool DeleteCharacter(const unsigned int uiCount) override; - bool InsertCharacter(const unsigned int uiCount) override; - bool EraseCharacters(const unsigned int numChars) override; + bool DeleteCharacter(const size_t count) override; + bool InsertCharacter(const size_t count) override; + bool EraseCharacters(const size_t numChars) override; bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; bool SetWindowTitle(std::wstring_view title) override; - bool SetColorTableEntry(const size_t tableIndex, const COLORREF dwColor) override; + bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override; - bool SetDefaultForeground(const COLORREF dwColor) override; - bool SetDefaultBackground(const COLORREF dwColor) override; + bool SetDefaultForeground(const COLORREF color) override; + bool SetDefaultBackground(const COLORREF color) override; #pragma endregion #pragma region ITerminalInput diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index b54a22581f..fafb6972f8 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -128,19 +128,19 @@ COORD Terminal::GetCursorPosition() } // Method Description: -// - deletes uiCount characters starting from the cursor's current position +// - deletes count characters starting from the cursor's current position // - it moves over the remaining text to 'replace' the deleted text // - for example, if the buffer looks like this ('|' is the cursor): [abc|def] // - calling DeleteCharacter(1) will change it to: [abc|ef], // - i.e. the 'd' gets deleted and the 'ef' gets shifted over 1 space and **retain their previous text attributes** // Arguments: -// - uiCount, the number of characters to delete +// - count, the number of characters to delete // Return value: // - true if succeeded, false otherwise -bool Terminal::DeleteCharacter(const unsigned int uiCount) +bool Terminal::DeleteCharacter(const size_t count) { SHORT dist; - if (!SUCCEEDED(UIntToShort(uiCount, &dist))) + if (!SUCCEEDED(SizeTToShort(count, &dist))) { return false; } @@ -175,22 +175,22 @@ bool Terminal::DeleteCharacter(const unsigned int uiCount) } // Method Description: -// - Inserts uiCount spaces starting from the cursor's current position, moving over the existing text +// - Inserts count spaces starting from the cursor's current position, moving over the existing text // - for example, if the buffer looks like this ('|' is the cursor): [abc|def] // - calling InsertCharacter(1) will change it to: [abc| def], // - i.e. the 'def' gets shifted over 1 space and **retain their previous text attributes** // Arguments: -// - uiCount, the number of spaces to insert +// - count, the number of spaces to insert // Return value: // - true if succeeded, false otherwise -bool Terminal::InsertCharacter(const unsigned int uiCount) +bool Terminal::InsertCharacter(const size_t count) { // NOTE: the code below is _extremely_ similar to DeleteCharacter // We will want to use this same logic and implement a helper function instead // that does the 'move a region from here to there' operation // TODO: Github issue #2163 SHORT dist; - if (!SUCCEEDED(UIntToShort(uiCount, &dist))) + if (!SUCCEEDED(SizeTToShort(count, &dist))) { return false; } @@ -227,7 +227,7 @@ bool Terminal::InsertCharacter(const unsigned int uiCount) return true; } -bool Terminal::EraseCharacters(const unsigned int numChars) +bool Terminal::EraseCharacters(const size_t numChars) { const auto absoluteCursorPos = _buffer->GetCursor().GetPosition(); const auto viewport = _GetMutableViewport(); @@ -374,17 +374,17 @@ bool Terminal::SetWindowTitle(std::wstring_view title) // Method Description: // - Updates the value in the colortable at index tableIndex to the new color -// dwColor. dwColor is a COLORREF, format 0x00BBGGRR. +// color. color is a COLORREF, format 0x00BBGGRR. // Arguments: // - tableIndex: the index of the color table to update. -// - dwColor: the new COLORREF to use as that color table value. +// - color: the new COLORREF to use as that color table value. // Return Value: // - true iff we successfully updated the color table entry. -bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF dwColor) +bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF color) { try { - _colorTable.at(tableIndex) = dwColor; + _colorTable.at(tableIndex) = color; // Repaint everything - the colors might have changed _buffer->GetRenderTarget().TriggerRedrawAll(); @@ -449,12 +449,12 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) // Method Description: // - Updates the default foreground color from a COLORREF, format 0x00BBGGRR. // Arguments: -// - dwColor: the new COLORREF to use as the default foreground color +// - color: the new COLORREF to use as the default foreground color // Return Value: // - true -bool Terminal::SetDefaultForeground(const COLORREF dwColor) +bool Terminal::SetDefaultForeground(const COLORREF color) { - _defaultFg = dwColor; + _defaultFg = color; // Repaint everything - the colors might have changed _buffer->GetRenderTarget().TriggerRedrawAll(); @@ -464,13 +464,13 @@ bool Terminal::SetDefaultForeground(const COLORREF dwColor) // Method Description: // - Updates the default background color from a COLORREF, format 0x00BBGGRR. // Arguments: -// - dwColor: the new COLORREF to use as the default background color +// - color: the new COLORREF to use as the default background color // Return Value: // - true -bool Terminal::SetDefaultBackground(const COLORREF dwColor) +bool Terminal::SetDefaultBackground(const COLORREF color) { - _defaultBg = dwColor; - _pfnBackgroundColorChanged(dwColor); + _defaultBg = color; + _pfnBackgroundColorChanged(color); // Repaint everything - the colors might have changed _buffer->GetRenderTarget().TriggerRedrawAll(); diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index d5b061d291..6b8e6215a0 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -25,45 +25,45 @@ void TerminalDispatch::Print(const wchar_t wchPrintable) _terminalApi.PrintString({ &wchPrintable, 1 }); } -void TerminalDispatch::PrintString(const wchar_t* const rgwch, const size_t cch) +void TerminalDispatch::PrintString(const std::wstring_view string) { - _terminalApi.PrintString({ rgwch, cch }); + _terminalApi.PrintString(string); } -bool TerminalDispatch::CursorPosition(const unsigned int uiLine, - const unsigned int uiColumn) +bool TerminalDispatch::CursorPosition(const size_t line, + const size_t column) { - const auto columnInBufferSpace = uiColumn - 1; - const auto lineInBufferSpace = uiLine - 1; - short x = static_cast(uiColumn - 1); - short y = static_cast(uiLine - 1); + const auto columnInBufferSpace = column - 1; + const auto lineInBufferSpace = line - 1; + short x = static_cast(column - 1); + short y = static_cast(line - 1); return _terminalApi.SetCursorPosition(x, y); } -bool TerminalDispatch::CursorForward(const unsigned int uiDistance) +bool TerminalDispatch::CursorForward(const size_t distance) { const auto cursorPos = _terminalApi.GetCursorPosition(); - const COORD newCursorPos{ cursorPos.X + gsl::narrow(uiDistance), cursorPos.Y }; + const COORD newCursorPos{ cursorPos.X + gsl::narrow(distance), cursorPos.Y }; return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y); } -bool TerminalDispatch::CursorBackward(const unsigned int uiDistance) +bool TerminalDispatch::CursorBackward(const size_t distance) { const auto cursorPos = _terminalApi.GetCursorPosition(); - const COORD newCursorPos{ cursorPos.X - gsl::narrow(uiDistance), cursorPos.Y }; + const COORD newCursorPos{ cursorPos.X - gsl::narrow(distance), cursorPos.Y }; return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y); } -bool TerminalDispatch::CursorUp(const unsigned int uiDistance) +bool TerminalDispatch::CursorUp(const size_t distance) { const auto cursorPos = _terminalApi.GetCursorPosition(); - const COORD newCursorPos{ cursorPos.X, cursorPos.Y + gsl::narrow(uiDistance) }; + const COORD newCursorPos{ cursorPos.X, cursorPos.Y + gsl::narrow(distance) }; return _terminalApi.SetCursorPosition(newCursorPos.X, newCursorPos.Y); } -bool TerminalDispatch::EraseCharacters(const unsigned int uiNumChars) +bool TerminalDispatch::EraseCharacters(const size_t numChars) { - return _terminalApi.EraseCharacters(uiNumChars); + return _terminalApi.EraseCharacters(numChars); } bool TerminalDispatch::SetWindowTitle(std::wstring_view title) @@ -75,13 +75,13 @@ bool TerminalDispatch::SetWindowTitle(std::wstring_view title) // - Sets a single entry of the colortable to a new value // Arguments: // - tableIndex: The VT color table index -// - dwColor: The new RGB color value to use. +// - color: The new RGB color value to use. // Return Value: // True if handled successfully. False otherwise. bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex, - const DWORD dwColor) + const DWORD color) { - return _terminalApi.SetColorTableEntry(tableIndex, dwColor); + return _terminalApi.SetColorTableEntry(tableIndex, color); } bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) @@ -92,23 +92,23 @@ bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorSty // Method Description: // - Sets the default foreground color to a new value // Arguments: -// - dwColor: The new RGB color value to use, in 0x00BBGGRR form +// - color: The new RGB color value to use, in 0x00BBGGRR form // Return Value: // True if handled successfully. False otherwise. -bool TerminalDispatch::SetDefaultForeground(const DWORD dwColor) +bool TerminalDispatch::SetDefaultForeground(const DWORD color) { - return _terminalApi.SetDefaultForeground(dwColor); + return _terminalApi.SetDefaultForeground(color); } // Method Description: // - Sets the default background color to a new value // Arguments: -// - dwColor: The new RGB color value to use, in 0x00BBGGRR form +// - color: The new RGB color value to use, in 0x00BBGGRR form // Return Value: // True if handled successfully. False otherwise. -bool TerminalDispatch::SetDefaultBackground(const DWORD dwColor) +bool TerminalDispatch::SetDefaultBackground(const DWORD color) { - return _terminalApi.SetDefaultBackground(dwColor); + return _terminalApi.SetDefaultBackground(color); } // Method Description: @@ -123,25 +123,25 @@ bool TerminalDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) } // Method Description: -// - Deletes uiCount number of characters starting from where the cursor is currently +// - Deletes count number of characters starting from where the cursor is currently // Arguments: -// - uiCount, the number of characters to delete +// - count, the number of characters to delete // Return Value: // True if handled successfully. False otherwise. -bool TerminalDispatch::DeleteCharacter(const unsigned int uiCount) +bool TerminalDispatch::DeleteCharacter(const size_t count) { - return _terminalApi.DeleteCharacter(uiCount); + return _terminalApi.DeleteCharacter(count); } // Method Description: -// - Adds uiCount number of spaces starting from where the cursor is currently +// - Adds count number of spaces starting from where the cursor is currently // Arguments: -// - uiCount, the number of spaces to add +// - count, the number of spaces to add // Return Value: // True if handled successfully, false otherwise -bool TerminalDispatch::InsertCharacter(const unsigned int uiCount) +bool TerminalDispatch::InsertCharacter(const size_t count) { - return _terminalApi.InsertCharacter(uiCount); + return _terminalApi.InsertCharacter(count); } // Method Description: diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index 5fa9758856..df418ad886 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -11,29 +11,28 @@ public: virtual ~TerminalDispatch(){}; virtual void Execute(const wchar_t wchControl) override; virtual void Print(const wchar_t wchPrintable) override; - virtual void PrintString(const wchar_t* const rgwch, const size_t cch) override; + virtual void PrintString(const std::wstring_view string) override; - bool SetGraphicsRendition(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions) override; + bool SetGraphicsRendition(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options) override; - virtual bool CursorPosition(const unsigned int uiLine, - const unsigned int uiColumn) override; // CUP + virtual bool CursorPosition(const size_t line, + const size_t column) override; // CUP - bool CursorForward(const unsigned int uiDistance) override; - bool CursorBackward(const unsigned int uiDistance) override; - bool CursorUp(const unsigned int uiDistance) override; + bool CursorForward(const size_t distance) override; + bool CursorBackward(const size_t distance) override; + bool CursorUp(const size_t distance) override; - bool EraseCharacters(const unsigned int uiNumChars) override; + bool EraseCharacters(const size_t numChars) override; bool SetWindowTitle(std::wstring_view title) override; - bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) override; + bool SetColorTableEntry(const size_t tableIndex, const DWORD color) override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override; - bool SetDefaultForeground(const DWORD dwColor) override; - bool SetDefaultBackground(const DWORD dwColor) override; + bool SetDefaultForeground(const DWORD color) override; + bool SetDefaultBackground(const DWORD color) override; bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; // ED - bool DeleteCharacter(const unsigned int uiCount) override; - bool InsertCharacter(const unsigned int uiCount) override; + bool DeleteCharacter(const size_t count) override; + bool InsertCharacter(const size_t count) override; bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) override; private: @@ -43,9 +42,8 @@ private: static bool s_IsBoldColorOption(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept; static bool s_IsDefaultColorOption(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt) noexcept; - bool _SetRgbColorsHelper(_In_reads_(cOptions) const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions, - _Out_ size_t* const pcOptionsConsumed); + bool _SetRgbColorsHelper(const std::basic_string_view<::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options, + size_t& optionsConsumed); bool _SetBoldColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions option); bool _SetDefaultColorHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions option); void _SetGraphicsOptionHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions opt); diff --git a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp index b73b9adee1..4e2d4ece6d 100644 --- a/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp @@ -69,9 +69,8 @@ bool TerminalDispatch::s_IsDefaultColorOption(const DispatchTypes::GraphicsOptio // RGB sequences then take 3 MORE params to designate the R, G, B parts of the color // Xterm index will use the param that follows to use a color from the preset 256 color xterm color table. // Arguments: -// - rgOptions - An array of options that will be used to generate the RGB color -// - cOptions - The count of options -// - pcOptionsConsumed - a pointer to place the number of options we consumed parsing this option. +// - options - An array of options that will be used to generate the RGB color +// - optionsConsumed - Returns the number of options we consumed parsing this option. // Return Value: // Returns true if we successfully parsed an extended color option from the options array. // - This corresponds to the following number of options consumed (pcOptionsConsumed): @@ -79,20 +78,19 @@ bool TerminalDispatch::s_IsDefaultColorOption(const DispatchTypes::GraphicsOptio // 2 - false, not enough options to parse. // 3 - true, parsed an xterm index to a color // 5 - true, parsed an RGB color. -bool TerminalDispatch::_SetRgbColorsHelper(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions, - _Out_ size_t* const pcOptionsConsumed) +bool TerminalDispatch::_SetRgbColorsHelper(const std::basic_string_view options, + size_t& optionsConsumed) { COLORREF color = 0; bool isForeground = false; - bool fSuccess = false; - *pcOptionsConsumed = 1; - if (cOptions >= 2 && s_IsRgbColorOption(rgOptions[0])) + bool success = false; + optionsConsumed = 1; + if (options.size() >= 2 && s_IsRgbColorOption(options.front())) { - *pcOptionsConsumed = 2; - DispatchTypes::GraphicsOptions extendedOpt = rgOptions[0]; - DispatchTypes::GraphicsOptions typeOpt = rgOptions[1]; + optionsConsumed = 2; + DispatchTypes::GraphicsOptions extendedOpt = options.at(0); + DispatchTypes::GraphicsOptions typeOpt = options.at(1); if (extendedOpt == DispatchTypes::GraphicsOptions::ForegroundExtended) { @@ -103,31 +101,32 @@ bool TerminalDispatch::_SetRgbColorsHelper(_In_reads_(cOptions) const DispatchTy isForeground = false; } - if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && cOptions >= 5) + if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && options.size() >= 5) { - *pcOptionsConsumed = 5; + optionsConsumed = 5; // ensure that each value fits in a byte - unsigned int red = rgOptions[2] > 255 ? 255 : rgOptions[2]; - unsigned int green = rgOptions[3] > 255 ? 255 : rgOptions[3]; - unsigned int blue = rgOptions[4] > 255 ? 255 : rgOptions[4]; + const auto limit = (DispatchTypes::GraphicsOptions)255; + const auto red = std::min(options.at(2), limit); + const auto green = std::min(options.at(3), limit); + const auto blue = std::min(options.at(4), limit); color = RGB(red, green, blue); - fSuccess = _terminalApi.SetTextRgbColor(color, isForeground); + success = _terminalApi.SetTextRgbColor(color, isForeground); } - else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && cOptions >= 3) + else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && options.size() >= 3) { - *pcOptionsConsumed = 3; - if (rgOptions[2] <= 255) // ensure that the provided index is on the table + optionsConsumed = 3; + if (options.at(2) <= 255) // ensure that the provided index is on the table { - unsigned int tableIndex = rgOptions[2]; - fSuccess = isForeground ? - _terminalApi.SetTextForegroundIndex((BYTE)tableIndex) : - _terminalApi.SetTextBackgroundIndex((BYTE)tableIndex); + unsigned int tableIndex = options.at(2); + success = isForeground ? + _terminalApi.SetTextForegroundIndex((BYTE)tableIndex) : + _terminalApi.SetTextBackgroundIndex((BYTE)tableIndex); } } } - return fSuccess; + return success; } bool TerminalDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option) @@ -288,41 +287,40 @@ void TerminalDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOpt } } -bool TerminalDispatch::SetGraphicsRendition(const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions) +bool TerminalDispatch::SetGraphicsRendition(const std::basic_string_view options) { - bool fSuccess = false; + bool success = false; // Run through the graphics options and apply them - for (size_t i = 0; i < cOptions; i++) + for (size_t i = 0; i < options.size(); i++) { - DispatchTypes::GraphicsOptions opt = rgOptions[i]; + DispatchTypes::GraphicsOptions opt = options.at(i); if (s_IsDefaultColorOption(opt)) { - fSuccess = _SetDefaultColorHelper(opt); + success = _SetDefaultColorHelper(opt); } else if (s_IsBoldColorOption(opt)) { - fSuccess = _SetBoldColorHelper(rgOptions[i]); + success = _SetBoldColorHelper(opt); } else if (s_IsRgbColorOption(opt)) { - size_t cOptionsConsumed = 0; + size_t optionsConsumed = 0; // _SetRgbColorsHelper will call the appropriate ConApi function - fSuccess = _SetRgbColorsHelper(&(rgOptions[i]), cOptions - i, &cOptionsConsumed); + success = _SetRgbColorsHelper(options.substr(i), optionsConsumed); - i += (cOptionsConsumed - 1); // cOptionsConsumed includes the opt we're currently on. + i += (optionsConsumed - 1); // optionsConsumed includes the opt we're currently on. } else { _SetGraphicsOptionHelper(opt); // Make sure we un-bold - if (fSuccess && opt == DispatchTypes::GraphicsOptions::Off) + if (success && opt == DispatchTypes::GraphicsOptions::Off) { - fSuccess = _SetBoldColorHelper(opt); + success = _SetBoldColorHelper(opt); } } } - return fSuccess; + return success; } diff --git a/src/host/VtInputThread.cpp b/src/host/VtInputThread.cpp index e7e968204b..7abe5258c1 100644 --- a/src/host/VtInputThread.cpp +++ b/src/host/VtInputThread.cpp @@ -38,13 +38,12 @@ VtInputThread::VtInputThread(_In_ wil::unique_hfile hPipe, CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); auto pGetSet = std::make_unique(gci); - THROW_IF_NULL_ALLOC(pGetSet.get()); - auto engine = std::make_unique(new InteractDispatch(pGetSet.release()), inheritCursor); - THROW_IF_NULL_ALLOC(engine.get()); + auto dispatch = std::make_unique(std::move(pGetSet)); - _pInputStateMachine = std::make_unique(engine.release()); - THROW_IF_NULL_ALLOC(_pInputStateMachine.get()); + auto engine = std::make_unique(std::move(dispatch), inheritCursor); + + _pInputStateMachine = std::make_unique(std::move(engine)); } // Method Description: @@ -77,7 +76,7 @@ VtInputThread::VtInputThread(_In_ wil::unique_hfile hPipe, { return S_FALSE; } - _pInputStateMachine->ProcessString(pwsSequence.get(), cchSequence); + _pInputStateMachine->ProcessString({ pwsSequence.get(), cchSequence }); } CATCH_RETURN(); diff --git a/src/host/_stream.cpp b/src/host/_stream.cpp index cfc80868a2..363eb4427a 100644 --- a/src/host/_stream.cpp +++ b/src/host/_stream.cpp @@ -968,7 +968,7 @@ constexpr unsigned int LOCAL_BUFFER_SIZE = 100; StateMachine& machine = screenInfo.GetStateMachine(); size_t const cch = BufferSize / sizeof(WCHAR); - machine.ProcessString(pwchRealUnicode, cch); + machine.ProcessString({ pwchRealUnicode, cch }); *pcb += BufferSize; } } diff --git a/src/host/getset.cpp b/src/host/getset.cpp index dd9bb35a59..f27d4bcbca 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -1067,10 +1067,10 @@ void ApiRoutines::GetConsoleInputCodePageImpl(ULONG& codepage) noexcept CATCH_LOG(); } -void DoSrvGetConsoleOutputCodePage(_Out_ unsigned int* const pCodePage) +void DoSrvGetConsoleOutputCodePage(unsigned int& codepage) { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - *pCodePage = gci.OutputCP; + codepage = gci.OutputCP; } // Routine Description: @@ -1083,9 +1083,9 @@ void ApiRoutines::GetConsoleOutputCodePageImpl(ULONG& codepage) noexcept { LockConsole(); auto Unlock = wil::scope_exit([&] { UnlockConsole(); }); - unsigned int uiCodepage; - DoSrvGetConsoleOutputCodePage(&uiCodepage); - codepage = uiCodepage; + unsigned int cp; + DoSrvGetConsoleOutputCodePage(cp); + codepage = cp; } CATCH_LOG(); } @@ -1322,25 +1322,25 @@ void DoSrvPrivateAllowCursorBlinking(SCREEN_INFORMATION& screenInfo, const bool // untouched. // Currently only accessible through the use of ANSI sequence DECSTBM // Parameters: -// - psrScrollMargins - A rect who's Top and Bottom members will be used to set +// - scrollMargins - A rect who's Top and Bottom members will be used to set // the new values of the top and bottom margins. If (0,0), then the margins // will be disabled. NOTE: This is a rect in the case that we'll need the // left and right margins in the future. // Return value: // - True if handled successfully. False otherwise. -[[nodiscard]] NTSTATUS DoSrvPrivateSetScrollingRegion(SCREEN_INFORMATION& screenInfo, const SMALL_RECT* const psrScrollMargins) +[[nodiscard]] NTSTATUS DoSrvPrivateSetScrollingRegion(SCREEN_INFORMATION& screenInfo, const SMALL_RECT& scrollMargins) { NTSTATUS Status = STATUS_SUCCESS; - if (psrScrollMargins->Top > psrScrollMargins->Bottom) + if (scrollMargins.Top > scrollMargins.Bottom) { Status = STATUS_INVALID_PARAMETER; } if (NT_SUCCESS(Status)) { SMALL_RECT srScrollMargins = screenInfo.GetRelativeScrollMargins().ToInclusive(); - srScrollMargins.Top = psrScrollMargins->Top; - srScrollMargins.Bottom = psrScrollMargins->Bottom; + srScrollMargins.Top = scrollMargins.Top; + srScrollMargins.Bottom = scrollMargins.Bottom; screenInfo.GetActiveBuffer().SetScrollMargins(Viewport::FromInclusive(srScrollMargins)); } @@ -1690,24 +1690,14 @@ void DoSrvSetCursorColor(SCREEN_INFORMATION& screenInfo, // of extra unnecessary data and takes a lot of extra processing time. // Parameters // - screenInfo - The screen buffer to retrieve default color attributes information from -// - pwAttributes - Pointer to space that will receive color attributes data +// - attributes - Space that will receive color attributes data // Return Value: // - STATUS_SUCCESS if we succeeded or STATUS_INVALID_PARAMETER for bad params (nullptr). -[[nodiscard]] NTSTATUS DoSrvPrivateGetConsoleScreenBufferAttributes(_In_ const SCREEN_INFORMATION& screenInfo, _Out_ WORD* const pwAttributes) +[[nodiscard]] NTSTATUS DoSrvPrivateGetConsoleScreenBufferAttributes(const SCREEN_INFORMATION& screenInfo, WORD& attributes) { - NTSTATUS Status = STATUS_SUCCESS; + attributes = screenInfo.GetActiveBuffer().GetAttributes().GetLegacyAttributes(); - if (pwAttributes == nullptr) - { - Status = STATUS_INVALID_PARAMETER; - } - - if (NT_SUCCESS(Status)) - { - *pwAttributes = screenInfo.GetActiveBuffer().GetAttributes().GetLegacyAttributes(); - } - - return Status; + return STATUS_SUCCESS; } // Routine Description: @@ -2056,10 +2046,10 @@ void DoSrvPrivateRefreshWindow(_In_ const SCREEN_INFORMATION& screenInfo) // - isPty: receives the bool indicating whether or not we're in pty mode. // Return value: // -void DoSrvIsConsolePty(_Out_ bool* const pIsPty) +void DoSrvIsConsolePty(bool& isPty) { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - *pIsPty = gci.IsInVtIoMode(); + isPty = gci.IsInVtIoMode(); } // Routine Description: @@ -2075,7 +2065,7 @@ void DoSrvPrivateSetDefaultTabStops() // Parameters: // - count - the number of lines to modify // - insert - true if inserting lines, false if deleting lines -void DoSrvPrivateModifyLinesImpl(const unsigned int count, const bool insert) +void DoSrvPrivateModifyLinesImpl(const size_t count, const bool insert) { auto& screenInfo = ServiceLocator::LocateGlobals().getConsoleInformation().GetActiveOutputBuffer().GetActiveBuffer(); auto& textBuffer = screenInfo.GetTextBuffer(); @@ -2123,7 +2113,7 @@ void DoSrvPrivateModifyLinesImpl(const unsigned int count, const bool insert) // - a private API call for deleting lines in the active screen buffer. // Parameters: // - count - the number of lines to delete -void DoSrvPrivateDeleteLines(const unsigned int count) +void DoSrvPrivateDeleteLines(const size_t count) { DoSrvPrivateModifyLinesImpl(count, false); } @@ -2132,7 +2122,7 @@ void DoSrvPrivateDeleteLines(const unsigned int count) // - a private API call for inserting lines in the active screen buffer. // Parameters: // - count - the number of lines to insert -void DoSrvPrivateInsertLines(const unsigned int count) +void DoSrvPrivateInsertLines(const size_t count) { DoSrvPrivateModifyLinesImpl(count, true); } diff --git a/src/host/getset.h b/src/host/getset.h index 0971b43519..0199a7660f 100644 --- a/src/host/getset.h +++ b/src/host/getset.h @@ -32,7 +32,7 @@ void DoSrvPrivateSetDefaultAttributes(SCREEN_INFORMATION& screenInfo, const bool void DoSrvPrivateShowCursor(SCREEN_INFORMATION& screenInfo, const bool show) noexcept; void DoSrvPrivateAllowCursorBlinking(SCREEN_INFORMATION& screenInfo, const bool fEnable); -[[nodiscard]] NTSTATUS DoSrvPrivateSetScrollingRegion(SCREEN_INFORMATION& screenInfo, const SMALL_RECT* const psrScrollMargins); +[[nodiscard]] NTSTATUS DoSrvPrivateSetScrollingRegion(SCREEN_INFORMATION& screenInfo, const SMALL_RECT& scrollMargins); [[nodiscard]] NTSTATUS DoSrvPrivateReverseLineFeed(SCREEN_INFORMATION& screenInfo); [[nodiscard]] HRESULT DoSrvMoveCursorVertically(SCREEN_INFORMATION& screenInfo, const short lines); @@ -71,19 +71,19 @@ void DoSrvSetCursorColor(SCREEN_INFORMATION& screenInfo, const COLORREF cursorColor); [[nodiscard]] NTSTATUS DoSrvPrivateGetConsoleScreenBufferAttributes(const SCREEN_INFORMATION& screenInfo, - _Out_ WORD* const pwAttributes); + WORD& attributes); void DoSrvPrivateRefreshWindow(const SCREEN_INFORMATION& screenInfo); -void DoSrvGetConsoleOutputCodePage(_Out_ unsigned int* const pCodePage); +void DoSrvGetConsoleOutputCodePage(unsigned int& codepage); [[nodiscard]] NTSTATUS DoSrvPrivateSuppressResizeRepaint(); -void DoSrvIsConsolePty(_Out_ bool* const pIsPty); +void DoSrvIsConsolePty(bool& isPty); void DoSrvPrivateSetDefaultTabStops(); -void DoSrvPrivateDeleteLines(const unsigned int count); -void DoSrvPrivateInsertLines(const unsigned int count); +void DoSrvPrivateDeleteLines(const size_t count); +void DoSrvPrivateInsertLines(const size_t count); void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo); diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index f69fa961be..ff713ae415 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -36,12 +36,12 @@ void WriteBuffer::Print(const wchar_t wch) // Routine Description: // - Handles the print action from the state machine // Arguments: -// - wch - The character to be printed. +// - string - The string to be printed. // Return Value: // - -void WriteBuffer::PrintString(const wchar_t* const rgwch, const size_t cch) +void WriteBuffer::PrintString(const std::wstring_view string) { - _DefaultStringCase(rgwch, cch); + _DefaultStringCase(string); } // Routine Description: @@ -63,25 +63,25 @@ void WriteBuffer::Execute(const wchar_t wch) // - void WriteBuffer::_DefaultCase(const wchar_t wch) { - _DefaultStringCase(const_cast(&wch), 1); // WriteCharsLegacy wants mutable chars, so we'll givve it mutable chars. + _DefaultStringCase({ &wch, 1 }); } // Routine Description: // - Default text editing/printing handler for all characters that were not routed elsewhere by other state machine intercepts. // Arguments: -// - wch - The character to be processed by our default text editing/printing mechanisms. +// - string - The string to be processed by our default text editing/printing mechanisms. // Return Value: // - -void WriteBuffer::_DefaultStringCase(_In_reads_(cch) const wchar_t* const rgwch, const size_t cch) +void WriteBuffer::_DefaultStringCase(const std::wstring_view string) { - size_t dwNumBytes = cch * sizeof(wchar_t); + size_t dwNumBytes = string.size() * sizeof(wchar_t); _io.GetActiveOutputBuffer().GetTextBuffer().GetCursor().SetIsOn(true); _ntstatus = WriteCharsLegacy(_io.GetActiveOutputBuffer(), - rgwch, - rgwch, - rgwch, + string.data(), + string.data(), + string.data(), &dwNumBytes, nullptr, _io.GetActiveOutputBuffer().GetTextBuffer().GetCursor().GetPosition().X, @@ -97,124 +97,124 @@ ConhostInternalGetSet::ConhostInternalGetSet(_In_ IIoProvider& io) : // Routine Description: // - Connects the GetConsoleScreenBufferInfoEx API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: -// - pConsoleScreenBufferInfoEx - Pointer to structure to hold screen buffer information like the public API call. +// - screenBufferInfo - Structure to hold screen buffer information like the public API call. // Return Value: -// - TRUE if successful (see DoSrvGetConsoleScreenBufferInfo). FALSE otherwise. -BOOL ConhostInternalGetSet::GetConsoleScreenBufferInfoEx(_Out_ CONSOLE_SCREEN_BUFFER_INFOEX* const pConsoleScreenBufferInfoEx) const +// - true if successful (see DoSrvGetConsoleScreenBufferInfo). false otherwise. +bool ConhostInternalGetSet::GetConsoleScreenBufferInfoEx(CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) const { - ServiceLocator::LocateGlobals().api.GetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), *pConsoleScreenBufferInfoEx); - return TRUE; + ServiceLocator::LocateGlobals().api.GetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), screenBufferInfo); + return true; } // Routine Description: // - Connects the SetConsoleScreenBufferInfoEx API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: -// - pConsoleScreenBufferInfoEx - Pointer to structure containing screen buffer information like the public API call. +// - screenBufferInfo - Structure containing screen buffer information like the public API call. // Return Value: -// - TRUE if successful (see DoSrvSetConsoleScreenBufferInfo). FALSE otherwise. -BOOL ConhostInternalGetSet::SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX* const pConsoleScreenBufferInfoEx) +// - true if successful (see DoSrvSetConsoleScreenBufferInfo). false otherwise. +bool ConhostInternalGetSet::SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) { - return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), *pConsoleScreenBufferInfoEx)); + return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleScreenBufferInfoExImpl(_io.GetActiveOutputBuffer(), screenBufferInfo)); } // Routine Description: // - Connects the SetConsoleCursorPosition API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: -// - coordCursorPosition - new cursor position to set like the public API call. +// - position - new cursor position to set like the public API call. // Return Value: -// - TRUE if successful (see DoSrvSetConsoleCursorPosition). FALSE otherwise. -BOOL ConhostInternalGetSet::SetConsoleCursorPosition(const COORD coordCursorPosition) +// - true if successful (see DoSrvSetConsoleCursorPosition). false otherwise. +bool ConhostInternalGetSet::SetConsoleCursorPosition(const COORD position) { - return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleCursorPositionImpl(_io.GetActiveOutputBuffer(), coordCursorPosition)); + return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleCursorPositionImpl(_io.GetActiveOutputBuffer(), position)); } // Routine Description: // - Connects the GetConsoleCursorInfo API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: -// - pConsoleCursorInfo - Pointer to structure to receive console cursor rendering info +// - cursorInfo - Structure to receive console cursor rendering info // Return Value: -// - TRUE if successful (see DoSrvGetConsoleCursorInfo). FALSE otherwise. -BOOL ConhostInternalGetSet::GetConsoleCursorInfo(_In_ CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) const +// - true if successful (see DoSrvGetConsoleCursorInfo). false otherwise. +bool ConhostInternalGetSet::GetConsoleCursorInfo(CONSOLE_CURSOR_INFO& cursorInfo) const { - bool bVisible; - DWORD dwSize; + bool visible; + DWORD size; - ServiceLocator::LocateGlobals().api.GetConsoleCursorInfoImpl(_io.GetActiveOutputBuffer(), dwSize, bVisible); - pConsoleCursorInfo->bVisible = bVisible; - pConsoleCursorInfo->dwSize = dwSize; - return TRUE; + ServiceLocator::LocateGlobals().api.GetConsoleCursorInfoImpl(_io.GetActiveOutputBuffer(), size, visible); + cursorInfo.bVisible = visible; + cursorInfo.dwSize = size; + return true; } // Routine Description: // - Connects the SetConsoleCursorInfo API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: -// - pConsoleCursorInfo - Updated size/visibility information to modify the cursor rendering behavior. +// - cursorInfo - Updated size/visibility information to modify the cursor rendering behavior. // Return Value: -// - TRUE if successful (see DoSrvSetConsoleCursorInfo). FALSE otherwise. -BOOL ConhostInternalGetSet::SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) +// - true if successful (see DoSrvSetConsoleCursorInfo). false otherwise. +bool ConhostInternalGetSet::SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO& cursorInfo) { - const bool visible = !!pConsoleCursorInfo->bVisible; - return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleCursorInfoImpl(_io.GetActiveOutputBuffer(), pConsoleCursorInfo->dwSize, visible)); + const bool visible = !!cursorInfo.bVisible; + return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleCursorInfoImpl(_io.GetActiveOutputBuffer(), cursorInfo.dwSize, visible)); } // Routine Description: // - Connects the SetConsoleTextAttribute API call directly into our Driver Message servicing call inside Conhost.exe // Sets BOTH the FG and the BG component of the attributes. // Arguments: -// - wAttr - new color/graphical attributes to apply as default within the console text buffer +// - attr - new color/graphical attributes to apply as default within the console text buffer // Return Value: -// - TRUE if successful (see DoSrvSetConsoleTextAttribute). FALSE otherwise. -BOOL ConhostInternalGetSet::SetConsoleTextAttribute(const WORD wAttr) +// - true if successful (see DoSrvSetConsoleTextAttribute). false otherwise. +bool ConhostInternalGetSet::SetConsoleTextAttribute(const WORD attr) { - return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleTextAttributeImpl(_io.GetActiveOutputBuffer(), wAttr)); + return SUCCEEDED(ServiceLocator::LocateGlobals().api.SetConsoleTextAttributeImpl(_io.GetActiveOutputBuffer(), attr)); } // Routine Description: // - Connects the PrivateSetDefaultAttributes API call directly into our Driver Message servicing call inside Conhost.exe // Sets the FG and/or BG to the Default attributes values. // Arguments: -// - fForeground - Set the foreground to the default attributes -// - fBackground - Set the background to the default attributes +// - foreground - Set the foreground to the default attributes +// - background - Set the background to the default attributes // Return Value: -// - TRUE if successful (see DoSrvPrivateSetDefaultAttributes). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSetDefaultAttributes(const bool fForeground, - const bool fBackground) +// - true if successful (see DoSrvPrivateSetDefaultAttributes). false otherwise. +bool ConhostInternalGetSet::PrivateSetDefaultAttributes(const bool foreground, + const bool background) { - DoSrvPrivateSetDefaultAttributes(_io.GetActiveOutputBuffer(), fForeground, fBackground); - return TRUE; + DoSrvPrivateSetDefaultAttributes(_io.GetActiveOutputBuffer(), foreground, background); + return true; } // Routine Description: // - Connects the PrivateSetLegacyAttributes API call directly into our Driver Message servicing call inside Conhost.exe -// Sets only the components of the attributes requested with the fForeground, fBackground, and fMeta flags. +// Sets only the components of the attributes requested with the foreground, background, and meta flags. // Arguments: -// - wAttr - new color/graphical attributes to apply as default within the console text buffer -// - fForeground - The new attributes contain an update to the foreground attributes -// - fBackground - The new attributes contain an update to the background attributes -// - fMeta - The new attributes contain an update to the meta attributes +// - attr - new color/graphical attributes to apply as default within the console text buffer +// - foreground - The new attributes contain an update to the foreground attributes +// - background - The new attributes contain an update to the background attributes +// - meta - The new attributes contain an update to the meta attributes // Return Value: -// - TRUE if successful (see DoSrvVtSetLegacyAttributes). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSetLegacyAttributes(const WORD wAttr, - const bool fForeground, - const bool fBackground, - const bool fMeta) +// - true if successful (see DoSrvVtSetLegacyAttributes). false otherwise. +bool ConhostInternalGetSet::PrivateSetLegacyAttributes(const WORD attr, + const bool foreground, + const bool background, + const bool meta) { - DoSrvPrivateSetLegacyAttributes(_io.GetActiveOutputBuffer(), wAttr, fForeground, fBackground, fMeta); - return TRUE; + DoSrvPrivateSetLegacyAttributes(_io.GetActiveOutputBuffer(), attr, foreground, background, meta); + return true; } // Routine Description: // - Sets the current attributes of the screen buffer to use the color table entry specified by -// the iXtermTableEntry. Sets either the FG or the BG component of the attributes. +// the xtermTableEntry. Sets either the FG or the BG component of the attributes. // Arguments: -// - iXtermTableEntry - The entry of the xterm table to use. -// - fIsForeground - Whether or not the color applies to the foreground. +// - xtermTableEntry - The entry of the xterm table to use. +// - isForeground - Whether or not the color applies to the foreground. // Return Value: -// - TRUE if successful (see DoSrvPrivateSetConsoleXtermTextAttribute). FALSE otherwise. -BOOL ConhostInternalGetSet::SetConsoleXtermTextAttribute(const int iXtermTableEntry, const bool fIsForeground) +// - true if successful (see DoSrvPrivateSetConsoleXtermTextAttribute). false otherwise. +bool ConhostInternalGetSet::SetConsoleXtermTextAttribute(const int xtermTableEntry, const bool isForeground) { - DoSrvPrivateSetConsoleXtermTextAttribute(_io.GetActiveOutputBuffer(), iXtermTableEntry, fIsForeground); - return TRUE; + DoSrvPrivateSetConsoleXtermTextAttribute(_io.GetActiveOutputBuffer(), xtermTableEntry, isForeground); + return true; } // Routine Description: @@ -222,32 +222,32 @@ BOOL ConhostInternalGetSet::SetConsoleXtermTextAttribute(const int iXtermTableEn // Sets either the FG or the BG component of the attributes. // Arguments: // - rgbColor - The rgb color to use. -// - fIsForeground - Whether or not the color applies to the foreground. +// - isForeground - Whether or not the color applies to the foreground. // Return Value: -// - TRUE if successful (see DoSrvPrivateSetConsoleRGBTextAttribute). FALSE otherwise. -BOOL ConhostInternalGetSet::SetConsoleRGBTextAttribute(const COLORREF rgbColor, const bool fIsForeground) +// - true if successful (see DoSrvPrivateSetConsoleRGBTextAttribute). false otherwise. +bool ConhostInternalGetSet::SetConsoleRGBTextAttribute(const COLORREF rgbColor, const bool isForeground) { - DoSrvPrivateSetConsoleRGBTextAttribute(_io.GetActiveOutputBuffer(), rgbColor, fIsForeground); - return TRUE; + DoSrvPrivateSetConsoleRGBTextAttribute(_io.GetActiveOutputBuffer(), rgbColor, isForeground); + return true; } -BOOL ConhostInternalGetSet::PrivateBoldText(const bool bolded) +bool ConhostInternalGetSet::PrivateBoldText(const bool bolded) { DoSrvPrivateBoldText(_io.GetActiveOutputBuffer(), bolded); - return TRUE; + return true; } // Method Description: // - Retrieves the currently active ExtendedAttributes. See also // DoSrvPrivateGetExtendedTextAttributes // Arguments: -// - pAttrs: Recieves the ExtendedAttributes value. +// - attrs: Recieves the ExtendedAttributes value. // Return Value: -// - TRUE if successful (see DoSrvPrivateGetExtendedTextAttributes). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateGetExtendedTextAttributes(ExtendedAttributes* const pAttrs) +// - true if successful (see DoSrvPrivateGetExtendedTextAttributes). false otherwise. +bool ConhostInternalGetSet::PrivateGetExtendedTextAttributes(ExtendedAttributes& attrs) { - *pAttrs = DoSrvPrivateGetExtendedTextAttributes(_io.GetActiveOutputBuffer()); - return TRUE; + attrs = DoSrvPrivateGetExtendedTextAttributes(_io.GetActiveOutputBuffer()); + return true; } // Method Description: @@ -256,23 +256,23 @@ BOOL ConhostInternalGetSet::PrivateGetExtendedTextAttributes(ExtendedAttributes* // Arguments: // - extendedAttrs: The new ExtendedAttributes to use // Return Value: -// - TRUE if successful (see DoSrvPrivateSetExtendedTextAttributes). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSetExtendedTextAttributes(const ExtendedAttributes attrs) +// - true if successful (see DoSrvPrivateSetExtendedTextAttributes). false otherwise. +bool ConhostInternalGetSet::PrivateSetExtendedTextAttributes(const ExtendedAttributes attrs) { DoSrvPrivateSetExtendedTextAttributes(_io.GetActiveOutputBuffer(), attrs); - return TRUE; + return true; } // Method Description: // - Retrieves the current TextAttribute of the active screen buffer. // Arguments: -// - pAttrs: Receives the TextAttribute value. +// - attrs: Receives the TextAttribute value. // Return Value: -// - TRUE if successful. FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateGetTextAttributes(TextAttribute* const pAttrs) const +// - true if successful. false otherwise. +bool ConhostInternalGetSet::PrivateGetTextAttributes(TextAttribute& attrs) const { - *pAttrs = _io.GetActiveOutputBuffer().GetAttributes(); - return TRUE; + attrs = _io.GetActiveOutputBuffer().GetAttributes(); + return true; } // Method Description: @@ -281,23 +281,23 @@ BOOL ConhostInternalGetSet::PrivateGetTextAttributes(TextAttribute* const pAttrs // Arguments: // - attrs: The new TextAttribute to use // Return Value: -// - TRUE if successful. FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSetTextAttributes(const TextAttribute& attrs) +// - true if successful. false otherwise. +bool ConhostInternalGetSet::PrivateSetTextAttributes(const TextAttribute& attrs) { _io.GetActiveOutputBuffer().SetAttributes(attrs); - return TRUE; + return true; } // Routine Description: // - Connects the WriteConsoleInput API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: // - events - the input events to be copied into the head of the input -// buffer for the underlying attached process +// buffer for the underlying attached process // - eventsWritten - on output, the number of events written // Return Value: -// - TRUE if successful (see DoSrvWriteConsoleInput). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateWriteConsoleInputW(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) +// - true if successful (see DoSrvWriteConsoleInput). false otherwise. +bool ConhostInternalGetSet::PrivateWriteConsoleInputW(std::deque>& events, + size_t& eventsWritten) { eventsWritten = 0; @@ -310,13 +310,13 @@ BOOL ConhostInternalGetSet::PrivateWriteConsoleInputW(_Inout_ std::deque // Return Value: -// - TRUE if successful (see PrivateHorizontalTabSet). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateHorizontalTabSet() +// - true if successful (see PrivateHorizontalTabSet). false otherwise. +bool ConhostInternalGetSet::PrivateHorizontalTabSet() { return NT_SUCCESS(DoSrvPrivateHorizontalTabSet()); } @@ -461,10 +467,16 @@ BOOL ConhostInternalGetSet::PrivateHorizontalTabSet() // Arguments: // - sNumTabs - the number of tabs to execute // Return Value: -// - TRUE if successful (see PrivateForwardTab). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateForwardTab(const SHORT sNumTabs) +// - true if successful (see PrivateForwardTab). false otherwise. +bool ConhostInternalGetSet::PrivateForwardTab(const size_t numTabs) { - return NT_SUCCESS(DoSrvPrivateForwardTab(sNumTabs)); + SHORT tabs; + if (FAILED(SizeTToShort(numTabs, &tabs))) + { + return false; + } + + return NT_SUCCESS(DoSrvPrivateForwardTab(tabs)); } // Routine Description: @@ -472,12 +484,18 @@ BOOL ConhostInternalGetSet::PrivateForwardTab(const SHORT sNumTabs) // PrivateBackwardsTab is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - sNumTabs - the number of tabs to execute +// - numTabs - the number of tabs to execute // Return Value: -// - TRUE if successful (see PrivateBackwardsTab). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateBackwardsTab(const SHORT sNumTabs) +// - true if successful (see PrivateBackwardsTab). false otherwise. +bool ConhostInternalGetSet::PrivateBackwardsTab(const size_t numTabs) { - return NT_SUCCESS(DoSrvPrivateBackwardsTab(sNumTabs)); + SHORT tabs; + if (FAILED(SizeTToShort(numTabs, &tabs))) + { + return false; + } + + return NT_SUCCESS(DoSrvPrivateBackwardsTab(tabs)); } // Routine Description: @@ -485,23 +503,23 @@ BOOL ConhostInternalGetSet::PrivateBackwardsTab(const SHORT sNumTabs) // PrivateTabClear is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fClearAll - set to true to enable blinking, false to disable +// - clearAll - set to true to enable blinking, false to disable // Return Value: -// - TRUE if successful (see PrivateTabClear). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateTabClear(const bool fClearAll) +// - true if successful (see PrivateTabClear). false otherwise. +bool ConhostInternalGetSet::PrivateTabClear(const bool clearAll) { - DoSrvPrivateTabClear(fClearAll); - return TRUE; + DoSrvPrivateTabClear(clearAll); + return true; } // Routine Description: // - Connects the PrivateSetDefaultTabStops call directly into the private api point // Return Value: -// - TRUE -BOOL ConhostInternalGetSet::PrivateSetDefaultTabStops() +// - true +bool ConhostInternalGetSet::PrivateSetDefaultTabStops() { DoSrvPrivateSetDefaultTabStops(); - return TRUE; + return true; } // Routine Description: @@ -509,13 +527,13 @@ BOOL ConhostInternalGetSet::PrivateSetDefaultTabStops() // PrivateEnableVT200MouseMode is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fEnabled - set to true to enable vt200 mouse mode, false to disable +// - enabled - set to true to enable vt200 mouse mode, false to disable // Return Value: -// - TRUE if successful (see DoSrvPrivateEnableVT200MouseMode). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateEnableVT200MouseMode(const bool fEnabled) +// - true if successful (see DoSrvPrivateEnableVT200MouseMode). false otherwise. +bool ConhostInternalGetSet::PrivateEnableVT200MouseMode(const bool enabled) { - DoSrvPrivateEnableVT200MouseMode(fEnabled); - return TRUE; + DoSrvPrivateEnableVT200MouseMode(enabled); + return true; } // Routine Description: @@ -523,13 +541,13 @@ BOOL ConhostInternalGetSet::PrivateEnableVT200MouseMode(const bool fEnabled) // PrivateEnableUTF8ExtendedMouseMode is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fEnabled - set to true to enable utf8 extended mouse mode, false to disable +// - enabled - set to true to enable utf8 extended mouse mode, false to disable // Return Value: -// - TRUE if successful (see DoSrvPrivateEnableUTF8ExtendedMouseMode). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateEnableUTF8ExtendedMouseMode(const bool fEnabled) +// - true if successful (see DoSrvPrivateEnableUTF8ExtendedMouseMode). false otherwise. +bool ConhostInternalGetSet::PrivateEnableUTF8ExtendedMouseMode(const bool enabled) { - DoSrvPrivateEnableUTF8ExtendedMouseMode(fEnabled); - return TRUE; + DoSrvPrivateEnableUTF8ExtendedMouseMode(enabled); + return true; } // Routine Description: @@ -537,13 +555,13 @@ BOOL ConhostInternalGetSet::PrivateEnableUTF8ExtendedMouseMode(const bool fEnabl // PrivateEnableSGRExtendedMouseMode is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fEnabled - set to true to enable SGR extended mouse mode, false to disable +// - enabled - set to true to enable SGR extended mouse mode, false to disable // Return Value: -// - TRUE if successful (see DoSrvPrivateEnableSGRExtendedMouseMode). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateEnableSGRExtendedMouseMode(const bool fEnabled) +// - true if successful (see DoSrvPrivateEnableSGRExtendedMouseMode). false otherwise. +bool ConhostInternalGetSet::PrivateEnableSGRExtendedMouseMode(const bool enabled) { - DoSrvPrivateEnableSGRExtendedMouseMode(fEnabled); - return TRUE; + DoSrvPrivateEnableSGRExtendedMouseMode(enabled); + return true; } // Routine Description: @@ -551,13 +569,13 @@ BOOL ConhostInternalGetSet::PrivateEnableSGRExtendedMouseMode(const bool fEnable // PrivateEnableButtonEventMouseMode is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fEnabled - set to true to enable button-event mouse mode, false to disable +// - enabled - set to true to enable button-event mouse mode, false to disable // Return Value: -// - TRUE if successful (see DoSrvPrivateEnableButtonEventMouseMode). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateEnableButtonEventMouseMode(const bool fEnabled) +// - true if successful (see DoSrvPrivateEnableButtonEventMouseMode). false otherwise. +bool ConhostInternalGetSet::PrivateEnableButtonEventMouseMode(const bool enabled) { - DoSrvPrivateEnableButtonEventMouseMode(fEnabled); - return TRUE; + DoSrvPrivateEnableButtonEventMouseMode(enabled); + return true; } // Routine Description: @@ -565,13 +583,13 @@ BOOL ConhostInternalGetSet::PrivateEnableButtonEventMouseMode(const bool fEnable // PrivateEnableAnyEventMouseMode is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fEnabled - set to true to enable any-event mouse mode, false to disable +// - enabled - set to true to enable any-event mouse mode, false to disable // Return Value: -// - TRUE if successful (see DoSrvPrivateEnableAnyEventMouseMode). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateEnableAnyEventMouseMode(const bool fEnabled) +// - true if successful (see DoSrvPrivateEnableAnyEventMouseMode). false otherwise. +bool ConhostInternalGetSet::PrivateEnableAnyEventMouseMode(const bool enabled) { - DoSrvPrivateEnableAnyEventMouseMode(fEnabled); - return TRUE; + DoSrvPrivateEnableAnyEventMouseMode(enabled); + return true; } // Routine Description: @@ -579,13 +597,13 @@ BOOL ConhostInternalGetSet::PrivateEnableAnyEventMouseMode(const bool fEnabled) // PrivateEnableAlternateScroll is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fEnabled - set to true to enable alternate scroll mode, false to disable +// - enabled - set to true to enable alternate scroll mode, false to disable // Return Value: -// - TRUE if successful (see DoSrvPrivateEnableAnyEventMouseMode). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateEnableAlternateScroll(const bool fEnabled) +// - true if successful (see DoSrvPrivateEnableAnyEventMouseMode). false otherwise. +bool ConhostInternalGetSet::PrivateEnableAlternateScroll(const bool enabled) { - DoSrvPrivateEnableAlternateScroll(fEnabled); - return TRUE; + DoSrvPrivateEnableAlternateScroll(enabled); + return true; } // Routine Description: @@ -595,8 +613,8 @@ BOOL ConhostInternalGetSet::PrivateEnableAlternateScroll(const bool fEnabled) // Arguments: // // Return Value: -// - TRUE if successful (see DoSrvPrivateEraseAll). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateEraseAll() +// - true if successful (see DoSrvPrivateEraseAll). false otherwise. +bool ConhostInternalGetSet::PrivateEraseAll() { return NT_SUCCESS(DoSrvPrivateEraseAll(_io.GetActiveOutputBuffer())); } @@ -606,13 +624,13 @@ BOOL ConhostInternalGetSet::PrivateEraseAll() // SetCursorStyle is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on our public API surface. // Arguments: -// - cursorType: The style of cursor to change the cursor to. +// - style: The style of cursor to change the cursor to. // Return Value: -// - TRUE if successful (see DoSrvSetCursorStyle). FALSE otherwise. -BOOL ConhostInternalGetSet::SetCursorStyle(const CursorType cursorType) +// - true if successful (see DoSrvSetCursorStyle). false otherwise. +bool ConhostInternalGetSet::SetCursorStyle(const CursorType style) { - DoSrvSetCursorStyle(_io.GetActiveOutputBuffer(), cursorType); - return TRUE; + DoSrvSetCursorStyle(_io.GetActiveOutputBuffer(), style); + return true; } // Routine Description: @@ -621,22 +639,22 @@ BOOL ConhostInternalGetSet::SetCursorStyle(const CursorType cursorType) // Arguments: // - pwAttributes - Pointer to space to receive color attributes data // Return Value: -// - TRUE if successful. FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateGetConsoleScreenBufferAttributes(_Out_ WORD* const pwAttributes) +// - true if successful. false otherwise. +bool ConhostInternalGetSet::PrivateGetConsoleScreenBufferAttributes(WORD& attributes) { - return NT_SUCCESS(DoSrvPrivateGetConsoleScreenBufferAttributes(_io.GetActiveOutputBuffer(), pwAttributes)); + return NT_SUCCESS(DoSrvPrivateGetConsoleScreenBufferAttributes(_io.GetActiveOutputBuffer(), attributes)); } // Routine Description: // - Connects the PrivatePrependConsoleInput API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: // - events - the input events to be copied into the head of the input -// buffer for the underlying attached process +// buffer for the underlying attached process // - eventsWritten - on output, the number of events written // Return Value: -// - TRUE if successful (see DoSrvPrivatePrependConsoleInput). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivatePrependConsoleInput(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) +// - true if successful (see DoSrvPrivatePrependConsoleInput). false otherwise. +bool ConhostInternalGetSet::PrivatePrependConsoleInput(std::deque>& events, + size_t& eventsWritten) { return SUCCEEDED(DoSrvPrivatePrependConsoleInput(_io.GetActiveInputBuffer(), events, @@ -648,11 +666,11 @@ BOOL ConhostInternalGetSet::PrivatePrependConsoleInput(_Inout_ std::deque // Return Value: -// - TRUE if successful (see DoSrvPrivateRefreshWindow). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateRefreshWindow() +// - true if successful (see DoSrvPrivateRefreshWindow). false otherwise. +bool ConhostInternalGetSet::PrivateRefreshWindow() { DoSrvPrivateRefreshWindow(_io.GetActiveOutputBuffer()); - return TRUE; + return true; } // Routine Description: @@ -660,8 +678,8 @@ BOOL ConhostInternalGetSet::PrivateRefreshWindow() // Arguments: // - key - a KeyEvent representing a special type of keypress, typically Ctrl-C // Return Value: -// - TRUE if successful (see DoSrvPrivateWriteConsoleControlInput). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateWriteConsoleControlInput(_In_ KeyEvent key) +// - true if successful (see DoSrvPrivateWriteConsoleControlInput). false otherwise. +bool ConhostInternalGetSet::PrivateWriteConsoleControlInput(const KeyEvent key) { return SUCCEEDED(DoSrvPrivateWriteConsoleControlInput(_io.GetActiveInputBuffer(), key)); @@ -670,13 +688,13 @@ BOOL ConhostInternalGetSet::PrivateWriteConsoleControlInput(_In_ KeyEvent key) // Routine Description: // - Connects the GetConsoleOutputCP API call directly into our Driver Message servicing call inside Conhost.exe // Arguments: -// - puiOutputCP - recieves the outputCP of the console. +// - codepage - recieves the outputCP of the console. // Return Value: -// - TRUE if successful (see DoSrvPrivateWriteConsoleControlInput). FALSE otherwise. -BOOL ConhostInternalGetSet::GetConsoleOutputCP(_Out_ unsigned int* const puiOutputCP) +// - true if successful (see DoSrvPrivateWriteConsoleControlInput). false otherwise. +bool ConhostInternalGetSet::GetConsoleOutputCP(unsigned int& codepage) { - DoSrvGetConsoleOutputCodePage(puiOutputCP); - return TRUE; + DoSrvGetConsoleOutputCodePage(codepage); + return true; } // Routine Description: @@ -685,8 +703,8 @@ BOOL ConhostInternalGetSet::GetConsoleOutputCP(_Out_ unsigned int* const puiOutp // Arguments: // - // Return Value: -// - TRUE if successful (see DoSrvPrivateSuppressResizeRepaint). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSuppressResizeRepaint() +// - true if successful (see DoSrvPrivateSuppressResizeRepaint). false otherwise. +bool ConhostInternalGetSet::PrivateSuppressResizeRepaint() { return SUCCEEDED(DoSrvPrivateSuppressResizeRepaint()); } @@ -699,11 +717,11 @@ BOOL ConhostInternalGetSet::PrivateSuppressResizeRepaint() // - cursorColor: The color to change the cursor to. INVALID_COLOR will revert // it to the legacy inverting behavior. // Return Value: -// - TRUE if successful (see DoSrvSetCursorStyle). FALSE otherwise. -BOOL ConhostInternalGetSet::SetCursorColor(const COLORREF cursorColor) +// - true if successful (see DoSrvSetCursorStyle). false otherwise. +bool ConhostInternalGetSet::SetCursorColor(const COLORREF cursorColor) { DoSrvSetCursorColor(_io.GetActiveOutputBuffer(), cursorColor); - return TRUE; + return true; } // Routine Description: @@ -711,23 +729,23 @@ BOOL ConhostInternalGetSet::SetCursorColor(const COLORREF cursorColor) // Arguments: // - isPty: recieves the bool indicating whether or not we're in pty mode. // Return Value: -// - TRUE if successful (see DoSrvIsConsolePty). FALSE otherwise. -BOOL ConhostInternalGetSet::IsConsolePty(_Out_ bool* const pIsPty) const +// - true if successful (see DoSrvIsConsolePty). false otherwise. +bool ConhostInternalGetSet::IsConsolePty(bool& isPty) const { - DoSrvIsConsolePty(pIsPty); - return TRUE; + DoSrvIsConsolePty(isPty); + return true; } -BOOL ConhostInternalGetSet::DeleteLines(const unsigned int count) +bool ConhostInternalGetSet::DeleteLines(const size_t count) { DoSrvPrivateDeleteLines(count); - return TRUE; + return true; } -BOOL ConhostInternalGetSet::InsertLines(const unsigned int count) +bool ConhostInternalGetSet::InsertLines(const size_t count) { DoSrvPrivateInsertLines(count); - return TRUE; + return true; } // Method Description: @@ -736,11 +754,11 @@ BOOL ConhostInternalGetSet::InsertLines(const unsigned int count) // Arguments: // // Return Value: -// - TRUE if successful (see DoSrvPrivateMoveToBottom). FALSE otherwise. -BOOL ConhostInternalGetSet::MoveToBottom() const +// - true if successful (see DoSrvPrivateMoveToBottom). false otherwise. +bool ConhostInternalGetSet::MoveToBottom() const { DoSrvPrivateMoveToBottom(_io.GetActiveOutputBuffer()); - return TRUE; + return true; } // Method Description: @@ -750,8 +768,8 @@ BOOL ConhostInternalGetSet::MoveToBottom() const // - index: the index in the table to change. // - value: the new RGB value to use for that index in the color table. // Return Value: -// - TRUE if successful (see DoSrvPrivateSetColorTableEntry). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept +// - true if successful (see DoSrvPrivateSetColorTableEntry). false otherwise. +bool ConhostInternalGetSet::PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept { return SUCCEEDED(DoSrvPrivateSetColorTableEntry(index, value)); } @@ -762,8 +780,8 @@ BOOL ConhostInternalGetSet::PrivateSetColorTableEntry(const short index, const C // Arguments: // - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. // Return Value: -// - TRUE if successful (see DoSrvPrivateSetDefaultForegroundColor). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSetDefaultForeground(const COLORREF value) const noexcept +// - true if successful (see DoSrvPrivateSetDefaultForegroundColor). false otherwise. +bool ConhostInternalGetSet::PrivateSetDefaultForeground(const COLORREF value) const noexcept { return SUCCEEDED(DoSrvPrivateSetDefaultForegroundColor(value)); } @@ -774,8 +792,8 @@ BOOL ConhostInternalGetSet::PrivateSetDefaultForeground(const COLORREF value) co // Arguments: // - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. // Return Value: -// - TRUE if successful (see DoSrvPrivateSetDefaultBackgroundColor). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateSetDefaultBackground(const COLORREF value) const noexcept +// - true if successful (see DoSrvPrivateSetDefaultBackgroundColor). false otherwise. +bool ConhostInternalGetSet::PrivateSetDefaultBackground(const COLORREF value) const noexcept { return SUCCEEDED(DoSrvPrivateSetDefaultBackgroundColor(value)); } @@ -793,8 +811,8 @@ BOOL ConhostInternalGetSet::PrivateSetDefaultBackground(const COLORREF value) co // - standardFillAttrs - If true, fill with the standard erase attributes. // If false, fill with the default attributes. // Return value: -// - TRUE if successful (see DoSrvPrivateScrollRegion). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateFillRegion(const COORD startPosition, +// - true if successful (see DoSrvPrivateScrollRegion). false otherwise. +bool ConhostInternalGetSet::PrivateFillRegion(const COORD startPosition, const size_t fillLength, const wchar_t fillChar, const bool standardFillAttrs) noexcept @@ -818,8 +836,8 @@ BOOL ConhostInternalGetSet::PrivateFillRegion(const COORD startPosition, // - standardFillAttrs - If true, fill with the standard erase attributes. // If false, fill with the default attributes. // Return value: -// - TRUE if successful (see DoSrvPrivateScrollRegion). FALSE otherwise. -BOOL ConhostInternalGetSet::PrivateScrollRegion(const SMALL_RECT scrollRect, +// - true if successful (see DoSrvPrivateScrollRegion). false otherwise. +bool ConhostInternalGetSet::PrivateScrollRegion(const SMALL_RECT scrollRect, const std::optional clipRect, const COORD destinationOrigin, const bool standardFillAttrs) noexcept diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index 244ce172ac..f7f6d720f4 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -29,14 +29,14 @@ public: // Implement Adapter callbacks for default cases (non-escape sequences) void Print(const wchar_t wch) override; - void PrintString(const wchar_t* const rgwch, const size_t cch) override; + void PrintString(const std::wstring_view string) override; void Execute(const wchar_t wch) override; [[nodiscard]] NTSTATUS GetResult() { return _ntstatus; }; private: void _DefaultCase(const wchar_t wch); - void _DefaultStringCase(_In_reads_(cch) const wchar_t* const rgwch, const size_t cch); + void _DefaultStringCase(const std::wstring_view string); Microsoft::Console::IIoProvider& _io; NTSTATUS _ntstatus; @@ -54,109 +54,109 @@ class ConhostInternalGetSet final : public Microsoft::Console::VirtualTerminal:: public: ConhostInternalGetSet(_In_ Microsoft::Console::IIoProvider& io); - BOOL GetConsoleScreenBufferInfoEx(_Out_ CONSOLE_SCREEN_BUFFER_INFOEX* const pConsoleScreenBufferInfoEx) const override; - BOOL SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX* const pConsoleScreenBufferInfoEx) override; + bool GetConsoleScreenBufferInfoEx(CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) const override; + bool SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) override; - BOOL SetConsoleCursorPosition(const COORD coordCursorPosition) override; + bool SetConsoleCursorPosition(const COORD position) override; - BOOL GetConsoleCursorInfo(_In_ CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) const override; - BOOL SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) override; + bool GetConsoleCursorInfo(CONSOLE_CURSOR_INFO& cursorInfo) const override; + bool SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO& cursorInfo) override; - BOOL SetConsoleTextAttribute(const WORD wAttr) override; + bool SetConsoleTextAttribute(const WORD attr) override; - BOOL PrivateSetLegacyAttributes(const WORD wAttr, - const bool fForeground, - const bool fBackground, - const bool fMeta) override; + bool PrivateSetLegacyAttributes(const WORD attr, + const bool foreground, + const bool background, + const bool meta) override; - BOOL PrivateSetDefaultAttributes(const bool fForeground, - const bool fBackground) override; + bool PrivateSetDefaultAttributes(const bool foreground, + const bool background) override; - BOOL SetConsoleXtermTextAttribute(const int iXtermTableEntry, - const bool fIsForeground) override; + bool SetConsoleXtermTextAttribute(const int xtermTableEntry, + const bool isForeground) override; - BOOL SetConsoleRGBTextAttribute(const COLORREF rgbColor, - const bool fIsForeground) override; + bool SetConsoleRGBTextAttribute(const COLORREF rgbColor, + const bool isForeground) override; - BOOL PrivateBoldText(const bool bolded) override; - BOOL PrivateGetExtendedTextAttributes(ExtendedAttributes* const pAttrs) override; - BOOL PrivateSetExtendedTextAttributes(const ExtendedAttributes attrs) override; - BOOL PrivateGetTextAttributes(TextAttribute* const pAttrs) const override; - BOOL PrivateSetTextAttributes(const TextAttribute& attrs) override; + bool PrivateBoldText(const bool bolded) override; + bool PrivateGetExtendedTextAttributes(ExtendedAttributes& attrs) override; + bool PrivateSetExtendedTextAttributes(const ExtendedAttributes attrs) override; + bool PrivateGetTextAttributes(TextAttribute& attrs) const override; + bool PrivateSetTextAttributes(const TextAttribute& attrs) override; - BOOL PrivateWriteConsoleInputW(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) override; + bool PrivateWriteConsoleInputW(std::deque>& events, + size_t& eventsWritten) override; - BOOL SetConsoleWindowInfo(BOOL const bAbsolute, - const SMALL_RECT* const lpConsoleWindow) override; + bool SetConsoleWindowInfo(bool const absolute, + const SMALL_RECT& window) override; - BOOL PrivateSetCursorKeysMode(const bool fApplicationMode) override; - BOOL PrivateSetKeypadMode(const bool fApplicationMode) override; + bool PrivateSetCursorKeysMode(const bool applicationMode) override; + bool PrivateSetKeypadMode(const bool applicationMode) override; - BOOL PrivateShowCursor(const bool show) noexcept override; - BOOL PrivateAllowCursorBlinking(const bool fEnable) override; + bool PrivateShowCursor(const bool show) noexcept override; + bool PrivateAllowCursorBlinking(const bool enable) override; - BOOL PrivateSetScrollingRegion(const SMALL_RECT* const srScrollMargins) override; + bool PrivateSetScrollingRegion(const SMALL_RECT& scrollMargins) override; - BOOL PrivateReverseLineFeed() override; + bool PrivateReverseLineFeed() override; - BOOL MoveCursorVertically(const short lines) override; + bool MoveCursorVertically(const ptrdiff_t lines) override; - BOOL SetConsoleTitleW(const std::wstring_view title) override; + bool SetConsoleTitleW(const std::wstring_view title) override; - BOOL PrivateUseAlternateScreenBuffer() override; + bool PrivateUseAlternateScreenBuffer() override; - BOOL PrivateUseMainScreenBuffer() override; + bool PrivateUseMainScreenBuffer() override; - BOOL PrivateHorizontalTabSet(); - BOOL PrivateForwardTab(const SHORT sNumTabs) override; - BOOL PrivateBackwardsTab(const SHORT sNumTabs) override; - BOOL PrivateTabClear(const bool fClearAll) override; - BOOL PrivateSetDefaultTabStops() override; + bool PrivateHorizontalTabSet(); + bool PrivateForwardTab(const size_t numTabs) override; + bool PrivateBackwardsTab(const size_t numTabs) override; + bool PrivateTabClear(const bool clearAll) override; + bool PrivateSetDefaultTabStops() override; - BOOL PrivateEnableVT200MouseMode(const bool fEnabled) override; - BOOL PrivateEnableUTF8ExtendedMouseMode(const bool fEnabled) override; - BOOL PrivateEnableSGRExtendedMouseMode(const bool fEnabled) override; - BOOL PrivateEnableButtonEventMouseMode(const bool fEnabled) override; - BOOL PrivateEnableAnyEventMouseMode(const bool fEnabled) override; - BOOL PrivateEnableAlternateScroll(const bool fEnabled) override; - BOOL PrivateEraseAll() override; + bool PrivateEnableVT200MouseMode(const bool enabled) override; + bool PrivateEnableUTF8ExtendedMouseMode(const bool enabled) override; + bool PrivateEnableSGRExtendedMouseMode(const bool enabled) override; + bool PrivateEnableButtonEventMouseMode(const bool enabled) override; + bool PrivateEnableAnyEventMouseMode(const bool enabled) override; + bool PrivateEnableAlternateScroll(const bool enabled) override; + bool PrivateEraseAll() override; - BOOL PrivateGetConsoleScreenBufferAttributes(_Out_ WORD* const pwAttributes) override; + bool PrivateGetConsoleScreenBufferAttributes(WORD& attributes) override; - BOOL PrivatePrependConsoleInput(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) override; + bool PrivatePrependConsoleInput(std::deque>& events, + size_t& eventsWritten) override; - BOOL SetCursorStyle(CursorType const cursorType) override; - BOOL SetCursorColor(COLORREF const cursorColor) override; + bool SetCursorStyle(CursorType const style) override; + bool SetCursorColor(COLORREF const color) override; - BOOL PrivateRefreshWindow() override; + bool PrivateRefreshWindow() override; - BOOL PrivateSuppressResizeRepaint() override; + bool PrivateSuppressResizeRepaint() override; - BOOL PrivateWriteConsoleControlInput(_In_ KeyEvent key) override; + bool PrivateWriteConsoleControlInput(const KeyEvent key) override; - BOOL GetConsoleOutputCP(_Out_ unsigned int* const puiOutputCP) override; + bool GetConsoleOutputCP(unsigned int& codepage) override; - BOOL IsConsolePty(_Out_ bool* const pIsPty) const override; + bool IsConsolePty(bool& isPty) const override; - BOOL DeleteLines(const unsigned int count) override; - BOOL InsertLines(const unsigned int count) override; + bool DeleteLines(const size_t count) override; + bool InsertLines(const size_t count) override; - BOOL MoveToBottom() const override; + bool MoveToBottom() const override; - BOOL PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept override; + bool PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept override; - BOOL PrivateSetDefaultForeground(const COLORREF value) const noexcept override; + bool PrivateSetDefaultForeground(const COLORREF value) const noexcept override; - BOOL PrivateSetDefaultBackground(const COLORREF value) const noexcept override; + bool PrivateSetDefaultBackground(const COLORREF value) const noexcept override; - BOOL PrivateFillRegion(const COORD startPosition, + bool PrivateFillRegion(const COORD startPosition, const size_t fillLength, const wchar_t fillChar, const bool standardFillAttrs) noexcept override; - BOOL PrivateScrollRegion(const SMALL_RECT scrollRect, + bool PrivateScrollRegion(const SMALL_RECT scrollRect, const std::optional clipRect, const COORD destinationOrigin, const bool standardFillAttrs) noexcept override; diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index bed6d12b60..21c589c2f8 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -275,15 +275,14 @@ void SCREEN_INFORMATION::s_RemoveScreenBuffer(_In_ SCREEN_INFORMATION* const pSc { try { - auto adapter = std::make_unique(new ConhostInternalGetSet{ *this }, - new WriteBuffer{ *this }); - THROW_IF_NULL_ALLOC(adapter.get()); - + auto getset = std::make_unique(*this); + auto defaults = std::make_unique(*this); + auto adapter = std::make_unique(std::move(getset), std::move(defaults)); + auto engine = std::make_unique(std::move(adapter)); // Note that at this point in the setup, we haven't determined if we're // in VtIo mode or not yet. We'll set the OutputStateMachine's // TerminalConnection later, in VtIo::StartIfNeeded - _stateMachine = std::make_shared(new OutputStateMachineEngine(adapter.release())); - THROW_IF_NULL_ALLOC(_stateMachine.get()); + _stateMachine = std::make_shared(std::move(engine)); } catch (...) { @@ -2508,7 +2507,7 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport, // Method Description: // - Sets up the Output state machine to be in pty mode. Sequences it doesn't -// understand will be written to tthe pTtyConnection passed in here. +// understand will be written to the pTtyConnection passed in here. // Arguments: // - pTtyConnection: This is a TerminaOutputConnection that we can write the // sequence we didn't understand to. diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 07ac3527bd..fa6fd10290 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -341,7 +341,7 @@ void ScreenBufferTests::TestReverseLineFeed() //////////////////////////////////////////////////////////////////////// Log::Comment(L"Case 1: RI from below top of viewport"); - stateMachine.ProcessString(L"foo\nfoo", 7); + stateMachine.ProcessString(L"foo\nfoo"); VERIFY_ARE_EQUAL(cursor.GetPosition().X, 3); VERIFY_ARE_EQUAL(cursor.GetPosition().Y, 1); VERIFY_ARE_EQUAL(viewport.Top(), 0); @@ -362,7 +362,7 @@ void ScreenBufferTests::TestReverseLineFeed() //////////////////////////////////////////////////////////////////////// Log::Comment(L"Case 2: RI from top of viewport"); cursor.SetPosition({ 0, 0 }); - stateMachine.ProcessString(L"123456789", 9); + stateMachine.ProcessString(L"123456789"); VERIFY_ARE_EQUAL(cursor.GetPosition().X, 9); VERIFY_ARE_EQUAL(cursor.GetPosition().Y, 0); VERIFY_ARE_EQUAL(screenInfo.GetViewport().Top(), 0); @@ -762,7 +762,7 @@ void ScreenBufferTests::EraseAllTests() //////////////////////////////////////////////////////////////////////// Log::Comment(L"Case 1: Erase a single line of text in the buffer\n"); - stateMachine.ProcessString(L"foo", 3); + stateMachine.ProcessString(L"foo"); COORD originalRelativePosition = { 3, 0 }; VERIFY_ARE_EQUAL(si.GetViewport().Top(), 0); VERIFY_ARE_EQUAL(cursor.GetPosition(), originalRelativePosition); @@ -784,7 +784,7 @@ void ScreenBufferTests::EraseAllTests() //////////////////////////////////////////////////////////////////////// Log::Comment(L"Case 2: Erase multiple lines, below the top of the buffer\n"); - stateMachine.ProcessString(L"bar\nbar\nbar", 11); + stateMachine.ProcessString(L"bar\nbar\nbar"); viewport = si._viewport; originalRelativePosition = cursor.GetPosition(); viewport.ConvertToOrigin(&originalRelativePosition); @@ -814,7 +814,7 @@ void ScreenBufferTests::EraseAllTests() cursor.SetPosition({ 0, 275 }); VERIFY_SUCCEEDED(si.SetViewportOrigin(true, { 0, 220 }, true)); - stateMachine.ProcessString(L"bar\nbar\nbar", 11); + stateMachine.ProcessString(L"bar\nbar\nbar"); viewport = si._viewport; VERIFY_ARE_EQUAL(cursor.GetPosition().X, 3); VERIFY_ARE_EQUAL(cursor.GetPosition().Y, 277); @@ -855,19 +855,19 @@ void ScreenBufferTests::OutputNULTest() Log::Comment(NoThrowString().Format( L"Writing a single NUL")); - stateMachine.ProcessString(L"\0", 1); + stateMachine.ProcessString({ L"\0", 1 }); VERIFY_ARE_EQUAL(0, cursor.GetPosition().X); VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y); Log::Comment(NoThrowString().Format( L"Writing many NULs")); - stateMachine.ProcessString(L"\0\0\0\0\0\0\0\0", 8); + stateMachine.ProcessString({ L"\0\0\0\0\0\0\0\0", 8 }); VERIFY_ARE_EQUAL(0, cursor.GetPosition().X); VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y); Log::Comment(NoThrowString().Format( L"Testing a single NUL followed by real text")); - stateMachine.ProcessString(L"\0foo", 4); + stateMachine.ProcessString({ L"\0foo", 4 }); VERIFY_ARE_EQUAL(3, cursor.GetPosition().X); VERIFY_ARE_EQUAL(0, cursor.GetPosition().Y); @@ -877,7 +877,7 @@ void ScreenBufferTests::OutputNULTest() Log::Comment(NoThrowString().Format( L"Writing NULs in between other strings")); - stateMachine.ProcessString(L"\0foo\0bar\0", 9); + stateMachine.ProcessString({ L"\0foo\0bar\0", 9 }); VERIFY_ARE_EQUAL(6, cursor.GetPosition().X); VERIFY_ARE_EQUAL(1, cursor.GetPosition().Y); } @@ -909,8 +909,7 @@ void ScreenBufferTests::VtResize() L" The Screen buffer height should remain unchanged, but the width should be 80 columns" L" The viewport should be w,h=80,30")); - std::wstring sequence = L"\x1b[8;30;80t"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(L"\x1b[8;30;80t"); auto newSbHeight = si.GetBufferSize().Height(); auto newSbWidth = si.GetBufferSize().Width(); @@ -932,8 +931,7 @@ void ScreenBufferTests::VtResize() L" The Screen buffer height should remain unchanged, but the width should be 80 columns" L" The viewport should be w,h=80,40")); - sequence = L"\x1b[8;40;80t"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(L"\x1b[8;40;80t"); newSbHeight = si.GetBufferSize().Height(); newSbWidth = si.GetBufferSize().Width(); @@ -955,8 +953,7 @@ void ScreenBufferTests::VtResize() L" The Screen buffer height should remain unchanged, but the width should be 90 columns" L" The viewport should be w,h=90,40")); - sequence = L"\x1b[8;40;90t"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(L"\x1b[8;40;90t"); newSbHeight = si.GetBufferSize().Height(); newSbWidth = si.GetBufferSize().Width(); @@ -978,8 +975,7 @@ void ScreenBufferTests::VtResize() L" The Screen buffer height should remain unchanged, but the width should be 12 columns" L" The viewport should be w,h=12,12")); - sequence = L"\x1b[8;12;12t"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(L"\x1b[8;12;12t"); newSbHeight = si.GetBufferSize().Height(); newSbWidth = si.GetBufferSize().Width(); @@ -1000,8 +996,7 @@ void ScreenBufferTests::VtResize() L"Write '\x1b[8;0;0t'" L" Nothing should change")); - sequence = L"\x1b[8;0;0t"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(L"\x1b[8;0;0t"); newSbHeight = si.GetBufferSize().Height(); newSbWidth = si.GetBufferSize().Width(); @@ -1054,8 +1049,7 @@ void ScreenBufferTests::VtResizeComprehensive() expectedViewWidth, expectedViewHeight)); - std::wstring sequence = ss.str(); - stateMachine.ProcessString(sequence); + stateMachine.ProcessString(ss.str()); auto newViewHeight = si.GetViewport().Height(); auto newViewWidth = si.GetViewport().Width(); @@ -1210,29 +1204,24 @@ void ScreenBufferTests::VtSoftResetCursorPosition() L"Move the cursor to 2,2, then execute a soft reset.\n" L"The cursor should not move.")); - std::wstring seq = L"\x1b[2;2H"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[2;2H"); VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition()); - seq = L"\x1b[!p"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[!p"); VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition()); Log::Comment(NoThrowString().Format( L"Set some margins. The cursor should move home.")); - seq = L"\x1b[2;10r"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[2;10r"); VERIFY_ARE_EQUAL(COORD({ 0, 0 }), cursor.GetPosition()); Log::Comment(NoThrowString().Format( L"Move the cursor to 2,2, then execute a soft reset.\n" L"The cursor should not move, even though there are margins.")); - seq = L"\x1b[2;2H"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[2;2H"); VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition()); - seq = L"\x1b[!p"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[!p"); VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition()); Log::Comment( @@ -1273,16 +1262,13 @@ void ScreenBufferTests::VtScrollMarginsNewlineColor() Log::Comment(NoThrowString().Format(L"Begin by clearing the screen.")); - std::wstring seq = L"\x1b[2J"; - stateMachine.ProcessString(seq); - seq = L"\x1b[m"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[2J"); + stateMachine.ProcessString(L"\x1b[m"); Log::Comment(NoThrowString().Format( L"Set the margins to 2, 5, then emit 10 'X\\n' strings. " L"Each time, check that rows 0-10 have default attributes in their entire row.")); - seq = L"\x1b[2;5r"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[2;5r"); // Make sure we clear the margins to not screw up another test. auto clearMargins = wil::scope_exit([&] { stateMachine.ProcessString(L"\x1b[r"); }); @@ -1290,10 +1276,8 @@ void ScreenBufferTests::VtScrollMarginsNewlineColor() { Log::Comment(NoThrowString().Format( L"Iteration:%d", iteration)); - seq = L"X"; - stateMachine.ProcessString(seq); - seq = L"\n"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(L"\n"); const COORD cursorPos = cursor.GetPosition(); @@ -1339,10 +1323,8 @@ void ScreenBufferTests::VtNewlinePastViewport() VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); cursor.SetPosition(COORD({ 0, 0 })); - std::wstring seq = L"\x1b[m"; - stateMachine.ProcessString(seq); - seq = L"\x1b[2J"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[m"); + stateMachine.ProcessString(L"\x1b[2J"); const TextAttribute defaultAttrs{}; @@ -1365,8 +1347,7 @@ void ScreenBufferTests::VtNewlinePastViewport() auto expectedFillAttr = fillAttr; expectedFillAttr.SetStandardErase(); - seq = L"\n"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\n"); const auto viewport = si.GetViewport(); Log::Comment(NoThrowString().Format( @@ -1415,10 +1396,8 @@ void ScreenBufferTests::VtNewlinePastEndOfBuffer() VERIFY_SUCCEEDED(si.SetViewportOrigin(true, COORD({ 0, 0 }), true)); cursor.SetPosition(COORD({ 0, 0 })); - std::wstring seq = L"\x1b[m"; - stateMachine.ProcessString(seq); - seq = L"\x1b[2J"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[m"); + stateMachine.ProcessString(L"\x1b[2J"); const TextAttribute defaultAttrs{}; @@ -1444,8 +1423,7 @@ void ScreenBufferTests::VtNewlinePastEndOfBuffer() auto expectedFillAttr = fillAttr; expectedFillAttr.SetStandardErase(); - seq = L"\n"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\n"); const auto viewport = si.GetViewport(); Log::Comment(NoThrowString().Format( @@ -1521,96 +1499,79 @@ void ScreenBufferTests::VtSetColorTable() Log::Comment(NoThrowString().Format( L"Process some valid sequences for setting the table")); - std::wstring seq = L"\x1b]4;0;rgb:1/1/1\x7"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;0;rgb:1/1/1\x7"); VERIFY_ARE_EQUAL(RGB(1, 1, 1), gci.GetColorTableEntry(::XtermToWindowsIndex(0))); - seq = L"\x1b]4;1;rgb:1/23/1\x7"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;1;rgb:1/23/1\x7"); VERIFY_ARE_EQUAL(RGB(1, 0x23, 1), gci.GetColorTableEntry(::XtermToWindowsIndex(1))); - seq = L"\x1b]4;2;rgb:1/23/12\x7"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;2;rgb:1/23/12\x7"); VERIFY_ARE_EQUAL(RGB(1, 0x23, 0x12), gci.GetColorTableEntry(::XtermToWindowsIndex(2))); - seq = L"\x1b]4;3;rgb:12/23/12\x7"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;3;rgb:12/23/12\x7"); VERIFY_ARE_EQUAL(RGB(0x12, 0x23, 0x12), gci.GetColorTableEntry(::XtermToWindowsIndex(3))); - seq = L"\x1b]4;4;rgb:ff/a1/1b\x7"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;4;rgb:ff/a1/1b\x7"); VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(::XtermToWindowsIndex(4))); - seq = L"\x1b]4;5;rgb:ff/a1/1b\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgb:ff/a1/1b\x1b\\"); VERIFY_ARE_EQUAL(RGB(0xff, 0xa1, 0x1b), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"Try a bunch of invalid sequences.")); Log::Comment(NoThrowString().Format( L"First start by setting an entry to a known value to compare to.")); - seq = L"\x1b]4;5;rgb:9/9/9\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgb:9/9/9\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: Missing the first component")); - seq = L"\x1b]4;5;rgb:/1/1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgb:/1/1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: too many characters in a component")); - seq = L"\x1b]4;5;rgb:111/1/1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgb:111/1/1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( - L"invalid: too many componenets")); - seq = L"\x1b]4;5;rgb:1/1/1/1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + L"invalid: too many components")); + stateMachine.ProcessString(L"\x1b]4;5;rgb:1/1/1/1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: no second component")); - seq = L"\x1b]4;5;rgb:1//1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgb:1//1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: no components")); - seq = L"\x1b]4;5;rgb://\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgb://\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: no third component")); - seq = L"\x1b]4;5;rgb:1/11/\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgb:1/11/\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: rgbi is not a supported color space")); - seq = L"\x1b]4;5;rgbi:1/1/1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;rgbi:1/1/1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: cmyk is not a supported color space")); - seq = L"\x1b]4;5;cmyk:1/1/1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;cmyk:1/1/1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: no table index should do nothing")); - seq = L"\x1b]4;;rgb:1/1/1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;;rgb:1/1/1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); Log::Comment(NoThrowString().Format( L"invalid: need to specify a color space")); - seq = L"\x1b]4;5;1/1/1\x1b\\"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b]4;5;1/1/1\x1b\\"); VERIFY_ARE_EQUAL(RGB(9, 9, 9), gci.GetColorTableEntry(::XtermToWindowsIndex(5))); } @@ -1690,8 +1651,7 @@ void ScreenBufferTests::ResizeAltBuffer() Log::Comment(NoThrowString().Format( L"Switch to alt buffer")); - std::wstring seq = L"\x1b[?1049h"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[?1049h"); VERIFY_IS_FALSE(si._IsAltBuffer()); VERIFY_IS_NOT_NULL(si._psiAlternateBuffer); @@ -1708,8 +1668,7 @@ void ScreenBufferTests::ResizeAltBuffer() Log::Comment(NoThrowString().Format( L"Switch back from buffer")); - seq = L"\x1b[?1049l"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[?1049l"); VERIFY_IS_FALSE(si._IsAltBuffer()); VERIFY_IS_NULL(si._psiAlternateBuffer); } @@ -1744,8 +1703,7 @@ void ScreenBufferTests::ResizeAltBufferGetScreenBufferInfo() Log::Comment(NoThrowString().Format( L"Switch to alt buffer")); - std::wstring seq = L"\x1b[?1049h"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[?1049h"); VERIFY_IS_FALSE(mainBuffer._IsAltBuffer()); VERIFY_IS_NOT_NULL(mainBuffer._psiAlternateBuffer); @@ -1797,12 +1755,10 @@ void ScreenBufferTests::VtEraseAllPersistCursor() L"Move the cursor to 2,2, then execute a Erase All.\n" L"The cursor should not move relative to the viewport.")); - std::wstring seq = L"\x1b[2;2H"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[2;2H"); VERIFY_ARE_EQUAL(COORD({ 1, 1 }), cursor.GetPosition()); - seq = L"\x1b[2J"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[2J"); auto newViewport = si._viewport; COORD expectedCursor = { 1, 1 }; @@ -1827,13 +1783,11 @@ void ScreenBufferTests::VtEraseAllPersistCursorFillColor() L"The viewport should be full of dark_red on bright_blue")); auto expectedAttr = TextAttribute(XtermToLegacy(1, 12)); - std::wstring seq = L"\x1b[31;104m"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[31;104m"); VERIFY_ARE_EQUAL(expectedAttr, si.GetAttributes()); - seq = L"\x1b[2J"; - stateMachine.ProcessString(&seq[0], seq.length()); + stateMachine.ProcessString(L"\x1b[2J"); VERIFY_ARE_EQUAL(expectedAttr, si.GetAttributes()); @@ -2165,35 +2119,23 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault() Log::Comment(NoThrowString().Format(L" The fifth with bright-green on dark-blue")); Log::Comment(NoThrowString().Format(L" The sixth with bright-green on default-bg")); - std::wstring seq = L"\x1b[m"; // Reset to defaults - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[m"); // Reset to defaults + stateMachine.ProcessString(L"X"); - seq = L"\x1b[92;44m"; // bright-green on dark-blue - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[92;44m"); // bright-green on dark-blue + stateMachine.ProcessString(L"X"); - seq = L"\x1b[39m"; // reset fg - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[39m"); // reset fg + stateMachine.ProcessString(L"X"); - seq = L"\x1b[49m"; // reset bg - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[49m"); // reset bg + stateMachine.ProcessString(L"X"); - seq = L"\x1b[92;44m"; // bright-green on dark-blue - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[92;44m"); // bright-green on dark-blue + stateMachine.ProcessString(L"X"); - seq = L"\x1b[49m"; // reset bg - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[49m"); // reset bg + stateMachine.ProcessString(L"X"); // See the log comment above for description of these values. TextAttribute expectedDefaults{}; @@ -2356,16 +2298,11 @@ void ScreenBufferTests::ReverseResetWithDefaultBackground() Log::Comment(NoThrowString().Format(L" The second with reversed attrs")); Log::Comment(NoThrowString().Format(L" The third after resetting the attrs back")); - std::wstring seq = L"X"; - stateMachine.ProcessString(seq); - seq = L"\x1b[7m"; - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); - seq = L"\x1b[27m"; - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(L"\x1b[7m"); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(L"\x1b[27m"); + stateMachine.ProcessString(L"X"); TextAttribute expectedDefaults{ gci.GetFillAttribute() }; expectedDefaults.SetDefaultBackground(); @@ -2426,13 +2363,9 @@ void ScreenBufferTests::BackspaceDefaultAttrs() Log::Comment(NoThrowString().Format(L"Write 2 X's, then backspace one.")); - std::wstring seq = L"\x1b[m"; - stateMachine.ProcessString(seq); - seq = L"XX"; - stateMachine.ProcessString(seq); - - seq = UNICODE_BACKSPACE; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[m"); + stateMachine.ProcessString(L"XX"); + stateMachine.ProcessString({ &UNICODE_BACKSPACE, 1 }); TextAttribute expectedDefaults{}; expectedDefaults.SetDefaultBackground(); @@ -2493,8 +2426,7 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy() Log::Comment(NoThrowString().Format(L"Write 2 X's, then backspace one.")); - std::wstring seq = L"\x1b[m"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[m"); if (writeSingly) { @@ -2564,12 +2496,10 @@ void ScreenBufferTests::BackspaceDefaultAttrsInPrompt() Log::Comment(NoThrowString().Format(L"Write 3 X's, move to the left, then delete-char the second.")); Log::Comment(NoThrowString().Format(L"This emulates editing the prompt line on bash")); - std::wstring seq = L"\x1b[m"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[m"); Log::Comment(NoThrowString().Format( L"Clear the screen - make sure the line is filled with the current attributes.")); - seq = L"\x1b[2J"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[2J"); const auto viewport = si.GetViewport(); const ROW& row = tbi.GetRowByOffset(cursor.GetPosition().Y); @@ -2591,12 +2521,9 @@ void ScreenBufferTests::BackspaceDefaultAttrsInPrompt() Log::Comment(NoThrowString().Format( L"Print 'XXX', move the cursor left 2, delete a character.")); - seq = L"XXX"; - stateMachine.ProcessString(seq); - seq = L"\x1b[2D"; - stateMachine.ProcessString(seq); - seq = L"\x1b[P"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"XXX"); + stateMachine.ProcessString(L"\x1b[2D"); + stateMachine.ProcessString(L"\x1b[P"); COORD expectedCursor{ 1, 1 }; // We're expecting y=1, because the 2J above // should have moved the viewport down a line. @@ -2639,10 +2566,8 @@ void ScreenBufferTests::SetGlobalColorTable() const COLORREF testColor = RGB(0x11, 0x22, 0x33); VERIFY_ARE_NOT_EQUAL(originalRed, testColor); - std::wstring seq = L"\x1b[41m"; - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[41m"); + stateMachine.ProcessString(L"X"); COORD expectedCursor{ 1, 0 }; VERIFY_ARE_EQUAL(expectedCursor, mainCursor.GetPosition()); { @@ -2668,10 +2593,8 @@ void ScreenBufferTests::SetGlobalColorTable() Log::Comment(NoThrowString().Format( L"Print one X in red, should be the original red color")); - seq = L"\x1b[41m"; - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[41m"); + stateMachine.ProcessString(L"X"); VERIFY_ARE_EQUAL(expectedCursor, altCursor.GetPosition()); { const ROW& row = altBuffer.GetTextBuffer().GetRowByOffset(altCursor.GetPosition().Y); @@ -2683,12 +2606,10 @@ void ScreenBufferTests::SetGlobalColorTable() } Log::Comment(NoThrowString().Format(L"Change the value of red to RGB(0x11, 0x22, 0x33)")); - seq = L"\x1b]4;1;rgb:11/22/33\x07"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]4;1;rgb:11/22/33\x07"); Log::Comment(NoThrowString().Format( L"Print another X, both should be the new \"red\" color")); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"X"); VERIFY_ARE_EQUAL(COORD({ 2, 0 }), altCursor.GetPosition()); { const ROW& row = altBuffer.GetTextBuffer().GetRowByOffset(altCursor.GetPosition().Y); @@ -2711,8 +2632,7 @@ void ScreenBufferTests::SetGlobalColorTable() Log::Comment(NoThrowString().Format( L"Print another X, both should be the new \"red\" color")); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"X"); VERIFY_ARE_EQUAL(COORD({ 2, 0 }), mainCursor.GetPosition()); { const ROW& row = mainBuffer.GetTextBuffer().GetRowByOffset(mainCursor.GetPosition().Y); @@ -2752,10 +2672,8 @@ void ScreenBufferTests::SetColorTableThreeDigits() const COLORREF testColor = RGB(0x11, 0x22, 0x33); VERIFY_ARE_NOT_EQUAL(originalRed, testColor); - std::wstring seq = L"\x1b[48;5;123m"; - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[48;5;123m"); + stateMachine.ProcessString(L"X"); COORD expectedCursor{ 1, 0 }; VERIFY_ARE_EQUAL(expectedCursor, mainCursor.GetPosition()); { @@ -2781,10 +2699,8 @@ void ScreenBufferTests::SetColorTableThreeDigits() Log::Comment(NoThrowString().Format( L"Print one X in red, should be the original red color")); - seq = L"\x1b[48;5;123m"; - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[48;5;123m"); + stateMachine.ProcessString(L"X"); VERIFY_ARE_EQUAL(expectedCursor, altCursor.GetPosition()); { const ROW& row = altBuffer.GetTextBuffer().GetRowByOffset(altCursor.GetPosition().Y); @@ -2796,16 +2712,13 @@ void ScreenBufferTests::SetColorTableThreeDigits() } Log::Comment(NoThrowString().Format(L"Change the value of red to RGB(0x11, 0x22, 0x33)")); - seq = L"\x1b]4;123;rgb:11/22/33\x07"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]4;123;rgb:11/22/33\x07"); Log::Comment(NoThrowString().Format( L"Print another X, it should be the new \"red\" color")); // TODO MSFT:20105972 - // You shouldn't need to manually update the attributes again. - seq = L"\x1b[48;5;123m"; - stateMachine.ProcessString(seq); - seq = L"X"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[48;5;123m"); + stateMachine.ProcessString(L"X"); VERIFY_ARE_EQUAL(COORD({ 2, 0 }), altCursor.GetPosition()); { const ROW& row = altBuffer.GetTextBuffer().GetRowByOffset(altCursor.GetPosition().Y); @@ -2839,8 +2752,7 @@ void ScreenBufferTests::SetDefaultForegroundColor() VERIFY_ARE_NOT_EQUAL(originalColor, testColor); Log::Comment(L"Valid Hexadecimal Notation"); - std::wstring seq = L"\x1b]10;rgb:33/66/99\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]10;rgb:33/66/99\x1b\\"); newColor = gci.GetDefaultForegroundColor(); VERIFY_ARE_EQUAL(testColor, newColor); @@ -2848,8 +2760,7 @@ void ScreenBufferTests::SetDefaultForegroundColor() Log::Comment(L"Valid Hexadecimal Notation"); originalColor = newColor; testColor = RGB(0xff, 0xff, 0xff); - seq = L"\x1b]10;rgb:ff/ff/ff\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]10;rgb:ff/ff/ff\x1b\\"); newColor = gci.GetDefaultForegroundColor(); VERIFY_ARE_EQUAL(testColor, newColor); @@ -2857,8 +2768,7 @@ void ScreenBufferTests::SetDefaultForegroundColor() Log::Comment(L"Invalid Decimal Notation"); originalColor = newColor; testColor = RGB(153, 102, 51); - seq = L"\x1b]10;rgb:153/102/51\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]10;rgb:153/102/51\x1b\\"); newColor = gci.GetDefaultForegroundColor(); VERIFY_ARE_NOT_EQUAL(testColor, newColor); @@ -2867,8 +2777,7 @@ void ScreenBufferTests::SetDefaultForegroundColor() Log::Comment(L"Invalid syntax"); testColor = RGB(153, 102, 51); - seq = L"\x1b]10;99/66/33\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]10;99/66/33\x1b\\"); newColor = gci.GetDefaultForegroundColor(); VERIFY_ARE_NOT_EQUAL(testColor, newColor); @@ -2897,8 +2806,7 @@ void ScreenBufferTests::SetDefaultBackgroundColor() VERIFY_ARE_NOT_EQUAL(originalColor, testColor); Log::Comment(L"Valid Hexadecimal Notation"); - std::wstring seq = L"\x1b]11;rgb:33/66/99\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]11;rgb:33/66/99\x1b\\"); newColor = gci.GetDefaultBackgroundColor(); VERIFY_ARE_EQUAL(testColor, newColor); @@ -2906,8 +2814,7 @@ void ScreenBufferTests::SetDefaultBackgroundColor() Log::Comment(L"Valid Hexadecimal Notation"); originalColor = newColor; testColor = RGB(0xff, 0xff, 0xff); - seq = L"\x1b]11;rgb:ff/ff/ff\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]11;rgb:ff/ff/ff\x1b\\"); newColor = gci.GetDefaultBackgroundColor(); VERIFY_ARE_EQUAL(testColor, newColor); @@ -2915,8 +2822,7 @@ void ScreenBufferTests::SetDefaultBackgroundColor() Log::Comment(L"Invalid Decimal Notation"); originalColor = newColor; testColor = RGB(153, 102, 51); - seq = L"\x1b]11;rgb:153/102/51\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]11;rgb:153/102/51\x1b\\"); newColor = gci.GetDefaultBackgroundColor(); VERIFY_ARE_NOT_EQUAL(testColor, newColor); @@ -2925,8 +2831,7 @@ void ScreenBufferTests::SetDefaultBackgroundColor() Log::Comment(L"Invalid Syntax"); testColor = RGB(153, 102, 51); - seq = L"\x1b]11;99/66/33\x1b\\"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b]11;99/66/33\x1b\\"); newColor = gci.GetDefaultBackgroundColor(); VERIFY_ARE_NOT_EQUAL(testColor, newColor); @@ -2995,10 +2900,9 @@ void ScreenBufferTests::DeleteCharsNearEndOfLine() VERIFY_ARE_EQUAL(mainBuffer.GetBufferSize().Width(), mainView.Width()); VERIFY_IS_GREATER_THAN(mainView.Width(), (dx + numCharsToDelete)); - std::wstring seq = L"X"; for (int x = 0; x < mainView.Width(); x++) { - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"X"); } VERIFY_ARE_EQUAL(COORD({ mainView.Width() - 1, 0 }), mainCursor.GetPosition()); @@ -3009,9 +2913,8 @@ void ScreenBufferTests::DeleteCharsNearEndOfLine() mainCursor.SetPosition({ mainView.Width() - static_cast(dx), 0 }); std::wstringstream ss; - ss << L"\x1b[" << numCharsToDelete << L"P"; - seq = ss.str(); // Delete N chars - stateMachine.ProcessString(seq); + ss << L"\x1b[" << numCharsToDelete << L"P"; // Delete N chars + stateMachine.ProcessString(ss.str()); Log::Comment(NoThrowString().Format( L"row_f=[%s]", @@ -3066,8 +2969,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleFirstCase() VERIFY_ARE_EQUAL(newBufferWidth, mainView.Width()); VERIFY_ARE_EQUAL(mainBuffer.GetBufferSize().Width(), mainView.Width()); - std::wstring seq = L"ABCDEFG"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"ABCDEFG"); VERIFY_ARE_EQUAL(COORD({ 7, 0 }), mainCursor.GetPosition()); // Place the cursor on the 'D' @@ -3077,8 +2979,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleFirstCase() // Delete 3 chars - [D, E, F] std::wstringstream ss; ss << L"\x1b[" << 3 << L"P"; - seq = ss.str(); - stateMachine.ProcessString(seq); + stateMachine.ProcessString(ss.str()); Log::Comment(NoThrowString().Format(L"after =[%s]", tbi.GetRowByOffset(0).GetText().c_str())); @@ -3128,8 +3029,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleSecondCase() VERIFY_ARE_EQUAL(newBufferWidth, mainView.Width()); VERIFY_ARE_EQUAL(mainBuffer.GetBufferSize().Width(), mainView.Width()); - std::wstring seq = L"ABCDEFG"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"ABCDEFG"); VERIFY_ARE_EQUAL(COORD({ 7, 0 }), mainCursor.GetPosition()); @@ -3141,8 +3041,7 @@ void ScreenBufferTests::DeleteCharsNearEndOfLineSimpleSecondCase() // Delete 4 chars - [C, D, E, F] std::wstringstream ss; ss << L"\x1b[" << 4 << L"P"; - seq = ss.str(); - stateMachine.ProcessString(seq); + stateMachine.ProcessString(ss.str()); Log::Comment(NoThrowString().Format(L"after =[%s]", tbi.GetRowByOffset(0).GetText().c_str())); @@ -4030,17 +3929,12 @@ void _CommonScrollingSetup() const auto view = Viewport::FromDimensions({ 0, 0 }, { oldView.Width(), 6 }); si.SetViewport(view, true); cursor.SetPosition({ 0, 0 }); - std::wstring seq = L"A"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"A"); cursor.SetPosition({ 0, 5 }); - seq = L"B"; - stateMachine.ProcessString(seq); - seq = L"\x1b[2;5r"; - stateMachine.ProcessString(seq); - seq = L"\x1b[2;1H"; - stateMachine.ProcessString(seq); - seq = L"1\n2\n3\n4"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"B"); + stateMachine.ProcessString(L"\x1b[2;5r"); + stateMachine.ProcessString(L"\x1b[2;1H"); + stateMachine.ProcessString(L"1\n2\n3\n4"); Log::Comment(NoThrowString().Format( L"cursor=%s", VerifyOutputTraits::ToString(cursor.GetPosition()).GetBuffer())); @@ -4064,8 +3958,7 @@ void _CommonScrollingSetup() VERIFY_ARE_EQUAL(L"B", iter5->Chars()); } - seq = L"\n5\n6\n7\n"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\n5\n6\n7\n"); Log::Comment(NoThrowString().Format( L"cursor=%s", VerifyOutputTraits::ToString(cursor.GetPosition()).GetBuffer())); @@ -4105,8 +3998,7 @@ void ScreenBufferTests::ScrollUpInMargins() auto& cursor = si.GetTextBuffer().GetCursor(); // Execute a Scroll Up command - std::wstring seq = L"\x1b[S"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[S"); Log::Comment(NoThrowString().Format( L"cursor=%s", VerifyOutputTraits::ToString(cursor.GetPosition()).GetBuffer())); @@ -4145,8 +4037,7 @@ void ScreenBufferTests::ScrollDownInMargins() auto& cursor = si.GetTextBuffer().GetCursor(); // Execute a Scroll Down command - std::wstring seq = L"\x1b[T"; - stateMachine.ProcessString(seq); + stateMachine.ProcessString(L"\x1b[T"); Log::Comment(NoThrowString().Format( L"cursor=%s", VerifyOutputTraits::ToString(cursor.GetPosition()).GetBuffer())); @@ -4438,7 +4329,7 @@ void ScreenBufferTests::ScrollLines256Colors() auto& cursor = si.GetTextBuffer().GetCursor(); TextAttribute expectedAttr{ si.GetAttributes() }; - std::wstring sgrSeq = L"\x1b[48;5;2m"; + std::wstring_view sgrSeq = L"\x1b[48;5;2m"; if (colorStyle == Use16Color) { expectedAttr.SetBackground(gci.GetColorTableEntry(2)); @@ -4466,7 +4357,7 @@ void ScreenBufferTests::ScrollLines256Colors() stateMachine.ProcessString(L"\x1b[H"); // Insert/Delete/Reverse Index 10 lines - std::wstring scrollSeq = L""; + std::wstring_view scrollSeq = L""; if (scrollType == InsertLines) { scrollSeq = L"\x1b[10L"; diff --git a/src/host/ut_host/TextBufferTests.cpp b/src/host/ut_host/TextBufferTests.cpp index 226b4ced32..7ad1fa874e 100644 --- a/src/host/ut_host/TextBufferTests.cpp +++ b/src/host/ut_host/TextBufferTests.cpp @@ -639,7 +639,7 @@ void TextBufferTests::TestMixedRgbAndLegacyForeground() wchar_t* sequence = L"\x1b[m\x1b[38;2;64;128;255mX\x1b[49mX\x1b[m"; - stateMachine.ProcessString(sequence, std::wcslen(sequence)); + stateMachine.ProcessString(sequence); const short x = cursor.GetPosition().X; const short y = cursor.GetPosition().Y; const ROW& row = tbi.GetRowByOffset(y); @@ -665,7 +665,7 @@ void TextBufferTests::TestMixedRgbAndLegacyForeground() VERIFY_ARE_EQUAL(gci.LookupBackgroundColor(attrB), gci.LookupBackgroundColor(si.GetAttributes())); wchar_t* reset = L"\x1b[0m"; - stateMachine.ProcessString(reset, std::wcslen(reset)); + stateMachine.ProcessString(reset); } void TextBufferTests::TestMixedRgbAndLegacyBackground() @@ -683,7 +683,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBackground() Log::Comment(L"Case 2 \"\\E[m\\E[48;2;64;128;255mX\\E[39mX\\E[m\""); wchar_t* sequence = L"\x1b[m\x1b[48;2;64;128;255mX\x1b[39mX\x1b[m"; - stateMachine.ProcessString(sequence, std::wcslen(sequence)); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; const auto& row = tbi.GetRowByOffset(y); @@ -709,7 +709,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBackground() VERIFY_ARE_EQUAL(gci.LookupForegroundColor(attrB), gci.LookupForegroundColor(si.GetAttributes())); wchar_t* reset = L"\x1b[0m"; - stateMachine.ProcessString(reset, std::wcslen(reset)); + stateMachine.ProcessString(reset); } void TextBufferTests::TestMixedRgbAndLegacyUnderline() @@ -725,7 +725,7 @@ void TextBufferTests::TestMixedRgbAndLegacyUnderline() // Make sure that the second X has RGB attributes AND underline Log::Comment(L"Case 3 \"\\E[m\\E[48;2;64;128;255mX\\E[4mX\\E[m\""); wchar_t* sequence = L"\x1b[m\x1b[48;2;64;128;255mX\x1b[4mX\x1b[m"; - stateMachine.ProcessString(sequence, std::wcslen(sequence)); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; const auto& row = tbi.GetRowByOffset(y); @@ -754,7 +754,7 @@ void TextBufferTests::TestMixedRgbAndLegacyUnderline() VERIFY_ARE_EQUAL(attrB.GetLegacyAttributes() & COMMON_LVB_UNDERSCORE, COMMON_LVB_UNDERSCORE); wchar_t* reset = L"\x1b[0m"; - stateMachine.ProcessString(reset, std::wcslen(reset)); + stateMachine.ProcessString(reset); } void TextBufferTests::TestMixedRgbAndLegacyBrightness() @@ -773,7 +773,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness() VERIFY_ARE_NOT_EQUAL(dark_green, bright_green); wchar_t* sequence = L"\x1b[m\x1b[32mX\x1b[1mX"; - stateMachine.ProcessString(sequence, std::wcslen(sequence)); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; const auto& row = tbi.GetRowByOffset(y); @@ -796,7 +796,7 @@ void TextBufferTests::TestMixedRgbAndLegacyBrightness() VERIFY_ARE_EQUAL(gci.LookupForegroundColor(attrB), bright_green); wchar_t* reset = L"\x1b[0m"; - stateMachine.ProcessString(reset, std::wcslen(reset)); + stateMachine.ProcessString(reset); } void TextBufferTests::TestRgbEraseLine() @@ -815,15 +815,15 @@ void TextBufferTests::TestRgbEraseLine() // BG = rgb(128;128;255) { std::wstring sequence = L"\x1b[m\x1b[48;2;64;128;255m"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); sequence = L"X"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); sequence = L"\x1b[48;2;128;128;255m"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); sequence = L"\x1b[K"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); sequence = L"X"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -853,7 +853,7 @@ void TextBufferTests::TestRgbEraseLine() VERIFY_ARE_EQUAL(gci.LookupBackgroundColor(attr), RGB(128, 128, 255)); } std::wstring reset = L"\x1b[0m"; - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); } } @@ -872,7 +872,7 @@ void TextBufferTests::TestUnBold() // The first X should be bright green. // The second x should be dark green. std::wstring sequence = L"\x1b[1;32mX\x1b[22mX"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -905,7 +905,7 @@ void TextBufferTests::TestUnBold() VERIFY_ARE_EQUAL(gci.LookupForegroundColor(attrB), dark_green); std::wstring reset = L"\x1b[0m"; - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); } void TextBufferTests::TestUnBoldRgb() @@ -924,7 +924,7 @@ void TextBufferTests::TestUnBoldRgb() // The second X should be dark green, and not legacy. // BG = rgb(1;2;3) std::wstring sequence = L"\x1b[1;32m\x1b[48;2;1;2;3mX\x1b[22mX"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -960,7 +960,7 @@ void TextBufferTests::TestUnBoldRgb() VERIFY_ARE_EQUAL(gci.LookupForegroundColor(attrB), dark_green); std::wstring reset = L"\x1b[0m"; - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); } void TextBufferTests::TestComplexUnBold() @@ -984,7 +984,7 @@ void TextBufferTests::TestComplexUnBold() // BG = rgb(1;2;3) std::wstring sequence = L"\x1b[1;32m\x1b[48;2;1;2;3mA\x1b[22mB\x1b[38;2;32;32;32mC\x1b[1mD\x1b[38;2;64;64;64mE\x1b[22mF"; Log::Comment(NoThrowString().Format(sequence.c_str())); - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -1054,7 +1054,7 @@ void TextBufferTests::TestComplexUnBold() VERIFY_IS_FALSE(attrF.IsBold()); std::wstring reset = L"\x1b[0m"; - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); } void TextBufferTests::CopyAttrs() @@ -1073,7 +1073,7 @@ void TextBufferTests::CopyAttrs() // The third X should be blue // The fourth X should be magenta std::wstring sequence = L"\x1b[32mX\x1b[33mX\n\x1b[34mX\x1b[35mX\x1b[H\x1b[M"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -1119,7 +1119,7 @@ void TextBufferTests::EmptySgrTest() cursor.SetYPosition(0); std::wstring reset = L"\x1b[0m"; - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); const COLORREF defaultFg = gci.LookupForegroundColor(si.GetAttributes()); const COLORREF defaultBg = gci.LookupBackgroundColor(si.GetAttributes()); @@ -1129,7 +1129,7 @@ void TextBufferTests::EmptySgrTest() // The second X should be (darkRed,default). // The third X should be default colors. std::wstring sequence = L"\x1b[0mX\x1b[31mX\x1b[31;mX"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -1166,7 +1166,7 @@ void TextBufferTests::EmptySgrTest() VERIFY_ARE_EQUAL(gci.LookupForegroundColor(attrC), defaultFg); VERIFY_ARE_EQUAL(gci.LookupBackgroundColor(attrC), defaultBg); - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); } void TextBufferTests::TestReverseReset() @@ -1183,7 +1183,7 @@ void TextBufferTests::TestReverseReset() cursor.SetYPosition(0); std::wstring reset = L"\x1b[0m"; - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); const COLORREF defaultFg = gci.LookupForegroundColor(si.GetAttributes()); const COLORREF defaultBg = gci.LookupBackgroundColor(si.GetAttributes()); @@ -1193,7 +1193,7 @@ void TextBufferTests::TestReverseReset() // The second X should be (fg,bg) = (dark_green, rgb(128;5;255)) // The third X should be (fg,bg) = (rgb(128;5;255), dark_green) std::wstring sequence = L"\x1b[42m\x1b[38;2;128;5;255mX\x1b[7mX\x1b[27mX"; - stateMachine.ProcessString(&sequence[0], sequence.length()); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -1232,7 +1232,7 @@ void TextBufferTests::TestReverseReset() VERIFY_ARE_EQUAL(gci.LookupForegroundColor(attrC), rgbColor); VERIFY_ARE_EQUAL(gci.LookupBackgroundColor(attrC), dark_green); - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); } void TextBufferTests::CopyLastAttr() @@ -1251,7 +1251,7 @@ void TextBufferTests::CopyLastAttr() cursor.SetYPosition(0); std::wstring reset = L"\x1b[0m"; - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); const COLORREF defaultFg = gci.LookupForegroundColor(si.GetAttributes()); const COLORREF defaultBg = gci.LookupBackgroundColor(si.GetAttributes()); @@ -1278,30 +1278,30 @@ void TextBufferTests::CopyLastAttr() // then go home, and insert a line. // Row 1 - stateMachine.ProcessString(&solFgSeq[0], solFgSeq.length()); - stateMachine.ProcessString(&solBgSeq[0], solBgSeq.length()); - stateMachine.ProcessString(L"X", 1); - stateMachine.ProcessString(L"\n", 1); + stateMachine.ProcessString(solFgSeq); + stateMachine.ProcessString(solBgSeq); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(L"\n"); // Row 2 // Remember that the colors from before persist here too, so we don't need // to emit both the FG and BG if they haven't changed. - stateMachine.ProcessString(L"X", 1); - stateMachine.ProcessString(&solCyanSeq[0], solCyanSeq.length()); - stateMachine.ProcessString(L"X", 1); - stateMachine.ProcessString(L"\n", 1); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(solCyanSeq); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(L"\n"); // Row 3 - stateMachine.ProcessString(&solFgSeq[0], solFgSeq.length()); - stateMachine.ProcessString(&solBgSeq[0], solBgSeq.length()); - stateMachine.ProcessString(L"X", 1); - stateMachine.ProcessString(&solCyanSeq[0], solCyanSeq.length()); - stateMachine.ProcessString(L"X", 1); - stateMachine.ProcessString(&solFgSeq[0], solFgSeq.length()); - stateMachine.ProcessString(L"X", 1); + stateMachine.ProcessString(solFgSeq); + stateMachine.ProcessString(solBgSeq); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(solCyanSeq); + stateMachine.ProcessString(L"X"); + stateMachine.ProcessString(solFgSeq); + stateMachine.ProcessString(L"X"); std::wstring insertLineAtHome = L"\x1b[H\x1b[L"; - stateMachine.ProcessString(&insertLineAtHome[0], insertLineAtHome.length()); + stateMachine.ProcessString(insertLineAtHome); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -1359,7 +1359,7 @@ void TextBufferTests::CopyLastAttr() VERIFY_ARE_EQUAL(gci.LookupForegroundColor(attr3C), solFg); VERIFY_ARE_EQUAL(gci.LookupBackgroundColor(attr3C), solBg); - stateMachine.ProcessString(&reset[0], reset.length()); + stateMachine.ProcessString(reset); } void TextBufferTests::TestRgbThenBold() @@ -1377,7 +1377,7 @@ void TextBufferTests::TestRgbThenBold() const auto background = RGB(168, 153, 132); const wchar_t* const sequence = L"\x1b[38;2;40;40;40m\x1b[48;2;168;153;132mX\x1b[1mX\x1b[m"; - stateMachine.ProcessString(sequence, std::wcslen(sequence)); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; const auto& row = tbi.GetRowByOffset(y); @@ -1404,7 +1404,7 @@ void TextBufferTests::TestRgbThenBold() VERIFY_ARE_EQUAL(gci.LookupBackgroundColor(attrB), background); wchar_t* reset = L"\x1b[0m"; - stateMachine.ProcessString(reset, std::wcslen(reset)); + stateMachine.ProcessString(reset); } void TextBufferTests::TestResetClearsBoldness() @@ -1430,7 +1430,7 @@ void TextBufferTests::TestResetClearsBoldness() wchar_t* sequence = L"\x1b[32mA\x1b[1mB\x1b[0mC\x1b[32mD"; Log::Comment(NoThrowString().Format(sequence)); - stateMachine.ProcessString(sequence, std::wcslen(sequence)); + stateMachine.ProcessString(sequence); const auto x = cursor.GetPosition().X; const auto y = cursor.GetPosition().Y; @@ -1464,7 +1464,7 @@ void TextBufferTests::TestResetClearsBoldness() VERIFY_IS_FALSE(attrD.IsBold()); wchar_t* reset = L"\x1b[0m"; - stateMachine.ProcessString(reset, std::wcslen(reset)); + stateMachine.ProcessString(reset); } void TextBufferTests::TestBackspaceRightSideVt() @@ -1482,7 +1482,7 @@ void TextBufferTests::TestBackspaceRightSideVt() Log::Comment(NoThrowString().Format(sequence)); const auto preCursorPosition = cursor.GetPosition(); - stateMachine.ProcessString(sequence, std::wcslen(sequence)); + stateMachine.ProcessString(sequence); const auto postCursorPosition = cursor.GetPosition(); // make sure newline was handled correctly @@ -1514,7 +1514,7 @@ void TextBufferTests::TestBackspaceStrings() x0, y0)); std::wstring seq = L"a\b \b"; - stateMachine.ProcessString(seq.c_str(), seq.length()); + stateMachine.ProcessString(seq); const auto x1 = cursor.GetPosition().X; const auto y1 = cursor.GetPosition().Y; @@ -1523,13 +1523,13 @@ void TextBufferTests::TestBackspaceStrings() VERIFY_ARE_EQUAL(y1, y0); seq = L"a"; - stateMachine.ProcessString(seq.c_str(), seq.length()); + stateMachine.ProcessString(seq); seq = L"\b"; - stateMachine.ProcessString(seq.c_str(), seq.length()); + stateMachine.ProcessString(seq); seq = L" "; - stateMachine.ProcessString(seq.c_str(), seq.length()); + stateMachine.ProcessString(seq); seq = L"\b"; - stateMachine.ProcessString(seq.c_str(), seq.length()); + stateMachine.ProcessString(seq); const auto x2 = cursor.GetPosition().X; const auto y2 = cursor.GetPosition().Y; diff --git a/src/inc/ITerminalOutputConnection.hpp b/src/inc/ITerminalOutputConnection.hpp index 3b1875d14a..0d7569e63e 100644 --- a/src/inc/ITerminalOutputConnection.hpp +++ b/src/inc/ITerminalOutputConnection.hpp @@ -21,8 +21,8 @@ namespace Microsoft::Console public: virtual ~ITerminalOutputConnection() = 0; - [[nodiscard]] virtual HRESULT WriteTerminalUtf8(const std::string& str) = 0; - [[nodiscard]] virtual HRESULT WriteTerminalW(const std::wstring& wstr) = 0; + [[nodiscard]] virtual HRESULT WriteTerminalUtf8(const std::string_view str) = 0; + [[nodiscard]] virtual HRESULT WriteTerminalW(const std::wstring_view wstr) = 0; }; inline Microsoft::Console::ITerminalOutputConnection::~ITerminalOutputConnection() {} diff --git a/src/inc/LibraryIncludes.h b/src/inc/LibraryIncludes.h index b27e84f805..fb65e0a8a4 100644 --- a/src/inc/LibraryIncludes.h +++ b/src/inc/LibraryIncludes.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/src/renderer/vt/WinTelnetEngine.cpp b/src/renderer/vt/WinTelnetEngine.cpp index a2a9283808..b9e48c166f 100644 --- a/src/renderer/vt/WinTelnetEngine.cpp +++ b/src/renderer/vt/WinTelnetEngine.cpp @@ -109,7 +109,7 @@ WinTelnetEngine::WinTelnetEngine(_In_ wil::unique_hfile hPipe, // - wstr - wstring of text to be written // Return Value: // - S_OK or suitable HRESULT error from either conversion or writing pipe. -[[nodiscard]] HRESULT WinTelnetEngine::WriteTerminalW(_In_ const std::wstring& wstr) noexcept +[[nodiscard]] HRESULT WinTelnetEngine::WriteTerminalW(_In_ const std::wstring_view wstr) noexcept { return VtEngine::_WriteTerminalAscii(wstr); } diff --git a/src/renderer/vt/WinTelnetEngine.hpp b/src/renderer/vt/WinTelnetEngine.hpp index bbaeb6aea6..179697a5ab 100644 --- a/src/renderer/vt/WinTelnetEngine.hpp +++ b/src/renderer/vt/WinTelnetEngine.hpp @@ -39,7 +39,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override; - [[nodiscard]] HRESULT WriteTerminalW(const std::wstring& wstr) noexcept override; + [[nodiscard]] HRESULT WriteTerminalW(const std::wstring_view wstr) noexcept override; protected: [[nodiscard]] HRESULT _MoveCursor(const COORD coord) noexcept; diff --git a/src/renderer/vt/XtermEngine.cpp b/src/renderer/vt/XtermEngine.cpp index 88eda0389a..2c1d8a08ed 100644 --- a/src/renderer/vt/XtermEngine.cpp +++ b/src/renderer/vt/XtermEngine.cpp @@ -433,7 +433,7 @@ XtermEngine::XtermEngine(_In_ wil::unique_hfile hPipe, // - wstr - wstring of text to be written // Return Value: // - S_OK or suitable HRESULT error from either conversion or writing pipe. -[[nodiscard]] HRESULT XtermEngine::WriteTerminalW(const std::wstring& wstr) noexcept +[[nodiscard]] HRESULT XtermEngine::WriteTerminalW(const std::wstring_view wstr) noexcept { return _fUseAsciiOnly ? VtEngine::_WriteTerminalAscii(wstr) : diff --git a/src/renderer/vt/XtermEngine.hpp b/src/renderer/vt/XtermEngine.hpp index 6be72d6c78..dc64a8c1a1 100644 --- a/src/renderer/vt/XtermEngine.hpp +++ b/src/renderer/vt/XtermEngine.hpp @@ -53,7 +53,7 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept override; - [[nodiscard]] HRESULT WriteTerminalW(_In_ const std::wstring& str) noexcept override; + [[nodiscard]] HRESULT WriteTerminalW(const std::wstring_view str) noexcept override; protected: const COLORREF* const _ColorTable; diff --git a/src/renderer/vt/state.cpp b/src/renderer/vt/state.cpp index 31cca05d4a..11131d3921 100644 --- a/src/renderer/vt/state.cpp +++ b/src/renderer/vt/state.cpp @@ -125,7 +125,7 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe, // Method Description: // - Wrapper for ITerminalOutputConnection. See _Write. -[[nodiscard]] HRESULT VtEngine::WriteTerminalUtf8(const std::string& str) noexcept +[[nodiscard]] HRESULT VtEngine::WriteTerminalUtf8(const std::string_view str) noexcept { return _Write(str); } @@ -137,7 +137,7 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe, // - wstr - wstring of text to be written // Return Value: // - S_OK or suitable HRESULT error from either conversion or writing pipe. -[[nodiscard]] HRESULT VtEngine::_WriteTerminalUtf8(const std::wstring& wstr) noexcept +[[nodiscard]] HRESULT VtEngine::_WriteTerminalUtf8(const std::wstring_view wstr) noexcept { try { @@ -156,7 +156,7 @@ VtEngine::VtEngine(_In_ wil::unique_hfile pipe, // - wstr - wstring of text to be written // Return Value: // - S_OK or suitable HRESULT error from writing pipe. -[[nodiscard]] HRESULT VtEngine::_WriteTerminalAscii(const std::wstring& wstr) noexcept +[[nodiscard]] HRESULT VtEngine::_WriteTerminalAscii(const std::wstring_view wstr) noexcept { const size_t cchActual = wstr.length(); diff --git a/src/renderer/vt/vtrenderer.hpp b/src/renderer/vt/vtrenderer.hpp index c462958584..5adf1cd1d9 100644 --- a/src/renderer/vt/vtrenderer.hpp +++ b/src/renderer/vt/vtrenderer.hpp @@ -89,9 +89,9 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT RequestCursor() noexcept; [[nodiscard]] HRESULT InheritCursor(const COORD coordCursor) noexcept; - [[nodiscard]] HRESULT WriteTerminalUtf8(const std::string& str) noexcept; + [[nodiscard]] HRESULT WriteTerminalUtf8(const std::string_view str) noexcept; - [[nodiscard]] virtual HRESULT WriteTerminalW(const std::wstring& str) noexcept = 0; + [[nodiscard]] virtual HRESULT WriteTerminalW(const std::wstring_view str) noexcept = 0; void SetTerminalOwner(Microsoft::Console::ITerminalOwner* const terminalOwner); void BeginResizeRequest(); @@ -209,8 +209,8 @@ namespace Microsoft::Console::Render [[nodiscard]] HRESULT _PaintAsciiBufferLine(std::basic_string_view const clusters, const COORD coord) noexcept; - [[nodiscard]] HRESULT _WriteTerminalUtf8(const std::wstring& str) noexcept; - [[nodiscard]] HRESULT _WriteTerminalAscii(const std::wstring& str) noexcept; + [[nodiscard]] HRESULT _WriteTerminalUtf8(const std::wstring_view str) noexcept; + [[nodiscard]] HRESULT _WriteTerminalAscii(const std::wstring_view str) noexcept; [[nodiscard]] virtual HRESULT _DoUpdateTitle(const std::wstring& newTitle) noexcept override; diff --git a/src/terminal/adapter/DispatchCommon.cpp b/src/terminal/adapter/DispatchCommon.cpp index 6d022299d5..a7ef93f38f 100644 --- a/src/terminal/adapter/DispatchCommon.cpp +++ b/src/terminal/adapter/DispatchCommon.cpp @@ -13,27 +13,27 @@ using namespace Microsoft::Console::VirtualTerminal; // - Resizes the window to the specified dimensions, in characters. // Arguments: // - conApi: The ConGetSet implementation to call back into. -// - usWidth: The new width of the window, in columns -// - usHeight: The new height of the window, in rows +// - width: The new width of the window, in columns +// - height: The new height of the window, in rows // Return Value: // True if handled successfully. False othewise. bool DispatchCommon::s_ResizeWindow(ConGetSet& conApi, - const unsigned short usWidth, - const unsigned short usHeight) + const size_t width, + const size_t height) { SHORT sColumns = 0; SHORT sRows = 0; // We should do nothing if 0 is passed in for a size. - bool fSuccess = SUCCEEDED(UShortToShort(usWidth, &sColumns)) && - SUCCEEDED(UShortToShort(usHeight, &sRows)) && - (usWidth > 0 && usHeight > 0); + bool fSuccess = SUCCEEDED(SizeTToShort(width, &sColumns)) && + SUCCEEDED(SizeTToShort(height, &sRows)) && + (width > 0 && height > 0); if (fSuccess) { CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); - fSuccess = !!conApi.GetConsoleScreenBufferInfoEx(&csbiex); + fSuccess = !!conApi.GetConsoleScreenBufferInfoEx(csbiex); if (fSuccess) { @@ -57,10 +57,10 @@ bool DispatchCommon::s_ResizeWindow(ConGetSet& conApi, SMALL_RECT sre = newViewport.ToExclusive(); csbiex.srWindow = sre; - fSuccess = !!conApi.SetConsoleScreenBufferInfoEx(&csbiex); + fSuccess = conApi.SetConsoleScreenBufferInfoEx(csbiex); if (fSuccess) { - fSuccess = !!conApi.SetConsoleWindowInfo(true, &sri); + fSuccess = conApi.SetConsoleWindowInfo(true, sri); } } } @@ -75,7 +75,7 @@ bool DispatchCommon::s_ResizeWindow(ConGetSet& conApi, // True if handled successfully. False othewise. bool DispatchCommon::s_RefreshWindow(ConGetSet& conApi) { - return !!conApi.PrivateRefreshWindow(); + return conApi.PrivateRefreshWindow(); } // Routine Description: @@ -89,5 +89,5 @@ bool DispatchCommon::s_RefreshWindow(ConGetSet& conApi) // True if handled successfully. False othewise. bool DispatchCommon::s_SuppressResizeRepaint(ConGetSet& conApi) { - return !!conApi.PrivateSuppressResizeRepaint(); + return conApi.PrivateSuppressResizeRepaint(); } diff --git a/src/terminal/adapter/DispatchCommon.hpp b/src/terminal/adapter/DispatchCommon.hpp index 5f06a6559b..f7af1e28d0 100644 --- a/src/terminal/adapter/DispatchCommon.hpp +++ b/src/terminal/adapter/DispatchCommon.hpp @@ -23,8 +23,8 @@ namespace Microsoft::Console::VirtualTerminal { public: static bool s_ResizeWindow(ConGetSet& conApi, - const unsigned short usWidth, - const unsigned short usHeight); + const size_t width, + const size_t height); static bool s_RefreshWindow(ConGetSet& conApi); diff --git a/src/terminal/adapter/IInteractDispatch.hpp b/src/terminal/adapter/IInteractDispatch.hpp index 954f75094d..d974e93b06 100644 --- a/src/terminal/adapter/IInteractDispatch.hpp +++ b/src/terminal/adapter/IInteractDispatch.hpp @@ -25,17 +25,16 @@ namespace Microsoft::Console::VirtualTerminal public: virtual ~IInteractDispatch() = default; - virtual bool WriteInput(_In_ std::deque>& inputEvents) = 0; + virtual bool WriteInput(std::deque>& inputEvents) = 0; virtual bool WriteCtrlC() = 0; - virtual bool WriteString(_In_reads_(cch) const wchar_t* const pws, const size_t cch) = 0; + virtual bool WriteString(const std::wstring_view string) = 0; - virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) = 0; + virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) = 0; - virtual bool MoveCursor(const unsigned int row, - const unsigned int col) = 0; + virtual bool MoveCursor(const size_t row, + const size_t col) = 0; }; } diff --git a/src/terminal/adapter/ITermDispatch.hpp b/src/terminal/adapter/ITermDispatch.hpp index d76e2f6577..c5bbd81494 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -25,63 +25,60 @@ public: virtual ~ITermDispatch() = 0; virtual void Execute(const wchar_t wchControl) = 0; virtual void Print(const wchar_t wchPrintable) = 0; - virtual void PrintString(const wchar_t* const rgwch, const size_t cch) = 0; + virtual void PrintString(const std::wstring_view string) = 0; - virtual bool CursorUp(const unsigned int uiDistance) = 0; // CUU - virtual bool CursorDown(const unsigned int uiDistance) = 0; // CUD - virtual bool CursorForward(const unsigned int uiDistance) = 0; // CUF - virtual bool CursorBackward(const unsigned int uiDistance) = 0; // CUB - virtual bool CursorNextLine(const unsigned int uiDistance) = 0; // CNL - virtual bool CursorPrevLine(const unsigned int uiDistance) = 0; // CPL - virtual bool CursorHorizontalPositionAbsolute(const unsigned int uiColumn) = 0; // CHA - virtual bool VerticalLinePositionAbsolute(const unsigned int uiLine) = 0; // VPA - virtual bool CursorPosition(const unsigned int uiLine, const unsigned int uiColumn) = 0; // CUP + virtual bool CursorUp(const size_t distance) = 0; // CUU + virtual bool CursorDown(const size_t distance) = 0; // CUD + virtual bool CursorForward(const size_t distance) = 0; // CUF + virtual bool CursorBackward(const size_t distance) = 0; // CUB + virtual bool CursorNextLine(const size_t distance) = 0; // CNL + virtual bool CursorPrevLine(const size_t distance) = 0; // CPL + virtual bool CursorHorizontalPositionAbsolute(const size_t column) = 0; // CHA + virtual bool VerticalLinePositionAbsolute(const size_t line) = 0; // VPA + virtual bool CursorPosition(const size_t line, const size_t column) = 0; // CUP virtual bool CursorSaveState() = 0; // DECSC virtual bool CursorRestoreState() = 0; // DECRC - virtual bool CursorVisibility(const bool fIsVisible) = 0; // DECTCEM - virtual bool InsertCharacter(const unsigned int uiCount) = 0; // ICH - virtual bool DeleteCharacter(const unsigned int uiCount) = 0; // DCH - virtual bool ScrollUp(const unsigned int uiDistance) = 0; // SU - virtual bool ScrollDown(const unsigned int uiDistance) = 0; // SD - virtual bool InsertLine(const unsigned int uiDistance) = 0; // IL - virtual bool DeleteLine(const unsigned int uiDistance) = 0; // DL - virtual bool SetColumns(const unsigned int uiColumns) = 0; // DECSCPP, DECCOLM - virtual bool SetCursorKeysMode(const bool fApplicationMode) = 0; // DECCKM - virtual bool SetKeypadMode(const bool fApplicationMode) = 0; // DECKPAM, DECKPNM - virtual bool EnableCursorBlinking(const bool fEnable) = 0; // ATT610 - virtual bool SetOriginMode(const bool fRelativeMode) = 0; // DECOM - virtual bool SetTopBottomScrollingMargins(const SHORT sTopMargin, const SHORT sBottomMargin) = 0; // DECSTBM + virtual bool CursorVisibility(const bool isVisible) = 0; // DECTCEM + virtual bool InsertCharacter(const size_t count) = 0; // ICH + virtual bool DeleteCharacter(const size_t count) = 0; // DCH + virtual bool ScrollUp(const size_t distance) = 0; // SU + virtual bool ScrollDown(const size_t distance) = 0; // SD + virtual bool InsertLine(const size_t distance) = 0; // IL + virtual bool DeleteLine(const size_t distance) = 0; // DL + virtual bool SetColumns(const size_t columns) = 0; // DECSCPP, DECCOLM + virtual bool SetCursorKeysMode(const bool applicationMode) = 0; // DECCKM + virtual bool SetKeypadMode(const bool applicationMode) = 0; // DECKPAM, DECKPNM + virtual bool EnableCursorBlinking(const bool enable) = 0; // ATT610 + virtual bool SetOriginMode(const bool relativeMode) = 0; // DECOM + virtual bool SetTopBottomScrollingMargins(const size_t topMargin, const size_t bottomMargin) = 0; // DECSTBM virtual bool ReverseLineFeed() = 0; // RI virtual bool SetWindowTitle(std::wstring_view title) = 0; // OscWindowTitle virtual bool UseAlternateScreenBuffer() = 0; // ASBSET virtual bool UseMainScreenBuffer() = 0; // ASBRST virtual bool HorizontalTabSet() = 0; // HTS - virtual bool ForwardTab(const SHORT sNumTabs) = 0; // CHT - virtual bool BackwardsTab(const SHORT sNumTabs) = 0; // CBT - virtual bool TabClear(const SHORT sClearType) = 0; // TBC - virtual bool EnableDECCOLMSupport(const bool fEnabled) = 0; // ?40 - virtual bool EnableVT200MouseMode(const bool fEnabled) = 0; // ?1000 - virtual bool EnableUTF8ExtendedMouseMode(const bool fEnabled) = 0; // ?1005 - virtual bool EnableSGRExtendedMouseMode(const bool fEnabled) = 0; // ?1006 - virtual bool EnableButtonEventMouseMode(const bool fEnabled) = 0; // ?1002 - virtual bool EnableAnyEventMouseMode(const bool fEnabled) = 0; // ?1003 - virtual bool EnableAlternateScroll(const bool fEnabled) = 0; // ?1007 - virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) = 0; // OSCColorTable - virtual bool SetDefaultForeground(const DWORD dwColor) = 0; // OSCDefaultForeground - virtual bool SetDefaultBackground(const DWORD dwColor) = 0; // OSCDefaultBackground + virtual bool ForwardTab(const size_t numTabs) = 0; // CHT + virtual bool BackwardsTab(const size_t numTabs) = 0; // CBT + virtual bool TabClear(const size_t clearType) = 0; // TBC + virtual bool EnableDECCOLMSupport(const bool enabled) = 0; // ?40 + virtual bool EnableVT200MouseMode(const bool enabled) = 0; // ?1000 + virtual bool EnableUTF8ExtendedMouseMode(const bool enabled) = 0; // ?1005 + virtual bool EnableSGRExtendedMouseMode(const bool enabled) = 0; // ?1006 + virtual bool EnableButtonEventMouseMode(const bool enabled) = 0; // ?1002 + virtual bool EnableAnyEventMouseMode(const bool enabled) = 0; // ?1003 + virtual bool EnableAlternateScroll(const bool enabled) = 0; // ?1007 + virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; // OSCColorTable + virtual bool SetDefaultForeground(const DWORD color) = 0; // OSCDefaultForeground + virtual bool SetDefaultBackground(const DWORD color) = 0; // OSCDefaultBackground virtual bool EraseInDisplay(const DispatchTypes::EraseType eraseType) = 0; // ED virtual bool EraseInLine(const DispatchTypes::EraseType eraseType) = 0; // EL - virtual bool EraseCharacters(const unsigned int uiNumChars) = 0; // ECH + virtual bool EraseCharacters(const size_t numChars) = 0; // ECH - virtual bool SetGraphicsRendition(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions) = 0; // SGR + virtual bool SetGraphicsRendition(const std::basic_string_view options) = 0; // SGR - virtual bool SetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rgParams, - const size_t cParams) = 0; // DECSET + virtual bool SetPrivateModes(const std::basic_string_view params) = 0; // DECSET - virtual bool ResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rgParams, - const size_t cParams) = 0; // DECRST + virtual bool ResetPrivateModes(const std::basic_string_view params) = 0; // DECRST virtual bool DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType) = 0; // DSR virtual bool DeviceAttributes() = 0; // DA @@ -93,11 +90,10 @@ public: virtual bool ScreenAlignmentPattern() = 0; // DECALN virtual bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR - virtual bool SetCursorColor(const COLORREF Color) = 0; // OSCSetCursorColor, OSCResetCursorColor + virtual bool SetCursorColor(const COLORREF color) = 0; // OSCSetCursorColor, OSCResetCursorColor // DTTERM_WindowManipulation - virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) = 0; + virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) = 0; }; inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() {} diff --git a/src/terminal/adapter/InteractDispatch.cpp b/src/terminal/adapter/InteractDispatch.cpp index 74c918bffe..a78db37b18 100644 --- a/src/terminal/adapter/InteractDispatch.cpp +++ b/src/terminal/adapter/InteractDispatch.cpp @@ -14,9 +14,10 @@ using namespace Microsoft::Console::Types; using namespace Microsoft::Console::VirtualTerminal; // takes ownership of pConApi -InteractDispatch::InteractDispatch(ConGetSet* const pConApi) : - _pConApi(THROW_IF_NULL_ALLOC(pConApi)) +InteractDispatch::InteractDispatch(std::unique_ptr pConApi) : + _pConApi(std::move(pConApi)) { + THROW_IF_NULL_ALLOC(_pConApi.get()); } // Method Description: @@ -29,10 +30,10 @@ InteractDispatch::InteractDispatch(ConGetSet* const pConApi) : // - inputEvents: a collection of IInputEvents // Return Value: // True if handled successfully. False otherwise. -bool InteractDispatch::WriteInput(_In_ std::deque>& inputEvents) +bool InteractDispatch::WriteInput(std::deque>& inputEvents) { - size_t dwWritten = 0; - return !!_pConApi->PrivateWriteConsoleInputW(inputEvents, dwWritten); + size_t written = 0; + return _pConApi->PrivateWriteConsoleInputW(inputEvents, written); } // Method Description: @@ -46,43 +47,41 @@ bool InteractDispatch::WriteInput(_In_ std::deque>& bool InteractDispatch::WriteCtrlC() { KeyEvent key = KeyEvent(true, 1, 'C', 0, UNICODE_ETX, LEFT_CTRL_PRESSED); - return !!_pConApi->PrivateWriteConsoleControlInput(key); + return _pConApi->PrivateWriteConsoleControlInput(key); } // Method Description: // - Writes a string of input to the host. The string is converted to keystrokes // that will faithfully represent the input by CharToKeyEvents. // Arguments: -// - pws: a string to write to the console. -// - cch: the number of chars in pws. +// - string : a string to write to the console. // Return Value: // True if handled successfully. False otherwise. -bool InteractDispatch::WriteString(_In_reads_(cch) const wchar_t* const pws, - const size_t cch) +bool InteractDispatch::WriteString(const std::wstring_view string) { - if (cch == 0) + if (string.empty()) { return true; } unsigned int codepage = 0; - bool fSuccess = !!_pConApi->GetConsoleOutputCP(&codepage); - if (fSuccess) + bool success = _pConApi->GetConsoleOutputCP(codepage); + if (success) { std::deque> keyEvents; - for (size_t i = 0; i < cch; ++i) + for (const auto& wch : string) { - std::deque> convertedEvents = CharToKeyEvents(pws[i], codepage); + std::deque> convertedEvents = CharToKeyEvents(wch, codepage); std::move(convertedEvents.begin(), convertedEvents.end(), std::back_inserter(keyEvents)); } - fSuccess = WriteInput(keyEvents); + success = WriteInput(keyEvents); } - return fSuccess; + return success; } //Method Description: @@ -92,45 +91,43 @@ bool InteractDispatch::WriteString(_In_reads_(cch) const wchar_t* const pws, // This is kept seperate from the output version, as there may be // codes that are supported in one direction but not the other. //Arguments: -// - uiFunction - An identifier of the WindowManipulation function to perform -// - rgusParams - Additional parameters to pass to the function -// - cParams - size of rgusParams +// - function - An identifier of the WindowManipulation function to perform +// - parameters - Additional parameters to pass to the function // Return value: // True if handled successfully. False otherwise. -bool InteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) +bool InteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) { - bool fSuccess = false; + bool success = false; // Other Window Manipulation functions: // MSFT:13271098 - QueryViewport // MSFT:13271146 - QueryScreenSize - switch (uiFunction) + switch (function) { case DispatchTypes::WindowManipulationType::RefreshWindow: - if (cParams == 0) + if (parameters.empty()) { - fSuccess = DispatchCommon::s_RefreshWindow(*_pConApi); + success = DispatchCommon::s_RefreshWindow(*_pConApi); } break; case DispatchTypes::WindowManipulationType::ResizeWindowInCharacters: // TODO:GH#1765 We should introduce a better `ResizeConpty` function to // the ConGetSet interface, that specifically handles a conpty resize. - if (cParams == 2) + if (parameters.size() == 2) { - fSuccess = DispatchCommon::s_ResizeWindow(*_pConApi, rgusParams[1], rgusParams[0]); - if (fSuccess) + success = DispatchCommon::s_ResizeWindow(*_pConApi, parameters[1], parameters[0]); + if (success) { DispatchCommon::s_SuppressResizeRepaint(*_pConApi); } } break; default: - fSuccess = false; + success = false; break; } - return fSuccess; + return success; } //Method Description: @@ -143,66 +140,66 @@ bool InteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulatio // True if we successfully moved the cursor to the given location. // False otherwise, including if given invalid coordinates (either component being 0) // or if any API calls failed. -bool InteractDispatch::MoveCursor(const unsigned int row, const unsigned int col) +bool InteractDispatch::MoveCursor(const size_t row, const size_t col) { - unsigned int uiRow = row; - unsigned int uiCol = col; + size_t rowFixed = row; + size_t colFixed = col; - bool fSuccess = true; + bool success = true; // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1. if (row != 0) { - uiRow = row - 1; + rowFixed = row - 1; } else { // The parser should never return 0 (0 maps to 1), so this is a failure condition. - fSuccess = false; + success = false; } if (col != 0) { - uiCol = col - 1; + colFixed = col - 1; } else { // The parser should never return 0 (0 maps to 1), so this is a failure condition. - fSuccess = false; + success = false; } - if (fSuccess) + if (success) { // First retrieve some information about the buffer CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); - fSuccess = !!_pConApi->GetConsoleScreenBufferInfoEx(&csbiex); + success = _pConApi->GetConsoleScreenBufferInfoEx(csbiex); - if (fSuccess) + if (success) { COORD coordCursor = csbiex.dwCursorPosition; - // Safely convert the UINT positions we were given into shorts (which is the size the console deals with) - fSuccess = SUCCEEDED(UIntToShort(uiRow, &coordCursor.Y)) && - SUCCEEDED(UIntToShort(uiCol, &coordCursor.X)); + // Safely convert the size_t positions we were given into shorts (which is the size the console deals with) + success = SUCCEEDED(SizeTToShort(rowFixed, &coordCursor.Y)) && + SUCCEEDED(SizeTToShort(colFixed, &coordCursor.X)); - if (fSuccess) + if (success) { // Set the line and column values as offsets from the viewport edge. Use safe math to prevent overflow. - fSuccess = SUCCEEDED(ShortAdd(coordCursor.Y, csbiex.srWindow.Top, &coordCursor.Y)) && - SUCCEEDED(ShortAdd(coordCursor.X, csbiex.srWindow.Left, &coordCursor.X)); + success = SUCCEEDED(ShortAdd(coordCursor.Y, csbiex.srWindow.Top, &coordCursor.Y)) && + SUCCEEDED(ShortAdd(coordCursor.X, csbiex.srWindow.Left, &coordCursor.X)); - if (fSuccess) + if (success) { // Apply boundary tests to ensure the cursor isn't outside the viewport rectangle. coordCursor.Y = std::clamp(coordCursor.Y, csbiex.srWindow.Top, gsl::narrow(csbiex.srWindow.Bottom - 1)); coordCursor.X = std::clamp(coordCursor.X, csbiex.srWindow.Left, gsl::narrow(csbiex.srWindow.Right - 1)); // Finally, attempt to set the adjusted cursor position back into the console. - fSuccess = !!_pConApi->SetConsoleCursorPosition(coordCursor); + success = _pConApi->SetConsoleCursorPosition(coordCursor); } } } } - return fSuccess; + return success; } diff --git a/src/terminal/adapter/InteractDispatch.hpp b/src/terminal/adapter/InteractDispatch.hpp index 6914194c85..503c5cd980 100644 --- a/src/terminal/adapter/InteractDispatch.hpp +++ b/src/terminal/adapter/InteractDispatch.hpp @@ -23,18 +23,16 @@ namespace Microsoft::Console::VirtualTerminal class InteractDispatch : public IInteractDispatch { public: - InteractDispatch(ConGetSet* const pConApi); + InteractDispatch(std::unique_ptr pConApi); ~InteractDispatch() = default; - bool WriteInput(_In_ std::deque>& inputEvents) override; + bool WriteInput(std::deque>& inputEvents) override; bool WriteCtrlC() override; - bool WriteString(_In_reads_(cch) const wchar_t* const pws, const size_t cch) override; - bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) override; // DTTERM_WindowManipulation - bool MoveCursor(const unsigned int row, - const unsigned int col) override; + bool WriteString(const std::wstring_view string) override; + bool WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) override; // DTTERM_WindowManipulation + bool MoveCursor(const size_t row, const size_t col) override; private: std::unique_ptr _pConApi; diff --git a/src/terminal/adapter/adaptDefaults.hpp b/src/terminal/adapter/adaptDefaults.hpp index a97ae829de..63a7b0eb86 100644 --- a/src/terminal/adapter/adaptDefaults.hpp +++ b/src/terminal/adapter/adaptDefaults.hpp @@ -23,7 +23,7 @@ namespace Microsoft::Console::VirtualTerminal public: virtual void Print(const wchar_t wch) = 0; // These characters need to be mutable so that they can be processed by the TerminalInput translater. - virtual void PrintString(const wchar_t* const rgwch, const size_t cch) = 0; + virtual void PrintString(const std::wstring_view string) = 0; virtual void Execute(const wchar_t wch) = 0; }; } diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index fb60da0992..63402b2dda 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -23,42 +23,58 @@ bool NoOp() } // Note: AdaptDispatch will take ownership of pConApi and pDefaults -AdaptDispatch::AdaptDispatch(ConGetSet* const pConApi, - AdaptDefaults* const pDefaults) : - _conApi{ THROW_IF_NULL_ALLOC(pConApi) }, - _pDefaults{ THROW_IF_NULL_ALLOC(pDefaults) }, +AdaptDispatch::AdaptDispatch(std::unique_ptr pConApi, + std::unique_ptr pDefaults) : + _pConApi{ std::move(pConApi) }, + _pDefaults{ std::move(pDefaults) }, _usingAltBuffer(false), - _fIsOriginModeRelative(false), // by default, the DECOM origin mode is absolute. - _fIsDECCOLMAllowed(false), // by default, DECCOLM is not allowed. - _fChangedBackground(false), - _fChangedForeground(false), - _fChangedMetaAttrs(false), - _TermOutput() + _isOriginModeRelative(false), // by default, the DECOM origin mode is absolute. + _isDECCOLMAllowed(false), // by default, DECCOLM is not allowed. + _changedBackground(false), + _changedForeground(false), + _changedMetaAttrs(false), + _termOutput() { - _srScrollMargins = { 0 }; // initially, there are no scroll margins. + THROW_IF_NULL_ALLOC(_pConApi.get()); + THROW_IF_NULL_ALLOC(_pDefaults.get()); + _scrollMargins = { 0 }; // initially, there are no scroll margins. } +// Routine Description: +// - Translates and displays a single character +// Arguments: +// - wchPrintable - Printable character +// Return Value: +// - void AdaptDispatch::Print(const wchar_t wchPrintable) { - _pDefaults->Print(_TermOutput.TranslateKey(wchPrintable)); + _pDefaults->Print(_termOutput.TranslateKey(wchPrintable)); } -void AdaptDispatch::PrintString(const wchar_t* const rgwch, const size_t cch) +// Routine Description +// - Forward an entire string through. May translate, if necessary, to key input sequences +// based on the locale +// Arguments: +// - string - Text to display +// Return Value: +// - +void AdaptDispatch::PrintString(const std::wstring_view string) { try { - if (_TermOutput.NeedToTranslate()) + if (_termOutput.NeedToTranslate()) { - std::unique_ptr tempArray = std::make_unique(cch); - for (size_t i = 0; i < cch; i++) + std::wstring buffer; + buffer.reserve(string.size()); + for (auto& wch : string) { - tempArray[i] = _TermOutput.TranslateKey(rgwch[i]); + buffer.push_back(_termOutput.TranslateKey(wch)); } - _pDefaults->PrintString(tempArray.get(), cch); + _pDefaults->PrintString(buffer); } else { - _pDefaults->PrintString(rgwch, cch); + _pDefaults->PrintString(string); } } CATCH_LOG(); @@ -68,40 +84,40 @@ void AdaptDispatch::PrintString(const wchar_t* const rgwch, const size_t cch) // - Generalizes cursor movement for up/down/left/right and next/previous line. // Arguments: // - dir - Specific direction to move -// - uiDistance - Magnitude of the move +// - distance - Magnitude of the move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::_CursorMovement(const CursorDirection dir, _In_ unsigned int const uiDistance) const +bool AdaptDispatch::_CursorMovement(const CursorDirection dir, const size_t distance) const { // First retrieve some information about the buffer CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - bool fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + bool success = (_pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex)); - if (fSuccess) + if (success) { - COORD coordCursor = csbiex.dwCursorPosition; + COORD cursor = csbiex.dwCursorPosition; // For next/previous line, we unconditionally need to move the X position to the left edge of the viewport. switch (dir) { case CursorDirection::NextLine: case CursorDirection::PrevLine: - coordCursor.X = csbiex.srWindow.Left; + cursor.X = csbiex.srWindow.Left; break; } // Safely convert the UINT magnitude of the move we were given into a short (which is the size the console deals with) - SHORT sDelta = 0; - fSuccess = SUCCEEDED(UIntToShort(uiDistance, &sDelta)); + SHORT delta = 0; + success = SUCCEEDED(SizeTToShort(distance, &delta)); - if (fSuccess) + if (success) { // Prepare our variables for math. All operations are some variation on these two parameters - SHORT* pcoordVal = nullptr; // The coordinate X or Y gets modified - SHORT sBoundaryVal = 0; // There is a particular edge of the viewport that is our boundary condition as we approach it. + SHORT* pModify = nullptr; // The coordinate X or Y gets modified + SHORT boundary = 0; // There is a particular edge of the viewport that is our boundary condition as we approach it. // Up and Down modify the Y coordinate. Left and Right modify the X. switch (dir) @@ -110,14 +126,14 @@ bool AdaptDispatch::_CursorMovement(const CursorDirection dir, _In_ unsigned int case CursorDirection::Down: case CursorDirection::NextLine: case CursorDirection::PrevLine: - pcoordVal = &coordCursor.Y; + pModify = &cursor.Y; break; case CursorDirection::Left: case CursorDirection::Right: - pcoordVal = &coordCursor.X; + pModify = &cursor.X; break; default: - fSuccess = false; + success = false; break; } @@ -126,24 +142,24 @@ bool AdaptDispatch::_CursorMovement(const CursorDirection dir, _In_ unsigned int { case CursorDirection::Up: case CursorDirection::PrevLine: - sBoundaryVal = csbiex.srWindow.Top; + boundary = csbiex.srWindow.Top; break; case CursorDirection::Down: case CursorDirection::NextLine: - sBoundaryVal = csbiex.srWindow.Bottom; + boundary = csbiex.srWindow.Bottom; break; case CursorDirection::Left: - sBoundaryVal = csbiex.srWindow.Left; + boundary = csbiex.srWindow.Left; break; case CursorDirection::Right: - sBoundaryVal = csbiex.srWindow.Right; + boundary = csbiex.srWindow.Right; break; default: - fSuccess = false; + success = false; break; } - if (fSuccess) + if (success) { // For up and left, we need to subtract the magnitude of the vector to get the new spot. Right/down = add. // Use safe short subtraction to prevent under/overflow. @@ -152,16 +168,16 @@ bool AdaptDispatch::_CursorMovement(const CursorDirection dir, _In_ unsigned int case CursorDirection::Up: case CursorDirection::Left: case CursorDirection::PrevLine: - fSuccess = SUCCEEDED(ShortSub(*pcoordVal, sDelta, pcoordVal)); + success = SUCCEEDED(ShortSub(*pModify, delta, pModify)); break; case CursorDirection::Down: case CursorDirection::Right: case CursorDirection::NextLine: - fSuccess = SUCCEEDED(ShortAdd(*pcoordVal, sDelta, pcoordVal)); + success = SUCCEEDED(ShortAdd(*pModify, delta, pModify)); break; } - if (fSuccess) + if (success) { // Now apply the boundary condition. Up, Left can't be smaller than their boundary. Top, Right can't be larger. switch (dir) @@ -169,30 +185,30 @@ bool AdaptDispatch::_CursorMovement(const CursorDirection dir, _In_ unsigned int case CursorDirection::Up: case CursorDirection::Left: case CursorDirection::PrevLine: - *pcoordVal = std::max(*pcoordVal, sBoundaryVal); + *pModify = std::max(*pModify, boundary); break; case CursorDirection::Down: case CursorDirection::Right: case CursorDirection::NextLine: // For the bottom and right edges, the viewport value is stated to be one outside the rectangle. - *pcoordVal = std::min(*pcoordVal, gsl::narrow(sBoundaryVal - 1)); + *pModify = std::min(*pModify, gsl::narrow(boundary - 1)); break; default: - fSuccess = false; + success = false; break; } - if (fSuccess) + if (success) { // Finally, attempt to set the adjusted cursor position back into the console. - fSuccess = !!_conApi->SetConsoleCursorPosition(coordCursor); + success = _pConApi->SetConsoleCursorPosition(cursor); } } } } } - return fSuccess; + return success; } // Routine Description: @@ -203,15 +219,15 @@ bool AdaptDispatch::_CursorMovement(const CursorDirection dir, _In_ unsigned int // "The cursor stops at the top margin. If the cursor is already above the top // margin, then the cursor stops at the top line." // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorUp(_In_ unsigned int const uiDistance) +bool AdaptDispatch::CursorUp(const size_t distance) { SHORT sDelta = 0; - if (SUCCEEDED(UIntToShort(uiDistance, &sDelta))) + if (SUCCEEDED(SizeTToShort(distance, &sDelta))) { - return !!_conApi->MoveCursorVertically(-sDelta); + return _pConApi->MoveCursorVertically(-sDelta); } return false; } @@ -224,15 +240,15 @@ bool AdaptDispatch::CursorUp(_In_ unsigned int const uiDistance) // "The cursor stops at the bottom margin. If the cursor is already above the // bottom margin, then the cursor stops at the bottom line." // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorDown(_In_ unsigned int const uiDistance) +bool AdaptDispatch::CursorDown(const size_t distance) { SHORT sDelta = 0; - if (SUCCEEDED(UIntToShort(uiDistance, &sDelta))) + if (SUCCEEDED(SizeTToShort(distance, &sDelta))) { - return !!_conApi->MoveCursorVertically(sDelta); + return _pConApi->MoveCursorVertically(sDelta); } return false; } @@ -240,175 +256,175 @@ bool AdaptDispatch::CursorDown(_In_ unsigned int const uiDistance) // Routine Description: // - CUF - Handles cursor forward movement by given distance // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorForward(_In_ unsigned int const uiDistance) +bool AdaptDispatch::CursorForward(const size_t distance) { - return _CursorMovement(CursorDirection::Right, uiDistance); + return _CursorMovement(CursorDirection::Right, distance); } // Routine Description: // - CUB - Handles cursor backward movement by given distance // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorBackward(_In_ unsigned int const uiDistance) +bool AdaptDispatch::CursorBackward(const size_t distance) { - return _CursorMovement(CursorDirection::Left, uiDistance); + return _CursorMovement(CursorDirection::Left, distance); } // Routine Description: // - CNL - Handles cursor movement to the following line (or N lines down) // - Moves to the beginning X/Column position of the line. // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorNextLine(_In_ unsigned int const uiDistance) +bool AdaptDispatch::CursorNextLine(const size_t distance) { - return _CursorMovement(CursorDirection::NextLine, uiDistance); + return _CursorMovement(CursorDirection::NextLine, distance); } // Routine Description: // - CPL - Handles cursor movement to the previous line (or N lines up) // - Moves to the beginning X/Column position of the line. // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorPrevLine(_In_ unsigned int const uiDistance) +bool AdaptDispatch::CursorPrevLine(const size_t distance) { - return _CursorMovement(CursorDirection::PrevLine, uiDistance); + return _CursorMovement(CursorDirection::PrevLine, distance); } // Routine Description: // - Generalizes cursor movement to a specific coordinate position // - If a parameter is left blank, we will maintain the existing position in that dimension. // Arguments: -// - puiRow - Optional row to move to -// - puiColumn - Optional column to move to +// - row - Optional row to move to +// - column - Optional column to move to // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::_CursorMovePosition(_In_opt_ const unsigned int* const puiRow, _In_opt_ const unsigned int* const puiCol) const +bool AdaptDispatch::_CursorMovePosition(const std::optional row, const std::optional column) const { - bool fSuccess = true; + bool success = true; // First retrieve some information about the buffer CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + success = (_pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex)); - if (fSuccess) + if (success) { // handle optional parameters. If not specified, keep same cursor position from what we just loaded. - unsigned int uiRow = 0; - unsigned int uiCol = 0; + size_t rowActual = 0; + size_t columnActual = 0; - if (puiRow != nullptr) + if (row) { - if (*puiRow != 0) + if (row.value() != 0) { - uiRow = *puiRow - 1; // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1. + rowActual = row.value() - 1; // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1. // If the origin mode is relative, and the scrolling region is set (the bottom is non-zero), // line numbers start at the top margin of the scrolling region, and cannot move below the bottom. - if (_fIsOriginModeRelative && _srScrollMargins.Bottom != 0) + if (_isOriginModeRelative && _scrollMargins.Bottom != 0) { - uiRow += _srScrollMargins.Top; - uiRow = std::min(uiRow, _srScrollMargins.Bottom); + rowActual += _scrollMargins.Top; + rowActual = std::min(rowActual, _scrollMargins.Bottom); } } else { - fSuccess = false; // The parser should never return 0 (0 maps to 1), so this is a failure condition. + success = false; // The parser should never return 0 (0 maps to 1), so this is a failure condition. } } else { - uiRow = csbiex.dwCursorPosition.Y - csbiex.srWindow.Top; // remember, in VT speak, this is relative to the viewport. not absolute. + rowActual = csbiex.dwCursorPosition.Y - csbiex.srWindow.Top; // remember, in VT speak, this is relative to the viewport. not absolute. } - if (puiCol != nullptr) + if (column) { - if (*puiCol != 0) + if (column.value() != 0) { - uiCol = *puiCol - 1; // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1. + columnActual = column.value() - 1; // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1. } else { - fSuccess = false; // The parser should never return 0 (0 maps to 1), so this is a failure condition. + success = false; // The parser should never return 0 (0 maps to 1), so this is a failure condition. } } else { - uiCol = csbiex.dwCursorPosition.X - csbiex.srWindow.Left; // remember, in VT speak, this is relative to the viewport. not absolute. + columnActual = csbiex.dwCursorPosition.X - csbiex.srWindow.Left; // remember, in VT speak, this is relative to the viewport. not absolute. } - if (fSuccess) + if (success) { - COORD coordCursor = csbiex.dwCursorPosition; + COORD cursor = csbiex.dwCursorPosition; - // Safely convert the UINT positions we were given into shorts (which is the size the console deals with) - fSuccess = SUCCEEDED(UIntToShort(uiRow, &coordCursor.Y)) && SUCCEEDED(UIntToShort(uiCol, &coordCursor.X)); + // Safely convert the size_t positions we were given into shorts (which is the size the console deals with) + success = SUCCEEDED(SizeTToShort(rowActual, &cursor.Y)) && SUCCEEDED(SizeTToShort(columnActual, &cursor.X)); - if (fSuccess) + if (success) { // Set the line and column values as offsets from the viewport edge. Use safe math to prevent overflow. - fSuccess = SUCCEEDED(ShortAdd(coordCursor.Y, csbiex.srWindow.Top, &coordCursor.Y)) && - SUCCEEDED(ShortAdd(coordCursor.X, csbiex.srWindow.Left, &coordCursor.X)); + success = SUCCEEDED(ShortAdd(cursor.Y, csbiex.srWindow.Top, &cursor.Y)) && + SUCCEEDED(ShortAdd(cursor.X, csbiex.srWindow.Left, &cursor.X)); - if (fSuccess) + if (success) { // Apply boundary tests to ensure the cursor isn't outside the viewport rectangle. - coordCursor.Y = std::clamp(coordCursor.Y, csbiex.srWindow.Top, gsl::narrow(csbiex.srWindow.Bottom - 1)); - coordCursor.X = std::clamp(coordCursor.X, csbiex.srWindow.Left, gsl::narrow(csbiex.srWindow.Right - 1)); + cursor.Y = std::clamp(cursor.Y, csbiex.srWindow.Top, gsl::narrow(csbiex.srWindow.Bottom - 1)); + cursor.X = std::clamp(cursor.X, csbiex.srWindow.Left, gsl::narrow(csbiex.srWindow.Right - 1)); // Finally, attempt to set the adjusted cursor position back into the console. - fSuccess = !!_conApi->SetConsoleCursorPosition(coordCursor); + success = _pConApi->SetConsoleCursorPosition(cursor); } } } } - return fSuccess; + return success; } // Routine Description: // - CHA - Moves the cursor to an exact X/Column position on the current line. // Arguments: -// - uiColumn - Specific X/Column position to move to +// - column - Specific X/Column position to move to // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorHorizontalPositionAbsolute(_In_ unsigned int const uiColumn) +bool AdaptDispatch::CursorHorizontalPositionAbsolute(const size_t column) { - return _CursorMovePosition(nullptr, &uiColumn); + return _CursorMovePosition(std::nullopt, column); } // Routine Description: // - VPA - Moves the cursor to an exact Y/row position on the current column. // Arguments: -// - uiLine - Specific Y/Row position to move to +// - line - Specific Y/Row position to move to // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::VerticalLinePositionAbsolute(_In_ unsigned int const uiLine) +bool AdaptDispatch::VerticalLinePositionAbsolute(const size_t line) { - return _CursorMovePosition(&uiLine, nullptr); + return _CursorMovePosition(line, std::nullopt); } // Routine Description: // - CUP - Moves the cursor to an exact X/Column and Y/Row/Line coordinate position. // Arguments: -// - uiLine - Specific Y/Row/Line position to move to -// - uiColumn - Specific X/Column position to move to +// - line - Specific Y/Row/Line position to move to +// - column - Specific X/Column position to move to // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::CursorPosition(_In_ unsigned int const uiLine, _In_ unsigned int const uiColumn) +bool AdaptDispatch::CursorPosition(const size_t line, const size_t column) { - return _CursorMovePosition(&uiLine, &uiColumn); + return _CursorMovePosition(line, column); } // Routine Description: @@ -426,12 +442,12 @@ bool AdaptDispatch::CursorSaveState() csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - bool fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + bool success = (_pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex)); TextAttribute attributes; - fSuccess = fSuccess && !!(_conApi->PrivateGetTextAttributes(&attributes)); + success = success && (_pConApi->PrivateGetTextAttributes(attributes)); - if (fSuccess) + if (success) { // The cursor is given to us by the API as relative to the whole buffer. // But in VT speak, the cursor should be relative to the current viewport. Adjust. @@ -440,15 +456,15 @@ bool AdaptDispatch::CursorSaveState() SMALL_RECT const srViewport = csbiex.srWindow; // VT is also 1 based, not 0 based, so correct by 1. - auto& savedCursorState = _savedCursorState[_usingAltBuffer]; + auto& savedCursorState = _savedCursorState.at(_usingAltBuffer); savedCursorState.Column = coordCursor.X - srViewport.Left + 1; savedCursorState.Row = coordCursor.Y - srViewport.Top + 1; - savedCursorState.IsOriginModeRelative = _fIsOriginModeRelative; + savedCursorState.IsOriginModeRelative = _isOriginModeRelative; savedCursorState.Attributes = attributes; - savedCursorState.TermOutput = _TermOutput; + savedCursorState.TermOutput = _termOutput; } - return fSuccess; + return success; } // Routine Description: @@ -461,33 +477,33 @@ bool AdaptDispatch::CursorSaveState() // - True if handled successfully. False otherwise. bool AdaptDispatch::CursorRestoreState() { - auto& savedCursorState = _savedCursorState[_usingAltBuffer]; + auto& savedCursorState = _savedCursorState.at(_usingAltBuffer); - auto uiRow = savedCursorState.Row; - auto uiCol = savedCursorState.Column; + auto row = savedCursorState.Row; + auto col = savedCursorState.Column; // If the origin mode is relative, and the scrolling region is set (the bottom is non-zero), // we need to make sure the restored position is clamped within the margins. - if (savedCursorState.IsOriginModeRelative && _srScrollMargins.Bottom != 0) + if (savedCursorState.IsOriginModeRelative && _scrollMargins.Bottom != 0) { // VT origin is at 1,1 so we need to add 1 to these margins. - uiRow = std::clamp(uiRow, _srScrollMargins.Top + 1u, _srScrollMargins.Bottom + 1u); + row = std::clamp(row, _scrollMargins.Top + 1u, _scrollMargins.Bottom + 1u); } // The saved coordinates are always absolute, so we need reset the origin mode temporarily. - _fIsOriginModeRelative = false; - bool fSuccess = _CursorMovePosition(&uiRow, &uiCol); + _isOriginModeRelative = false; + bool success = _CursorMovePosition(row, col); // Once the cursor position is restored, we can then restore the actual origin mode. - _fIsOriginModeRelative = savedCursorState.IsOriginModeRelative; + _isOriginModeRelative = savedCursorState.IsOriginModeRelative; // Restore text attributes. - fSuccess = !!(_conApi->PrivateSetTextAttributes(savedCursorState.Attributes)) && fSuccess; + success = (_pConApi->PrivateSetTextAttributes(savedCursorState.Attributes)) && success; // Restore designated character set. - _TermOutput = savedCursorState.TermOutput; + _termOutput = savedCursorState.TermOutput; - return fSuccess; + return success; } // Routine Description: @@ -500,30 +516,30 @@ bool AdaptDispatch::CursorVisibility(const bool fIsVisible) { // This uses a private API instead of the public one, because the public API // will set the cursor shape back to legacy. - return !!_conApi->PrivateShowCursor(fIsVisible); + return _pConApi->PrivateShowCursor(fIsVisible); } // Routine Description: // - This helper will do the work of performing an insert or delete character operation // - Both operations are similar in that they cut text and move it left or right in the buffer, padding the leftover area with spaces. // Arguments: -// - uiCount - The number of characters to insert -// - fIsInsert - TRUE if insert mode (cut and paste to the right, away from the cursor). FALSE if delete mode (cut and paste to the left, toward the cursor) +// - count - The number of characters to insert +// - isInsert - TRUE if insert mode (cut and paste to the right, away from the cursor). FALSE if delete mode (cut and paste to the left, toward the cursor) // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::_InsertDeleteHelper(_In_ unsigned int const uiCount, const bool fIsInsert) const +bool AdaptDispatch::_InsertDeleteHelper(const size_t count, const bool isInsert) const { // We'll be doing short math on the distance since all console APIs use shorts. So check that we can successfully convert the uint into a short first. - SHORT sDistance; - RETURN_BOOL_IF_FALSE(SUCCEEDED(UIntToShort(uiCount, &sDistance))); + SHORT distance; + RETURN_BOOL_IF_FALSE(SUCCEEDED(SizeTToShort(count, &distance))); // get current cursor, attributes CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - RETURN_BOOL_IF_FALSE(_conApi->MoveToBottom()); - RETURN_BOOL_IF_FALSE(_conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + RETURN_BOOL_IF_FALSE(_pConApi->MoveToBottom()); + RETURN_BOOL_IF_FALSE(_pConApi->GetConsoleScreenBufferInfoEx(csbiex)); const auto cursor = csbiex.dwCursorPosition; // Rectangle to cut out of the existing buffer. This is inclusive. @@ -539,65 +555,70 @@ bool AdaptDispatch::_InsertDeleteHelper(_In_ unsigned int const uiCount, const b coordDestination.Y = cursor.Y; coordDestination.X = cursor.X; - bool fSuccess = false; - if (fIsInsert) + bool success = false; + if (isInsert) { // Insert makes space by moving characters out to the right. So move the destination of the cut/paste region. - fSuccess = SUCCEEDED(ShortAdd(coordDestination.X, sDistance, &coordDestination.X)); + success = SUCCEEDED(ShortAdd(coordDestination.X, distance, &coordDestination.X)); } else { // Delete scrolls the affected region to the left, relying on the clipping rect to actually delete the characters. - fSuccess = SUCCEEDED(ShortSub(coordDestination.X, sDistance, &coordDestination.X)); + success = SUCCEEDED(ShortSub(coordDestination.X, distance, &coordDestination.X)); } - if (fSuccess) + if (success) { // Note the revealed characters are filled with the standard erase attributes. - fSuccess = !!_conApi->PrivateScrollRegion(srScroll, srScroll, coordDestination, true); + success = _pConApi->PrivateScrollRegion(srScroll, srScroll, coordDestination, true); } - return fSuccess; + return success; } // Routine Description: // ICH - Insert Character - Blank/default attribute characters will be inserted at the current cursor position. // - Each inserted character will push all text in the row to the right. // Arguments: -// - uiCount - The number of characters to insert +// - count - The number of characters to insert // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::InsertCharacter(_In_ unsigned int const uiCount) +bool AdaptDispatch::InsertCharacter(const size_t count) { - return _InsertDeleteHelper(uiCount, true); + return _InsertDeleteHelper(count, true); } // Routine Description: // DCH - Delete Character - The character at the cursor position will be deleted. Blank/attribute characters will // be inserted from the right edge of the current line. // Arguments: -// - uiCount - The number of characters to delete +// - count - The number of characters to delete // Return Value: // - True if handled successfuly. False otherwise. -bool AdaptDispatch::DeleteCharacter(_In_ unsigned int const uiCount) +bool AdaptDispatch::DeleteCharacter(const size_t count) { - return _InsertDeleteHelper(uiCount, false); + return _InsertDeleteHelper(count, false); } // Routine Description: // - Internal helper to erase one particular line of the buffer. Either from beginning to the cursor, from the cursor to the end, or the entire line. // - Used by both erase line (used just once) and by erase screen (used in a loop) to erase a portion of the buffer. // Arguments: -// - pcsbiex - Pointer to the console screen buffer that we will be erasing (and getting cursor data from within) -// - DispatchTypes::EraseType - Enumeration mode of which kind of erase to perform: beginning to cursor, cursor to end, or entire line. -// - sLineId - The line number (array index value, starts at 0) of the line to operate on within the buffer. +// - csbiex - Pointer to the console screen buffer that we will be erasing (and getting cursor data from within) +// - eraseType - Enumeration mode of which kind of erase to perform: beginning to cursor, cursor to end, or entire line. +// - lineId - The line number (array index value, starts at 0) of the line to operate on within the buffer. // - This is not aware of circular buffer. Line 0 is always the top visible line if you scrolled the whole way up the window. // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::_EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX* const pcsbiex, const DispatchTypes::EraseType eraseType, const SHORT sLineId) const +bool AdaptDispatch::_EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX& csbiex, + const DispatchTypes::EraseType eraseType, + const size_t lineId) const { COORD coordStartPosition = { 0 }; - coordStartPosition.Y = sLineId; + if (FAILED(SizeTToShort(lineId, &coordStartPosition.Y))) + { + return false; + } // determine start position from the erase type // remember that erases are inclusive of the current cursor position. @@ -608,7 +629,7 @@ bool AdaptDispatch::_EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX* c coordStartPosition.X = 0; // from beginning and the whole line start from the left most edge of the buffer. break; case DispatchTypes::EraseType::ToEnd: - coordStartPosition.X = pcsbiex->dwCursorPosition.X; // from the current cursor position (including it) + coordStartPosition.X = csbiex.dwCursorPosition.X; // from the current cursor position (including it) break; } @@ -619,17 +640,17 @@ bool AdaptDispatch::_EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX* c { case DispatchTypes::EraseType::FromBeginning: // +1 because if cursor were at the left edge, the length would be 0 and we want to paint at least the 1 character the cursor is on. - nLength = pcsbiex->dwCursorPosition.X + 1; + nLength = csbiex.dwCursorPosition.X + 1; break; case DispatchTypes::EraseType::ToEnd: case DispatchTypes::EraseType::All: // Remember the .X value is 1 farther than the right most column in the buffer. Therefore no +1. - nLength = pcsbiex->dwSize.X - coordStartPosition.X; + nLength = csbiex.dwSize.X - coordStartPosition.X; break; } // Note that the region is filled with the standard erase attributes. - return !!_conApi->PrivateFillRegion(coordStartPosition, nLength, L' ', true); + return _pConApi->PrivateFillRegion(coordStartPosition, nLength, L' ', true); } // Routine Description: @@ -638,34 +659,34 @@ bool AdaptDispatch::_EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX* c // and won't wrap to the next. The attributes of any erased positions // recieve the currently selected attributes. // Arguments: -// - uiNumChars - The number of characters to erase. +// - numChars - The number of characters to erase. // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::EraseCharacters(_In_ unsigned int const uiNumChars) +bool AdaptDispatch::EraseCharacters(const size_t numChars) { CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); - bool fSuccess = !!_conApi->GetConsoleScreenBufferInfoEx(&csbiex); + bool success = _pConApi->GetConsoleScreenBufferInfoEx(csbiex); - if (fSuccess) + if (success) { - const COORD coordStartPosition = csbiex.dwCursorPosition; + const COORD startPosition = csbiex.dwCursorPosition; - const SHORT sRemainingSpaces = csbiex.dwSize.X - coordStartPosition.X; - const unsigned short usActualRemaining = (sRemainingSpaces < 0) ? 0 : sRemainingSpaces; + const size_t remainingSpaces = csbiex.dwSize.X - startPosition.X; + const auto actualRemaining = (remainingSpaces < 0) ? 0 : remainingSpaces; // erase at max the number of characters remaining in the line from the current position. - const DWORD dwEraseLength = (uiNumChars <= usActualRemaining) ? uiNumChars : usActualRemaining; + const auto eraseLength = (numChars <= actualRemaining) ? numChars : actualRemaining; // Note that the region is filled with the standard erase attributes. - fSuccess = !!_conApi->PrivateFillRegion(coordStartPosition, dwEraseLength, L' ', true); + success = _pConApi->PrivateFillRegion(startPosition, eraseLength, L' ', true); } - return fSuccess; + return success; } // Routine Description: // - ED - Erases a portion of the current viewable area (viewport) of the console. // Arguments: -// - DispatchTypes::EraseType - Determines whether to erase: +// - eraseType - Determines whether to erase: // From beginning (top-left corner) to the cursor // From cursor to end (bottom-right corner) // The entire viewport area @@ -692,9 +713,9 @@ bool AdaptDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType) csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - bool fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + bool success = (_pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex)); - if (fSuccess) + if (success) { // What we need to erase is grouped into 3 types: // 1. Lines before cursor @@ -709,35 +730,35 @@ bool AdaptDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType) if (eraseType == DispatchTypes::EraseType::FromBeginning) { // For beginning and all, erase all complete lines before (above vertically) from the cursor position. - for (SHORT sStartLine = csbiex.srWindow.Top; sStartLine < csbiex.dwCursorPosition.Y; sStartLine++) + for (SHORT startLine = csbiex.srWindow.Top; startLine < csbiex.dwCursorPosition.Y; startLine++) { - fSuccess = _EraseSingleLineHelper(&csbiex, DispatchTypes::EraseType::All, sStartLine); + success = _EraseSingleLineHelper(csbiex, DispatchTypes::EraseType::All, startLine); - if (!fSuccess) + if (!success) { break; } } } - if (fSuccess) + if (success) { // 2. Cursor Line - fSuccess = _EraseSingleLineHelper(&csbiex, eraseType, csbiex.dwCursorPosition.Y); + success = _EraseSingleLineHelper(csbiex, eraseType, csbiex.dwCursorPosition.Y); } - if (fSuccess) + if (success) { // 3. Lines after cursor line if (eraseType == DispatchTypes::EraseType::ToEnd) { // For beginning and all, erase all complete lines after (below vertically) the cursor position. // Remember that the viewport bottom value is 1 beyond the viewable area of the viewport. - for (SHORT sStartLine = csbiex.dwCursorPosition.Y + 1; sStartLine < csbiex.srWindow.Bottom; sStartLine++) + for (SHORT startLine = csbiex.dwCursorPosition.Y + 1; startLine < csbiex.srWindow.Bottom; startLine++) { - fSuccess = _EraseSingleLineHelper(&csbiex, DispatchTypes::EraseType::All, sStartLine); + success = _EraseSingleLineHelper(csbiex, DispatchTypes::EraseType::All, startLine); - if (!fSuccess) + if (!success) { break; } @@ -746,27 +767,27 @@ bool AdaptDispatch::EraseInDisplay(const DispatchTypes::EraseType eraseType) } } - return fSuccess; + return success; } // Routine Description: // - EL - Erases the line that the cursor is currently on. // Arguments: -// - DispatchTypes::EraseType - Determines whether to erase: From beginning (left edge) to the cursor, from cursor to end (right edge), or the entire line. +// - eraseType - Determines whether to erase: From beginning (left edge) to the cursor, from cursor to end (right edge), or the entire line. // Return Value: // - True if handled successfully. False otherwise. bool AdaptDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) { CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); - bool fSuccess = !!_conApi->GetConsoleScreenBufferInfoEx(&csbiex); + bool success = _pConApi->GetConsoleScreenBufferInfoEx(csbiex); - if (fSuccess) + if (success) { - fSuccess = _EraseSingleLineHelper(&csbiex, eraseType, csbiex.dwCursorPosition.Y); + success = _EraseSingleLineHelper(csbiex, eraseType, csbiex.dwCursorPosition.Y); } - return fSuccess; + return success; } // Routine Description: @@ -778,16 +799,16 @@ bool AdaptDispatch::EraseInLine(const DispatchTypes::EraseType eraseType) // - True if handled successfully. False otherwise. bool AdaptDispatch::DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType) { - bool fSuccess = false; + bool success = false; switch (statusType) { case DispatchTypes::AnsiStatusType::CPR_CursorPositionReport: - fSuccess = _CursorPositionReport(); + success = _CursorPositionReport(); break; } - return fSuccess; + return success; } // Routine Description: @@ -800,9 +821,7 @@ bool AdaptDispatch::DeviceStatusReport(const DispatchTypes::AnsiStatusType statu bool AdaptDispatch::DeviceAttributes() { // See: http://vt100.net/docs/vt100-ug/chapter3.html#DA - wchar_t* const pwszResponse = L"\x1b[?1;0c"; - - return _WriteResponse(pwszResponse, wcslen(pwszResponse)); + return _WriteResponse(L"\x1b[?1;0c"); } // Routine Description: @@ -817,9 +836,9 @@ bool AdaptDispatch::_CursorPositionReport() const csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - bool fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + bool success = (_pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex)); - if (fSuccess) + if (success) { // First pull the cursor position relative to the entire buffer out of the console. COORD coordCursorPos = csbiex.dwCursorPosition; @@ -833,22 +852,18 @@ bool AdaptDispatch::_CursorPositionReport() const coordCursorPos.Y++; // If the origin mode is relative, line numbers start at top margin of the scrolling region. - if (_fIsOriginModeRelative) + if (_isOriginModeRelative) { - coordCursorPos.Y -= _srScrollMargins.Top; + coordCursorPos.Y -= _scrollMargins.Top; } // Now send it back into the input channel of the console. // First format the response string. - wchar_t pwszResponseBuffer[50]; - swprintf_s(pwszResponseBuffer, ARRAYSIZE(pwszResponseBuffer), L"\x1b[%d;%dR", coordCursorPos.Y, coordCursorPos.X); - - size_t const cBuffer = wcslen(pwszResponseBuffer); - - fSuccess = _WriteResponse(pwszResponseBuffer, cBuffer); + const auto response = wil::str_printf(L"\x1b[%d;%dR", coordCursorPos.Y, coordCursorPos.X); + success = _WriteResponse(response); } - return fSuccess; + return success; } // Routine Description: @@ -856,22 +871,21 @@ bool AdaptDispatch::_CursorPositionReport() const // - Used by various commands where the program attached would like a reply to one of the commands issued. // - This will generate two "key presses" (one down, one up) for every character in the string and place them into the head of the console's input stream. // Arguments: -// - pwszReply - The reply string to transmit back to the input stream -// - cReply - The length of the string. +// - reply - The reply string to transmit back to the input stream // Return Value: // - True if the string was converted to input events and placed into the console input buffer successfuly. False otherwise. -bool AdaptDispatch::_WriteResponse(_In_reads_(cchReply) PCWSTR pwszReply, const size_t cchReply) const +bool AdaptDispatch::_WriteResponse(const std::wstring_view reply) const { - bool fSuccess = false; + bool success = false; std::deque> inEvents; try { // generate a paired key down and key up event for every // character to be sent into the console's input buffer - for (size_t i = 0; i < cchReply; ++i) + for (const auto& wch : reply) { // This wasn't from a real keyboard, so we're leaving key/scan codes blank. - KeyEvent keyEvent{ TRUE, 1, 0, 0, pwszReply[i], 0 }; + KeyEvent keyEvent{ TRUE, 1, 0, 0, wch, 0 }; inEvents.push_back(std::make_unique(keyEvent)); keyEvent.SetKeyDown(false); @@ -885,34 +899,34 @@ bool AdaptDispatch::_WriteResponse(_In_reads_(cchReply) PCWSTR pwszReply, const } size_t eventsWritten; - fSuccess = !!_conApi->PrivatePrependConsoleInput(inEvents, eventsWritten); + success = _pConApi->PrivatePrependConsoleInput(inEvents, eventsWritten); - return fSuccess; + return success; } // Routine Description: // - Generalizes scrolling movement for up/down // Arguments: -// - sdDirection - Specific direction to move -// - uiDistance - Magnitude of the move +// - scrollDirection - Specific direction to move +// - distance - Magnitude of the move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::_ScrollMovement(const ScrollDirection sdDirection, _In_ unsigned int const uiDistance) const +bool AdaptDispatch::_ScrollMovement(const ScrollDirection scrollDirection, const size_t distance) const { - // We'll be doing short math on the distance since all console APIs use shorts. So check that we can successfully convert the uint into a short first. - SHORT sDistance; - bool fSuccess = SUCCEEDED(UIntToShort(uiDistance, &sDistance)); + // We'll be doing short math on the distance since all console APIs use shorts. So check that we can successfully convert the size_t into a short first. + SHORT dist; + bool success = SUCCEEDED(SizeTToShort(distance, &dist)); - if (fSuccess) + if (success) { // get current cursor CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + success = (_pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex)); - if (fSuccess) + if (success) { // Rectangle to cut out of the existing buffer. This is inclusive. // It will be clipped to the buffer boundaries so SHORT_MAX gives us the full buffer width. @@ -922,43 +936,43 @@ bool AdaptDispatch::_ScrollMovement(const ScrollDirection sdDirection, _In_ unsi srScreen.Top = csbiex.srWindow.Top; srScreen.Bottom = csbiex.srWindow.Bottom - 1; // srWindow is exclusive, hence the - 1 // Clip to the DECSTBM margin boundaries - if (_srScrollMargins.Top < _srScrollMargins.Bottom) + if (_scrollMargins.Top < _scrollMargins.Bottom) { - srScreen.Top = csbiex.srWindow.Top + _srScrollMargins.Top; - srScreen.Bottom = csbiex.srWindow.Top + _srScrollMargins.Bottom; + srScreen.Top = csbiex.srWindow.Top + _scrollMargins.Top; + srScreen.Bottom = csbiex.srWindow.Top + _scrollMargins.Bottom; } // Paste coordinate for cut text above COORD coordDestination; coordDestination.X = srScreen.Left; - coordDestination.Y = srScreen.Top + sDistance * (sdDirection == ScrollDirection::Up ? -1 : 1); + coordDestination.Y = srScreen.Top + dist * (scrollDirection == ScrollDirection::Up ? -1 : 1); // Note the revealed lines are filled with the standard erase attributes. - fSuccess = !!_conApi->PrivateScrollRegion(srScreen, srScreen, coordDestination, true); + success = _pConApi->PrivateScrollRegion(srScreen, srScreen, coordDestination, true); } } - return fSuccess; + return success; } // Routine Description: -// - SU - Pans the window DOWN by given distance (uiDistance new lines appear at the bottom of the screen) +// - SU - Pans the window DOWN by given distance (distance new lines appear at the bottom of the screen) // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::ScrollUp(_In_ unsigned int const uiDistance) +bool AdaptDispatch::ScrollUp(const size_t uiDistance) { return _ScrollMovement(ScrollDirection::Up, uiDistance); } // Routine Description: -// - SD - Pans the window UP by given distance (uiDistance new lines appear at the top of the screen) +// - SD - Pans the window UP by given distance (distance new lines appear at the top of the screen) // Arguments: -// - uiDistance - Distance to move +// - distance - Distance to move // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::ScrollDown(_In_ unsigned int const uiDistance) +bool AdaptDispatch::ScrollDown(const size_t uiDistance) { return _ScrollMovement(ScrollDirection::Down, uiDistance); } @@ -968,115 +982,122 @@ bool AdaptDispatch::ScrollDown(_In_ unsigned int const uiDistance) // DECCOLM also clear the screen (like a CSI 2 J sequence), while DECSCPP just sets the width. // (DECCOLM will do this seperately of this function) // Arguments: -// - uiColumns - Number of columns +// - columns - Number of columns // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::SetColumns(_In_ unsigned int const uiColumns) +bool AdaptDispatch::SetColumns(const size_t columns) { - SHORT sColumns; - bool fSuccess = SUCCEEDED(UIntToShort(uiColumns, &sColumns)); - if (fSuccess) + SHORT col; + bool success = SUCCEEDED(SizeTToShort(columns, &col)); + if (success) { CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); - fSuccess = !!_conApi->GetConsoleScreenBufferInfoEx(&csbiex); + success = _pConApi->GetConsoleScreenBufferInfoEx(csbiex); - if (fSuccess) + if (success) { - csbiex.dwSize.X = sColumns; - fSuccess = !!_conApi->SetConsoleScreenBufferInfoEx(&csbiex); + csbiex.dwSize.X = col; + success = _pConApi->SetConsoleScreenBufferInfoEx(csbiex); } } - return fSuccess; + return success; } // Routine Description: // - DECCOLM not only sets the number of columns, but also clears the screen buffer, // resets the page margins and origin mode, and places the cursor at 1,1 // Arguments: -// - uiColumns - Number of columns +// - columns - Number of columns // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::_DoDECCOLMHelper(_In_ unsigned int const uiColumns) +bool AdaptDispatch::_DoDECCOLMHelper(const size_t columns) { - if (!_fIsDECCOLMAllowed) + if (!_isDECCOLMAllowed) { // Only proceed if DECCOLM is allowed. Return true, as this is technically a successful handling. return true; } - bool fSuccess = SetColumns(uiColumns); - if (fSuccess) + bool success = SetColumns(columns); + if (success) { - fSuccess = SetOriginMode(false); - if (fSuccess) + success = SetOriginMode(false); + if (success) { - fSuccess = CursorPosition(1, 1); - if (fSuccess) + success = CursorPosition(1, 1); + if (success) { - fSuccess = EraseInDisplay(DispatchTypes::EraseType::All); - if (fSuccess) + success = EraseInDisplay(DispatchTypes::EraseType::All); + if (success) { - fSuccess = _DoSetTopBottomScrollingMargins(0, 0); + success = _DoSetTopBottomScrollingMargins(0, 0); } } } } - return fSuccess; + return success; } -bool AdaptDispatch::_PrivateModeParamsHelper(_In_ DispatchTypes::PrivateModeParams const param, const bool fEnable) +// Routine Description: +// - Support routine for routing private mode parameters to be set/reset as flags +// Arguments: +// - params - array of params to set/reset +// - enable - True for set, false for unset. +// Return Value: +// - True if handled successfully. False otherwise. +bool AdaptDispatch::_PrivateModeParamsHelper(const DispatchTypes::PrivateModeParams param, const bool enable) { - bool fSuccess = false; + bool success = false; switch (param) { case DispatchTypes::PrivateModeParams::DECCKM_CursorKeysMode: // set - Enable Application Mode, reset - Normal mode - fSuccess = SetCursorKeysMode(fEnable); + success = SetCursorKeysMode(enable); break; case DispatchTypes::PrivateModeParams::DECCOLM_SetNumberOfColumns: - fSuccess = _DoDECCOLMHelper(fEnable ? DispatchTypes::s_sDECCOLMSetColumns : DispatchTypes::s_sDECCOLMResetColumns); + success = _DoDECCOLMHelper(enable ? DispatchTypes::s_sDECCOLMSetColumns : DispatchTypes::s_sDECCOLMResetColumns); break; case DispatchTypes::PrivateModeParams::DECOM_OriginMode: // The cursor is also moved to the new home position when the origin mode is set or reset. - fSuccess = SetOriginMode(fEnable) && CursorPosition(1, 1); + success = SetOriginMode(enable) && CursorPosition(1, 1); break; case DispatchTypes::PrivateModeParams::ATT610_StartCursorBlink: - fSuccess = EnableCursorBlinking(fEnable); + success = EnableCursorBlinking(enable); break; case DispatchTypes::PrivateModeParams::DECTCEM_TextCursorEnableMode: - fSuccess = CursorVisibility(fEnable); + success = CursorVisibility(enable); break; case DispatchTypes::PrivateModeParams::XTERM_EnableDECCOLMSupport: - fSuccess = EnableDECCOLMSupport(fEnable); + success = EnableDECCOLMSupport(enable); break; case DispatchTypes::PrivateModeParams::VT200_MOUSE_MODE: - fSuccess = EnableVT200MouseMode(fEnable); + success = EnableVT200MouseMode(enable); break; case DispatchTypes::PrivateModeParams::BUTTTON_EVENT_MOUSE_MODE: - fSuccess = EnableButtonEventMouseMode(fEnable); + success = EnableButtonEventMouseMode(enable); break; case DispatchTypes::PrivateModeParams::ANY_EVENT_MOUSE_MODE: - fSuccess = EnableAnyEventMouseMode(fEnable); + success = EnableAnyEventMouseMode(enable); break; case DispatchTypes::PrivateModeParams::UTF8_EXTENDED_MODE: - fSuccess = EnableUTF8ExtendedMouseMode(fEnable); + success = EnableUTF8ExtendedMouseMode(enable); break; case DispatchTypes::PrivateModeParams::SGR_EXTENDED_MODE: - fSuccess = EnableSGRExtendedMouseMode(fEnable); + success = EnableSGRExtendedMouseMode(enable); break; case DispatchTypes::PrivateModeParams::ALTERNATE_SCROLL: - fSuccess = EnableAlternateScroll(fEnable); + success = EnableAlternateScroll(enable); break; case DispatchTypes::PrivateModeParams::ASB_AlternateScreenBuffer: - fSuccess = fEnable ? UseAlternateScreenBuffer() : UseMainScreenBuffer(); + success = enable ? UseAlternateScreenBuffer() : UseMainScreenBuffer(); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } - return fSuccess; + return success; } // Routine Description: @@ -1085,74 +1106,72 @@ bool AdaptDispatch::_PrivateModeParamsHelper(_In_ DispatchTypes::PrivateModePara // fails, to allow us to successfully re/set params that are chained with // params we don't yet support. // Arguments: -// - rgParams - array of params to set/reset -// - cParams - length of rgParams +// - params - array of params to set/reset +// - enable - True for set, false for unset. // Return Value: // - True if ALL params were handled successfully. False otherwise. -bool AdaptDispatch::_SetResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rgParams, const size_t cParams, const bool fEnable) +bool AdaptDispatch::_SetResetPrivateModes(const std::basic_string_view params, const bool enable) { // because the user might chain together params we don't support with params we DO support, execute all // params in the sequence, and only return failure if we failed at least one of them - size_t cFailures = 0; - for (size_t i = 0; i < cParams; i++) + size_t failures = 0; + for (const auto& p : params) { - cFailures += _PrivateModeParamsHelper(rgParams[i], fEnable) ? 0 : 1; // increment the number of failures if we fail. + failures += _PrivateModeParamsHelper(p, enable) ? 0 : 1; // increment the number of failures if we fail. } - return cFailures == 0; + return failures == 0; } // Routine Description: // - DECSET - Enables the given DEC private mode params. // Arguments: -// - rgParams - array of params to set -// - cParams - length of rgParams +// - params - array of params to set // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::SetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rgParams, const size_t cParams) +bool AdaptDispatch::SetPrivateModes(const std::basic_string_view params) { - return _SetResetPrivateModes(rgParams, cParams, true); + return _SetResetPrivateModes(params, true); } // Routine Description: // - DECRST - Disables the given DEC private mode params. // Arguments: -// - rgParams - array of params to reset -// - cParams - length of rgParams +// - params - array of params to reset // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::ResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rgParams, const size_t cParams) +bool AdaptDispatch::ResetPrivateModes(const std::basic_string_view params) { - return _SetResetPrivateModes(rgParams, cParams, false); + return _SetResetPrivateModes(params, false); } // - DECKPAM, DECKPNM - Sets the keypad input mode to either Application mode or Numeric mode (true, false respectively) // Arguments: -// - fApplicationMode - set to true to enable Application Mode Input, false for Numeric Mode Input. +// - applicationMode - set to true to enable Application Mode Input, false for Numeric Mode Input. // Return Value: // - True if handled successfully. False otherwise. bool AdaptDispatch::SetKeypadMode(const bool fApplicationMode) { - return !!_conApi->PrivateSetKeypadMode(fApplicationMode); + return _pConApi->PrivateSetKeypadMode(fApplicationMode); } // - DECCKM - Sets the cursor keys input mode to either Application mode or Normal mode (true, false respectively) // Arguments: -// - fApplicationMode - set to true to enable Application Mode Input, false for Normal Mode Input. +// - applicationMode - set to true to enable Application Mode Input, false for Normal Mode Input. // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::SetCursorKeysMode(const bool fApplicationMode) +bool AdaptDispatch::SetCursorKeysMode(const bool applicationMode) { - return !!_conApi->PrivateSetCursorKeysMode(fApplicationMode); + return _pConApi->PrivateSetCursorKeysMode(applicationMode); } // - att610 - Enables or disables the cursor blinking. // Arguments: -// - fEnable - set to true to enable blinking, false to disable +// - enable - set to true to enable blinking, false to disable // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::EnableCursorBlinking(const bool fEnable) +bool AdaptDispatch::EnableCursorBlinking(const bool enable) { - return !!_conApi->PrivateAllowCursorBlinking(fEnable); + return _pConApi->PrivateAllowCursorBlinking(enable); } // Routine Description: @@ -1160,12 +1179,12 @@ bool AdaptDispatch::EnableCursorBlinking(const bool fEnable) // As lines are inserted, lines below the cursor and in the scrolling region move down. // Lines scrolled off the page are lost. IL has no effect outside the page margins. // Arguments: -// - uiDistance - number of lines to insert +// - distance - number of lines to insert // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::InsertLine(_In_ unsigned int const uiDistance) +bool AdaptDispatch::InsertLine(const size_t distance) { - return !!_conApi->InsertLines(uiDistance); + return _pConApi->InsertLines(distance); } // Routine Description: @@ -1173,16 +1192,16 @@ bool AdaptDispatch::InsertLine(_In_ unsigned int const uiDistance) // region, starting with the line that has the cursor. // As lines are deleted, lines below the cursor and in the scrolling region // move up. The terminal adds blank lines with no visual character -// attributes at the bottom of the scrolling region. If uiDistance is greater than +// attributes at the bottom of the scrolling region. If distance is greater than // the number of lines remaining on the page, DL deletes only the remaining // lines. DL has no effect outside the scrolling margins. // Arguments: -// - uiDistance - number of lines to delete +// - distance - number of lines to delete // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::DeleteLine(_In_ unsigned int const uiDistance) +bool AdaptDispatch::DeleteLine(const size_t distance) { - return !!_conApi->DeleteLines(uiDistance); + return _pConApi->DeleteLines(distance); } // Routine Description: @@ -1190,12 +1209,12 @@ bool AdaptDispatch::DeleteLine(_In_ unsigned int const uiDistance) // When relative, line numbers start at top margin of the user-defined scrolling region. // When absolute, line numbers are independent of the scrolling region. // Arguments: -// - fRelativeMode - set to true to use relative addressing, false for absolute addressing. +// - relativeMode - set to true to use relative addressing, false for absolute addressing. // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::SetOriginMode(const bool fRelativeMode) +bool AdaptDispatch::SetOriginMode(const bool relativeMode) { - _fIsOriginModeRelative = fRelativeMode; + _isOriginModeRelative = relativeMode; return true; } @@ -1205,65 +1224,69 @@ bool AdaptDispatch::SetOriginMode(const bool fRelativeMode) // You cannot perform scrolling outside the margins. // Default: Margins are at the page limits. // Arguments: -// - sTopMargin - the line number for the top margin. -// - sBottomMargin - the line number for the bottom margin. +// - topMargin - the line number for the top margin. +// - bottomMargin - the line number for the bottom margin. // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::_DoSetTopBottomScrollingMargins(const SHORT sTopMargin, - const SHORT sBottomMargin) +bool AdaptDispatch::_DoSetTopBottomScrollingMargins(const size_t topMargin, + const size_t bottomMargin) { CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - bool fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + bool success = (_pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex)); // so notes time: (input -> state machine out -> adapter out -> conhost internal) // having only a top param is legal ([3;r -> 3,0 -> 3,h -> 3,h,true) // having only a bottom param is legal ([;3r -> 0,3 -> 1,3 -> 1,3,true) // having neither uses the defaults ([;r [r -> 0,0 -> 0,0 -> 0,0,false) // an illegal combo (eg, 3;2r) is ignored - if (fSuccess) + if (success) { - SHORT sActualTop = sTopMargin; - SHORT sActualBottom = sBottomMargin; - SHORT sScreenHeight = csbiex.srWindow.Bottom - csbiex.srWindow.Top; - // The default top margin is line 1 - if (sActualTop == 0) + SHORT actualTop = 0; + SHORT actualBottom = 0; + success = SUCCEEDED(SizeTToShort(topMargin, &actualTop)) && SUCCEEDED(SizeTToShort(bottomMargin, &actualBottom)); + if (success) { - sActualTop = 1; - } - // The default bottom margin is the screen height - if (sActualBottom == 0) - { - sActualBottom = sScreenHeight; - } - // The top margin must be less than the bottom margin, and the - // bottom margin must be less than or equal to the screen height - fSuccess = (sActualTop < sActualBottom && sActualBottom <= sScreenHeight); - if (fSuccess) - { - if (sActualTop == 1 && sActualBottom == sScreenHeight) + SHORT screenHeight = csbiex.srWindow.Bottom - csbiex.srWindow.Top; + // The default top margin is line 1 + if (actualTop == 0) { - // Client requests setting margins to the entire screen - // - clear them instead of setting them. - // This is for apps like `apt` (NOT `apt-get` which set scroll - // margins, but don't use the alt buffer.) - sActualTop = 0; - sActualBottom = 0; + actualTop = 1; } - else + // The default bottom margin is the screen height + if (actualBottom == 0) { - // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1. - sActualTop -= 1; - sActualBottom -= 1; + actualBottom = screenHeight; + } + // The top margin must be less than the bottom margin, and the + // bottom margin must be less than or equal to the screen height + success = (actualTop < actualBottom && actualBottom <= screenHeight); + if (success) + { + if (actualTop == 1 && actualBottom == screenHeight) + { + // Client requests setting margins to the entire screen + // - clear them instead of setting them. + // This is for apps like `apt` (NOT `apt-get` which set scroll + // margins, but don't use the alt buffer.) + actualTop = 0; + actualBottom = 0; + } + else + { + // In VT, the origin is 1,1. For our array, it's 0,0. So subtract 1. + actualTop -= 1; + actualBottom -= 1; + } + _scrollMargins.Top = actualTop; + _scrollMargins.Bottom = actualBottom; + success = _pConApi->PrivateSetScrollingRegion(_scrollMargins); } - _srScrollMargins.Top = sActualTop; - _srScrollMargins.Bottom = sActualBottom; - fSuccess = !!_conApi->PrivateSetScrollingRegion(&_srScrollMargins); } } - return fSuccess; + return success; } // Routine Description: @@ -1272,16 +1295,16 @@ bool AdaptDispatch::_DoSetTopBottomScrollingMargins(const SHORT sTopMargin, // You cannot perform scrolling outside the margins. // Default: Margins are at the page limits. // Arguments: -// - sTopMargin - the line number for the top margin. -// - sBottomMargin - the line number for the bottom margin. +// - topMargin - the line number for the top margin. +// - bottomMargin - the line number for the bottom margin. // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::SetTopBottomScrollingMargins(const SHORT sTopMargin, - const SHORT sBottomMargin) +bool AdaptDispatch::SetTopBottomScrollingMargins(const size_t topMargin, + const size_t bottomMargin) { // When this is called, the cursor should also be moved to home. // Other functions that only need to set/reset the margins should call _DoSetTopBottomScrollingMargins - return _DoSetTopBottomScrollingMargins(sTopMargin, sBottomMargin) && CursorPosition(1, 1); + return _DoSetTopBottomScrollingMargins(topMargin, bottomMargin) && CursorPosition(1, 1); } // Routine Description: @@ -1293,7 +1316,7 @@ bool AdaptDispatch::SetTopBottomScrollingMargins(const SHORT sTopMargin, // - True if handled successfully. False otherwise. bool AdaptDispatch::ReverseLineFeed() { - return !!_conApi->PrivateReverseLineFeed(); + return _pConApi->PrivateReverseLineFeed(); } // Routine Description: @@ -1304,7 +1327,7 @@ bool AdaptDispatch::ReverseLineFeed() // - True if handled successfully. False otherwise. bool AdaptDispatch::SetWindowTitle(std::wstring_view title) { - return !!_conApi->SetConsoleTitleW(title); + return _pConApi->SetConsoleTitleW(title); } // - ASBSET - Creates and swaps to the alternate screen buffer. In virtual terminals, there exists both a "main" @@ -1316,16 +1339,16 @@ bool AdaptDispatch::SetWindowTitle(std::wstring_view title) // - True if handled successfully. False otherwise. bool AdaptDispatch::UseAlternateScreenBuffer() { - bool fSuccess = CursorSaveState(); - if (fSuccess) + bool success = CursorSaveState(); + if (success) { - fSuccess = !!_conApi->PrivateUseAlternateScreenBuffer(); - if (fSuccess) + success = _pConApi->PrivateUseAlternateScreenBuffer(); + if (success) { _usingAltBuffer = true; } } - return fSuccess; + return success; } // Routine Description: @@ -1337,16 +1360,16 @@ bool AdaptDispatch::UseAlternateScreenBuffer() // - True if handled successfully. False otherwise. bool AdaptDispatch::UseMainScreenBuffer() { - bool fSuccess = !!_conApi->PrivateUseMainScreenBuffer(); - if (fSuccess) + bool success = _pConApi->PrivateUseMainScreenBuffer(); + if (success) { _usingAltBuffer = false; - if (fSuccess) + if (success) { - fSuccess = CursorRestoreState(); + success = CursorRestoreState(); } } - return fSuccess; + return success; } //Routine Description: @@ -1357,7 +1380,7 @@ bool AdaptDispatch::UseMainScreenBuffer() // True if handled successfully. False otherwise. bool AdaptDispatch::HorizontalTabSet() { - return !!_conApi->PrivateHorizontalTabSet(); + return _pConApi->PrivateHorizontalTabSet(); } //Routine Description: @@ -1366,24 +1389,24 @@ bool AdaptDispatch::HorizontalTabSet() // more tabs in this row, it will take it to the right side of the window. // If it's already in the last column of the row, it will move it to the next line. //Arguments: -// - sNumTabs - the number of tabs to perform +// - numTabs - the number of tabs to perform // Return value: // True if handled successfully. False otherwise. -bool AdaptDispatch::ForwardTab(const SHORT sNumTabs) +bool AdaptDispatch::ForwardTab(const size_t numTabs) { - return !!_conApi->PrivateForwardTab(sNumTabs); + return _pConApi->PrivateForwardTab(numTabs); } //Routine Description: // CBT - performing a backwards tab. This will take the cursor to the tab stop // previous to its current location. It will not reverse line feed. //Arguments: -// - sNumTabs - the number of tabs to perform +// - numTabs - the number of tabs to perform // Return value: // True if handled successfully. False otherwise. -bool AdaptDispatch::BackwardsTab(const SHORT sNumTabs) +bool AdaptDispatch::BackwardsTab(const size_t numTabs) { - return !!_conApi->PrivateBackwardsTab(sNumTabs); + return _pConApi->PrivateBackwardsTab(numTabs); } //Routine Description: @@ -1391,22 +1414,22 @@ bool AdaptDispatch::BackwardsTab(const SHORT sNumTabs) // in clearing only the tab stop in the cursor's current column, if there // is one. ClearAllColumns (3) results in resetting all set tab stops. //Arguments: -// - sClearType - Whether to clear the current column, or all columns, defined in DispatchTypes::TabClearType +// - clearType - Whether to clear the current column, or all columns, defined in DispatchTypes::TabClearType // Return value: // True if handled successfully. False otherwise. -bool AdaptDispatch::TabClear(const SHORT sClearType) +bool AdaptDispatch::TabClear(const size_t clearType) { - bool fSuccess = false; - switch (sClearType) + bool success = false; + switch (clearType) { case DispatchTypes::TabClearType::ClearCurrentColumn: - fSuccess = !!_conApi->PrivateTabClear(false); + success = _pConApi->PrivateTabClear(false); break; case DispatchTypes::TabClearType::ClearAllColumns: - fSuccess = !!_conApi->PrivateTabClear(true); + success = _pConApi->PrivateTabClear(true); break; } - return fSuccess; + return success; } //Routine Description: @@ -1421,7 +1444,7 @@ bool AdaptDispatch::TabClear(const SHORT sClearType) // True if handled successfully. False otherwise. bool AdaptDispatch::DesignateCharset(const wchar_t wchCharset) { - return _TermOutput.DesignateCharset(wchCharset); + return _termOutput.DesignateCharset(wchCharset); } //Routine Description: @@ -1457,43 +1480,43 @@ bool AdaptDispatch::DesignateCharset(const wchar_t wchCharset) // True if handled successfully. False otherwise. bool AdaptDispatch::SoftReset() { - bool fSuccess = CursorVisibility(true); // Cursor enabled. - if (fSuccess) + bool success = CursorVisibility(true); // Cursor enabled. + if (success) { - fSuccess = SetOriginMode(false); // Absolute cursor addressing. + success = SetOriginMode(false); // Absolute cursor addressing. } - if (fSuccess) + if (success) { - fSuccess = SetCursorKeysMode(false); // Normal characters. + success = SetCursorKeysMode(false); // Normal characters. } - if (fSuccess) + if (success) { - fSuccess = SetKeypadMode(false); // Numeric characters. + success = SetKeypadMode(false); // Numeric characters. } - if (fSuccess) + if (success) { // Top margin = 1; bottom margin = page length. - fSuccess = _DoSetTopBottomScrollingMargins(0, 0); + success = _DoSetTopBottomScrollingMargins(0, 0); } - if (fSuccess) + if (success) { - fSuccess = DesignateCharset(DispatchTypes::VTCharacterSets::USASCII); // Default Charset + success = DesignateCharset(DispatchTypes::VTCharacterSets::USASCII); // Default Charset } - if (fSuccess) + if (success) { DispatchTypes::GraphicsOptions opt = DispatchTypes::GraphicsOptions::Off; - fSuccess = SetGraphicsRendition(&opt, 1); // Normal rendition. + success = SetGraphicsRendition({ &opt, 1 }); // Normal rendition. } - if (fSuccess) + if (success) { // Reset the saved cursor state. // Note that XTerm only resets the main buffer state, but that // seems likely to be a bug. Most other terminals reset both. - _savedCursorState[0] = {}; // Main buffer - _savedCursorState[1] = {}; // Alt buffer + _savedCursorState.at(0) = {}; // Main buffer + _savedCursorState.at(1) = {}; // Alt buffer } - return fSuccess; + return success; } //Routine Description: @@ -1519,28 +1542,28 @@ bool AdaptDispatch::HardReset() { // Sets the SGR state to normal - this must be done before EraseInDisplay // to ensure that it clears with the default background color. - bool fSuccess = SoftReset(); + bool success = SoftReset(); // Clears the screen - Needs to be done in two operations. - if (fSuccess) + if (success) { - fSuccess = EraseInDisplay(DispatchTypes::EraseType::All); + success = EraseInDisplay(DispatchTypes::EraseType::All); } - if (fSuccess) + if (success) { - fSuccess = _EraseScrollback(); + success = _EraseScrollback(); } // Cursor to 1,1 - the Soft Reset guarantees this is absolute - if (fSuccess) + if (success) { - fSuccess = CursorPosition(1, 1); + success = CursorPosition(1, 1); } // delete all current tab stops and reapply - _conApi->PrivateSetDefaultTabStops(); + _pConApi->PrivateSetDefaultTabStops(); - return fSuccess; + return success; } // Routine Description: @@ -1557,96 +1580,96 @@ bool AdaptDispatch::ScreenAlignmentPattern() csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - bool fSuccess = !!(_conApi->MoveToBottom() && _conApi->GetConsoleScreenBufferInfoEx(&csbiex)); + bool success = _pConApi->MoveToBottom() && _pConApi->GetConsoleScreenBufferInfoEx(csbiex); - if (fSuccess) + if (success) { // Fill the screen with the letter E using the default attributes. auto fillPosition = COORD{ 0, csbiex.srWindow.Top }; auto fillLength = (csbiex.srWindow.Bottom - csbiex.srWindow.Top) * csbiex.dwSize.X; - fSuccess = _conApi->PrivateFillRegion(fillPosition, fillLength, L'E', false); + success = _pConApi->PrivateFillRegion(fillPosition, fillLength, L'E', false); // Reset the meta/extended attributes (but leave the colors unchanged). - fSuccess = fSuccess && _conApi->PrivateSetLegacyAttributes(0, false, false, true); - fSuccess = fSuccess && _conApi->PrivateSetExtendedTextAttributes(ExtendedAttributes::Normal); + success = success && _pConApi->PrivateSetLegacyAttributes(0, false, false, true); + success = success && _pConApi->PrivateSetExtendedTextAttributes(ExtendedAttributes::Normal); // Reset the origin mode to absolute. - fSuccess = fSuccess && SetOriginMode(false); + success = success && SetOriginMode(false); // Clear the scrolling margins. - fSuccess = fSuccess && _DoSetTopBottomScrollingMargins(0, 0); + success = success && _DoSetTopBottomScrollingMargins(0, 0); // Set the cursor position to home. - fSuccess = fSuccess && CursorPosition(1, 1); + success = success && CursorPosition(1, 1); } - return fSuccess; + return success; } //Routine Description: -// Erase Scrollback (^[[3J - ED extension by xterm) -// Because conhost doesn't exactly have a scrollback, We have to be tricky here. -// We need to move the entire viewport to 0,0, and clear everything outside +// - Erase Scrollback (^[[3J - ED extension by xterm) +// Because conhost doesn't exactly have a scrollback, We have to be tricky here. +// We need to move the entire viewport to 0,0, and clear everything outside // (0, 0, viewportWidth, viewportHeight) To give the appearance that // everything above the viewport was cleared. -// We don't want to save the text BELOW the viewport, because in *nix, there isn't anything there +// We don't want to save the text BELOW the viewport, because in *nix, there isn't anything there // (There isn't a scroll-forward, only a scrollback) -//Arguments: -// +// Arguments: +// - // Return value: -// True if handled successfully. False otherwise. +// - True if handled successfully. False otherwise. bool AdaptDispatch::_EraseScrollback() { CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; - csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX); + csbiex.cbSize = sizeof(csbiex); // Make sure to reset the viewport (with MoveToBottom )to where it was // before the user scrolled the console output - bool fSuccess = !!(_conApi->GetConsoleScreenBufferInfoEx(&csbiex) && _conApi->MoveToBottom()); - if (fSuccess) + bool success = (_pConApi->GetConsoleScreenBufferInfoEx(csbiex) && _pConApi->MoveToBottom()); + if (success) { - const SMALL_RECT Screen = csbiex.srWindow; - const short sHeight = Screen.Bottom - Screen.Top; - FAIL_FAST_IF(!(sHeight > 0)); - const COORD Cursor = csbiex.dwCursorPosition; + const SMALL_RECT screen = csbiex.srWindow; + const SHORT height = screen.Bottom - screen.Top; + FAIL_FAST_IF(!(height > 0)); + const COORD cursor = csbiex.dwCursorPosition; // Rectangle to cut out of the existing buffer // It will be clipped to the buffer boundaries so SHORT_MAX gives us the full buffer width. - SMALL_RECT srScroll = Screen; - srScroll.Left = 0; - srScroll.Right = SHORT_MAX; + SMALL_RECT scroll = screen; + scroll.Left = 0; + scroll.Right = SHORT_MAX; // Paste coordinate for cut text above - COORD coordDestination; - coordDestination.X = 0; - coordDestination.Y = 0; + COORD destination; + destination.X = 0; + destination.Y = 0; // Typically a scroll operation should fill with standard erase attributes, but in // this case we need to use the default attributes, hence standardFillAttrs is false. - fSuccess = !!_conApi->PrivateScrollRegion(srScroll, std::nullopt, coordDestination, false); - if (fSuccess) + success = _pConApi->PrivateScrollRegion(scroll, std::nullopt, destination, false); + if (success) { // Clear everything after the viewport. - const DWORD dwTotalAreaBelow = csbiex.dwSize.X * (csbiex.dwSize.Y - sHeight); - const COORD coordBelowStartPosition = { 0, sHeight }; + const DWORD totalAreaBelow = csbiex.dwSize.X * (csbiex.dwSize.Y - height); + const COORD coordBelowStartPosition = { 0, height }; // Again we need to use the default attributes, hence standardFillAttrs is false. - fSuccess = _conApi->PrivateFillRegion(coordBelowStartPosition, dwTotalAreaBelow, L' ', false); + success = _pConApi->PrivateFillRegion(coordBelowStartPosition, totalAreaBelow, L' ', false); - if (fSuccess) + if (success) { - // Move the viewport (CAN'T be done in one call with SetConsoleScreenBufferInfoEx, because legacy) - SMALL_RECT srNewViewport; - srNewViewport.Left = Screen.Left; - srNewViewport.Top = 0; - // SetConsoleWindowInfo uses an inclusive rect, while GetConsoleScreenBufferInfo is exclusive - srNewViewport.Right = Screen.Right - 1; - srNewViewport.Bottom = sHeight - 1; - fSuccess = !!_conApi->SetConsoleWindowInfo(true, &srNewViewport); + // Move the viewport (CAN'T be done in one call with SetConsolescreenBufferInfoEx, because legacy) + SMALL_RECT newViewport; + newViewport.Left = screen.Left; + newViewport.Top = 0; + // SetConsoleWindowInfo uses an inclusive rect, while GetConsolescreenBufferInfo is exclusive + newViewport.Right = screen.Right - 1; + newViewport.Bottom = height - 1; + success = _pConApi->SetConsoleWindowInfo(true, newViewport); - if (fSuccess) + if (success) { // Move the cursor to the same relative location. - const COORD newCursor = { Cursor.X, Cursor.Y - Screen.Top }; - fSuccess = !!_conApi->SetConsoleCursorPosition(newCursor); + const COORD newcursor = { cursor.X, cursor.Y - screen.Top }; + success = _pConApi->SetConsoleCursorPosition(newcursor); } } } } - return fSuccess; + return success; } //Routine Description: @@ -1662,7 +1685,7 @@ bool AdaptDispatch::_EraseScrollback() // True if handled successfully. False otherwise. bool AdaptDispatch::_EraseAll() { - return !!_conApi->PrivateEraseAll(); + return _pConApi->PrivateEraseAll(); } // Routine Description: @@ -1673,7 +1696,7 @@ bool AdaptDispatch::_EraseAll() // - True if handled successfully. False otherwise. bool AdaptDispatch::EnableDECCOLMSupport(const bool fEnabled) { - _fIsDECCOLMAllowed = fEnabled; + _isDECCOLMAllowed = fEnabled; return true; } @@ -1685,7 +1708,7 @@ bool AdaptDispatch::EnableDECCOLMSupport(const bool fEnabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableVT200MouseMode(const bool fEnabled) { - return !!_conApi->PrivateEnableVT200MouseMode(fEnabled); + return _pConApi->PrivateEnableVT200MouseMode(fEnabled); } //Routine Description: @@ -1697,7 +1720,7 @@ bool AdaptDispatch::EnableVT200MouseMode(const bool fEnabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableUTF8ExtendedMouseMode(const bool fEnabled) { - return !!_conApi->PrivateEnableUTF8ExtendedMouseMode(fEnabled); + return _pConApi->PrivateEnableUTF8ExtendedMouseMode(fEnabled); } //Routine Description: @@ -1709,7 +1732,7 @@ bool AdaptDispatch::EnableUTF8ExtendedMouseMode(const bool fEnabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableSGRExtendedMouseMode(const bool fEnabled) { - return !!_conApi->PrivateEnableSGRExtendedMouseMode(fEnabled); + return _pConApi->PrivateEnableSGRExtendedMouseMode(fEnabled); } //Routine Description: @@ -1720,7 +1743,7 @@ bool AdaptDispatch::EnableSGRExtendedMouseMode(const bool fEnabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableButtonEventMouseMode(const bool fEnabled) { - return !!_conApi->PrivateEnableButtonEventMouseMode(fEnabled); + return _pConApi->PrivateEnableButtonEventMouseMode(fEnabled); } //Routine Description: @@ -1732,7 +1755,7 @@ bool AdaptDispatch::EnableButtonEventMouseMode(const bool fEnabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableAnyEventMouseMode(const bool fEnabled) { - return !!_conApi->PrivateEnableAnyEventMouseMode(fEnabled); + return _pConApi->PrivateEnableAnyEventMouseMode(fEnabled); } //Routine Description: @@ -1744,7 +1767,7 @@ bool AdaptDispatch::EnableAnyEventMouseMode(const bool fEnabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableAlternateScroll(const bool fEnabled) { - return !!_conApi->PrivateEnableAlternateScroll(fEnabled); + return _pConApi->PrivateEnableAlternateScroll(fEnabled); } //Routine Description: @@ -1757,7 +1780,7 @@ bool AdaptDispatch::EnableAlternateScroll(const bool fEnabled) bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) { bool isPty = false; - _conApi->IsConsolePty(&isPty); + _pConApi->IsConsolePty(isPty); if (isPty) { return false; @@ -1797,13 +1820,13 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) break; } - bool fSuccess = !!_conApi->SetCursorStyle(actualType); - if (fSuccess) + bool success = _pConApi->SetCursorStyle(actualType); + if (success) { - fSuccess = !!_conApi->PrivateAllowCursorBlinking(fEnableBlinking); + success = _pConApi->PrivateAllowCursorBlinking(fEnableBlinking); } - return fSuccess; + return success; } // Method Description: @@ -1816,13 +1839,13 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor) { bool isPty = false; - _conApi->IsConsolePty(&isPty); + _pConApi->IsConsolePty(isPty); if (isPty) { return false; } - return !!_conApi->SetCursorColor(cursorColor); + return _pConApi->SetCursorColor(cursorColor); } // Method Description: @@ -1834,11 +1857,11 @@ bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor) // True if handled successfully. False otherwise. bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) { - bool fSuccess = tableIndex < 256; - if (fSuccess) + bool success = tableIndex < 256; + if (success) { const auto realIndex = ::Xterm256ToWindowsIndex(tableIndex); - fSuccess = !!_conApi->PrivateSetColorTableEntry(realIndex, dwColor); + success = _pConApi->PrivateSetColorTableEntry(realIndex, dwColor); } // If we're a conpty, always return false, so that we send the updated color @@ -1846,13 +1869,13 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo // the API or VT to query the values of the color table still read the // correct color. bool isPty = false; - _conApi->IsConsolePty(&isPty); + _pConApi->IsConsolePty(isPty); if (isPty) { return false; } - return fSuccess; + return success; } // Method Description: @@ -1863,21 +1886,21 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo // True if handled successfully. False otherwise. bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultForeground(const DWORD dwColor) { - bool fSuccess = true; - fSuccess = !!_conApi->PrivateSetDefaultForeground(dwColor); + bool success = true; + success = _pConApi->PrivateSetDefaultForeground(dwColor); // If we're a conpty, always return false, so that we send the updated color // value to the terminal. Still handle the sequence so apps that use // the API or VT to query the values of the color table still read the // correct color. bool isPty = false; - _conApi->IsConsolePty(&isPty); + _pConApi->IsConsolePty(isPty); if (isPty) { return false; } - return fSuccess; + return success; } // Method Description: @@ -1888,21 +1911,21 @@ bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultForeground(co // True if handled successfully. False otherwise. bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultBackground(const DWORD dwColor) { - bool fSuccess = true; - fSuccess = !!_conApi->PrivateSetDefaultBackground(dwColor); + bool success = true; + success = _pConApi->PrivateSetDefaultBackground(dwColor); // If we're a conpty, always return false, so that we send the updated color // value to the terminal. Still handle the sequence so apps that use // the API or VT to query the values of the color table still read the // correct color. bool isPty = false; - _conApi->IsConsolePty(&isPty); + _pConApi->IsConsolePty(isPty); if (isPty) { return false; } - return fSuccess; + return success; } //Routine Description: @@ -1912,36 +1935,34 @@ bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultBackground(co // This is kept seperate from the input version, as there may be // codes that are supported in one direction but not the other. //Arguments: -// - uiFunction - An identifier of the WindowManipulation function to perform -// - rgusParams - Additional parameters to pass to the function -// - cParams - size of rgusParams +// - function - An identifier of the WindowManipulation function to perform +// - parameters - Additional parameters to pass to the function // Return value: // True if handled successfully. False otherwise. -bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) +bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) { - bool fSuccess = false; + bool success = false; // Other Window Manipulation functions: // MSFT:13271098 - QueryViewport // MSFT:13271146 - QueryScreenSize - switch (uiFunction) + switch (function) { case DispatchTypes::WindowManipulationType::RefreshWindow: - if (cParams == 0) + if (parameters.empty()) { - fSuccess = DispatchCommon::s_RefreshWindow(*_conApi); + success = DispatchCommon::s_RefreshWindow(*_pConApi); } break; case DispatchTypes::WindowManipulationType::ResizeWindowInCharacters: - if (cParams == 2) + if (parameters.size() == 2) { - fSuccess = DispatchCommon::s_ResizeWindow(*_conApi, rgusParams[1], rgusParams[0]); + success = DispatchCommon::s_ResizeWindow(*_pConApi, parameters[1], parameters[0]); } break; default: - fSuccess = false; + success = false; } - return fSuccess; + return success; } diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index 77a5ded263..ce7b948d09 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -19,90 +19,85 @@ Author(s): #include "conGetSet.hpp" #include "adaptDefaults.hpp" #include "terminalOutput.hpp" -#include namespace Microsoft::Console::VirtualTerminal { class AdaptDispatch : public ITermDispatch { public: - AdaptDispatch(ConGetSet* const pConApi, - AdaptDefaults* const pDefaults); + AdaptDispatch(std::unique_ptr pConApi, + std::unique_ptr pDefaults); void Execute(const wchar_t wchControl) override { _pDefaults->Execute(wchControl); } - void PrintString(const wchar_t* const rgwch, const size_t cch) override; + void PrintString(const std::wstring_view string) override; void Print(const wchar_t wchPrintable) override; - bool CursorUp(_In_ unsigned int const uiDistance) override; // CUU - bool CursorDown(_In_ unsigned int const uiDistance) override; // CUD - bool CursorForward(_In_ unsigned int const uiDistance) override; // CUF - bool CursorBackward(_In_ unsigned int const uiDistance) override; // CUB - bool CursorNextLine(_In_ unsigned int const uiDistance) override; // CNL - bool CursorPrevLine(_In_ unsigned int const uiDistance) override; // CPL - bool CursorHorizontalPositionAbsolute(_In_ unsigned int const uiColumn) override; // CHA - bool VerticalLinePositionAbsolute(_In_ unsigned int const uiLine) override; // VPA - bool CursorPosition(_In_ unsigned int const uiLine, _In_ unsigned int const uiColumn) override; // CUP + bool CursorUp(const size_t distance) override; // CUU + bool CursorDown(const size_t distance) override; // CUD + bool CursorForward(const size_t distance) override; // CUF + bool CursorBackward(const size_t distance) override; // CUB + bool CursorNextLine(const size_t distance) override; // CNL + bool CursorPrevLine(const size_t distance) override; // CPL + bool CursorHorizontalPositionAbsolute(const size_t column) override; // CHA + bool VerticalLinePositionAbsolute(const size_t line) override; // VPA + bool CursorPosition(const size_t line, const size_t column) override; // CUP bool CursorSaveState() override; // DECSC bool CursorRestoreState() override; // DECRC - bool CursorVisibility(const bool fIsVisible) override; // DECTCEM + bool CursorVisibility(const bool isVisible) override; // DECTCEM bool EraseInDisplay(const DispatchTypes::EraseType eraseType) override; // ED bool EraseInLine(const DispatchTypes::EraseType eraseType) override; // EL - bool EraseCharacters(_In_ unsigned int const uiNumChars) override; // ECH - bool InsertCharacter(_In_ unsigned int const uiCount) override; // ICH - bool DeleteCharacter(_In_ unsigned int const uiCount) override; // DCH - bool SetGraphicsRendition(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions) override; // SGR + bool EraseCharacters(const size_t numChars) override; // ECH + bool InsertCharacter(const size_t count) override; // ICH + bool DeleteCharacter(const size_t count) override; // DCH + bool SetGraphicsRendition(const std::basic_string_view options) override; // SGR bool DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType) override; // DSR bool DeviceAttributes() override; // DA - bool ScrollUp(_In_ unsigned int const uiDistance) override; // SU - bool ScrollDown(_In_ unsigned int const uiDistance) override; // SD - bool InsertLine(_In_ unsigned int const uiDistance) override; // IL - bool DeleteLine(_In_ unsigned int const uiDistance) override; // DL - bool SetColumns(_In_ unsigned int const uiColumns) override; // DECSCPP, DECCOLM - bool SetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, - const size_t cParams) override; // DECSET - bool ResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, - const size_t cParams) override; // DECRST - bool SetCursorKeysMode(const bool fApplicationMode) override; // DECCKM - bool SetKeypadMode(const bool fApplicationMode) override; // DECKPAM, DECKPNM - bool EnableCursorBlinking(const bool bEnable) override; // ATT610 - bool SetOriginMode(const bool fRelativeMode) override; // DECOM - bool SetTopBottomScrollingMargins(const SHORT sTopMargin, - const SHORT sBottomMargin) override; // DECSTBM + bool ScrollUp(const size_t distance) override; // SU + bool ScrollDown(const size_t distance) override; // SD + bool InsertLine(const size_t distance) override; // IL + bool DeleteLine(const size_t distance) override; // DL + bool SetColumns(const size_t columns) override; // DECSCPP, DECCOLM + bool SetPrivateModes(const std::basic_string_view params) override; // DECSET + bool ResetPrivateModes(const std::basic_string_view params) override; // DECRST + bool SetCursorKeysMode(const bool applicationMode) override; // DECCKM + bool SetKeypadMode(const bool applicationMode) override; // DECKPAM, DECKPNM + bool EnableCursorBlinking(const bool enable) override; // ATT610 + bool SetOriginMode(const bool relativeMode) override; // DECOM + bool SetTopBottomScrollingMargins(const size_t topMargin, + const size_t bottomMargin) override; // DECSTBM bool ReverseLineFeed() override; // RI bool SetWindowTitle(const std::wstring_view title) override; // OscWindowTitle bool UseAlternateScreenBuffer() override; // ASBSET bool UseMainScreenBuffer() override; // ASBRST bool HorizontalTabSet() override; // HTS - bool ForwardTab(const SHORT sNumTabs) override; // CHT - bool BackwardsTab(const SHORT sNumTabs) override; // CBT - bool TabClear(const SHORT sClearType) override; // TBC + bool ForwardTab(const size_t numTabs) override; // CHT + bool BackwardsTab(const size_t numTabs) override; // CBT + bool TabClear(const size_t clearType) override; // TBC bool DesignateCharset(const wchar_t wchCharset) override; // DesignateCharset bool SoftReset() override; // DECSTR bool HardReset() override; // RIS bool ScreenAlignmentPattern() override; // DECALN - bool EnableDECCOLMSupport(const bool fEnabled) override; // ?40 - bool EnableVT200MouseMode(const bool fEnabled) override; // ?1000 - bool EnableUTF8ExtendedMouseMode(const bool fEnabled) override; // ?1005 - bool EnableSGRExtendedMouseMode(const bool fEnabled) override; // ?1006 - bool EnableButtonEventMouseMode(const bool fEnabled) override; // ?1002 - bool EnableAnyEventMouseMode(const bool fEnabled) override; // ?1003 - bool EnableAlternateScroll(const bool fEnabled) override; // ?1007 + bool EnableDECCOLMSupport(const bool enabled) override; // ?40 + bool EnableVT200MouseMode(const bool enabled) override; // ?1000 + bool EnableUTF8ExtendedMouseMode(const bool enabled) override; // ?1005 + bool EnableSGRExtendedMouseMode(const bool enabled) override; // ?1006 + bool EnableButtonEventMouseMode(const bool enabled) override; // ?1002 + bool EnableAnyEventMouseMode(const bool enabled) override; // ?1003 + bool EnableAlternateScroll(const bool enabled) override; // ?1007 bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR bool SetCursorColor(const COLORREF cursorColor) override; bool SetColorTableEntry(const size_t tableIndex, - const DWORD dwColor) override; // OscColorTable - bool SetDefaultForeground(const DWORD dwColor) override; // OSCDefaultForeground - bool SetDefaultBackground(const DWORD dwColor) override; // OSCDefaultBackground + const DWORD color) override; // OscColorTable + bool SetDefaultForeground(const DWORD color) override; // OSCDefaultForeground + bool SetDefaultBackground(const DWORD color) override; // OSCDefaultBackground - bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) override; // DTTERM_WindowManipulation + bool WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) override; // DTTERM_WindowManipulation private: enum class CursorDirection @@ -128,62 +123,59 @@ namespace Microsoft::Console::VirtualTerminal TerminalOutput TermOutput = {}; }; - bool _CursorMovement(const CursorDirection dir, _In_ unsigned int const uiDistance) const; - bool _CursorMovePosition(_In_opt_ const unsigned int* const puiRow, _In_opt_ const unsigned int* const puiCol) const; - bool _EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX* const pcsbiex, const DispatchTypes::EraseType eraseType, const SHORT sLineId) const; - void _SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt, _Inout_ WORD* const pAttr); + bool _CursorMovement(const CursorDirection dir, const size_t distance) const; + bool _CursorMovePosition(const std::optional row, const std::optional column) const; + bool _EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX& csbiex, + const DispatchTypes::EraseType eraseType, + const size_t lineId) const; + void _SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt, WORD& attr); bool _EraseScrollback(); bool _EraseAll(); - void _SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt, _Inout_ WORD* const pAttr) const; - bool _InsertDeleteHelper(_In_ unsigned int const uiCount, const bool fIsInsert) const; - bool _ScrollMovement(const ScrollDirection dir, _In_ unsigned int const uiDistance) const; - static void s_DisableAllColors(_Inout_ WORD* const pAttr, const bool fIsForeground); - static void s_ApplyColors(_Inout_ WORD* const pAttr, const WORD wApplyThis, const bool fIsForeground); + bool _InsertDeleteHelper(const size_t count, const bool isInsert) const; + bool _ScrollMovement(const ScrollDirection dir, const size_t distance) const; + static void s_DisableAllColors(WORD& attr, const bool isForeground); + static void s_ApplyColors(WORD& attr, const WORD applyThis, const bool isForeground); - bool _DoSetTopBottomScrollingMargins(const SHORT sTopMargin, - const SHORT sBottomMargin); + bool _DoSetTopBottomScrollingMargins(const size_t topMargin, + const size_t bottomMargin); bool _CursorPositionReport() const; - bool _WriteResponse(_In_reads_(cchReply) PCWSTR pwszReply, const size_t cchReply) const; - bool _SetResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rgParams, const size_t cParams, const bool fEnable); - bool _PrivateModeParamsHelper(_In_ DispatchTypes::PrivateModeParams const param, const bool fEnable); - bool _DoDECCOLMHelper(_In_ unsigned int uiColumns); + bool _WriteResponse(const std::wstring_view reply) const; + bool _SetResetPrivateModes(const std::basic_string_view params, const bool enable); + bool _PrivateModeParamsHelper(const DispatchTypes::PrivateModeParams param, const bool enable); + bool _DoDECCOLMHelper(const size_t columns); - std::unique_ptr _conApi; + std::unique_ptr _pConApi; std::unique_ptr _pDefaults; - TerminalOutput _TermOutput; + TerminalOutput _termOutput; // We have two instances of the saved cursor state, because we need // one for the main buffer (at index 0), and another for the alt buffer // (at index 1). The _usingAltBuffer property keeps tracks of which // buffer is active, so can be used as an index into this array to // obtain the saved state that should be currently active. - CursorState _savedCursorState[2]; + std::array _savedCursorState; bool _usingAltBuffer; - SMALL_RECT _srScrollMargins; + SMALL_RECT _scrollMargins; - bool _fIsOriginModeRelative; + bool _isOriginModeRelative; - bool _fIsSetColumnsEnabled; + bool _isDECCOLMAllowed; - bool _fIsDECCOLMAllowed; + bool _changedForeground; + bool _changedBackground; + bool _changedMetaAttrs; - bool _fChangedForeground; - bool _fChangedBackground; - bool _fChangedMetaAttrs; - - bool _SetRgbColorsHelper(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions, - _Out_ COLORREF* const prgbColor, - _Out_ bool* const pfIsForeground, - _Out_ size_t* const pcOptionsConsumed); + bool _SetRgbColorsHelper(const std::basic_string_view options, + COLORREF& rgbColor, + bool& isForeground, + size_t& optionsConsumed); bool _SetBoldColorHelper(const DispatchTypes::GraphicsOptions option); bool _SetDefaultColorHelper(const DispatchTypes::GraphicsOptions option); bool _SetExtendedTextAttributeHelper(const DispatchTypes::GraphicsOptions option); - static bool s_IsXtermColorOption(const DispatchTypes::GraphicsOptions opt); static bool s_IsRgbColorOption(const DispatchTypes::GraphicsOptions opt); static bool s_IsBoldColorOption(const DispatchTypes::GraphicsOptions opt) noexcept; static bool s_IsDefaultColorOption(const DispatchTypes::GraphicsOptions opt) noexcept; diff --git a/src/terminal/adapter/adaptDispatchGraphics.cpp b/src/terminal/adapter/adaptDispatchGraphics.cpp index 85076d0823..088f80f495 100644 --- a/src/terminal/adapter/adaptDispatchGraphics.cpp +++ b/src/terminal/adapter/adaptDispatchGraphics.cpp @@ -16,51 +16,51 @@ using namespace Microsoft::Console::VirtualTerminal::DispatchTypes; // Routine Description: // - Small helper to disable all color flags within a given font attributes field // Arguments: -// - pAttr - Pointer to font attributes field to adjust -// - fIsForeground - True if we're modifying the FOREGROUND colors. False if we're doing BACKGROUND. +// - attr - Font attributes field to adjust +// - isForeground - True if we're modifying the FOREGROUND colors. False if we're doing BACKGROUND. // Return Value: // - -void AdaptDispatch::s_DisableAllColors(_Inout_ WORD* const pAttr, const bool fIsForeground) +void AdaptDispatch::s_DisableAllColors(WORD& attr, const bool isForeground) { - if (fIsForeground) + if (isForeground) { - *pAttr &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); + attr &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); } else { - *pAttr &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); + attr &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); } } // Routine Description: // - Small helper to help mask off the appropriate foreground/background bits in the colors bitfield. // Arguments: -// - pAttr - Pointer to font attributes field to adjust -// - wApplyThis - Color values to apply to the low or high word of the font attributes field. -// - fIsForeground - TRUE = foreground color. FALSE = background color. +// - attr - Font attributes field to adjust +// - applyThis - Color values to apply to the low or high word of the font attributes field. +// - isForeground - TRUE = foreground color. FALSE = background color. // Specifies which half of the bit field to reset and then apply wApplyThis // upon. // Return Value: // - -void AdaptDispatch::s_ApplyColors(_Inout_ WORD* const pAttr, const WORD wApplyThis, const bool fIsForeground) +void AdaptDispatch::s_ApplyColors(WORD& attr, const WORD applyThis, const bool isForeground) { // Copy the new attribute to apply - WORD wNewColors = wApplyThis; + WORD wNewColors = applyThis; // Mask off only the foreground or background - if (fIsForeground) + if (isForeground) { - *pAttr &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); + attr &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); wNewColors &= (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); } else { - *pAttr &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); + attr &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); wNewColors &= (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); } // Apply appropriate flags. - *pAttr |= wNewColors; + attr |= wNewColors; } // Routine Description: @@ -70,10 +70,10 @@ void AdaptDispatch::s_ApplyColors(_Inout_ WORD* const pAttr, const WORD wApplyTh // command. // Arguments: // - opt - Graphics option sent to us by the parser/requestor. -// - pAttr - Pointer to the font attribute field to adjust +// - attr - Font attribute field to adjust // Return Value: // - -void AdaptDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt, _Inout_ WORD* const pAttr) +void AdaptDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOptions opt, WORD& attr) { switch (opt) { @@ -84,185 +84,185 @@ void AdaptDispatch::_SetGraphicsOptionHelper(const DispatchTypes::GraphicsOption // case DispatchTypes::GraphicsOptions::BoldBright: // case DispatchTypes::GraphicsOptions::UnBold: case DispatchTypes::GraphicsOptions::Negative: - *pAttr |= COMMON_LVB_REVERSE_VIDEO; - _fChangedMetaAttrs = true; + attr |= COMMON_LVB_REVERSE_VIDEO; + _changedMetaAttrs = true; break; case DispatchTypes::GraphicsOptions::Underline: // TODO:GH#2915 Treat underline separately from LVB_UNDERSCORE - *pAttr |= COMMON_LVB_UNDERSCORE; - _fChangedMetaAttrs = true; + attr |= COMMON_LVB_UNDERSCORE; + _changedMetaAttrs = true; break; case DispatchTypes::GraphicsOptions::Positive: - *pAttr &= ~COMMON_LVB_REVERSE_VIDEO; - _fChangedMetaAttrs = true; + attr &= ~COMMON_LVB_REVERSE_VIDEO; + _changedMetaAttrs = true; break; case DispatchTypes::GraphicsOptions::NoUnderline: - *pAttr &= ~COMMON_LVB_UNDERSCORE; - _fChangedMetaAttrs = true; + attr &= ~COMMON_LVB_UNDERSCORE; + _changedMetaAttrs = true; break; case DispatchTypes::GraphicsOptions::ForegroundBlack: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundBlue: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - *pAttr |= FOREGROUND_BLUE; - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + attr |= FOREGROUND_BLUE; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundGreen: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - *pAttr |= FOREGROUND_GREEN; - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + attr |= FOREGROUND_GREEN; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundCyan: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - *pAttr |= FOREGROUND_BLUE | FOREGROUND_GREEN; - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + attr |= FOREGROUND_BLUE | FOREGROUND_GREEN; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundRed: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - *pAttr |= FOREGROUND_RED; - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + attr |= FOREGROUND_RED; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundMagenta: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - *pAttr |= FOREGROUND_BLUE | FOREGROUND_RED; - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + attr |= FOREGROUND_BLUE | FOREGROUND_RED; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundYellow: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - *pAttr |= FOREGROUND_GREEN | FOREGROUND_RED; - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + attr |= FOREGROUND_GREEN | FOREGROUND_RED; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundWhite: - s_DisableAllColors(pAttr, true); // turn off all color flags first. - *pAttr |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - _fChangedForeground = true; + s_DisableAllColors(attr, true); // turn off all color flags first. + attr |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundDefault: FAIL_FAST_MSG("GraphicsOptions::ForegroundDefault should be handled by _SetDefaultColorHelper"); break; case DispatchTypes::GraphicsOptions::BackgroundBlack: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundBlue: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - *pAttr |= BACKGROUND_BLUE; - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + attr |= BACKGROUND_BLUE; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundGreen: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - *pAttr |= BACKGROUND_GREEN; - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + attr |= BACKGROUND_GREEN; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundCyan: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - *pAttr |= BACKGROUND_BLUE | BACKGROUND_GREEN; - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + attr |= BACKGROUND_BLUE | BACKGROUND_GREEN; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundRed: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - *pAttr |= BACKGROUND_RED; - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + attr |= BACKGROUND_RED; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundMagenta: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - *pAttr |= BACKGROUND_BLUE | BACKGROUND_RED; - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + attr |= BACKGROUND_BLUE | BACKGROUND_RED; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundYellow: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - *pAttr |= BACKGROUND_GREEN | BACKGROUND_RED; - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + attr |= BACKGROUND_GREEN | BACKGROUND_RED; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundWhite: - s_DisableAllColors(pAttr, false); // turn off all color flags first. - *pAttr |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; - _fChangedBackground = true; + s_DisableAllColors(attr, false); // turn off all color flags first. + attr |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundDefault: FAIL_FAST_MSG("GraphicsOptions::BackgroundDefault should be handled by _SetDefaultColorHelper"); break; case DispatchTypes::GraphicsOptions::BrightForegroundBlack: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundBlack, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundBlack, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundBlue: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundBlue, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundBlue, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundGreen: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundGreen, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundGreen, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundCyan: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundCyan, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundCyan, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundRed: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundRed, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundRed, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundMagenta: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundMagenta, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundMagenta, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundYellow: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundYellow, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundYellow, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundWhite: - _SetGraphicsOptionHelper(GraphicsOptions::ForegroundWhite, pAttr); - *pAttr |= FOREGROUND_INTENSITY; - _fChangedForeground = true; + _SetGraphicsOptionHelper(GraphicsOptions::ForegroundWhite, attr); + attr |= FOREGROUND_INTENSITY; + _changedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlack: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundBlack, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundBlack, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlue: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundBlue, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundBlue, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundGreen: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundGreen, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundGreen, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundCyan: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundCyan, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundCyan, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundRed: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundRed, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundRed, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundMagenta, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundMagenta, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundYellow: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundYellow, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundYellow, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundWhite: - _SetGraphicsOptionHelper(GraphicsOptions::BackgroundWhite, pAttr); - *pAttr |= BACKGROUND_INTENSITY; - _fChangedBackground = true; + _SetGraphicsOptionHelper(GraphicsOptions::BackgroundWhite, attr); + attr |= BACKGROUND_INTENSITY; + _changedBackground = true; break; } } @@ -331,13 +331,10 @@ bool AdaptDispatch::s_IsDefaultColorOption(const DispatchTypes::GraphicsOptions // RGB sequences then take 3 MORE params to designate the R, G, B parts of the color // Xterm index will use the param that follows to use a color from the preset 256 color xterm color table. // Arguments: -// - rgOptions - An array of options that will be used to generate the RGB color -// - cOptions - The count of options -// - prgbColor - A pointer to place the generated RGB color into. -// - pfIsForeground - a pointer to place whether or not the parsed color is for the foreground or not. -// - pcOptionsConsumed - a pointer to place the number of options we consumed parsing this option. -// - ColorTable - the windows color table, for xterm indices < 16 -// - cColorTable - The number of elements in the windows color table. +// - options - An array of options that will be used to generate the RGB color +// - rgbColor - Location to place the generated RGB color into. +// - isForeground - Location to place whether or not the parsed color is for the foreground or not. +// - optionsConsumed - Location to place the number of options we consumed parsing this option. // Return Value: // Returns true if we successfully parsed an extended color option from the options array. // - This corresponds to the following number of options consumed (pcOptionsConsumed): @@ -345,59 +342,58 @@ bool AdaptDispatch::s_IsDefaultColorOption(const DispatchTypes::GraphicsOptions // 2 - false, not enough options to parse. // 3 - true, parsed an xterm index to a color // 5 - true, parsed an RGB color. -bool AdaptDispatch::_SetRgbColorsHelper(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions, - _Out_ COLORREF* const prgbColor, - _Out_ bool* const pfIsForeground, - _Out_ size_t* const pcOptionsConsumed) +bool AdaptDispatch::_SetRgbColorsHelper(const std::basic_string_view options, + COLORREF& rgbColor, + bool& isForeground, + size_t& optionsConsumed) { - bool fSuccess = false; - *pcOptionsConsumed = 1; - if (cOptions >= 2 && s_IsRgbColorOption(rgOptions[0])) + bool success = false; + optionsConsumed = 1; + if (options.size() >= 2 && s_IsRgbColorOption(options.at(0))) { - *pcOptionsConsumed = 2; - DispatchTypes::GraphicsOptions extendedOpt = rgOptions[0]; - DispatchTypes::GraphicsOptions typeOpt = rgOptions[1]; + optionsConsumed = 2; + DispatchTypes::GraphicsOptions extendedOpt = options.at(0); + DispatchTypes::GraphicsOptions typeOpt = options.at(1); if (extendedOpt == DispatchTypes::GraphicsOptions::ForegroundExtended) { - *pfIsForeground = true; + isForeground = true; } else if (extendedOpt == DispatchTypes::GraphicsOptions::BackgroundExtended) { - *pfIsForeground = false; + isForeground = false; } - if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && cOptions >= 5) + if (typeOpt == DispatchTypes::GraphicsOptions::RGBColorOrFaint && options.size() >= 5) { - *pcOptionsConsumed = 5; + optionsConsumed = 5; // ensure that each value fits in a byte - unsigned int red = rgOptions[2] > 255 ? 255 : rgOptions[2]; - unsigned int green = rgOptions[3] > 255 ? 255 : rgOptions[3]; - unsigned int blue = rgOptions[4] > 255 ? 255 : rgOptions[4]; + unsigned int red = std::min(static_cast(options.at(2)), 255u); + unsigned int green = std::min(static_cast(options.at(3)), 255u); + unsigned int blue = std::min(static_cast(options.at(4)), 255u); - *prgbColor = RGB(red, green, blue); + rgbColor = RGB(red, green, blue); - fSuccess = !!_conApi->SetConsoleRGBTextAttribute(*prgbColor, *pfIsForeground); + success = _pConApi->SetConsoleRGBTextAttribute(rgbColor, isForeground); } - else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && cOptions >= 3) + else if (typeOpt == DispatchTypes::GraphicsOptions::BlinkOrXterm256Index && options.size() >= 3) { - *pcOptionsConsumed = 3; - if (rgOptions[2] <= 255) // ensure that the provided index is on the table + optionsConsumed = 3; + if (options.at(2) <= 255) // ensure that the provided index is on the table { - unsigned int tableIndex = rgOptions[2]; + unsigned int tableIndex = options.at(2); - fSuccess = !!_conApi->SetConsoleXtermTextAttribute(tableIndex, *pfIsForeground); + success = _pConApi->SetConsoleXtermTextAttribute(tableIndex, isForeground); } } } - return fSuccess; + return success; } bool AdaptDispatch::_SetBoldColorHelper(const DispatchTypes::GraphicsOptions option) { const bool bold = (option == DispatchTypes::GraphicsOptions::BoldBright); - return !!_conApi->PrivateBoldText(bold); + return _pConApi->PrivateBoldText(bold); } bool AdaptDispatch::_SetDefaultColorHelper(const DispatchTypes::GraphicsOptions option) @@ -405,15 +401,15 @@ bool AdaptDispatch::_SetDefaultColorHelper(const DispatchTypes::GraphicsOptions const bool fg = option == GraphicsOptions::Off || option == GraphicsOptions::ForegroundDefault; const bool bg = option == GraphicsOptions::Off || option == GraphicsOptions::BackgroundDefault; - bool success = _conApi->PrivateSetDefaultAttributes(fg, bg); + bool success = _pConApi->PrivateSetDefaultAttributes(fg, bg); if (success && fg && bg) { // If we're resetting both the FG & BG, also reset the meta attributes (underline) // as well as the boldness - success = _conApi->PrivateSetLegacyAttributes(0, false, false, true) && - _conApi->PrivateBoldText(false) && - _conApi->PrivateSetExtendedTextAttributes(ExtendedAttributes::Normal); + success = _pConApi->PrivateSetLegacyAttributes(0, false, false, true) && + _pConApi->PrivateBoldText(false) && + _pConApi->PrivateSetExtendedTextAttributes(ExtendedAttributes::Normal); } return success; } @@ -432,7 +428,7 @@ bool AdaptDispatch::_SetExtendedTextAttributeHelper(const DispatchTypes::Graphic { ExtendedAttributes attrs{ ExtendedAttributes::Normal }; - RETURN_BOOL_IF_FALSE(_conApi->PrivateGetExtendedTextAttributes(&attrs)); + RETURN_BOOL_IF_FALSE(_pConApi->PrivateGetExtendedTextAttributes(attrs)); switch (opt) { @@ -466,7 +462,7 @@ bool AdaptDispatch::_SetExtendedTextAttributeHelper(const DispatchTypes::Graphic // case DispatchTypes::GraphicsOptions::DoublyUnderlined: } - return _conApi->PrivateSetExtendedTextAttributes(attrs); + return _pConApi->PrivateSetExtendedTextAttributes(attrs); } // Routine Description: @@ -476,13 +472,11 @@ bool AdaptDispatch::_SetExtendedTextAttributeHelper(const DispatchTypes::Graphic // type options. // Arguments: -// - rgOptions - An array of options that will be applied from 0 to N, in order, +// - options - An array of options that will be applied from 0 to N, in order, // one at a time by setting or removing flags in the font style properties. -// - cOptions - The count of options (a.k.a. the N in the above line of comments) // Return Value: // - True if handled successfully. False otherwise. -bool AdaptDispatch::SetGraphicsRendition(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions) +bool AdaptDispatch::SetGraphicsRendition(const std::basic_string_view options) { // We use the private function here to get just the default color attributes // as a performance optimization. Calling the public @@ -491,62 +485,61 @@ bool AdaptDispatch::SetGraphicsRendition(_In_reads_(cOptions) const DispatchType // OS and wastes time memcpying colors and other data we do not need to // resolve this Set Graphics Rendition request. WORD attr; - bool fSuccess = !!_conApi->PrivateGetConsoleScreenBufferAttributes(&attr); + bool success = _pConApi->PrivateGetConsoleScreenBufferAttributes(attr); - if (fSuccess) + if (success) { // Run through the graphics options and apply them - for (size_t i = 0; i < cOptions; i++) + for (size_t i = 0; i < options.size(); i++) { - DispatchTypes::GraphicsOptions opt = rgOptions[i]; + DispatchTypes::GraphicsOptions opt = options.at(i); if (s_IsDefaultColorOption(opt)) { - fSuccess = _SetDefaultColorHelper(opt); + success = _SetDefaultColorHelper(opt); } else if (s_IsBoldColorOption(opt)) { - fSuccess = _SetBoldColorHelper(rgOptions[i]); + success = _SetBoldColorHelper(opt); } else if (s_IsExtendedTextAttribute(opt)) { - fSuccess = _SetExtendedTextAttributeHelper(rgOptions[i]); + success = _SetExtendedTextAttributeHelper(opt); } else if (s_IsRgbColorOption(opt)) { COLORREF rgbColor; - bool fIsForeground = true; + bool isForeground = true; - size_t cOptionsConsumed = 0; + size_t optionsConsumed = 0; // _SetRgbColorsHelper will call the appropriate ConApi function - fSuccess = _SetRgbColorsHelper(&(rgOptions[i]), - cOptions - i, - &rgbColor, - &fIsForeground, - &cOptionsConsumed); + success = _SetRgbColorsHelper(options.substr(i), + rgbColor, + isForeground, + optionsConsumed); - i += (cOptionsConsumed - 1); // cOptionsConsumed includes the opt we're currently on. + i += (optionsConsumed - 1); // cOptionsConsumed includes the opt we're currently on. } else { - _SetGraphicsOptionHelper(opt, &attr); - fSuccess = !!_conApi->PrivateSetLegacyAttributes(attr, - _fChangedForeground, - _fChangedBackground, - _fChangedMetaAttrs); + _SetGraphicsOptionHelper(opt, attr); + success = _pConApi->PrivateSetLegacyAttributes(attr, + _changedForeground, + _changedBackground, + _changedMetaAttrs); // Make sure we un-bold - if (fSuccess && opt == DispatchTypes::GraphicsOptions::Off) + if (success && opt == DispatchTypes::GraphicsOptions::Off) { - fSuccess = _SetBoldColorHelper(opt); + success = _SetBoldColorHelper(opt); } - _fChangedForeground = false; - _fChangedBackground = false; - _fChangedMetaAttrs = false; + _changedForeground = false; + _changedBackground = false; + _changedMetaAttrs = false; } } } - return fSuccess; + return success; } diff --git a/src/terminal/adapter/conGetSet.hpp b/src/terminal/adapter/conGetSet.hpp index 59c391872f..6b6f9e0b8e 100644 --- a/src/terminal/adapter/conGetSet.hpp +++ b/src/terminal/adapter/conGetSet.hpp @@ -27,87 +27,87 @@ namespace Microsoft::Console::VirtualTerminal class ConGetSet { public: - virtual BOOL GetConsoleCursorInfo(_In_ CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) const = 0; - virtual BOOL GetConsoleScreenBufferInfoEx(_Out_ CONSOLE_SCREEN_BUFFER_INFOEX* const pConsoleScreenBufferInfoEx) const = 0; - virtual BOOL SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX* const pConsoleScreenBufferInfoEx) = 0; - virtual BOOL SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) = 0; - virtual BOOL SetConsoleCursorPosition(const COORD coordCursorPosition) = 0; - virtual BOOL SetConsoleTextAttribute(const WORD wAttr) = 0; + virtual bool GetConsoleCursorInfo(CONSOLE_CURSOR_INFO& cursorInfo) const = 0; + virtual bool GetConsoleScreenBufferInfoEx(CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) const = 0; + virtual bool SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX& screenBufferInfo) = 0; + virtual bool SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO& cursorInfo) = 0; + virtual bool SetConsoleCursorPosition(const COORD position) = 0; + virtual bool SetConsoleTextAttribute(const WORD attr) = 0; - virtual BOOL PrivateSetLegacyAttributes(const WORD wAttr, - const bool fForeground, - const bool fBackground, - const bool fMeta) = 0; + virtual bool PrivateSetLegacyAttributes(const WORD attr, + const bool foreground, + const bool background, + const bool meta) = 0; - virtual BOOL PrivateSetDefaultAttributes(const bool fForeground, const bool fBackground) = 0; + virtual bool PrivateSetDefaultAttributes(const bool foreground, const bool background) = 0; - virtual BOOL SetConsoleXtermTextAttribute(const int iXtermTableEntry, - const bool fIsForeground) = 0; - virtual BOOL SetConsoleRGBTextAttribute(const COLORREF rgbColor, const bool fIsForeground) = 0; - virtual BOOL PrivateBoldText(const bool bolded) = 0; - virtual BOOL PrivateGetExtendedTextAttributes(ExtendedAttributes* const pAttrs) = 0; - virtual BOOL PrivateSetExtendedTextAttributes(const ExtendedAttributes attrs) = 0; - virtual BOOL PrivateGetTextAttributes(TextAttribute* const pAttrs) const = 0; - virtual BOOL PrivateSetTextAttributes(const TextAttribute& attrs) = 0; + virtual bool SetConsoleXtermTextAttribute(const int xtermTableEntry, + const bool isForeground) = 0; + virtual bool SetConsoleRGBTextAttribute(const COLORREF rgbColor, const bool isForeground) = 0; + virtual bool PrivateBoldText(const bool bolded) = 0; + virtual bool PrivateGetExtendedTextAttributes(ExtendedAttributes& attrs) = 0; + virtual bool PrivateSetExtendedTextAttributes(const ExtendedAttributes attrs) = 0; + virtual bool PrivateGetTextAttributes(TextAttribute& attrs) const = 0; + virtual bool PrivateSetTextAttributes(const TextAttribute& attrs) = 0; - virtual BOOL PrivateWriteConsoleInputW(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) = 0; - virtual BOOL SetConsoleWindowInfo(const BOOL bAbsolute, - const SMALL_RECT* const lpConsoleWindow) = 0; - virtual BOOL PrivateSetCursorKeysMode(const bool fApplicationMode) = 0; - virtual BOOL PrivateSetKeypadMode(const bool fApplicationMode) = 0; + virtual bool PrivateWriteConsoleInputW(std::deque>& events, + size_t& eventsWritten) = 0; + virtual bool SetConsoleWindowInfo(const bool absolute, + const SMALL_RECT& window) = 0; + virtual bool PrivateSetCursorKeysMode(const bool applicationMode) = 0; + virtual bool PrivateSetKeypadMode(const bool applicationMode) = 0; - virtual BOOL PrivateShowCursor(const bool show) = 0; - virtual BOOL PrivateAllowCursorBlinking(const bool fEnable) = 0; + virtual bool PrivateShowCursor(const bool show) = 0; + virtual bool PrivateAllowCursorBlinking(const bool enable) = 0; - virtual BOOL PrivateSetScrollingRegion(const SMALL_RECT* const psrScrollMargins) = 0; - virtual BOOL PrivateReverseLineFeed() = 0; - virtual BOOL SetConsoleTitleW(const std::wstring_view title) = 0; - virtual BOOL PrivateUseAlternateScreenBuffer() = 0; - virtual BOOL PrivateUseMainScreenBuffer() = 0; - virtual BOOL PrivateHorizontalTabSet() = 0; - virtual BOOL PrivateForwardTab(const SHORT sNumTabs) = 0; - virtual BOOL PrivateBackwardsTab(const SHORT sNumTabs) = 0; - virtual BOOL PrivateTabClear(const bool fClearAll) = 0; - virtual BOOL PrivateSetDefaultTabStops() = 0; + virtual bool PrivateSetScrollingRegion(const SMALL_RECT& scrollMargins) = 0; + virtual bool PrivateReverseLineFeed() = 0; + virtual bool SetConsoleTitleW(const std::wstring_view title) = 0; + virtual bool PrivateUseAlternateScreenBuffer() = 0; + virtual bool PrivateUseMainScreenBuffer() = 0; + virtual bool PrivateHorizontalTabSet() = 0; + virtual bool PrivateForwardTab(const size_t numTabs) = 0; + virtual bool PrivateBackwardsTab(const size_t numTabs) = 0; + virtual bool PrivateTabClear(const bool clearAll) = 0; + virtual bool PrivateSetDefaultTabStops() = 0; - virtual BOOL PrivateEnableVT200MouseMode(const bool fEnabled) = 0; - virtual BOOL PrivateEnableUTF8ExtendedMouseMode(const bool fEnabled) = 0; - virtual BOOL PrivateEnableSGRExtendedMouseMode(const bool fEnabled) = 0; - virtual BOOL PrivateEnableButtonEventMouseMode(const bool fEnabled) = 0; - virtual BOOL PrivateEnableAnyEventMouseMode(const bool fEnabled) = 0; - virtual BOOL PrivateEnableAlternateScroll(const bool fEnabled) = 0; - virtual BOOL PrivateEraseAll() = 0; - virtual BOOL SetCursorStyle(const CursorType cursorType) = 0; - virtual BOOL SetCursorColor(const COLORREF cursorColor) = 0; - virtual BOOL PrivateGetConsoleScreenBufferAttributes(_Out_ WORD* const pwAttributes) = 0; - virtual BOOL PrivatePrependConsoleInput(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) = 0; - virtual BOOL PrivateWriteConsoleControlInput(_In_ KeyEvent key) = 0; - virtual BOOL PrivateRefreshWindow() = 0; + virtual bool PrivateEnableVT200MouseMode(const bool enabled) = 0; + virtual bool PrivateEnableUTF8ExtendedMouseMode(const bool enabled) = 0; + virtual bool PrivateEnableSGRExtendedMouseMode(const bool enabled) = 0; + virtual bool PrivateEnableButtonEventMouseMode(const bool enabled) = 0; + virtual bool PrivateEnableAnyEventMouseMode(const bool enabled) = 0; + virtual bool PrivateEnableAlternateScroll(const bool enabled) = 0; + virtual bool PrivateEraseAll() = 0; + virtual bool SetCursorStyle(const CursorType style) = 0; + virtual bool SetCursorColor(const COLORREF color) = 0; + virtual bool PrivateGetConsoleScreenBufferAttributes(WORD& attributes) = 0; + virtual bool PrivatePrependConsoleInput(std::deque>& events, + size_t& eventsWritten) = 0; + virtual bool PrivateWriteConsoleControlInput(const KeyEvent key) = 0; + virtual bool PrivateRefreshWindow() = 0; - virtual BOOL GetConsoleOutputCP(_Out_ unsigned int* const puiOutputCP) = 0; + virtual bool GetConsoleOutputCP(unsigned int& codepage) = 0; - virtual BOOL PrivateSuppressResizeRepaint() = 0; - virtual BOOL IsConsolePty(_Out_ bool* const pIsPty) const = 0; + virtual bool PrivateSuppressResizeRepaint() = 0; + virtual bool IsConsolePty(bool& isPty) const = 0; - virtual BOOL MoveCursorVertically(const short lines) = 0; + virtual bool MoveCursorVertically(const ptrdiff_t lines) = 0; - virtual BOOL DeleteLines(const unsigned int count) = 0; - virtual BOOL InsertLines(const unsigned int count) = 0; + virtual bool DeleteLines(const size_t count) = 0; + virtual bool InsertLines(const size_t count) = 0; - virtual BOOL MoveToBottom() const = 0; + virtual bool MoveToBottom() const = 0; - virtual BOOL PrivateSetColorTableEntry(const short index, const COLORREF value) const = 0; - virtual BOOL PrivateSetDefaultForeground(const COLORREF value) const = 0; - virtual BOOL PrivateSetDefaultBackground(const COLORREF value) const = 0; + virtual bool PrivateSetColorTableEntry(const short index, const COLORREF value) const = 0; + virtual bool PrivateSetDefaultForeground(const COLORREF value) const = 0; + virtual bool PrivateSetDefaultBackground(const COLORREF value) const = 0; - virtual BOOL PrivateFillRegion(const COORD startPosition, + virtual bool PrivateFillRegion(const COORD startPosition, const size_t fillLength, const wchar_t fillChar, const bool standardFillAttrs) = 0; - virtual BOOL PrivateScrollRegion(const SMALL_RECT scrollRect, + virtual bool PrivateScrollRegion(const SMALL_RECT scrollRect, const std::optional clipRect, const COORD destinationOrigin, const bool standardFillAttrs) = 0; diff --git a/src/terminal/adapter/termDispatch.hpp b/src/terminal/adapter/termDispatch.hpp index 39850028e7..4ac7cc4b7b 100644 --- a/src/terminal/adapter/termDispatch.hpp +++ b/src/terminal/adapter/termDispatch.hpp @@ -22,63 +22,60 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons public: void Execute(const wchar_t wchControl) override = 0; void Print(const wchar_t wchPrintable) override = 0; - void PrintString(const wchar_t* const rgwch, const size_t cch) override = 0; + void PrintString(const std::wstring_view string) override = 0; - bool CursorUp(const unsigned int /*uiDistance*/) override { return false; } // CUU - bool CursorDown(const unsigned int /*uiDistance*/) override { return false; } // CUD - bool CursorForward(const unsigned int /*uiDistance*/) override { return false; } // CUF - bool CursorBackward(const unsigned int /*uiDistance*/) override { return false; } // CUB - bool CursorNextLine(const unsigned int /*uiDistance*/) override { return false; } // CNL - bool CursorPrevLine(const unsigned int /*uiDistance*/) override { return false; } // CPL - bool CursorHorizontalPositionAbsolute(const unsigned int /*uiColumn*/) override { return false; } // CHA - bool VerticalLinePositionAbsolute(const unsigned int /*uiLine*/) override { return false; } // VPA - bool CursorPosition(const unsigned int /*uiLine*/, const unsigned int /*uiColumn*/) override { return false; } // CUP + bool CursorUp(const size_t /*distance*/) override { return false; } // CUU + bool CursorDown(const size_t /*distance*/) override { return false; } // CUD + bool CursorForward(const size_t /*distance*/) override { return false; } // CUF + bool CursorBackward(const size_t /*distance*/) override { return false; } // CUB + bool CursorNextLine(const size_t /*distance*/) override { return false; } // CNL + bool CursorPrevLine(const size_t /*distance*/) override { return false; } // CPL + bool CursorHorizontalPositionAbsolute(const size_t /*column*/) override { return false; } // CHA + bool VerticalLinePositionAbsolute(const size_t /*line*/) override { return false; } // VPA + bool CursorPosition(const size_t /*line*/, const size_t /*column*/) override { return false; } // CUP bool CursorSaveState() override { return false; } // DECSC bool CursorRestoreState() override { return false; } // DECRC - bool CursorVisibility(const bool /*fIsVisible*/) override { return false; } // DECTCEM - bool InsertCharacter(const unsigned int /*uiCount*/) override { return false; } // ICH - bool DeleteCharacter(const unsigned int /*uiCount*/) override { return false; } // DCH - bool ScrollUp(const unsigned int /*uiDistance*/) override { return false; } // SU - bool ScrollDown(const unsigned int /*uiDistance*/) override { return false; } // SD - bool InsertLine(const unsigned int /*uiDistance*/) override { return false; } // IL - bool DeleteLine(const unsigned int /*uiDistance*/) override { return false; } // DL - bool SetColumns(const unsigned int /*uiColumns*/) override { return false; } // DECSCPP, DECCOLM - bool SetCursorKeysMode(const bool /*fApplicationMode*/) override { return false; } // DECCKM - bool SetKeypadMode(const bool /*fApplicationMode*/) override { return false; } // DECKPAM, DECKPNM - bool EnableCursorBlinking(const bool /*fEnable*/) override { return false; } // ATT610 - bool SetOriginMode(const bool /*fRelativeMode*/) override { return false; }; // DECOM - bool SetTopBottomScrollingMargins(const SHORT /*sTopMargin*/, const SHORT /*sBottomMargin*/) override { return false; } // DECSTBM + bool CursorVisibility(const bool /*isVisible*/) override { return false; } // DECTCEM + bool InsertCharacter(const size_t /*count*/) override { return false; } // ICH + bool DeleteCharacter(const size_t /*count*/) override { return false; } // DCH + bool ScrollUp(const size_t /*distance*/) override { return false; } // SU + bool ScrollDown(const size_t /*distance*/) override { return false; } // SD + bool InsertLine(const size_t /*distance*/) override { return false; } // IL + bool DeleteLine(const size_t /*distance*/) override { return false; } // DL + bool SetColumns(const size_t /*columns*/) override { return false; } // DECSCPP, DECCOLM + bool SetCursorKeysMode(const bool /*applicationMode*/) override { return false; } // DECCKM + bool SetKeypadMode(const bool /*applicationMode*/) override { return false; } // DECKPAM, DECKPNM + bool EnableCursorBlinking(const bool /*enable*/) override { return false; } // ATT610 + bool SetOriginMode(const bool /*relativeMode*/) override { return false; }; // DECOM + bool SetTopBottomScrollingMargins(const size_t /*topMargin*/, const size_t /*bottomMargin*/) override { return false; } // DECSTBM bool ReverseLineFeed() override { return false; } // RI bool SetWindowTitle(std::wstring_view /*title*/) override { return false; } // OscWindowTitle bool UseAlternateScreenBuffer() override { return false; } // ASBSET bool UseMainScreenBuffer() override { return false; } // ASBRST bool HorizontalTabSet() override { return false; } // HTS - bool ForwardTab(const SHORT /*sNumTabs*/) override { return false; } // CHT - bool BackwardsTab(const SHORT /*sNumTabs*/) override { return false; } // CBT - bool TabClear(const SHORT /*sClearType*/) override { return false; } // TBC - bool EnableDECCOLMSupport(const bool /*fEnabled*/) override { return false; } // ?40 - bool EnableVT200MouseMode(const bool /*fEnabled*/) override { return false; } // ?1000 - bool EnableUTF8ExtendedMouseMode(const bool /*fEnabled*/) override { return false; } // ?1005 - bool EnableSGRExtendedMouseMode(const bool /*fEnabled*/) override { return false; } // ?1006 - bool EnableButtonEventMouseMode(const bool /*fEnabled*/) override { return false; } // ?1002 - bool EnableAnyEventMouseMode(const bool /*fEnabled*/) override { return false; } // ?1003 - bool EnableAlternateScroll(const bool /*fEnabled*/) override { return false; } // ?1007 - bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*dwColor*/) override { return false; } // OSCColorTable - bool SetDefaultForeground(const DWORD /*dwColor*/) override { return false; } // OSCDefaultForeground - bool SetDefaultBackground(const DWORD /*dwColor*/) override { return false; } // OSCDefaultBackground + bool ForwardTab(const size_t /*numTabs*/) override { return false; } // CHT + bool BackwardsTab(const size_t /*numTabs*/) override { return false; } // CBT + bool TabClear(const size_t /*clearType*/) override { return false; } // TBC + bool EnableDECCOLMSupport(const bool /*enabled*/) override { return false; } // ?40 + bool EnableVT200MouseMode(const bool /*enabled*/) override { return false; } // ?1000 + bool EnableUTF8ExtendedMouseMode(const bool /*enabled*/) override { return false; } // ?1005 + bool EnableSGRExtendedMouseMode(const bool /*enabled*/) override { return false; } // ?1006 + bool EnableButtonEventMouseMode(const bool /*enabled*/) override { return false; } // ?1002 + bool EnableAnyEventMouseMode(const bool /*enabled*/) override { return false; } // ?1003 + bool EnableAlternateScroll(const bool /*enabled*/) override { return false; } // ?1007 + bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*color*/) override { return false; } // OSCColorTable + bool SetDefaultForeground(const DWORD /*color*/) override { return false; } // OSCDefaultForeground + bool SetDefaultBackground(const DWORD /*color*/) override { return false; } // OSCDefaultBackground bool EraseInDisplay(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // ED bool EraseInLine(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // EL - bool EraseCharacters(const unsigned int /*uiNumChars*/) override { return false; } // ECH + bool EraseCharacters(const size_t /*numChars*/) override { return false; } // ECH - bool SetGraphicsRendition(_In_reads_(_Param_(2)) const DispatchTypes::GraphicsOptions* const /*rgOptions*/, - const size_t /*cOptions*/) override { return false; } // SGR + bool SetGraphicsRendition(const std::basic_string_view /*options*/) override { return false; } // SGR - bool SetPrivateModes(_In_reads_(_Param_(2)) const DispatchTypes::PrivateModeParams* const /*rgParams*/, - const size_t /*cParams*/) override { return false; } // DECSET + bool SetPrivateModes(const std::basic_string_view /*params*/) override { return false; } // DECSET - bool ResetPrivateModes(_In_reads_(_Param_(2)) const DispatchTypes::PrivateModeParams* const /*rgParams*/, - const size_t /*cParams*/) override { return false; } // DECRST + bool ResetPrivateModes(const std::basic_string_view /*params*/) override { return false; } // DECRST bool DeviceStatusReport(const DispatchTypes::AnsiStatusType /*statusType*/) override { return false; } // DSR bool DeviceAttributes() override { return false; } // DA @@ -90,10 +87,9 @@ public: bool ScreenAlignmentPattern() override { return false; } // DECALN bool SetCursorStyle(const DispatchTypes::CursorStyle /*cursorStyle*/) override { return false; } // DECSCUSR - bool SetCursorColor(const COLORREF /*Color*/) override { return false; } // OSCSetCursorColor, OSCResetCursorColor + bool SetCursorColor(const COLORREF /*color*/) override { return false; } // OSCSetCursorColor, OSCResetCursorColor // DTTERM_WindowManipulation - bool WindowManipulation(const DispatchTypes::WindowManipulationType /*uiFunction*/, - _In_reads_(_Param_(3)) const unsigned short* const /*rgusParams*/, - const size_t /*cParams*/) override { return false; } + bool WindowManipulation(const DispatchTypes::WindowManipulationType /*function*/, + const std::basic_string_view /*params*/) override { return false; } }; diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index 4328a876e6..99d8600729 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -37,7 +37,7 @@ enum class CursorX XCENTER }; -enum class CursorDirection : unsigned int +enum class CursorDirection : size_t { UP = 0, DOWN = 1, @@ -47,7 +47,7 @@ enum class CursorDirection : unsigned int PREVLINE = 5 }; -enum class AbsolutePosition : unsigned int +enum class AbsolutePosition : size_t { CursorHorizontal = 0, VerticalLine = 1, @@ -58,111 +58,111 @@ using namespace Microsoft::Console::VirtualTerminal; class TestGetSet final : public ConGetSet { public: - BOOL GetConsoleScreenBufferInfoEx(_Out_ CONSOLE_SCREEN_BUFFER_INFOEX* const psbiex) const override + bool GetConsoleScreenBufferInfoEx(CONSOLE_SCREEN_BUFFER_INFOEX& sbiex) const override { Log::Comment(L"GetConsoleScreenBufferInfoEx MOCK returning data..."); - if (_fGetConsoleScreenBufferInfoExResult) + if (_getConsoleScreenBufferInfoExResult) { - psbiex->dwSize = _coordBufferSize; - psbiex->srWindow = _srViewport; - psbiex->dwCursorPosition = _coordCursorPos; - psbiex->wAttributes = _wAttribute; + sbiex.dwSize = _bufferSize; + sbiex.srWindow = _viewport; + sbiex.dwCursorPosition = _cursorPos; + sbiex.wAttributes = _attribute; } - return _fGetConsoleScreenBufferInfoExResult; + return _getConsoleScreenBufferInfoExResult; } - BOOL SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX* const psbiex) override + bool SetConsoleScreenBufferInfoEx(const CONSOLE_SCREEN_BUFFER_INFOEX& sbiex) override { Log::Comment(L"SetConsoleScreenBufferInfoEx MOCK returning data..."); - if (_fSetConsoleScreenBufferInfoExResult) + if (_setConsoleScreenBufferInfoExResult) { - VERIFY_ARE_EQUAL(_coordExpectedCursorPos, psbiex->dwCursorPosition); - VERIFY_ARE_EQUAL(_coordExpectedScreenBufferSize, psbiex->dwSize); - VERIFY_ARE_EQUAL(_srExpectedScreenBufferViewport, psbiex->srWindow); - VERIFY_ARE_EQUAL(_wExpectedAttributes, psbiex->wAttributes); + VERIFY_ARE_EQUAL(_expectedCursorPos, sbiex.dwCursorPosition); + VERIFY_ARE_EQUAL(_expectedScreenBufferSize, sbiex.dwSize); + VERIFY_ARE_EQUAL(_expectedScreenBufferViewport, sbiex.srWindow); + VERIFY_ARE_EQUAL(_expectedAttributes, sbiex.wAttributes); } - return _fSetConsoleScreenBufferInfoExResult; + return _setConsoleScreenBufferInfoExResult; } - BOOL SetConsoleCursorPosition(const COORD dwCursorPosition) override + bool SetConsoleCursorPosition(const COORD position) override { Log::Comment(L"SetConsoleCursorPosition MOCK called..."); - if (_fSetConsoleCursorPositionResult) + if (_setConsoleCursorPositionResult) { - VERIFY_ARE_EQUAL(_coordExpectedCursorPos, dwCursorPosition); - _coordCursorPos = dwCursorPosition; + VERIFY_ARE_EQUAL(_expectedCursorPos, position); + _cursorPos = position; } - return _fSetConsoleCursorPositionResult; + return _setConsoleCursorPositionResult; } - BOOL GetConsoleCursorInfo(_In_ CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) const override + bool GetConsoleCursorInfo(CONSOLE_CURSOR_INFO& cursorInfo) const override { Log::Comment(L"GetConsoleCursorInfo MOCK called..."); - if (_fGetConsoleCursorInfoResult) + if (_getConsoleCursorInfoResult) { - pConsoleCursorInfo->dwSize = _dwCursorSize; - pConsoleCursorInfo->bVisible = _fCursorVisible; + cursorInfo.dwSize = _cursorSize; + cursorInfo.bVisible = _cursorVisible; } - return _fGetConsoleCursorInfoResult; + return _getConsoleCursorInfoResult; } - BOOL SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO* const pConsoleCursorInfo) override + bool SetConsoleCursorInfo(const CONSOLE_CURSOR_INFO& cursorInfo) override { Log::Comment(L"SetConsoleCursorInfo MOCK called..."); - if (_fSetConsoleCursorInfoResult) + if (_setConsoleCursorInfoResult) { - VERIFY_ARE_EQUAL(_dwExpectedCursorSize, pConsoleCursorInfo->dwSize); - VERIFY_ARE_EQUAL(_fExpectedCursorVisible, pConsoleCursorInfo->bVisible); + VERIFY_ARE_EQUAL(_expectedCursorSize, cursorInfo.dwSize); + VERIFY_ARE_EQUAL(_expectedCursorVisible, !!cursorInfo.bVisible); } - return _fSetConsoleCursorInfoResult; + return _setConsoleCursorInfoResult; } - BOOL SetConsoleWindowInfo(const BOOL bAbsolute, const SMALL_RECT* const lpConsoleWindow) override + bool SetConsoleWindowInfo(const bool absolute, const SMALL_RECT& window) override { Log::Comment(L"SetConsoleWindowInfo MOCK called..."); - if (_fSetConsoleWindowInfoResult) + if (_setConsoleWindowInfoResult) { - VERIFY_ARE_EQUAL(_fExpectedWindowAbsolute, bAbsolute); - VERIFY_ARE_EQUAL(_srExpectedConsoleWindow, *lpConsoleWindow); - _srViewport = *lpConsoleWindow; + VERIFY_ARE_EQUAL(_expectedWindowAbsolute, absolute); + VERIFY_ARE_EQUAL(_expectedConsoleWindow, window); + _viewport = window; } - return _fSetConsoleWindowInfoResult; + return _setConsoleWindowInfoResult; } - BOOL PrivateSetCursorKeysMode(const bool fCursorKeysApplicationMode) override + bool PrivateSetCursorKeysMode(const bool applicationMode) override { Log::Comment(L"PrivateSetCursorKeysMode MOCK called..."); - if (_fPrivateSetCursorKeysModeResult) + if (_privateSetCursorKeysModeResult) { - VERIFY_ARE_EQUAL(_fCursorKeysApplicationMode, fCursorKeysApplicationMode); + VERIFY_ARE_EQUAL(_cursorKeysApplicationMode, applicationMode); } - return _fPrivateSetCursorKeysModeResult; + return _privateSetCursorKeysModeResult; } - BOOL PrivateSetKeypadMode(const bool fKeypadApplicationMode) override + bool PrivateSetKeypadMode(const bool applicationMode) override { Log::Comment(L"PrivateSetKeypadMode MOCK called..."); - if (_fPrivateSetKeypadModeResult) + if (_privateSetKeypadModeResult) { - VERIFY_ARE_EQUAL(_fKeypadApplicationMode, fKeypadApplicationMode); + VERIFY_ARE_EQUAL(_keypadApplicationMode, applicationMode); } - return _fPrivateSetKeypadModeResult; + return _privateSetKeypadModeResult; } - BOOL PrivateShowCursor(const bool show) override + bool PrivateShowCursor(const bool show) override { Log::Comment(L"PrivateShowCursor MOCK called..."); @@ -174,145 +174,145 @@ public: return _privateShowCursorResult; } - BOOL PrivateAllowCursorBlinking(const bool fEnable) override + bool PrivateAllowCursorBlinking(const bool enable) override { Log::Comment(L"PrivateAllowCursorBlinking MOCK called..."); - if (_fPrivateAllowCursorBlinkingResult) + if (_privateAllowCursorBlinkingResult) { - VERIFY_ARE_EQUAL(_fEnable, fEnable); + VERIFY_ARE_EQUAL(_enable, enable); } - return _fPrivateAllowCursorBlinkingResult; + return _privateAllowCursorBlinkingResult; } - BOOL SetConsoleTextAttribute(const WORD wAttr) override + bool SetConsoleTextAttribute(const WORD attr) override { Log::Comment(L"SetConsoleTextAttribute MOCK called..."); - if (_fSetConsoleTextAttributeResult) + if (_setConsoleTextAttributeResult) { - VERIFY_ARE_EQUAL(_wExpectedAttribute, wAttr); - _wAttribute = wAttr; - _fUsingRgbColor = false; + VERIFY_ARE_EQUAL(_expectedAttribute, attr); + _attribute = attr; + _usingRgbColor = false; } - return _fSetConsoleTextAttributeResult; + return _setConsoleTextAttributeResult; } - BOOL PrivateSetLegacyAttributes(const WORD wAttr, const bool fForeground, const bool fBackground, const bool fMeta) override + bool PrivateSetLegacyAttributes(const WORD attr, const bool foreground, const bool background, const bool meta) override { Log::Comment(L"PrivateSetLegacyAttributes MOCK called..."); - if (_fPrivateSetLegacyAttributesResult) + if (_privateSetLegacyAttributesResult) { - VERIFY_ARE_EQUAL(_fExpectedForeground, fForeground); - VERIFY_ARE_EQUAL(_fExpectedBackground, fBackground); - VERIFY_ARE_EQUAL(_fExpectedMeta, fMeta); - if (fForeground) + VERIFY_ARE_EQUAL(_expectedForeground, foreground); + VERIFY_ARE_EQUAL(_expectedBackground, background); + VERIFY_ARE_EQUAL(_expectedMeta, meta); + if (foreground) { - WI_UpdateFlagsInMask(_wAttribute, FG_ATTRS, wAttr); + WI_UpdateFlagsInMask(_attribute, FG_ATTRS, attr); } - if (fBackground) + if (background) { - WI_UpdateFlagsInMask(_wAttribute, BG_ATTRS, wAttr); + WI_UpdateFlagsInMask(_attribute, BG_ATTRS, attr); } - if (fMeta) + if (meta) { - WI_UpdateFlagsInMask(_wAttribute, META_ATTRS, wAttr); + WI_UpdateFlagsInMask(_attribute, META_ATTRS, attr); } - VERIFY_ARE_EQUAL(_wExpectedAttribute, wAttr); + VERIFY_ARE_EQUAL(_expectedAttribute, attr); - _fExpectedForeground = _fExpectedBackground = _fExpectedMeta = false; + _expectedForeground = _expectedBackground = _expectedMeta = false; } - return _fPrivateSetLegacyAttributesResult; + return _privateSetLegacyAttributesResult; } - BOOL SetConsoleXtermTextAttribute(const int iXtermTableEntry, const bool fIsForeground) override + bool SetConsoleXtermTextAttribute(const int xtermTableEntry, const bool isForeground) override { Log::Comment(L"SetConsoleXtermTextAttribute MOCK called..."); - if (_fSetConsoleXtermTextAttributeResult) + if (_setConsoleXtermTextAttributeResult) { - VERIFY_ARE_EQUAL(_fExpectedIsForeground, fIsForeground); - _fIsForeground = fIsForeground; - VERIFY_ARE_EQUAL(_iExpectedXtermTableEntry, iXtermTableEntry); - _iXtermTableEntry = iXtermTableEntry; + VERIFY_ARE_EQUAL(_expectedIsForeground, isForeground); + _isForeground = isForeground; + VERIFY_ARE_EQUAL(_iExpectedXtermTableEntry, xtermTableEntry); + _xtermTableEntry = xtermTableEntry; // if the table entry is less than 16, keep using the legacy attr - _fUsingRgbColor = iXtermTableEntry > 16; - if (!_fUsingRgbColor) + _usingRgbColor = xtermTableEntry > 16; + if (!_usingRgbColor) { //Convert the xterm index to the win index - bool fRed = (iXtermTableEntry & 0x01) > 0; - bool fGreen = (iXtermTableEntry & 0x02) > 0; - bool fBlue = (iXtermTableEntry & 0x04) > 0; - bool fBright = (iXtermTableEntry & 0x08) > 0; - WORD iWinEntry = (fRed ? 0x4 : 0x0) | (fGreen ? 0x2 : 0x0) | (fBlue ? 0x1 : 0x0) | (fBright ? 0x8 : 0x0); - _wAttribute = fIsForeground ? ((_wAttribute & 0xF0) | iWinEntry) : ((iWinEntry << 4) | (_wAttribute & 0x0F)); + const auto red = (xtermTableEntry & 0x01) > 0; + const auto green = (xtermTableEntry & 0x02) > 0; + const auto blue = (xtermTableEntry & 0x04) > 0; + const auto bright = (xtermTableEntry & 0x08) > 0; + WORD winEntry = (red ? 0x4 : 0x0) | (green ? 0x2 : 0x0) | (blue ? 0x1 : 0x0) | (bright ? 0x8 : 0x0); + _attribute = isForeground ? ((_attribute & 0xF0) | winEntry) : ((winEntry << 4) | (_attribute & 0x0F)); } } - return _fSetConsoleXtermTextAttributeResult; + return _setConsoleXtermTextAttributeResult; } - BOOL SetConsoleRGBTextAttribute(const COLORREF rgbColor, const bool fIsForeground) override + bool SetConsoleRGBTextAttribute(const COLORREF rgbColor, const bool isForeground) override { Log::Comment(L"SetConsoleRGBTextAttribute MOCK called..."); - if (_fSetConsoleRGBTextAttributeResult) + if (_setConsoleRGBTextAttributeResult) { - VERIFY_ARE_EQUAL(_fExpectedIsForeground, fIsForeground); - _fIsForeground = fIsForeground; - VERIFY_ARE_EQUAL(_ExpectedColor, rgbColor); + VERIFY_ARE_EQUAL(_expectedIsForeground, isForeground); + _isForeground = isForeground; + VERIFY_ARE_EQUAL(_expectedColor, rgbColor); _rgbColor = rgbColor; - _fUsingRgbColor = true; + _usingRgbColor = true; } - return _fSetConsoleRGBTextAttributeResult; + return _setConsoleRGBTextAttributeResult; } - BOOL PrivateBoldText(const bool isBold) override + bool PrivateBoldText(const bool isBold) override { Log::Comment(L"PrivateBoldText MOCK called..."); - if (_fPrivateBoldTextResult) + if (_privateBoldTextResult) { - VERIFY_ARE_EQUAL(_fExpectedIsBold, isBold); - _fIsBold = isBold; - _fExpectedIsBold = false; + VERIFY_ARE_EQUAL(_expectedIsBold, isBold); + _isBold = isBold; + _expectedIsBold = false; } - return !!_fPrivateBoldTextResult; + return !!_privateBoldTextResult; } - BOOL PrivateGetExtendedTextAttributes(ExtendedAttributes* const /*pAttrs*/) + bool PrivateGetExtendedTextAttributes(ExtendedAttributes& /*attrs*/) { Log::Comment(L"PrivateGetExtendedTextAttributes MOCK called..."); return true; } - BOOL PrivateSetExtendedTextAttributes(const ExtendedAttributes /*attrs*/) + bool PrivateSetExtendedTextAttributes(const ExtendedAttributes /*attrs*/) { Log::Comment(L"PrivateSetExtendedTextAttributes MOCK called..."); return true; } - BOOL PrivateGetTextAttributes(TextAttribute* const /*pAttrs*/) const + bool PrivateGetTextAttributes(TextAttribute& /*attrs*/) const { Log::Comment(L"PrivateGetTextAttributes MOCK called..."); return true; } - BOOL PrivateSetTextAttributes(const TextAttribute& /*attrs*/) + bool PrivateSetTextAttributes(const TextAttribute& /*attrs*/) { Log::Comment(L"PrivateSetTextAttributes MOCK called..."); return true; } - BOOL PrivateWriteConsoleInputW(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) override + bool PrivateWriteConsoleInputW(std::deque>& events, + size_t& eventsWritten) override { Log::Comment(L"PrivateWriteConsoleInputW MOCK called..."); - if (_fPrivateWriteConsoleInputWResult) + if (_privateWriteConsoleInputWResult) { // move all the input events we were given into local storage so we can test against them Log::Comment(NoThrowString().Format(L"Moving %zu input events into local storage...", events.size())); @@ -322,15 +322,15 @@ public: eventsWritten = _events.size(); } - return _fPrivateWriteConsoleInputWResult; + return _privateWriteConsoleInputWResult; } - BOOL PrivatePrependConsoleInput(_Inout_ std::deque>& events, - _Out_ size_t& eventsWritten) override + bool PrivatePrependConsoleInput(std::deque>& events, + size_t& eventsWritten) override { Log::Comment(L"PrivatePrependConsoleInput MOCK called..."); - if (_fPrivatePrependConsoleInputResult) + if (_privatePrependConsoleInputResult) { // move all the input events we were given into local storage so we can test against them Log::Comment(NoThrowString().Format(L"Moving %zu input events into local storage...", events.size())); @@ -340,327 +340,330 @@ public: eventsWritten = _events.size(); } - return _fPrivatePrependConsoleInputResult; + return _privatePrependConsoleInputResult; } - BOOL PrivateWriteConsoleControlInput(_In_ KeyEvent key) override + bool PrivateWriteConsoleControlInput(_In_ KeyEvent key) override { Log::Comment(L"PrivateWriteConsoleControlInput MOCK called..."); - if (_fPrivateWriteConsoleControlInputResult) + if (_privateWriteConsoleControlInputResult) { VERIFY_ARE_EQUAL('C', key.GetVirtualKeyCode()); VERIFY_ARE_EQUAL(0x3, key.GetCharData()); VERIFY_ARE_EQUAL(true, key.IsCtrlPressed()); } - return _fPrivateWriteConsoleControlInputResult; + return _privateWriteConsoleControlInputResult; } - BOOL PrivateSetScrollingRegion(const SMALL_RECT* const psrScrollMargins) override + bool PrivateSetScrollingRegion(const SMALL_RECT& scrollMargins) override { Log::Comment(L"PrivateSetScrollingRegion MOCK called..."); - if (_fPrivateSetScrollingRegionResult) + if (_privateSetScrollingRegionResult) { - VERIFY_ARE_EQUAL(_srExpectedScrollRegion, *psrScrollMargins); + VERIFY_ARE_EQUAL(_expectedScrollRegion, scrollMargins); } - return _fPrivateSetScrollingRegionResult; + return _privateSetScrollingRegionResult; } - BOOL PrivateReverseLineFeed() override + bool PrivateReverseLineFeed() override { Log::Comment(L"PrivateReverseLineFeed MOCK called..."); // We made it through the adapter, woo! Return true. return TRUE; } - BOOL MoveCursorVertically(const short lines) override + bool MoveCursorVertically(const ptrdiff_t lines) override { Log::Comment(L"MoveCursorVertically MOCK called..."); - if (_fMoveCursorVerticallyResult) + short l; + VERIFY_SUCCEEDED(PtrdiffTToShort(lines, &l)); + if (_moveCursorVerticallyResult) { - VERIFY_ARE_EQUAL(_expectedLines, lines); - _coordCursorPos = { _coordCursorPos.X, _coordCursorPos.Y + lines }; + VERIFY_ARE_EQUAL(_expectedLines, l); + _cursorPos = { _cursorPos.X, _cursorPos.Y + l }; } - return !!_fMoveCursorVerticallyResult; + return !!_moveCursorVerticallyResult; } - BOOL SetConsoleTitleW(const std::wstring_view title) + bool SetConsoleTitleW(const std::wstring_view title) { Log::Comment(L"SetConsoleTitleW MOCK called..."); - if (_fSetConsoleTitleWResult) + if (_setConsoleTitleWResult) { - VERIFY_ARE_EQUAL(_pwchExpectedWindowTitle, title.data()); - VERIFY_ARE_EQUAL(_sCchExpectedTitleLength, title.size()); + // Put into WEX strings for rich logging when they don't compare. + VERIFY_ARE_EQUAL(String(_expectedWindowTitle.data(), gsl::narrow(_expectedWindowTitle.size())), + String(title.data(), gsl::narrow(title.size()))); } return TRUE; } - BOOL PrivateUseAlternateScreenBuffer() override + bool PrivateUseAlternateScreenBuffer() override { Log::Comment(L"PrivateUseAlternateScreenBuffer MOCK called..."); return true; } - BOOL PrivateUseMainScreenBuffer() override + bool PrivateUseMainScreenBuffer() override { Log::Comment(L"PrivateUseMainScreenBuffer MOCK called..."); return true; } - BOOL PrivateHorizontalTabSet() override + bool PrivateHorizontalTabSet() override { Log::Comment(L"PrivateHorizontalTabSet MOCK called..."); // We made it through the adapter, woo! Return true. return TRUE; } - BOOL PrivateForwardTab(const SHORT sNumTabs) override + bool PrivateForwardTab(const size_t numTabs) override { Log::Comment(L"PrivateForwardTab MOCK called..."); - if (_fPrivateForwardTabResult) + if (_privateForwardTabResult) { - VERIFY_ARE_EQUAL(_sExpectedNumTabs, sNumTabs); + VERIFY_ARE_EQUAL(_expectedNumTabs, numTabs); } return TRUE; } - BOOL PrivateBackwardsTab(const SHORT sNumTabs) override + bool PrivateBackwardsTab(const size_t numTabs) override { Log::Comment(L"PrivateBackwardsTab MOCK called..."); - if (_fPrivateBackwardsTabResult) + if (_privateBackwardsTabResult) { - VERIFY_ARE_EQUAL(_sExpectedNumTabs, sNumTabs); + VERIFY_ARE_EQUAL(_expectedNumTabs, numTabs); } return TRUE; } - BOOL PrivateTabClear(const bool fClearAll) override + bool PrivateTabClear(const bool clearAll) override { Log::Comment(L"PrivateTabClear MOCK called..."); - if (_fPrivateTabClearResult) + if (_privateTabClearResult) { - VERIFY_ARE_EQUAL(_fExpectedClearAll, fClearAll); + VERIFY_ARE_EQUAL(_expectedClearAll, clearAll); } return TRUE; } - BOOL PrivateSetDefaultTabStops() override + bool PrivateSetDefaultTabStops() override { Log::Comment(L"PrivateSetDefaultTabStops MOCK called..."); return TRUE; } - BOOL PrivateEnableVT200MouseMode(const bool fEnabled) override + bool PrivateEnableVT200MouseMode(const bool enabled) override { Log::Comment(L"PrivateEnableVT200MouseMode MOCK called..."); - if (_fPrivateEnableVT200MouseModeResult) + if (_privateEnableVT200MouseModeResult) { - VERIFY_ARE_EQUAL(_fExpectedMouseEnabled, fEnabled); + VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); } - return _fPrivateEnableVT200MouseModeResult; + return _privateEnableVT200MouseModeResult; } - BOOL PrivateEnableUTF8ExtendedMouseMode(const bool fEnabled) override + bool PrivateEnableUTF8ExtendedMouseMode(const bool enabled) override { Log::Comment(L"PrivateEnableUTF8ExtendedMouseMode MOCK called..."); - if (_fPrivateEnableUTF8ExtendedMouseModeResult) + if (_privateEnableUTF8ExtendedMouseModeResult) { - VERIFY_ARE_EQUAL(_fExpectedMouseEnabled, fEnabled); + VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); } - return _fPrivateEnableUTF8ExtendedMouseModeResult; + return _privateEnableUTF8ExtendedMouseModeResult; } - BOOL PrivateEnableSGRExtendedMouseMode(const bool fEnabled) override + bool PrivateEnableSGRExtendedMouseMode(const bool enabled) override { Log::Comment(L"PrivateEnableSGRExtendedMouseMode MOCK called..."); - if (_fPrivateEnableSGRExtendedMouseModeResult) + if (_privateEnableSGRExtendedMouseModeResult) { - VERIFY_ARE_EQUAL(_fExpectedMouseEnabled, fEnabled); + VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); } - return _fPrivateEnableSGRExtendedMouseModeResult; + return _privateEnableSGRExtendedMouseModeResult; } - BOOL PrivateEnableButtonEventMouseMode(const bool fEnabled) override + bool PrivateEnableButtonEventMouseMode(const bool enabled) override { Log::Comment(L"PrivateEnableButtonEventMouseMode MOCK called..."); - if (_fPrivateEnableButtonEventMouseModeResult) + if (_privateEnableButtonEventMouseModeResult) { - VERIFY_ARE_EQUAL(_fExpectedMouseEnabled, fEnabled); + VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); } - return _fPrivateEnableButtonEventMouseModeResult; + return _privateEnableButtonEventMouseModeResult; } - BOOL PrivateEnableAnyEventMouseMode(const bool fEnabled) override + bool PrivateEnableAnyEventMouseMode(const bool enabled) override { Log::Comment(L"PrivateEnableAnyEventMouseMode MOCK called..."); - if (_fPrivateEnableAnyEventMouseModeResult) + if (_privateEnableAnyEventMouseModeResult) { - VERIFY_ARE_EQUAL(_fExpectedMouseEnabled, fEnabled); + VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); } - return _fPrivateEnableAnyEventMouseModeResult; + return _privateEnableAnyEventMouseModeResult; } - BOOL PrivateEnableAlternateScroll(const bool fEnabled) override + bool PrivateEnableAlternateScroll(const bool enabled) override { Log::Comment(L"PrivateEnableAlternateScroll MOCK called..."); - if (_fPrivateEnableAlternateScrollResult) + if (_privateEnableAlternateScrollResult) { - VERIFY_ARE_EQUAL(_fExpectedAlternateScrollEnabled, fEnabled); + VERIFY_ARE_EQUAL(_expectedAlternateScrollEnabled, enabled); } - return _fPrivateEnableAlternateScrollResult; + return _privateEnableAlternateScrollResult; } - BOOL PrivateEraseAll() override + bool PrivateEraseAll() override { Log::Comment(L"PrivateEraseAll MOCK called..."); return TRUE; } - BOOL SetCursorStyle(const CursorType cursorType) override + bool SetCursorStyle(const CursorType cursorType) override { Log::Comment(L"SetCursorStyle MOCK called..."); - if (_fSetCursorStyleResult) + if (_setCursorStyleResult) { - VERIFY_ARE_EQUAL(_ExpectedCursorStyle, cursorType); + VERIFY_ARE_EQUAL(_expectedCursorStyle, cursorType); } - return _fSetCursorStyleResult; + return _setCursorStyleResult; } - BOOL SetCursorColor(const COLORREF cursorColor) override + bool SetCursorColor(const COLORREF cursorColor) override { Log::Comment(L"SetCursorColor MOCK called..."); - if (_fSetCursorColorResult) + if (_setCursorColorResult) { - VERIFY_ARE_EQUAL(_ExpectedCursorColor, cursorColor); + VERIFY_ARE_EQUAL(_expectedCursorColor, cursorColor); } - return _fSetCursorColorResult; + return _setCursorColorResult; } - BOOL PrivateGetConsoleScreenBufferAttributes(_Out_ WORD* const pwAttributes) override + bool PrivateGetConsoleScreenBufferAttributes(WORD& attributes) override { Log::Comment(L"PrivateGetConsoleScreenBufferAttributes MOCK returning data..."); - if (pwAttributes != nullptr && _fPrivateGetConsoleScreenBufferAttributesResult) + if (_privateGetConsoleScreenBufferAttributesResult) { - *pwAttributes = _wAttribute; + attributes = _attribute; } - return _fPrivateGetConsoleScreenBufferAttributesResult; + return _privateGetConsoleScreenBufferAttributesResult; } - BOOL PrivateRefreshWindow() override + bool PrivateRefreshWindow() override { Log::Comment(L"PrivateRefreshWindow MOCK called..."); // We made it through the adapter, woo! Return true. return TRUE; } - BOOL PrivateSuppressResizeRepaint() override + bool PrivateSuppressResizeRepaint() override { Log::Comment(L"PrivateSuppressResizeRepaint MOCK called..."); VERIFY_IS_TRUE(false, L"AdaptDispatch should never be calling this function."); return FALSE; } - BOOL GetConsoleOutputCP(_Out_ unsigned int* const puiOutputCP) override + bool GetConsoleOutputCP(unsigned int& codepage) override { Log::Comment(L"GetConsoleOutputCP MOCK called..."); - if (_fGetConsoleOutputCPResult) + if (_getConsoleOutputCPResult) { - *puiOutputCP = _uiExpectedOutputCP; + codepage = _expectedOutputCP; } - return _fGetConsoleOutputCPResult; + return _getConsoleOutputCPResult; } - BOOL IsConsolePty(_Out_ bool* const isPty) const override + bool IsConsolePty(bool& isPty) const override { Log::Comment(L"IsConsolePty MOCK called..."); - if (_fIsConsolePtyResult) + if (_isConsolePtyResult) { - *isPty = _fIsPty; + isPty = _isPty; } - return _fIsConsolePtyResult; + return _isConsolePtyResult; } - BOOL DeleteLines(const unsigned int /*count*/) override + bool DeleteLines(const size_t /*count*/) override { Log::Comment(L"DeleteLines MOCK called..."); return TRUE; } - BOOL InsertLines(const unsigned int /*count*/) override + bool InsertLines(const size_t /*count*/) override { Log::Comment(L"InsertLines MOCK called..."); return TRUE; } - BOOL PrivateSetDefaultAttributes(const bool fForeground, - const bool fBackground) override + bool PrivateSetDefaultAttributes(const bool foreground, + const bool background) override { Log::Comment(L"PrivateSetDefaultAttributes MOCK called..."); - if (_fPrivateSetDefaultAttributesResult) + if (_privateSetDefaultAttributesResult) { - VERIFY_ARE_EQUAL(_fExpectedForeground, fForeground); - VERIFY_ARE_EQUAL(_fExpectedBackground, fBackground); - if (fForeground) + VERIFY_ARE_EQUAL(_expectedForeground, foreground); + VERIFY_ARE_EQUAL(_expectedBackground, background); + if (foreground) { - WI_UpdateFlagsInMask(_wAttribute, FG_ATTRS, s_wDefaultFill); + WI_UpdateFlagsInMask(_attribute, FG_ATTRS, s_defaultFill); } - if (fBackground) + if (background) { - WI_UpdateFlagsInMask(_wAttribute, BG_ATTRS, s_wDefaultFill); + WI_UpdateFlagsInMask(_attribute, BG_ATTRS, s_defaultFill); } - _fExpectedForeground = _fExpectedBackground = false; + _expectedForeground = _expectedBackground = false; } - return _fPrivateSetDefaultAttributesResult; + return _privateSetDefaultAttributesResult; } - BOOL MoveToBottom() const override + bool MoveToBottom() const override { Log::Comment(L"MoveToBottom MOCK called..."); - return _fMoveToBottomResult; + return _moveToBottomResult; } - BOOL PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept override + bool PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept override { Log::Comment(L"PrivateSetColorTableEntry MOCK called..."); - if (_fPrivateSetColorTableEntryResult) + if (_privateSetColorTableEntryResult) { VERIFY_ARE_EQUAL(_expectedColorTableIndex, index); VERIFY_ARE_EQUAL(_expectedColorValue, value); } - return _fPrivateSetColorTableEntryResult; + return _privateSetColorTableEntryResult; } - BOOL PrivateSetDefaultForeground(const COLORREF value) const noexcept override + bool PrivateSetDefaultForeground(const COLORREF value) const noexcept override { Log::Comment(L"PrivateSetDefaultForeground MOCK called..."); - if (_fPrivateSetDefaultForegroundResult) + if (_privateSetDefaultForegroundResult) { VERIFY_ARE_EQUAL(_expectedDefaultForegroundColorValue, value); } - return _fPrivateSetDefaultForegroundResult; + return _privateSetDefaultForegroundResult; } - BOOL PrivateSetDefaultBackground(const COLORREF value) const noexcept override + bool PrivateSetDefaultBackground(const COLORREF value) const noexcept override { Log::Comment(L"PrivateSetDefaultForeground MOCK called..."); - if (_fPrivateSetDefaultBackgroundResult) + if (_privateSetDefaultBackgroundResult) { VERIFY_ARE_EQUAL(_expectedDefaultBackgroundColorValue, value); } - return _fPrivateSetDefaultBackgroundResult; + return _privateSetDefaultBackgroundResult; } - BOOL PrivateFillRegion(const COORD /*startPosition*/, + bool PrivateFillRegion(const COORD /*startPosition*/, const size_t /*fillLength*/, const wchar_t /*fillChar*/, const bool /*standardFillAttrs*/) noexcept override @@ -670,7 +673,7 @@ public: return TRUE; } - BOOL PrivateScrollRegion(const SMALL_RECT /*scrollRect*/, + bool PrivateScrollRegion(const SMALL_RECT /*scrollRect*/, const std::optional /*clipRect*/, const COORD /*destinationOrigin*/, const bool /*standardFillAttrs*/) noexcept override @@ -709,39 +712,39 @@ public: Log::Comment(L"Resetting mock data state."); // APIs succeed by default - _fSetConsoleCursorPositionResult = TRUE; - _fGetConsoleScreenBufferInfoExResult = TRUE; - _fGetConsoleCursorInfoResult = TRUE; - _fSetConsoleCursorInfoResult = TRUE; - _fSetConsoleTextAttributeResult = TRUE; - _fPrivateWriteConsoleInputWResult = TRUE; - _fPrivatePrependConsoleInputResult = TRUE; - _fPrivateWriteConsoleControlInputResult = TRUE; - _fSetConsoleWindowInfoResult = TRUE; - _fPrivateGetConsoleScreenBufferAttributesResult = TRUE; - _fMoveToBottomResult = true; + _setConsoleCursorPositionResult = TRUE; + _getConsoleScreenBufferInfoExResult = TRUE; + _getConsoleCursorInfoResult = TRUE; + _setConsoleCursorInfoResult = TRUE; + _setConsoleTextAttributeResult = TRUE; + _privateWriteConsoleInputWResult = TRUE; + _privatePrependConsoleInputResult = TRUE; + _privateWriteConsoleControlInputResult = TRUE; + _setConsoleWindowInfoResult = TRUE; + _privateGetConsoleScreenBufferAttributesResult = TRUE; + _moveToBottomResult = true; - _coordBufferSize.X = 100; - _coordBufferSize.Y = 600; + _bufferSize.X = 100; + _bufferSize.Y = 600; // Viewport sitting in the "middle" of the buffer somewhere (so all sides have excess buffer around them) - _srViewport.Top = 20; - _srViewport.Bottom = 49; - _srViewport.Left = 30; - _srViewport.Right = 59; + _viewport.Top = 20; + _viewport.Bottom = 49; + _viewport.Left = 30; + _viewport.Right = 59; // Call cursor positions seperately PrepCursor(xact, yact); - _dwCursorSize = 33; - _dwExpectedCursorSize = _dwCursorSize; + _cursorSize = 33; + _expectedCursorSize = _cursorSize; - _fCursorVisible = TRUE; - _fExpectedCursorVisible = _fCursorVisible; + _cursorVisible = TRUE; + _expectedCursorVisible = _cursorVisible; // Attribute default is gray on black. - _wAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - _wExpectedAttribute = _wAttribute; + _attribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + _expectedAttribute = _attribute; _expectedLines = 0; } @@ -754,15 +757,15 @@ public: { case CursorX::LEFT: Log::Comment(L"Cursor set to left edge of viewport."); - _coordCursorPos.X = _srViewport.Left; + _cursorPos.X = _viewport.Left; break; case CursorX::RIGHT: Log::Comment(L"Cursor set to right edge of viewport."); - _coordCursorPos.X = _srViewport.Right - 1; + _cursorPos.X = _viewport.Right - 1; break; case CursorX::XCENTER: Log::Comment(L"Cursor set to centered X of viewport."); - _coordCursorPos.X = _srViewport.Left + ((_srViewport.Right - _srViewport.Left) / 2); + _cursorPos.X = _viewport.Left + ((_viewport.Right - _viewport.Left) / 2); break; } @@ -770,19 +773,19 @@ public: { case CursorY::TOP: Log::Comment(L"Cursor set to top edge of viewport."); - _coordCursorPos.Y = _srViewport.Top; + _cursorPos.Y = _viewport.Top; break; case CursorY::BOTTOM: Log::Comment(L"Cursor set to bottom edge of viewport."); - _coordCursorPos.Y = _srViewport.Bottom - 1; + _cursorPos.Y = _viewport.Bottom - 1; break; case CursorY::YCENTER: Log::Comment(L"Cursor set to centered Y of viewport."); - _coordCursorPos.Y = _srViewport.Top + ((_srViewport.Bottom - _srViewport.Top) / 2); + _cursorPos.Y = _viewport.Top + ((_viewport.Bottom - _viewport.Top) / 2); break; } - _coordExpectedCursorPos = _coordCursorPos; + _expectedCursorPos = _cursorPos; } void ValidateInputEvent(_In_ PCWSTR pwszExpectedResponse) @@ -816,8 +819,8 @@ public: rect->Top = top; rect->Bottom = bottom; //The rectangle is going to get converted from VT space to conhost space - _srExpectedScrollRegion.Top = (top > 0) ? rect->Top - 1 : rect->Top; - _srExpectedScrollRegion.Bottom = (bottom > 0) ? rect->Bottom - 1 : rect->Bottom; + _expectedScrollRegion.Top = (top > 0) ? rect->Top - 1 : rect->Top; + _expectedScrollRegion.Bottom = (bottom > 0) ? rect->Bottom - 1 : rect->Bottom; } ~TestGetSet() @@ -828,109 +831,108 @@ public: static const WCHAR s_wchDefault = L'Z'; static const WORD s_wAttrErase = FOREGROUND_BLUE | FOREGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; static const WORD s_wDefaultAttribute = 0; - static const WORD s_wDefaultFill = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; // dark gray on black. + static const WORD s_defaultFill = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; // dark gray on black. std::deque> _events; - COORD _coordBufferSize = { 0, 0 }; - SMALL_RECT _srViewport = { 0, 0, 0, 0 }; - SMALL_RECT _srExpectedConsoleWindow = { 0, 0, 0, 0 }; - COORD _coordCursorPos = { 0, 0 }; - SMALL_RECT _srExpectedScrollRegion = { 0, 0, 0, 0 }; + COORD _bufferSize = { 0, 0 }; + SMALL_RECT _viewport = { 0, 0, 0, 0 }; + SMALL_RECT _expectedConsoleWindow = { 0, 0, 0, 0 }; + COORD _cursorPos = { 0, 0 }; + SMALL_RECT _expectedScrollRegion = { 0, 0, 0, 0 }; - DWORD _dwCursorSize = 0; - BOOL _fCursorVisible = false; + DWORD _cursorSize = 0; + bool _cursorVisible = false; - COORD _coordExpectedCursorPos = { 0, 0 }; - DWORD _dwExpectedCursorSize = 0; - BOOL _fExpectedCursorVisible = false; + COORD _expectedCursorPos = { 0, 0 }; + DWORD _expectedCursorSize = 0; + bool _expectedCursorVisible = false; - WORD _wAttribute = 0; - WORD _wExpectedAttribute = 0; - int _iXtermTableEntry = 0; + WORD _attribute = 0; + WORD _expectedAttribute = 0; + int _xtermTableEntry = 0; int _iExpectedXtermTableEntry = 0; COLORREF _rgbColor = 0; - COLORREF _ExpectedColor = 0; - bool _fIsForeground = false; - bool _fExpectedIsForeground = false; - bool _fUsingRgbColor = false; - bool _fExpectedForeground = false; - bool _fExpectedBackground = false; - bool _fExpectedMeta = false; - unsigned int _uiExpectedOutputCP = 0; - bool _fIsPty = false; + COLORREF _expectedColor = 0; + bool _isForeground = false; + bool _expectedIsForeground = false; + bool _usingRgbColor = false; + bool _expectedForeground = false; + bool _expectedBackground = false; + bool _expectedMeta = false; + unsigned int _expectedOutputCP = 0; + bool _isPty = false; short _expectedLines = 0; - bool _fPrivateBoldTextResult = false; - bool _fExpectedIsBold = false; - bool _fIsBold = false; + bool _privateBoldTextResult = false; + bool _expectedIsBold = false; + bool _isBold = false; bool _privateShowCursorResult = false; bool _expectedShowCursor = false; - BOOL _fGetConsoleScreenBufferInfoExResult = false; - BOOL _fSetConsoleCursorPositionResult = false; - BOOL _fGetConsoleCursorInfoResult = false; - BOOL _fSetConsoleCursorInfoResult = false; - BOOL _fSetConsoleTextAttributeResult = false; - BOOL _fPrivateWriteConsoleInputWResult = false; - BOOL _fPrivatePrependConsoleInputResult = false; - BOOL _fPrivateWriteConsoleControlInputResult = false; + bool _getConsoleScreenBufferInfoExResult = false; + bool _setConsoleCursorPositionResult = false; + bool _getConsoleCursorInfoResult = false; + bool _setConsoleCursorInfoResult = false; + bool _setConsoleTextAttributeResult = false; + bool _privateWriteConsoleInputWResult = false; + bool _privatePrependConsoleInputResult = false; + bool _privateWriteConsoleControlInputResult = false; - BOOL _fSetConsoleWindowInfoResult = false; - BOOL _fExpectedWindowAbsolute = false; - BOOL _fSetConsoleScreenBufferInfoExResult = false; + bool _setConsoleWindowInfoResult = false; + bool _expectedWindowAbsolute = false; + bool _setConsoleScreenBufferInfoExResult = false; - COORD _coordExpectedScreenBufferSize = { 0, 0 }; - SMALL_RECT _srExpectedScreenBufferViewport{ 0, 0, 0, 0 }; - WORD _wExpectedAttributes = 0; - BOOL _fPrivateSetCursorKeysModeResult = false; - BOOL _fPrivateSetKeypadModeResult = false; - bool _fCursorKeysApplicationMode = false; - bool _fKeypadApplicationMode = false; - BOOL _fPrivateAllowCursorBlinkingResult = false; - bool _fEnable = false; // for cursor blinking - BOOL _fPrivateSetScrollingRegionResult = false; - BOOL _fPrivateReverseLineFeedResult = false; + COORD _expectedScreenBufferSize = { 0, 0 }; + SMALL_RECT _expectedScreenBufferViewport{ 0, 0, 0, 0 }; + WORD _expectedAttributes = 0; + bool _privateSetCursorKeysModeResult = false; + bool _privateSetKeypadModeResult = false; + bool _cursorKeysApplicationMode = false; + bool _keypadApplicationMode = false; + bool _privateAllowCursorBlinkingResult = false; + bool _enable = false; // for cursor blinking + bool _privateSetScrollingRegionResult = false; + bool _privateReverseLineFeedResult = false; - BOOL _fSetConsoleTitleWResult = false; - wchar_t* _pwchExpectedWindowTitle = nullptr; - unsigned short _sCchExpectedTitleLength = 0; - BOOL _fPrivateHorizontalTabSetResult = false; - BOOL _fPrivateForwardTabResult = false; - BOOL _fPrivateBackwardsTabResult = false; - SHORT _sExpectedNumTabs = 0; - BOOL _fPrivateTabClearResult = false; - bool _fExpectedClearAll = false; - bool _fExpectedMouseEnabled = false; - bool _fExpectedAlternateScrollEnabled = false; - BOOL _fPrivateEnableVT200MouseModeResult = false; - BOOL _fPrivateEnableUTF8ExtendedMouseModeResult = false; - BOOL _fPrivateEnableSGRExtendedMouseModeResult = false; - BOOL _fPrivateEnableButtonEventMouseModeResult = false; - BOOL _fPrivateEnableAnyEventMouseModeResult = false; - BOOL _fPrivateEnableAlternateScrollResult = false; - BOOL _fSetConsoleXtermTextAttributeResult = false; - BOOL _fSetConsoleRGBTextAttributeResult = false; - BOOL _fPrivateSetLegacyAttributesResult = false; - BOOL _fPrivateGetConsoleScreenBufferAttributesResult = false; - BOOL _fSetCursorStyleResult = false; - CursorType _ExpectedCursorStyle; - BOOL _fSetCursorColorResult = false; - COLORREF _ExpectedCursorColor = 0; - BOOL _fGetConsoleOutputCPResult = false; - BOOL _fIsConsolePtyResult = false; - bool _fMoveCursorVerticallyResult = false; - bool _fPrivateSetDefaultAttributesResult = false; - bool _fMoveToBottomResult = false; + bool _setConsoleTitleWResult = false; + std::wstring_view _expectedWindowTitle{}; + bool _privateHorizontalTabSetResult = false; + bool _privateForwardTabResult = false; + bool _privateBackwardsTabResult = false; + size_t _expectedNumTabs = 0; + bool _privateTabClearResult = false; + bool _expectedClearAll = false; + bool _expectedMouseEnabled = false; + bool _expectedAlternateScrollEnabled = false; + bool _privateEnableVT200MouseModeResult = false; + bool _privateEnableUTF8ExtendedMouseModeResult = false; + bool _privateEnableSGRExtendedMouseModeResult = false; + bool _privateEnableButtonEventMouseModeResult = false; + bool _privateEnableAnyEventMouseModeResult = false; + bool _privateEnableAlternateScrollResult = false; + bool _setConsoleXtermTextAttributeResult = false; + bool _setConsoleRGBTextAttributeResult = false; + bool _privateSetLegacyAttributesResult = false; + bool _privateGetConsoleScreenBufferAttributesResult = false; + bool _setCursorStyleResult = false; + CursorType _expectedCursorStyle; + bool _setCursorColorResult = false; + COLORREF _expectedCursorColor = 0; + bool _getConsoleOutputCPResult = false; + bool _isConsolePtyResult = false; + bool _moveCursorVerticallyResult = false; + bool _privateSetDefaultAttributesResult = false; + bool _moveToBottomResult = false; - bool _fPrivateSetColorTableEntryResult = false; + bool _privateSetColorTableEntryResult = false; short _expectedColorTableIndex = -1; COLORREF _expectedColorValue = INVALID_COLOR; - bool _fPrivateSetDefaultForegroundResult = false; + bool _privateSetDefaultForegroundResult = false; COLORREF _expectedDefaultForegroundColorValue = INVALID_COLOR; - bool _fPrivateSetDefaultBackgroundResult = false; + bool _privateSetDefaultBackgroundResult = false; COLORREF _expectedDefaultBackgroundColorValue = INVALID_COLOR; private: @@ -943,7 +945,7 @@ class DummyAdapter : public AdaptDefaults { } - void PrintString(_In_reads_(_Param_(2)) const wchar_t* const /*rgwch*/, const size_t /*cch*/) override + void PrintString(const std::wstring_view /*string*/) override { } @@ -961,12 +963,15 @@ public: { bool fSuccess = true; - _testGetSet = new TestGetSet; - fSuccess = _testGetSet != nullptr; + auto api = std::make_unique(); + fSuccess = api.get() != nullptr; if (fSuccess) { + auto adapter = std::make_unique(); + // give AdaptDispatch ownership of _testGetSet - _pDispatch = new AdaptDispatch(_testGetSet, new DummyAdapter); + _testGetSet = api.get(); // keep a copy for us but don't manage its lifetime anymore. + _pDispatch = std::make_unique(std::move(api), std::move(adapter)); fSuccess = _pDispatch != nullptr; } return fSuccess; @@ -974,7 +979,7 @@ public: TEST_METHOD_CLEANUP(CleanupMethods) { - delete _pDispatch; + _pDispatch.reset(); _testGetSet = nullptr; return true; } @@ -988,12 +993,12 @@ public: Log::Comment(L"Starting test..."); // Used to switch between the various function options. - typedef bool (AdaptDispatch::*CursorMoveFunc)(unsigned int); + typedef bool (AdaptDispatch::*CursorMoveFunc)(size_t); CursorMoveFunc moveFunc = nullptr; // Modify variables based on directionality of this test CursorDirection direction; - unsigned int dir; + size_t dir; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiDirection", dir)); direction = (CursorDirection)dir; @@ -1041,20 +1046,20 @@ public: case CursorDirection::UP: Log::Comment(L"Testing up direction."); _testGetSet->_expectedLines = -1; - _testGetSet->_fMoveCursorVerticallyResult = true; + _testGetSet->_moveCursorVerticallyResult = true; break; case CursorDirection::DOWN: Log::Comment(L"Testing down direction."); _testGetSet->_expectedLines = 1; - _testGetSet->_fMoveCursorVerticallyResult = true; + _testGetSet->_moveCursorVerticallyResult = true; break; default: _testGetSet->_expectedLines = 0; - _testGetSet->_fMoveCursorVerticallyResult = false; + _testGetSet->_moveCursorVerticallyResult = false; break; } - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(1)); + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(1)); Log::Comment(L"Test 1b: Cursor moves to left of line with next/prev line command when cursor can't move higher/lower."); @@ -1074,8 +1079,8 @@ public: if (fDoTest1b) { - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left; - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(1)); + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left; + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(1)); } else { @@ -1089,32 +1094,32 @@ public: switch (direction) { case CursorDirection::UP: - _testGetSet->_coordExpectedCursorPos.Y--; + _testGetSet->_expectedCursorPos.Y--; _testGetSet->_expectedLines = -1; - _testGetSet->_fMoveCursorVerticallyResult = true; + _testGetSet->_moveCursorVerticallyResult = true; break; case CursorDirection::DOWN: - _testGetSet->_coordExpectedCursorPos.Y++; + _testGetSet->_expectedCursorPos.Y++; _testGetSet->_expectedLines = 1; - _testGetSet->_fMoveCursorVerticallyResult = true; + _testGetSet->_moveCursorVerticallyResult = true; break; case CursorDirection::RIGHT: - _testGetSet->_coordExpectedCursorPos.X++; + _testGetSet->_expectedCursorPos.X++; break; case CursorDirection::LEFT: - _testGetSet->_coordExpectedCursorPos.X--; + _testGetSet->_expectedCursorPos.X--; break; case CursorDirection::NEXTLINE: - _testGetSet->_coordExpectedCursorPos.Y++; - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left; + _testGetSet->_expectedCursorPos.Y++; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left; break; case CursorDirection::PREVLINE: - _testGetSet->_coordExpectedCursorPos.Y--; - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left; + _testGetSet->_expectedCursorPos.Y--; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left; break; } - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(1)); + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(1)); // place cursor and move it up too far. It should get bounded by the viewport. Log::Comment(L"Test 3: Cursor moves and gets stuck at viewport when started away from edges and moved beyond edges."); @@ -1125,40 +1130,40 @@ public: switch (direction) { case CursorDirection::UP: - _testGetSet->_coordExpectedCursorPos.Y = _testGetSet->_srViewport.Top; + _testGetSet->_expectedCursorPos.Y = _testGetSet->_viewport.Top; _testGetSet->_expectedLines = -100; - _testGetSet->_fMoveCursorVerticallyResult = true; + _testGetSet->_moveCursorVerticallyResult = true; break; case CursorDirection::DOWN: - _testGetSet->_coordExpectedCursorPos.Y = _testGetSet->_srViewport.Bottom - 1; + _testGetSet->_expectedCursorPos.Y = _testGetSet->_viewport.Bottom - 1; _testGetSet->_expectedLines = 100; - _testGetSet->_fMoveCursorVerticallyResult = true; + _testGetSet->_moveCursorVerticallyResult = true; break; case CursorDirection::RIGHT: - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Right - 1; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Right - 1; break; case CursorDirection::LEFT: - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left; break; case CursorDirection::NEXTLINE: - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left; - _testGetSet->_coordExpectedCursorPos.Y = _testGetSet->_srViewport.Bottom - 1; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left; + _testGetSet->_expectedCursorPos.Y = _testGetSet->_viewport.Bottom - 1; break; case CursorDirection::PREVLINE: - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left; - _testGetSet->_coordExpectedCursorPos.Y = _testGetSet->_srViewport.Top; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left; + _testGetSet->_expectedCursorPos.Y = _testGetSet->_viewport.Top; break; } - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(100)); + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(100)); // error cases // give too large an up distance, cursor move should fail, cursor should stay the same. Log::Comment(L"Test 4: When given invalid (massive) move distance that doesn't fit in a short, call fails and cursor doesn't move."); _testGetSet->PrepData(CursorX::XCENTER, CursorY::YCENTER); - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(UINT_MAX)); - VERIFY_ARE_EQUAL(_testGetSet->_coordExpectedCursorPos, _testGetSet->_coordCursorPos); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(UINT_MAX)); + VERIFY_ARE_EQUAL(_testGetSet->_expectedCursorPos, _testGetSet->_cursorPos); // cause short underflow. cursor move should fail. cursor should stay the same. Log::Comment(L"Test 5: When an over/underflow occurs in cursor math, call fails and cursor doesn't move."); @@ -1168,50 +1173,50 @@ public: { case CursorDirection::UP: case CursorDirection::PREVLINE: - _testGetSet->_coordCursorPos.Y = -10; + _testGetSet->_cursorPos.Y = -10; break; case CursorDirection::DOWN: case CursorDirection::NEXTLINE: - _testGetSet->_coordCursorPos.Y = 10; + _testGetSet->_cursorPos.Y = 10; break; case CursorDirection::RIGHT: - _testGetSet->_coordCursorPos.X = 10; + _testGetSet->_cursorPos.X = 10; break; case CursorDirection::LEFT: - _testGetSet->_coordCursorPos.X = -10; + _testGetSet->_cursorPos.X = -10; break; } - _testGetSet->_coordExpectedCursorPos = _testGetSet->_coordCursorPos; + _testGetSet->_expectedCursorPos = _testGetSet->_cursorPos; - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(SHRT_MAX + 1)); - VERIFY_ARE_EQUAL(_testGetSet->_coordExpectedCursorPos, _testGetSet->_coordCursorPos); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(SHRT_MAX + 1)); + VERIFY_ARE_EQUAL(_testGetSet->_expectedCursorPos, _testGetSet->_cursorPos); // SetConsoleCursorPosition throws failure. Parameters are otherwise normal. Log::Comment(L"Test 6: When SetConsoleCursorPosition throws a failure, call fails and cursor doesn't move."); _testGetSet->PrepData(direction); - _testGetSet->_fSetConsoleCursorPositionResult = FALSE; - _testGetSet->_fMoveCursorVerticallyResult = false; + _testGetSet->_setConsoleCursorPositionResult = FALSE; + _testGetSet->_moveCursorVerticallyResult = false; - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(0)); - VERIFY_ARE_EQUAL(_testGetSet->_coordExpectedCursorPos, _testGetSet->_coordCursorPos); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(0)); + VERIFY_ARE_EQUAL(_testGetSet->_expectedCursorPos, _testGetSet->_cursorPos); // GetConsoleScreenBufferInfo throws failure. Parameters are otherwise normal. Log::Comment(L"Test 7: When GetConsoleScreenBufferInfo throws a failure, call fails and cursor doesn't move."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - _testGetSet->_fGetConsoleScreenBufferInfoExResult = FALSE; - _testGetSet->_fMoveCursorVerticallyResult = true; + _testGetSet->_getConsoleScreenBufferInfoExResult = FALSE; + _testGetSet->_moveCursorVerticallyResult = true; Log::Comment(NoThrowString().Format( L"Cursor Up and Down don't need GetConsoleScreenBufferInfoEx, so they will succeed")); if (direction == CursorDirection::UP || direction == CursorDirection::DOWN) { - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(0)); + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(0)); } else { - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(0)); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(0)); } - VERIFY_ARE_EQUAL(_testGetSet->_coordExpectedCursorPos, _testGetSet->_coordCursorPos); + VERIFY_ARE_EQUAL(_testGetSet->_expectedCursorPos, _testGetSet->_cursorPos); } TEST_METHOD(CursorPositionTest) @@ -1221,64 +1226,64 @@ public: Log::Comment(L"Test 1: Place cursor within the viewport. Start from top left, move to middle."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - short sCol = (_testGetSet->_srViewport.Right - _testGetSet->_srViewport.Left) / 2; - short sRow = (_testGetSet->_srViewport.Bottom - _testGetSet->_srViewport.Top) / 2; + short sCol = (_testGetSet->_viewport.Right - _testGetSet->_viewport.Left) / 2; + short sRow = (_testGetSet->_viewport.Bottom - _testGetSet->_viewport.Top) / 2; - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left + (sCol - 1); - _testGetSet->_coordExpectedCursorPos.Y = _testGetSet->_srViewport.Top + (sRow - 1); + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left + (sCol - 1); + _testGetSet->_expectedCursorPos.Y = _testGetSet->_viewport.Top + (sRow - 1); - VERIFY_IS_TRUE(_pDispatch->CursorPosition(sRow, sCol)); + VERIFY_IS_TRUE(_pDispatch.get()->CursorPosition(sRow, sCol)); Log::Comment(L"Test 2: Move to 0, 0 (which is 1,1 in VT speak)"); _testGetSet->PrepData(CursorX::RIGHT, CursorY::BOTTOM); - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Left; - _testGetSet->_coordExpectedCursorPos.Y = _testGetSet->_srViewport.Top; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Left; + _testGetSet->_expectedCursorPos.Y = _testGetSet->_viewport.Top; - VERIFY_IS_TRUE(_pDispatch->CursorPosition(1, 1)); + VERIFY_IS_TRUE(_pDispatch.get()->CursorPosition(1, 1)); Log::Comment(L"Test 3: Move beyond rectangle (down/right too far). Should be bounded back in."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - sCol = (_testGetSet->_srViewport.Right - _testGetSet->_srViewport.Left) * 2; - sRow = (_testGetSet->_srViewport.Bottom - _testGetSet->_srViewport.Top) * 2; + sCol = (_testGetSet->_viewport.Right - _testGetSet->_viewport.Left) * 2; + sRow = (_testGetSet->_viewport.Bottom - _testGetSet->_viewport.Top) * 2; - _testGetSet->_coordExpectedCursorPos.X = _testGetSet->_srViewport.Right - 1; - _testGetSet->_coordExpectedCursorPos.Y = _testGetSet->_srViewport.Bottom - 1; + _testGetSet->_expectedCursorPos.X = _testGetSet->_viewport.Right - 1; + _testGetSet->_expectedCursorPos.Y = _testGetSet->_viewport.Bottom - 1; - VERIFY_IS_TRUE(_pDispatch->CursorPosition(sRow, sCol)); + VERIFY_IS_TRUE(_pDispatch.get()->CursorPosition(sRow, sCol)); Log::Comment(L"Test 4: Values too large for short. Cursor shouldn't move. Return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - VERIFY_IS_FALSE(_pDispatch->CursorPosition(UINT_MAX, UINT_MAX)); + VERIFY_IS_FALSE(_pDispatch.get()->CursorPosition(UINT_MAX, UINT_MAX)); Log::Comment(L"Test 5: Overflow during addition. Cursor shouldn't move. Return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - _testGetSet->_srViewport.Left = SHRT_MAX; - _testGetSet->_srViewport.Top = SHRT_MAX; + _testGetSet->_viewport.Left = SHRT_MAX; + _testGetSet->_viewport.Top = SHRT_MAX; - VERIFY_IS_FALSE(_pDispatch->CursorPosition(5, 5)); + VERIFY_IS_FALSE(_pDispatch.get()->CursorPosition(5, 5)); Log::Comment(L"Test 6: GetConsoleInfo API returns false. No move, return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - _testGetSet->_fGetConsoleScreenBufferInfoExResult = FALSE; + _testGetSet->_getConsoleScreenBufferInfoExResult = FALSE; - VERIFY_IS_FALSE(_pDispatch->CursorPosition(1, 1)); + VERIFY_IS_FALSE(_pDispatch.get()->CursorPosition(1, 1)); Log::Comment(L"Test 7: SetCursor API returns false. No move, return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - _testGetSet->_fSetConsoleCursorPositionResult = FALSE; + _testGetSet->_setConsoleCursorPositionResult = FALSE; - VERIFY_IS_FALSE(_pDispatch->CursorPosition(1, 1)); + VERIFY_IS_FALSE(_pDispatch.get()->CursorPosition(1, 1)); Log::Comment(L"Test 8: Move to 0,0. Cursor shouldn't move. Return false. 1,1 is the top left corner in VT100 speak. 0,0 isn't a position. The parser will give 1 for a 0 input."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - VERIFY_IS_FALSE(_pDispatch->CursorPosition(0, 0)); + VERIFY_IS_FALSE(_pDispatch.get()->CursorPosition(0, 0)); } TEST_METHOD(CursorSingleDimensionMoveTest) @@ -1290,7 +1295,7 @@ public: Log::Comment(L"Starting test..."); //// Used to switch between the various function options. - typedef bool (AdaptDispatch::*CursorMoveFunc)(unsigned int); + typedef bool (AdaptDispatch::*CursorMoveFunc)(size_t); CursorMoveFunc moveFunc = nullptr; SHORT* psViewportEnd = nullptr; SHORT* psViewportStart = nullptr; @@ -1298,7 +1303,7 @@ public: // Modify variables based on directionality of this test AbsolutePosition direction; - unsigned int dir; + size_t dir; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiDirection", dir)); direction = (AbsolutePosition)dir; @@ -1306,16 +1311,16 @@ public: { case AbsolutePosition::CursorHorizontal: Log::Comment(L"Testing cursor horizontal movement."); - psViewportEnd = &_testGetSet->_srViewport.Right; - psViewportStart = &_testGetSet->_srViewport.Left; - psCursorExpected = &_testGetSet->_coordExpectedCursorPos.X; + psViewportEnd = &_testGetSet->_viewport.Right; + psViewportStart = &_testGetSet->_viewport.Left; + psCursorExpected = &_testGetSet->_expectedCursorPos.X; moveFunc = &AdaptDispatch::CursorHorizontalPositionAbsolute; break; case AbsolutePosition::VerticalLine: Log::Comment(L"Testing vertical line movement."); - psViewportEnd = &_testGetSet->_srViewport.Bottom; - psViewportStart = &_testGetSet->_srViewport.Top; - psCursorExpected = &_testGetSet->_coordExpectedCursorPos.Y; + psViewportEnd = &_testGetSet->_viewport.Bottom; + psViewportStart = &_testGetSet->_viewport.Top; + psCursorExpected = &_testGetSet->_expectedCursorPos.Y; moveFunc = &AdaptDispatch::VerticalLinePositionAbsolute; break; } @@ -1333,7 +1338,7 @@ public: *psCursorExpected = *psViewportStart + (sVal - 1); - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(sVal)); Log::Comment(L"Test 2: Move to 0 (which is 1 in VT speak)"); _testGetSet->PrepData(CursorX::RIGHT, CursorY::BOTTOM); @@ -1341,7 +1346,7 @@ public: *psCursorExpected = *psViewportStart; sVal = 1; - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(sVal)); Log::Comment(L"Test 3: Move beyond rectangle (down/right too far). Should be bounded back in."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); @@ -1350,48 +1355,48 @@ public: *psCursorExpected = *psViewportEnd - 1; - VERIFY_IS_TRUE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_TRUE((_pDispatch.get()->*(moveFunc))(sVal)); Log::Comment(L"Test 4: Values too large for short. Cursor shouldn't move. Return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); sVal = SHORT_MAX; - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(sVal)); Log::Comment(L"Test 5: Overflow during addition. Cursor shouldn't move. Return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - _testGetSet->_srViewport.Left = SHRT_MAX; + _testGetSet->_viewport.Left = SHRT_MAX; sVal = 5; - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(sVal)); Log::Comment(L"Test 6: GetConsoleInfo API returns false. No move, return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - _testGetSet->_fGetConsoleScreenBufferInfoExResult = FALSE; + _testGetSet->_getConsoleScreenBufferInfoExResult = FALSE; sVal = 1; - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(sVal)); Log::Comment(L"Test 7: SetCursor API returns false. No move, return false."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - _testGetSet->_fSetConsoleCursorPositionResult = FALSE; + _testGetSet->_setConsoleCursorPositionResult = FALSE; sVal = 1; - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(sVal)); Log::Comment(L"Test 8: Move to 0. Cursor shouldn't move. Return false. 1 is the left edge in VT100 speak. 0 isn't a position. The parser will give 1 for a 0 input."); _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); sVal = 0; - VERIFY_IS_FALSE((_pDispatch->*(moveFunc))(sVal)); + VERIFY_IS_FALSE((_pDispatch.get()->*(moveFunc))(sVal)); } TEST_METHOD(CursorSaveRestoreTest) @@ -1404,29 +1409,29 @@ public: // Move cursor to top left and save off expected position. _testGetSet->PrepData(CursorX::LEFT, CursorY::TOP); - coordExpected = _testGetSet->_coordExpectedCursorPos; + coordExpected = _testGetSet->_expectedCursorPos; // Then move cursor to the middle and reset the expected to the top left. _testGetSet->PrepData(CursorX::XCENTER, CursorY::YCENTER); - _testGetSet->_coordExpectedCursorPos = coordExpected; + _testGetSet->_expectedCursorPos = coordExpected; - VERIFY_IS_TRUE(_pDispatch->CursorRestoreState(), L"By default, restore to top left corner (0,0 offset from viewport)."); + VERIFY_IS_TRUE(_pDispatch.get()->CursorRestoreState(), L"By default, restore to top left corner (0,0 offset from viewport)."); Log::Comment(L"Test 2: Place cursor in center. Save. Move cursor to corner. Restore. Should come back to center."); _testGetSet->PrepData(CursorX::XCENTER, CursorY::YCENTER); - VERIFY_IS_TRUE(_pDispatch->CursorSaveState(), L"Succeed at saving position."); + VERIFY_IS_TRUE(_pDispatch.get()->CursorSaveState(), L"Succeed at saving position."); Log::Comment(L"Backup expected cursor (in the middle). Move cursor to corner. Then re-set expected cursor to middle."); // save expected cursor position - coordExpected = _testGetSet->_coordExpectedCursorPos; + coordExpected = _testGetSet->_expectedCursorPos; // adjust cursor to corner _testGetSet->PrepData(CursorX::LEFT, CursorY::BOTTOM); // restore expected cursor position to center. - _testGetSet->_coordExpectedCursorPos = coordExpected; + _testGetSet->_expectedCursorPos = coordExpected; - VERIFY_IS_TRUE(_pDispatch->CursorRestoreState(), L"Restoring to corner should succeed. API call inside will test that cursor matched expected position."); + VERIFY_IS_TRUE(_pDispatch.get()->CursorRestoreState(), L"Restoring to corner should succeed. API call inside will test that cursor matched expected position."); } TEST_METHOD(CursorHideShowTest) @@ -1446,15 +1451,15 @@ public: Log::Comment(L"Test 1: Verify successful API call modifies visibility state."); _testGetSet->PrepData(); - _testGetSet->_fCursorVisible = fStart; + _testGetSet->_cursorVisible = fStart; _testGetSet->_privateShowCursorResult = true; _testGetSet->_expectedShowCursor = fEnd; - VERIFY_IS_TRUE(_pDispatch->CursorVisibility(fEnd)); + VERIFY_IS_TRUE(_pDispatch.get()->CursorVisibility(fEnd)); Log::Comment(L"Test 3: When we fail to set updated cursor information, the dispatch should fail."); _testGetSet->PrepData(); _testGetSet->_privateShowCursorResult = false; - VERIFY_IS_FALSE(_pDispatch->CursorVisibility(fEnd)); + VERIFY_IS_FALSE(_pDispatch.get()->CursorVisibility(fEnd)); } TEST_METHOD(GraphicsBaseTests) @@ -1468,23 +1473,23 @@ public: DispatchTypes::GraphicsOptions rgOptions[16]; size_t cOptions = 0; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 2: Gracefully fail when getting buffer information fails."); _testGetSet->PrepData(); - _testGetSet->_fPrivateGetConsoleScreenBufferAttributesResult = FALSE; + _testGetSet->_privateGetConsoleScreenBufferAttributesResult = FALSE; - VERIFY_IS_FALSE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + VERIFY_IS_FALSE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 3: Gracefully fail when setting attribute data fails."); _testGetSet->PrepData(); - _testGetSet->_fSetConsoleTextAttributeResult = FALSE; + _testGetSet->_setConsoleTextAttributeResult = FALSE; // Need at least one option in order for the call to be able to fail. rgOptions[0] = (DispatchTypes::GraphicsOptions)0; cOptions = 1; - VERIFY_IS_FALSE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + VERIFY_IS_FALSE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); } TEST_METHOD(GraphicsSingleTests) @@ -1498,7 +1503,7 @@ public: // Modify variables based on type of this test DispatchTypes::GraphicsOptions graphicsOption; - unsigned int uiGraphicsOption; + size_t uiGraphicsOption; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiGraphicsOptions", uiGraphicsOption)); graphicsOption = (DispatchTypes::GraphicsOptions)uiGraphicsOption; @@ -1506,272 +1511,272 @@ public: size_t cOptions = 1; rgOptions[0] = graphicsOption; - _testGetSet->_fPrivateSetLegacyAttributesResult = TRUE; + _testGetSet->_privateSetLegacyAttributesResult = TRUE; switch (graphicsOption) { case DispatchTypes::GraphicsOptions::Off: Log::Comment(L"Testing graphics 'Off/Reset'"); - _testGetSet->_wAttribute = (WORD)~_testGetSet->s_wDefaultFill; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fPrivateSetDefaultAttributesResult = true; - _testGetSet->_fExpectedForeground = true; - _testGetSet->_fExpectedBackground = true; - _testGetSet->_fExpectedMeta = true; - _testGetSet->_fPrivateBoldTextResult = true; - _testGetSet->_fExpectedIsBold = false; + _testGetSet->_attribute = (WORD)~_testGetSet->s_defaultFill; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_privateSetDefaultAttributesResult = true; + _testGetSet->_expectedForeground = true; + _testGetSet->_expectedBackground = true; + _testGetSet->_expectedMeta = true; + _testGetSet->_privateBoldTextResult = true; + _testGetSet->_expectedIsBold = false; break; case DispatchTypes::GraphicsOptions::BoldBright: Log::Comment(L"Testing graphics 'Bold/Bright'"); - _testGetSet->_wAttribute = 0; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY; - _testGetSet->_fExpectedForeground = true; - _testGetSet->_fPrivateBoldTextResult = true; - _testGetSet->_fExpectedIsBold = true; + _testGetSet->_attribute = 0; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY; + _testGetSet->_expectedForeground = true; + _testGetSet->_privateBoldTextResult = true; + _testGetSet->_expectedIsBold = true; break; case DispatchTypes::GraphicsOptions::Underline: Log::Comment(L"Testing graphics 'Underline'"); - _testGetSet->_wAttribute = 0; - _testGetSet->_wExpectedAttribute = COMMON_LVB_UNDERSCORE; - _testGetSet->_fExpectedMeta = true; + _testGetSet->_attribute = 0; + _testGetSet->_expectedAttribute = COMMON_LVB_UNDERSCORE; + _testGetSet->_expectedMeta = true; break; case DispatchTypes::GraphicsOptions::Negative: Log::Comment(L"Testing graphics 'Negative'"); - _testGetSet->_wAttribute = 0; - _testGetSet->_wExpectedAttribute = COMMON_LVB_REVERSE_VIDEO; - _testGetSet->_fExpectedMeta = true; + _testGetSet->_attribute = 0; + _testGetSet->_expectedAttribute = COMMON_LVB_REVERSE_VIDEO; + _testGetSet->_expectedMeta = true; break; case DispatchTypes::GraphicsOptions::NoUnderline: Log::Comment(L"Testing graphics 'No Underline'"); - _testGetSet->_wAttribute = COMMON_LVB_UNDERSCORE; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fExpectedMeta = true; + _testGetSet->_attribute = COMMON_LVB_UNDERSCORE; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedMeta = true; break; case DispatchTypes::GraphicsOptions::Positive: Log::Comment(L"Testing graphics 'Positive'"); - _testGetSet->_wAttribute = COMMON_LVB_REVERSE_VIDEO; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fExpectedMeta = true; + _testGetSet->_attribute = COMMON_LVB_REVERSE_VIDEO; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedMeta = true; break; case DispatchTypes::GraphicsOptions::ForegroundBlack: Log::Comment(L"Testing graphics 'Foreground Color Black'"); - _testGetSet->_wAttribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundBlue: Log::Comment(L"Testing graphics 'Foreground Color Blue'"); - _testGetSet->_wAttribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_BLUE; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundGreen: Log::Comment(L"Testing graphics 'Foreground Color Green'"); - _testGetSet->_wAttribute = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = FOREGROUND_GREEN; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_GREEN; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundCyan: Log::Comment(L"Testing graphics 'Foreground Color Cyan'"); - _testGetSet->_wAttribute = FOREGROUND_RED | FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundRed: Log::Comment(L"Testing graphics 'Foreground Color Red'"); - _testGetSet->_wAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundMagenta: Log::Comment(L"Testing graphics 'Foreground Color Magenta'"); - _testGetSet->_wAttribute = FOREGROUND_GREEN | FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE | FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_GREEN | FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundYellow: Log::Comment(L"Testing graphics 'Foreground Color Yellow'"); - _testGetSet->_wAttribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = FOREGROUND_GREEN | FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundWhite: Log::Comment(L"Testing graphics 'Foreground Color White'"); - _testGetSet->_wAttribute = FOREGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::ForegroundDefault: Log::Comment(L"Testing graphics 'Foreground Color Default'"); - _testGetSet->_fPrivateSetDefaultAttributesResult = true; - _testGetSet->_wAttribute = (WORD)~_testGetSet->s_wDefaultAttribute; // set the current attribute to the opposite of default so we can ensure all relevant bits flip. + _testGetSet->_privateSetDefaultAttributesResult = true; + _testGetSet->_attribute = (WORD)~_testGetSet->s_wDefaultAttribute; // set the current attribute to the opposite of default so we can ensure all relevant bits flip. // To get expected value, take what we started with and change ONLY the background series of bits to what the Default says. - _testGetSet->_wExpectedAttribute = _testGetSet->_wAttribute; // expect = starting - _testGetSet->_wExpectedAttribute &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); // turn off all bits related to the background - _testGetSet->_wExpectedAttribute |= (_testGetSet->s_wDefaultFill & (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)); // reapply ONLY background bits from the default attribute. - _testGetSet->_fExpectedForeground = true; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; // expect = starting + _testGetSet->_expectedAttribute &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); // turn off all bits related to the background + _testGetSet->_expectedAttribute |= (_testGetSet->s_defaultFill & (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY)); // reapply ONLY background bits from the default attribute. + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BackgroundBlack: Log::Comment(L"Testing graphics 'Background Color Black'"); - _testGetSet->_wAttribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundBlue: Log::Comment(L"Testing graphics 'Background Color Blue'"); - _testGetSet->_wAttribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = BACKGROUND_BLUE; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = BACKGROUND_BLUE; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundGreen: Log::Comment(L"Testing graphics 'Background Color Green'"); - _testGetSet->_wAttribute = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = BACKGROUND_GREEN; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = BACKGROUND_GREEN; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundCyan: Log::Comment(L"Testing graphics 'Background Color Cyan'"); - _testGetSet->_wAttribute = BACKGROUND_RED | BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundRed: Log::Comment(L"Testing graphics 'Background Color Red'"); - _testGetSet->_wAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundMagenta: Log::Comment(L"Testing graphics 'Background Color Magenta'"); - _testGetSet->_wAttribute = BACKGROUND_GREEN | BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = BACKGROUND_BLUE | BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_GREEN | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = BACKGROUND_BLUE | BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundYellow: Log::Comment(L"Testing graphics 'Background Color Yellow'"); - _testGetSet->_wAttribute = BACKGROUND_BLUE | BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = BACKGROUND_GREEN | BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_BLUE | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundWhite: Log::Comment(L"Testing graphics 'Background Color White'"); - _testGetSet->_wAttribute = BACKGROUND_INTENSITY; - _testGetSet->_wExpectedAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BackgroundDefault: Log::Comment(L"Testing graphics 'Background Color Default'"); - _testGetSet->_fPrivateSetDefaultAttributesResult = true; - _testGetSet->_wAttribute = (WORD)~_testGetSet->s_wDefaultAttribute; // set the current attribute to the opposite of default so we can ensure all relevant bits flip. + _testGetSet->_privateSetDefaultAttributesResult = true; + _testGetSet->_attribute = (WORD)~_testGetSet->s_wDefaultAttribute; // set the current attribute to the opposite of default so we can ensure all relevant bits flip. // To get expected value, take what we started with and change ONLY the background series of bits to what the Default says. - _testGetSet->_wExpectedAttribute = _testGetSet->_wAttribute; // expect = starting - _testGetSet->_wExpectedAttribute &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); // turn off all bits related to the background - _testGetSet->_wExpectedAttribute |= (_testGetSet->s_wDefaultFill & (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)); // reapply ONLY background bits from the default attribute. - _testGetSet->_fExpectedBackground = true; + _testGetSet->_expectedAttribute = _testGetSet->_attribute; // expect = starting + _testGetSet->_expectedAttribute &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); // turn off all bits related to the background + _testGetSet->_expectedAttribute |= (_testGetSet->s_defaultFill & (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY)); // reapply ONLY background bits from the default attribute. + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundBlack: Log::Comment(L"Testing graphics 'Bright Foreground Color Black'"); - _testGetSet->_wAttribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundBlue: Log::Comment(L"Testing graphics 'Bright Foreground Color Blue'"); - _testGetSet->_wAttribute = FOREGROUND_RED | FOREGROUND_GREEN; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundGreen: Log::Comment(L"Testing graphics 'Bright Foreground Color Green'"); - _testGetSet->_wAttribute = FOREGROUND_RED | FOREGROUND_BLUE; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_GREEN; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED | FOREGROUND_BLUE; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_GREEN; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundCyan: Log::Comment(L"Testing graphics 'Bright Foreground Color Cyan'"); - _testGetSet->_wAttribute = FOREGROUND_RED; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_RED; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundRed: Log::Comment(L"Testing graphics 'Bright Foreground Color Red'"); - _testGetSet->_wAttribute = FOREGROUND_BLUE | FOREGROUND_GREEN; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_BLUE | FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundMagenta: Log::Comment(L"Testing graphics 'Bright Foreground Color Magenta'"); - _testGetSet->_wAttribute = FOREGROUND_GREEN; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundYellow: Log::Comment(L"Testing graphics 'Bright Foreground Color Yellow'"); - _testGetSet->_wAttribute = FOREGROUND_BLUE; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = FOREGROUND_BLUE; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightForegroundWhite: Log::Comment(L"Testing graphics 'Bright Foreground Color White'"); - _testGetSet->_wAttribute = 0; - _testGetSet->_wExpectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - _testGetSet->_fExpectedForeground = true; + _testGetSet->_attribute = 0; + _testGetSet->_expectedAttribute = FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + _testGetSet->_expectedForeground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlack: Log::Comment(L"Testing graphics 'Bright Background Color Black'"); - _testGetSet->_wAttribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundBlue: Log::Comment(L"Testing graphics 'Bright Background Color Blue'"); - _testGetSet->_wAttribute = BACKGROUND_RED | BACKGROUND_GREEN; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_GREEN; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundGreen: Log::Comment(L"Testing graphics 'Bright Background Color Green'"); - _testGetSet->_wAttribute = BACKGROUND_RED | BACKGROUND_BLUE; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_GREEN; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED | BACKGROUND_BLUE; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_GREEN; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundCyan: Log::Comment(L"Testing graphics 'Bright Background Color Cyan'"); - _testGetSet->_wAttribute = BACKGROUND_RED; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_RED; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundRed: Log::Comment(L"Testing graphics 'Bright Background Color Red'"); - _testGetSet->_wAttribute = BACKGROUND_BLUE | BACKGROUND_GREEN; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_BLUE | BACKGROUND_GREEN; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundMagenta: Log::Comment(L"Testing graphics 'Bright Background Color Magenta'"); - _testGetSet->_wAttribute = BACKGROUND_GREEN; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_GREEN; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundYellow: Log::Comment(L"Testing graphics 'Bright Background Color Yellow'"); - _testGetSet->_wAttribute = BACKGROUND_BLUE; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = BACKGROUND_BLUE; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; case DispatchTypes::GraphicsOptions::BrightBackgroundWhite: Log::Comment(L"Testing graphics 'Bright Background Color White'"); - _testGetSet->_wAttribute = 0; - _testGetSet->_wExpectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; - _testGetSet->_fExpectedBackground = true; + _testGetSet->_attribute = 0; + _testGetSet->_expectedAttribute = BACKGROUND_INTENSITY | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED; + _testGetSet->_expectedBackground = true; break; default: VERIFY_FAIL(L"Test not implemented yet!"); break; } - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); } TEST_METHOD(GraphicsPersistBrightnessTests) @@ -1780,7 +1785,7 @@ public: _testGetSet->PrepData(); // default color from here is gray on black, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED - _testGetSet->_fPrivateSetLegacyAttributesResult = TRUE; + _testGetSet->_privateSetLegacyAttributesResult = TRUE; DispatchTypes::GraphicsOptions rgOptions[16]; size_t cOptions = 1; @@ -1788,113 +1793,113 @@ public: Log::Comment(L"Test 1: Basic brightness test"); Log::Comment(L"Reseting graphics options"); rgOptions[0] = DispatchTypes::GraphicsOptions::Off; - _testGetSet->_fPrivateSetDefaultAttributesResult = true; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fExpectedForeground = true; - _testGetSet->_fExpectedBackground = true; - _testGetSet->_fExpectedMeta = true; - _testGetSet->_fPrivateBoldTextResult = true; - _testGetSet->_fExpectedIsBold = false; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + _testGetSet->_privateSetDefaultAttributesResult = true; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedForeground = true; + _testGetSet->_expectedBackground = true; + _testGetSet->_expectedMeta = true; + _testGetSet->_privateBoldTextResult = true; + _testGetSet->_expectedIsBold = false; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Testing graphics 'Foreground Color Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + _testGetSet->_expectedAttribute = FOREGROUND_BLUE; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Enabling brightness"); rgOptions[0] = DispatchTypes::GraphicsOptions::BoldBright; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_fExpectedForeground = true; - _testGetSet->_fPrivateBoldTextResult = true; - _testGetSet->_fExpectedIsBold = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_TRUE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; + _testGetSet->_expectedForeground = true; + _testGetSet->_privateBoldTextResult = true; + _testGetSet->_expectedIsBold = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_TRUE(_testGetSet->_isBold); Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; - _testGetSet->_wExpectedAttribute = FOREGROUND_GREEN; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_TRUE(WI_IsFlagSet(_testGetSet->_wAttribute, FOREGROUND_GREEN)); - VERIFY_IS_TRUE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_GREEN; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_TRUE(WI_IsFlagSet(_testGetSet->_attribute, FOREGROUND_GREEN)); + VERIFY_IS_TRUE(_testGetSet->_isBold); Log::Comment(L"Test 2: Disable brightness, use a bright color, next normal call remains not bright"); Log::Comment(L"Reseting graphics options"); rgOptions[0] = DispatchTypes::GraphicsOptions::Off; - _testGetSet->_fPrivateSetDefaultAttributesResult = true; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fExpectedForeground = true; - _testGetSet->_fExpectedBackground = true; - _testGetSet->_fExpectedMeta = true; - _testGetSet->_fPrivateBoldTextResult = true; - _testGetSet->_fExpectedIsBold = false; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_TRUE(WI_IsFlagClear(_testGetSet->_wAttribute, FOREGROUND_INTENSITY)); - VERIFY_IS_FALSE(_testGetSet->_fIsBold); + _testGetSet->_privateSetDefaultAttributesResult = true; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedForeground = true; + _testGetSet->_expectedBackground = true; + _testGetSet->_expectedMeta = true; + _testGetSet->_privateBoldTextResult = true; + _testGetSet->_expectedIsBold = false; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_TRUE(WI_IsFlagClear(_testGetSet->_attribute, FOREGROUND_INTENSITY)); + VERIFY_IS_FALSE(_testGetSet->_isBold); Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::BrightForegroundBlue; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_FALSE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_FALSE(_testGetSet->_isBold); Log::Comment(L"Testing graphics 'Foreground Color Blue', brightness of 9x series doesn't persist"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_FALSE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_BLUE; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_FALSE(_testGetSet->_isBold); Log::Comment(L"Test 3: Enable brightness, use a bright color, brightness persists to next normal call"); Log::Comment(L"Reseting graphics options"); rgOptions[0] = DispatchTypes::GraphicsOptions::Off; - _testGetSet->_fPrivateSetDefaultAttributesResult = true; - _testGetSet->_wExpectedAttribute = 0; - _testGetSet->_fExpectedForeground = true; - _testGetSet->_fExpectedBackground = true; - _testGetSet->_fExpectedMeta = true; - _testGetSet->_fPrivateBoldTextResult = true; - _testGetSet->_fExpectedIsBold = false; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_FALSE(_testGetSet->_fIsBold); + _testGetSet->_privateSetDefaultAttributesResult = true; + _testGetSet->_expectedAttribute = 0; + _testGetSet->_expectedForeground = true; + _testGetSet->_expectedBackground = true; + _testGetSet->_expectedMeta = true; + _testGetSet->_privateBoldTextResult = true; + _testGetSet->_expectedIsBold = false; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_FALSE(_testGetSet->_isBold); Log::Comment(L"Testing graphics 'Foreground Color Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_FALSE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_BLUE; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_FALSE(_testGetSet->_isBold); Log::Comment(L"Enabling brightness"); rgOptions[0] = DispatchTypes::GraphicsOptions::BoldBright; - _testGetSet->_fPrivateBoldTextResult = true; - _testGetSet->_fExpectedIsBold = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_TRUE(_testGetSet->_fIsBold); + _testGetSet->_privateBoldTextResult = true; + _testGetSet->_expectedIsBold = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_TRUE(_testGetSet->_isBold); Log::Comment(L"Testing graphics 'Foreground Color Bright Blue'"); rgOptions[0] = DispatchTypes::GraphicsOptions::BrightForegroundBlue; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_TRUE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_BLUE | FOREGROUND_INTENSITY; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_TRUE(_testGetSet->_isBold); Log::Comment(L"Testing graphics 'Foreground Color Blue, with brightness', brightness of 9x series doesn't affect brightness"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundBlue; - _testGetSet->_wExpectedAttribute = FOREGROUND_BLUE; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_TRUE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_BLUE; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_TRUE(_testGetSet->_isBold); Log::Comment(L"Testing graphics 'Foreground Color Green, with brightness'"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundGreen; - _testGetSet->_wExpectedAttribute = FOREGROUND_GREEN; - _testGetSet->_fExpectedForeground = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); - VERIFY_IS_TRUE(_testGetSet->_fIsBold); + _testGetSet->_expectedAttribute = FOREGROUND_GREEN; + _testGetSet->_expectedForeground = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); + VERIFY_IS_TRUE(_testGetSet->_isBold); } TEST_METHOD(DeviceStatusReportTests) @@ -1903,7 +1908,7 @@ public: Log::Comment(L"Test 1: Verify failure when using bad status."); _testGetSet->PrepData(); - VERIFY_IS_FALSE(_pDispatch->DeviceStatusReport((DispatchTypes::AnsiStatusType)-1)); + VERIFY_IS_FALSE(_pDispatch.get()->DeviceStatusReport((DispatchTypes::AnsiStatusType)-1)); } TEST_METHOD(DeviceStatus_CursorPositionReportTests) @@ -1914,17 +1919,17 @@ public: _testGetSet->PrepData(CursorX::XCENTER, CursorY::YCENTER); // start with the cursor position in the buffer. - COORD coordCursorExpected = _testGetSet->_coordCursorPos; + COORD coordCursorExpected = _testGetSet->_cursorPos; // to get to VT, we have to adjust it to its position relative to the viewport. - coordCursorExpected.X -= _testGetSet->_srViewport.Left; - coordCursorExpected.Y -= _testGetSet->_srViewport.Top; + coordCursorExpected.X -= _testGetSet->_viewport.Left; + coordCursorExpected.Y -= _testGetSet->_viewport.Top; // Then note that VT is 1,1 based for the top left, so add 1. (The rest of the console uses 0,0 for array index bases.) coordCursorExpected.X++; coordCursorExpected.Y++; - VERIFY_IS_TRUE(_pDispatch->DeviceStatusReport(DispatchTypes::AnsiStatusType::CPR_CursorPositionReport)); + VERIFY_IS_TRUE(_pDispatch.get()->DeviceStatusReport(DispatchTypes::AnsiStatusType::CPR_CursorPositionReport)); wchar_t pwszBuffer[50]; @@ -1938,16 +1943,16 @@ public: Log::Comment(L"Test 1: Verify normal response."); _testGetSet->PrepData(); - VERIFY_IS_TRUE(_pDispatch->DeviceAttributes()); + VERIFY_IS_TRUE(_pDispatch.get()->DeviceAttributes()); PCWSTR pwszExpectedResponse = L"\x1b[?1;0c"; _testGetSet->ValidateInputEvent(pwszExpectedResponse); Log::Comment(L"Test 2: Verify failure when WriteConsoleInput doesn't work."); _testGetSet->PrepData(); - _testGetSet->_fPrivatePrependConsoleInputResult = FALSE; + _testGetSet->_privatePrependConsoleInputResult = FALSE; - VERIFY_IS_FALSE(_pDispatch->DeviceAttributes()); + VERIFY_IS_FALSE(_pDispatch.get()->DeviceAttributes()); } TEST_METHOD(CursorKeysModeTest) @@ -1957,17 +1962,17 @@ public: // success cases // set numeric mode = true Log::Comment(L"Test 1: application mode = false"); - _testGetSet->_fPrivateSetCursorKeysModeResult = TRUE; - _testGetSet->_fCursorKeysApplicationMode = false; + _testGetSet->_privateSetCursorKeysModeResult = TRUE; + _testGetSet->_cursorKeysApplicationMode = false; - VERIFY_IS_TRUE(_pDispatch->SetCursorKeysMode(false)); + VERIFY_IS_TRUE(_pDispatch.get()->SetCursorKeysMode(false)); // set numeric mode = false Log::Comment(L"Test 2: application mode = true"); - _testGetSet->_fPrivateSetCursorKeysModeResult = TRUE; - _testGetSet->_fCursorKeysApplicationMode = true; + _testGetSet->_privateSetCursorKeysModeResult = TRUE; + _testGetSet->_cursorKeysApplicationMode = true; - VERIFY_IS_TRUE(_pDispatch->SetCursorKeysMode(true)); + VERIFY_IS_TRUE(_pDispatch.get()->SetCursorKeysMode(true)); } TEST_METHOD(KeypadModeTest) @@ -1977,17 +1982,17 @@ public: // success cases // set numeric mode = true Log::Comment(L"Test 1: application mode = false"); - _testGetSet->_fPrivateSetKeypadModeResult = TRUE; - _testGetSet->_fKeypadApplicationMode = false; + _testGetSet->_privateSetKeypadModeResult = TRUE; + _testGetSet->_keypadApplicationMode = false; - VERIFY_IS_TRUE(_pDispatch->SetKeypadMode(false)); + VERIFY_IS_TRUE(_pDispatch.get()->SetKeypadMode(false)); // set numeric mode = false Log::Comment(L"Test 2: application mode = true"); - _testGetSet->_fPrivateSetKeypadModeResult = TRUE; - _testGetSet->_fKeypadApplicationMode = true; + _testGetSet->_privateSetKeypadModeResult = TRUE; + _testGetSet->_keypadApplicationMode = true; - VERIFY_IS_TRUE(_pDispatch->SetKeypadMode(true)); + VERIFY_IS_TRUE(_pDispatch.get()->SetKeypadMode(true)); } TEST_METHOD(AllowBlinkingTest) @@ -1997,17 +2002,17 @@ public: // success cases // set numeric mode = true Log::Comment(L"Test 1: enable blinking = true"); - _testGetSet->_fPrivateAllowCursorBlinkingResult = TRUE; - _testGetSet->_fEnable = true; + _testGetSet->_privateAllowCursorBlinkingResult = TRUE; + _testGetSet->_enable = true; - VERIFY_IS_TRUE(_pDispatch->EnableCursorBlinking(true)); + VERIFY_IS_TRUE(_pDispatch.get()->EnableCursorBlinking(true)); // set numeric mode = false Log::Comment(L"Test 2: enable blinking = false"); - _testGetSet->_fPrivateAllowCursorBlinkingResult = TRUE; - _testGetSet->_fEnable = false; + _testGetSet->_privateAllowCursorBlinkingResult = TRUE; + _testGetSet->_enable = false; - VERIFY_IS_TRUE(_pDispatch->EnableCursorBlinking(false)); + VERIFY_IS_TRUE(_pDispatch.get()->EnableCursorBlinking(false)); } TEST_METHOD(ScrollMarginsTest) @@ -2015,116 +2020,116 @@ public: Log::Comment(L"Starting test..."); SMALL_RECT srTestMargins = { 0 }; - _testGetSet->_srViewport.Right = 8; - _testGetSet->_srViewport.Bottom = 8; - _testGetSet->_fGetConsoleScreenBufferInfoExResult = TRUE; - SHORT sScreenHeight = _testGetSet->_srViewport.Bottom - _testGetSet->_srViewport.Top; + _testGetSet->_viewport.Right = 8; + _testGetSet->_viewport.Bottom = 8; + _testGetSet->_getConsoleScreenBufferInfoExResult = TRUE; + SHORT sScreenHeight = _testGetSet->_viewport.Bottom - _testGetSet->_viewport.Top; Log::Comment(L"Test 1: Verify having both values is valid."); _testGetSet->_SetMarginsHelper(&srTestMargins, 2, 6); - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - _testGetSet->_fSetConsoleCursorPositionResult = true; - _testGetSet->_fMoveToBottomResult = true; - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_privateSetScrollingRegionResult = TRUE; + _testGetSet->_setConsoleCursorPositionResult = true; + _testGetSet->_moveToBottomResult = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 2: Verify having only top is valid."); _testGetSet->_SetMarginsHelper(&srTestMargins, 7, 0); - _testGetSet->_srExpectedScrollRegion.Bottom = _testGetSet->_srViewport.Bottom - 1; // We expect the bottom to be the bottom of the viewport, exclusive. - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_expectedScrollRegion.Bottom = _testGetSet->_viewport.Bottom - 1; // We expect the bottom to be the bottom of the viewport, exclusive. + _testGetSet->_privateSetScrollingRegionResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 3: Verify having only bottom is valid."); _testGetSet->_SetMarginsHelper(&srTestMargins, 0, 7); - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_privateSetScrollingRegionResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 4: Verify having no values is valid."); _testGetSet->_SetMarginsHelper(&srTestMargins, 0, 0); - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_privateSetScrollingRegionResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 5: Verify having both values, but bad bounds is invalid."); _testGetSet->_SetMarginsHelper(&srTestMargins, 7, 3); - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - VERIFY_IS_FALSE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_privateSetScrollingRegionResult = TRUE; + VERIFY_IS_FALSE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 6: Verify setting margins to (0, height) clears them"); // First set, - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; + _testGetSet->_privateSetScrollingRegionResult = TRUE; _testGetSet->_SetMarginsHelper(&srTestMargins, 2, 6); - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); // Then clear _testGetSet->_SetMarginsHelper(&srTestMargins, 0, sScreenHeight); - _testGetSet->_srExpectedScrollRegion.Top = 0; - _testGetSet->_srExpectedScrollRegion.Bottom = 0; - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_expectedScrollRegion.Top = 0; + _testGetSet->_expectedScrollRegion.Bottom = 0; + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 7: Verify setting margins to (1, height) clears them"); // First set, - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; + _testGetSet->_privateSetScrollingRegionResult = TRUE; _testGetSet->_SetMarginsHelper(&srTestMargins, 2, 6); - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); // Then clear _testGetSet->_SetMarginsHelper(&srTestMargins, 1, sScreenHeight); - _testGetSet->_srExpectedScrollRegion.Top = 0; - _testGetSet->_srExpectedScrollRegion.Bottom = 0; - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_expectedScrollRegion.Top = 0; + _testGetSet->_expectedScrollRegion.Bottom = 0; + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 8: Verify setting margins to (1, 0) clears them"); // First set, - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; + _testGetSet->_privateSetScrollingRegionResult = TRUE; _testGetSet->_SetMarginsHelper(&srTestMargins, 2, 6); - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); // Then clear _testGetSet->_SetMarginsHelper(&srTestMargins, 1, 0); - _testGetSet->_srExpectedScrollRegion.Top = 0; - _testGetSet->_srExpectedScrollRegion.Bottom = 0; - VERIFY_IS_TRUE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_expectedScrollRegion.Top = 0; + _testGetSet->_expectedScrollRegion.Bottom = 0; + VERIFY_IS_TRUE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 9: Verify having top and bottom margin the same is invalid."); _testGetSet->_SetMarginsHelper(&srTestMargins, 4, 4); - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - VERIFY_IS_FALSE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_privateSetScrollingRegionResult = TRUE; + VERIFY_IS_FALSE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 10: Verify having top margin out of bounds is invalid."); _testGetSet->_SetMarginsHelper(&srTestMargins, sScreenHeight + 1, sScreenHeight + 10); - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - VERIFY_IS_FALSE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_privateSetScrollingRegionResult = TRUE; + VERIFY_IS_FALSE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); Log::Comment(L"Test 11: Verify having bottom margin out of bounds is invalid."); _testGetSet->_SetMarginsHelper(&srTestMargins, 1, sScreenHeight + 1); - _testGetSet->_fPrivateSetScrollingRegionResult = TRUE; - VERIFY_IS_FALSE(_pDispatch->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); + _testGetSet->_privateSetScrollingRegionResult = TRUE; + VERIFY_IS_FALSE(_pDispatch.get()->SetTopBottomScrollingMargins(srTestMargins.Top, srTestMargins.Bottom)); } TEST_METHOD(TabSetClearTests) { Log::Comment(L"Starting test..."); - _testGetSet->_fPrivateHorizontalTabSetResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->HorizontalTabSet()); + _testGetSet->_privateHorizontalTabSetResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->HorizontalTabSet()); - _testGetSet->_sExpectedNumTabs = 16; + _testGetSet->_expectedNumTabs = 16; - _testGetSet->_fPrivateForwardTabResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->ForwardTab(16)); + _testGetSet->_privateForwardTabResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->ForwardTab(16)); - _testGetSet->_fPrivateBackwardsTabResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->BackwardsTab(16)); + _testGetSet->_privateBackwardsTabResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->BackwardsTab(16)); - _testGetSet->_fPrivateTabClearResult = TRUE; - _testGetSet->_fExpectedClearAll = true; - VERIFY_IS_TRUE(_pDispatch->TabClear(DispatchTypes::TabClearType::ClearAllColumns)); + _testGetSet->_privateTabClearResult = TRUE; + _testGetSet->_expectedClearAll = true; + VERIFY_IS_TRUE(_pDispatch.get()->TabClear(DispatchTypes::TabClearType::ClearAllColumns)); - _testGetSet->_fExpectedClearAll = false; - VERIFY_IS_TRUE(_pDispatch->TabClear(DispatchTypes::TabClearType::ClearCurrentColumn)); + _testGetSet->_expectedClearAll = false; + VERIFY_IS_TRUE(_pDispatch.get()->TabClear(DispatchTypes::TabClearType::ClearCurrentColumn)); } TEST_METHOD(SetConsoleTitleTest) @@ -2132,18 +2137,16 @@ public: Log::Comment(L"Starting test..."); Log::Comment(L"Test 1: set title to be non-null"); - _testGetSet->_fSetConsoleTitleWResult = TRUE; - wchar_t* pwchTestString = L"Foo bar"; - _testGetSet->_pwchExpectedWindowTitle = pwchTestString; - _testGetSet->_sCchExpectedTitleLength = 8; + _testGetSet->_setConsoleTitleWResult = TRUE; + _testGetSet->_expectedWindowTitle = L"Foo bar"; - VERIFY_IS_TRUE(_pDispatch->SetWindowTitle({ pwchTestString, 8 })); + VERIFY_IS_TRUE(_pDispatch.get()->SetWindowTitle(_testGetSet->_expectedWindowTitle)); Log::Comment(L"Test 2: set title to be null"); - _testGetSet->_fSetConsoleTitleWResult = FALSE; - _testGetSet->_pwchExpectedWindowTitle = nullptr; + _testGetSet->_setConsoleTitleWResult = FALSE; + _testGetSet->_expectedWindowTitle = {}; - VERIFY_IS_TRUE(_pDispatch->SetWindowTitle({})); + VERIFY_IS_TRUE(_pDispatch.get()->SetWindowTitle({})); } TEST_METHOD(TestMouseModes) @@ -2151,46 +2154,46 @@ public: Log::Comment(L"Starting test..."); Log::Comment(L"Test 1: Test Default Mouse Mode"); - _testGetSet->_fExpectedMouseEnabled = true; - _testGetSet->_fPrivateEnableVT200MouseModeResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->EnableVT200MouseMode(true)); - _testGetSet->_fExpectedMouseEnabled = false; - VERIFY_IS_TRUE(_pDispatch->EnableVT200MouseMode(false)); + _testGetSet->_expectedMouseEnabled = true; + _testGetSet->_privateEnableVT200MouseModeResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->EnableVT200MouseMode(true)); + _testGetSet->_expectedMouseEnabled = false; + VERIFY_IS_TRUE(_pDispatch.get()->EnableVT200MouseMode(false)); Log::Comment(L"Test 2: Test UTF-8 Extended Mouse Mode"); - _testGetSet->_fExpectedMouseEnabled = true; - _testGetSet->_fPrivateEnableUTF8ExtendedMouseModeResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->EnableUTF8ExtendedMouseMode(true)); - _testGetSet->_fExpectedMouseEnabled = false; - VERIFY_IS_TRUE(_pDispatch->EnableUTF8ExtendedMouseMode(false)); + _testGetSet->_expectedMouseEnabled = true; + _testGetSet->_privateEnableUTF8ExtendedMouseModeResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->EnableUTF8ExtendedMouseMode(true)); + _testGetSet->_expectedMouseEnabled = false; + VERIFY_IS_TRUE(_pDispatch.get()->EnableUTF8ExtendedMouseMode(false)); Log::Comment(L"Test 3: Test SGR Extended Mouse Mode"); - _testGetSet->_fExpectedMouseEnabled = true; - _testGetSet->_fPrivateEnableSGRExtendedMouseModeResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->EnableSGRExtendedMouseMode(true)); - _testGetSet->_fExpectedMouseEnabled = false; - VERIFY_IS_TRUE(_pDispatch->EnableSGRExtendedMouseMode(false)); + _testGetSet->_expectedMouseEnabled = true; + _testGetSet->_privateEnableSGRExtendedMouseModeResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->EnableSGRExtendedMouseMode(true)); + _testGetSet->_expectedMouseEnabled = false; + VERIFY_IS_TRUE(_pDispatch.get()->EnableSGRExtendedMouseMode(false)); Log::Comment(L"Test 4: Test Button-Event Mouse Mode"); - _testGetSet->_fExpectedMouseEnabled = true; - _testGetSet->_fPrivateEnableButtonEventMouseModeResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->EnableButtonEventMouseMode(true)); - _testGetSet->_fExpectedMouseEnabled = false; - VERIFY_IS_TRUE(_pDispatch->EnableButtonEventMouseMode(false)); + _testGetSet->_expectedMouseEnabled = true; + _testGetSet->_privateEnableButtonEventMouseModeResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->EnableButtonEventMouseMode(true)); + _testGetSet->_expectedMouseEnabled = false; + VERIFY_IS_TRUE(_pDispatch.get()->EnableButtonEventMouseMode(false)); Log::Comment(L"Test 5: Test Any-Event Mouse Mode"); - _testGetSet->_fExpectedMouseEnabled = true; - _testGetSet->_fPrivateEnableAnyEventMouseModeResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->EnableAnyEventMouseMode(true)); - _testGetSet->_fExpectedMouseEnabled = false; - VERIFY_IS_TRUE(_pDispatch->EnableAnyEventMouseMode(false)); + _testGetSet->_expectedMouseEnabled = true; + _testGetSet->_privateEnableAnyEventMouseModeResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->EnableAnyEventMouseMode(true)); + _testGetSet->_expectedMouseEnabled = false; + VERIFY_IS_TRUE(_pDispatch.get()->EnableAnyEventMouseMode(false)); Log::Comment(L"Test 6: Test Alt Scroll Mouse Mode"); - _testGetSet->_fExpectedAlternateScrollEnabled = true; - _testGetSet->_fPrivateEnableAlternateScrollResult = TRUE; - VERIFY_IS_TRUE(_pDispatch->EnableAlternateScroll(true)); - _testGetSet->_fExpectedAlternateScrollEnabled = false; - VERIFY_IS_TRUE(_pDispatch->EnableAlternateScroll(false)); + _testGetSet->_expectedAlternateScrollEnabled = true; + _testGetSet->_privateEnableAlternateScrollResult = TRUE; + VERIFY_IS_TRUE(_pDispatch.get()->EnableAlternateScroll(true)); + _testGetSet->_expectedAlternateScrollEnabled = false; + VERIFY_IS_TRUE(_pDispatch.get()->EnableAlternateScroll(false)); } TEST_METHOD(Xterm256ColorTest) @@ -2202,45 +2205,45 @@ public: DispatchTypes::GraphicsOptions rgOptions[16]; size_t cOptions = 3; - _testGetSet->_fSetConsoleXtermTextAttributeResult = true; + _testGetSet->_setConsoleXtermTextAttributeResult = true; Log::Comment(L"Test 1: Change Foreground"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)2; // Green - _testGetSet->_wExpectedAttribute = FOREGROUND_GREEN; + _testGetSet->_expectedAttribute = FOREGROUND_GREEN; _testGetSet->_iExpectedXtermTableEntry = 2; - _testGetSet->_fExpectedIsForeground = true; - _testGetSet->_fUsingRgbColor = false; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + _testGetSet->_expectedIsForeground = true; + _testGetSet->_usingRgbColor = false; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 2: Change Background"); rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)9; // Bright Red - _testGetSet->_wExpectedAttribute = FOREGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; _testGetSet->_iExpectedXtermTableEntry = 9; - _testGetSet->_fExpectedIsForeground = false; - _testGetSet->_fUsingRgbColor = false; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + _testGetSet->_expectedIsForeground = false; + _testGetSet->_usingRgbColor = false; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 3: Change Foreground to RGB color"); rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)42; // Arbitrary Color _testGetSet->_iExpectedXtermTableEntry = 42; - _testGetSet->_fExpectedIsForeground = true; - _testGetSet->_fUsingRgbColor = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + _testGetSet->_expectedIsForeground = true; + _testGetSet->_usingRgbColor = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 4: Change Background to RGB color"); rgOptions[0] = DispatchTypes::GraphicsOptions::BackgroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)142; // Arbitrary Color _testGetSet->_iExpectedXtermTableEntry = 142; - _testGetSet->_fExpectedIsForeground = false; - _testGetSet->_fUsingRgbColor = true; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + _testGetSet->_expectedIsForeground = false; + _testGetSet->_usingRgbColor = true; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); Log::Comment(L"Test 5: Change Foreground to Legacy Attr while BG is RGB color"); // Unfortunately this test isn't all that good, because the adapterTest adapter isn't smart enough @@ -2249,84 +2252,84 @@ public: rgOptions[0] = DispatchTypes::GraphicsOptions::ForegroundExtended; rgOptions[1] = DispatchTypes::GraphicsOptions::BlinkOrXterm256Index; rgOptions[2] = (DispatchTypes::GraphicsOptions)9; // Bright Red - _testGetSet->_wExpectedAttribute = FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_INTENSITY; + _testGetSet->_expectedAttribute = FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_INTENSITY; _testGetSet->_iExpectedXtermTableEntry = 9; - _testGetSet->_fExpectedIsForeground = true; - _testGetSet->_fUsingRgbColor = false; - VERIFY_IS_TRUE(_pDispatch->SetGraphicsRendition(rgOptions, cOptions)); + _testGetSet->_expectedIsForeground = true; + _testGetSet->_usingRgbColor = false; + VERIFY_IS_TRUE(_pDispatch.get()->SetGraphicsRendition({ rgOptions, cOptions })); } TEST_METHOD(SetColorTableValue) { _testGetSet->PrepData(); - _testGetSet->_fPrivateSetColorTableEntryResult = true; + _testGetSet->_privateSetColorTableEntryResult = true; const auto testColor = RGB(1, 2, 3); _testGetSet->_expectedColorValue = testColor; _testGetSet->_expectedColorTableIndex = 0; // Windows DARK_BLACK - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(0, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(0, testColor)); _testGetSet->_expectedColorTableIndex = 4; // Windows DARK_RED - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(1, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(1, testColor)); _testGetSet->_expectedColorTableIndex = 2; // Windows DARK_GREEN - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(2, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(2, testColor)); _testGetSet->_expectedColorTableIndex = 6; // Windows DARK_YELLOW - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(3, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(3, testColor)); _testGetSet->_expectedColorTableIndex = 1; // Windows DARK_BLUE - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(4, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(4, testColor)); _testGetSet->_expectedColorTableIndex = 5; // Windows DARK_MAGENTA - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(5, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(5, testColor)); _testGetSet->_expectedColorTableIndex = 3; // Windows DARK_CYAN - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(6, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(6, testColor)); _testGetSet->_expectedColorTableIndex = 7; // Windows DARK_WHITE - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(7, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(7, testColor)); _testGetSet->_expectedColorTableIndex = 8; // Windows BRIGHT_BLACK - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(8, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(8, testColor)); _testGetSet->_expectedColorTableIndex = 12; // Windows BRIGHT_RED - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(9, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(9, testColor)); _testGetSet->_expectedColorTableIndex = 10; // Windows BRIGHT_GREEN - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(10, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(10, testColor)); _testGetSet->_expectedColorTableIndex = 14; // Windows BRIGHT_YELLOW - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(11, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(11, testColor)); _testGetSet->_expectedColorTableIndex = 9; // Windows BRIGHT_BLUE - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(12, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(12, testColor)); _testGetSet->_expectedColorTableIndex = 13; // Windows BRIGHT_MAGENTA - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(13, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(13, testColor)); _testGetSet->_expectedColorTableIndex = 11; // Windows BRIGHT_CYAN - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(14, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(14, testColor)); _testGetSet->_expectedColorTableIndex = 15; // Windows BRIGHT_WHITE - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(15, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(15, testColor)); for (short i = 16; i < 256; i++) { _testGetSet->_expectedColorTableIndex = i; - VERIFY_IS_TRUE(_pDispatch->SetColorTableEntry(i, testColor)); + VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(i, testColor)); } // Test in pty mode - we should fail, but PrivateSetColorTableEntry should still be called - _testGetSet->_fIsPty = true; - _testGetSet->_fIsConsolePtyResult = true; + _testGetSet->_isPty = true; + _testGetSet->_isConsolePtyResult = true; _testGetSet->_expectedColorTableIndex = 15; // Windows BRIGHT_WHITE - VERIFY_IS_FALSE(_pDispatch->SetColorTableEntry(15, testColor)); + VERIFY_IS_FALSE(_pDispatch.get()->SetColorTableEntry(15, testColor)); } private: TestGetSet* _testGetSet; // non-ownership pointer - AdaptDispatch* _pDispatch; + std::unique_ptr _pDispatch; }; diff --git a/src/terminal/parser/IStateMachineEngine.hpp b/src/terminal/parser/IStateMachineEngine.hpp index 691d0e92ad..2c75e7ec8e 100644 --- a/src/terminal/parser/IStateMachineEngine.hpp +++ b/src/terminal/parser/IStateMachineEngine.hpp @@ -26,33 +26,26 @@ namespace Microsoft::Console::VirtualTerminal virtual bool ActionExecute(const wchar_t wch) = 0; virtual bool ActionExecuteFromEscape(const wchar_t wch) = 0; virtual bool ActionPrint(const wchar_t wch) = 0; - virtual bool ActionPrintString(const wchar_t* const rgwch, - size_t const cch) = 0; + virtual bool ActionPrintString(const std::wstring_view string) = 0; - virtual bool ActionPassThroughString(const wchar_t* const rgwch, - size_t const cch) = 0; + virtual bool ActionPassThroughString(const std::wstring_view string) = 0; virtual bool ActionEscDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate) = 0; + const std::basic_string_view intermediates) = 0; virtual bool ActionCsiDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) = 0; + const std::basic_string_view intermediates, + const std::basic_string_view parameters) = 0; virtual bool ActionClear() = 0; virtual bool ActionIgnore() = 0; virtual bool ActionOscDispatch(const wchar_t wch, - const unsigned short sOscParam, - _Inout_updates_(cchOscString) wchar_t* const pwchOscStringBuffer, - const unsigned short cchOscString) = 0; + const size_t parameter, + const std::wstring_view string) = 0; virtual bool ActionSs3Dispatch(const wchar_t wch, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) = 0; + const std::basic_string_view parameters) = 0; virtual bool FlushAtEndOfString() const = 0; virtual bool DispatchControlCharsFromEscape() const = 0; diff --git a/src/terminal/parser/InputStateMachineEngine.cpp b/src/terminal/parser/InputStateMachineEngine.cpp index 0720e79ccd..88e948517e 100644 --- a/src/terminal/parser/InputStateMachineEngine.cpp +++ b/src/terminal/parser/InputStateMachineEngine.cpp @@ -38,52 +38,139 @@ const size_t WRAPPED_SEQUENCE_MAX_LENGTH = 8; // CAPSLOCK_ON 0x0080 // ENHANCED_KEY 0x0100 -const InputStateMachineEngine::CSI_TO_VKEY InputStateMachineEngine::s_rgCsiMap[]{ - { CsiActionCodes::ArrowUp, VK_UP }, - { CsiActionCodes::ArrowDown, VK_DOWN }, - { CsiActionCodes::ArrowRight, VK_RIGHT }, - { CsiActionCodes::ArrowLeft, VK_LEFT }, - { CsiActionCodes::Home, VK_HOME }, - { CsiActionCodes::End, VK_END }, - { CsiActionCodes::CSI_F1, VK_F1 }, - { CsiActionCodes::CSI_F2, VK_F2 }, - { CsiActionCodes::CSI_F3, VK_F3 }, - { CsiActionCodes::CSI_F4, VK_F4 }, +enum class CsiActionCodes : wchar_t +{ + ArrowUp = L'A', + ArrowDown = L'B', + ArrowRight = L'C', + ArrowLeft = L'D', + Home = L'H', + End = L'F', + Generic = L'~', // Used for a whole bunch of possible keys + CSI_F1 = L'P', + CSI_F2 = L'Q', + CSI_F3 = L'R', // Both F3 and DSR are on R. + // DSR_DeviceStatusReportResponse = L'R', + CSI_F4 = L'S', + DTTERM_WindowManipulation = L't', + CursorBackTab = L'Z', }; -const InputStateMachineEngine::GENERIC_TO_VKEY InputStateMachineEngine::s_rgGenericMap[]{ - { GenericKeyIdentifiers::GenericHome, VK_HOME }, - { GenericKeyIdentifiers::Insert, VK_INSERT }, - { GenericKeyIdentifiers::Delete, VK_DELETE }, - { GenericKeyIdentifiers::GenericEnd, VK_END }, - { GenericKeyIdentifiers::Prior, VK_PRIOR }, - { GenericKeyIdentifiers::Next, VK_NEXT }, - { GenericKeyIdentifiers::F5, VK_F5 }, - { GenericKeyIdentifiers::F6, VK_F6 }, - { GenericKeyIdentifiers::F7, VK_F7 }, - { GenericKeyIdentifiers::F8, VK_F8 }, - { GenericKeyIdentifiers::F9, VK_F9 }, - { GenericKeyIdentifiers::F10, VK_F10 }, - { GenericKeyIdentifiers::F11, VK_F11 }, - { GenericKeyIdentifiers::F12, VK_F12 }, +struct CsiToVkey +{ + CsiActionCodes action; + short vkey; }; -const InputStateMachineEngine::SS3_TO_VKEY InputStateMachineEngine::s_rgSs3Map[]{ - { Ss3ActionCodes::SS3_F1, VK_F1 }, - { Ss3ActionCodes::SS3_F2, VK_F2 }, - { Ss3ActionCodes::SS3_F3, VK_F3 }, - { Ss3ActionCodes::SS3_F4, VK_F4 }, +static constexpr std::array s_csiMap = { + CsiToVkey{ CsiActionCodes::ArrowUp, VK_UP }, + CsiToVkey{ CsiActionCodes::ArrowDown, VK_DOWN }, + CsiToVkey{ CsiActionCodes::ArrowRight, VK_RIGHT }, + CsiToVkey{ CsiActionCodes::ArrowLeft, VK_LEFT }, + CsiToVkey{ CsiActionCodes::Home, VK_HOME }, + CsiToVkey{ CsiActionCodes::End, VK_END }, + CsiToVkey{ CsiActionCodes::CSI_F1, VK_F1 }, + CsiToVkey{ CsiActionCodes::CSI_F2, VK_F2 }, + CsiToVkey{ CsiActionCodes::CSI_F3, VK_F3 }, + CsiToVkey{ CsiActionCodes::CSI_F4, VK_F4 } }; -InputStateMachineEngine::InputStateMachineEngine(IInteractDispatch* const pDispatch) : - InputStateMachineEngine(pDispatch, false) +static bool operator==(const CsiToVkey& pair, const CsiActionCodes code) noexcept +{ + return pair.action == code; +} + +// Sequences ending in '~' use these numbers as identifiers. +enum class GenericKeyIdentifiers : unsigned short +{ + GenericHome = 1, + Insert = 2, + Delete = 3, + GenericEnd = 4, + Prior = 5, //PgUp + Next = 6, //PgDn + F5 = 15, + F6 = 17, + F7 = 18, + F8 = 19, + F9 = 20, + F10 = 21, + F11 = 23, + F12 = 24, +}; + +struct GenericToVkey +{ + GenericKeyIdentifiers identifier; + short vkey; +}; + +static constexpr std::array s_genericMap = { + GenericToVkey{ GenericKeyIdentifiers::GenericHome, VK_HOME }, + GenericToVkey{ GenericKeyIdentifiers::Insert, VK_INSERT }, + GenericToVkey{ GenericKeyIdentifiers::Delete, VK_DELETE }, + GenericToVkey{ GenericKeyIdentifiers::GenericEnd, VK_END }, + GenericToVkey{ GenericKeyIdentifiers::Prior, VK_PRIOR }, + GenericToVkey{ GenericKeyIdentifiers::Next, VK_NEXT }, + GenericToVkey{ GenericKeyIdentifiers::F5, VK_F5 }, + GenericToVkey{ GenericKeyIdentifiers::F6, VK_F6 }, + GenericToVkey{ GenericKeyIdentifiers::F7, VK_F7 }, + GenericToVkey{ GenericKeyIdentifiers::F8, VK_F8 }, + GenericToVkey{ GenericKeyIdentifiers::F9, VK_F9 }, + GenericToVkey{ GenericKeyIdentifiers::F10, VK_F10 }, + GenericToVkey{ GenericKeyIdentifiers::F11, VK_F11 }, + GenericToVkey{ GenericKeyIdentifiers::F12, VK_F12 }, +}; + +static bool operator==(const GenericToVkey& pair, const GenericKeyIdentifiers identifier) noexcept +{ + return pair.identifier == identifier; +} + +enum class Ss3ActionCodes : wchar_t +{ + // The "Cursor Keys" are sometimes sent as a SS3 in "application mode" + // But for now we'll only accept them as Normal Mode sequences, as CSI's. + // ArrowUp = L'A', + // ArrowDown = L'B', + // ArrowRight = L'C', + // ArrowLeft = L'D', + // Home = L'H', + // End = L'F', + SS3_F1 = L'P', + SS3_F2 = L'Q', + SS3_F3 = L'R', + SS3_F4 = L'S', +}; + +struct Ss3ToVkey +{ + Ss3ActionCodes action; + short vkey; +}; + +static constexpr std::array s_ss3Map = { + Ss3ToVkey{ Ss3ActionCodes::SS3_F1, VK_F1 }, + Ss3ToVkey{ Ss3ActionCodes::SS3_F2, VK_F2 }, + Ss3ToVkey{ Ss3ActionCodes::SS3_F3, VK_F3 }, + Ss3ToVkey{ Ss3ActionCodes::SS3_F4, VK_F4 }, +}; + +static bool operator==(const Ss3ToVkey& pair, const Ss3ActionCodes code) noexcept +{ + return pair.action == code; +} + +InputStateMachineEngine::InputStateMachineEngine(std::unique_ptr pDispatch) : + InputStateMachineEngine(std::move(pDispatch), false) { } -InputStateMachineEngine::InputStateMachineEngine(IInteractDispatch* const pDispatch, const bool lookingForDSR) : - _pDispatch(THROW_IF_NULL_ALLOC(pDispatch)), +InputStateMachineEngine::InputStateMachineEngine(std::unique_ptr pDispatch, const bool lookingForDSR) : + _pDispatch(std::move(pDispatch)), _lookingForDSR(lookingForDSR) { + THROW_IF_NULL_ALLOC(_pDispatch.get()); } // Method Description: @@ -98,13 +185,20 @@ bool InputStateMachineEngine::ActionExecute(const wchar_t wch) return _DoControlCharacter(wch, false); } +// Routine Description: +// - Writes a control character into the buffer. Think characters like tab, backspace, etc. +// Arguments: +// - wch - The character to write +// - writeAlt - Pass in the alt-state information here as it's not embedded +// Return Value: +// - True if successfully generated and written. False otherwise. bool InputStateMachineEngine::_DoControlCharacter(const wchar_t wch, const bool writeAlt) { - bool fSuccess = false; + bool success = false; if (wch == UNICODE_ETX && !writeAlt) { // This is Ctrl+C, which is handled specially by the host. - fSuccess = _pDispatch->WriteCtrlC(); + success = _pDispatch->WriteCtrlC(); } else if (wch >= '\x0' && wch < '\x20') { @@ -114,16 +208,18 @@ bool InputStateMachineEngine::_DoControlCharacter(const wchar_t wch, const bool bool writeCtrl = true; short vkey = 0; - DWORD dwModifierState = 0; + DWORD modifierState = 0; switch (wch) { case L'\b': - fSuccess = _GenerateKeyFromChar(wch + 0x40, &vkey, nullptr); + success = _GenerateKeyFromChar(wch + 0x40, vkey, modifierState); + modifierState = 0; break; case L'\r': writeCtrl = false; - fSuccess = _GenerateKeyFromChar(wch, &vkey, nullptr); + success = _GenerateKeyFromChar(wch, vkey, modifierState); + modifierState = 0; break; case L'\x1b': // Translate escape as the ESC key, NOT C-[. @@ -131,29 +227,29 @@ bool InputStateMachineEngine::_DoControlCharacter(const wchar_t wch, const bool // which isn't the worst tradeoff. vkey = VK_ESCAPE; writeCtrl = false; - fSuccess = true; + success = true; break; case L'\t': writeCtrl = false; - fSuccess = _GenerateKeyFromChar(actualChar, &vkey, &dwModifierState); + success = _GenerateKeyFromChar(actualChar, vkey, modifierState); break; default: - fSuccess = _GenerateKeyFromChar(actualChar, &vkey, &dwModifierState); + success = _GenerateKeyFromChar(actualChar, vkey, modifierState); break; } - if (fSuccess) + if (success) { if (writeCtrl) { - WI_SetFlag(dwModifierState, LEFT_CTRL_PRESSED); + WI_SetFlag(modifierState, LEFT_CTRL_PRESSED); } if (writeAlt) { - WI_SetFlag(dwModifierState, LEFT_ALT_PRESSED); + WI_SetFlag(modifierState, LEFT_ALT_PRESSED); } - fSuccess = _WriteSingleKey(actualChar, vkey, dwModifierState); + success = _WriteSingleKey(actualChar, vkey, modifierState); } } else if (wch == '\x7f') @@ -165,13 +261,13 @@ bool InputStateMachineEngine::_DoControlCharacter(const wchar_t wch, const bool // "delete" any input at all, only backspace. // Because of this, we're treating x7f as backspace, like most // terminals do. - fSuccess = _WriteSingleKey('\x8', VK_BACK, writeAlt ? LEFT_ALT_PRESSED : 0); + success = _WriteSingleKey('\x8', VK_BACK, writeAlt ? LEFT_ALT_PRESSED : 0); } else { - fSuccess = ActionPrint(wch); + success = ActionPrint(wch); } - return fSuccess; + return success; } // Routine Description: @@ -200,45 +296,41 @@ bool InputStateMachineEngine::ActionExecuteFromEscape(const wchar_t wch) bool InputStateMachineEngine::ActionPrint(const wchar_t wch) { short vkey = 0; - DWORD dwModifierState = 0; - bool fSuccess = _GenerateKeyFromChar(wch, &vkey, &dwModifierState); - if (fSuccess) + DWORD modifierState = 0; + bool success = _GenerateKeyFromChar(wch, vkey, modifierState); + if (success) { - fSuccess = _WriteSingleKey(wch, vkey, dwModifierState); + success = _WriteSingleKey(wch, vkey, modifierState); } - return fSuccess; + return success; } // Method Description: // - Triggers the Print action to indicate that the listener should render the // string of characters given. // Arguments: -// - rgwch - string to dispatch. -// - cch - length of rgwch +// - string - string to dispatch. // Return Value: // - true iff we successfully dispatched the sequence. -bool InputStateMachineEngine::ActionPrintString(const wchar_t* const rgwch, - const size_t cch) +bool InputStateMachineEngine::ActionPrintString(const std::wstring_view string) { - if (cch == 0) + if (string.empty()) { return true; } - return _pDispatch->WriteString(rgwch, cch); + return _pDispatch->WriteString(string); } // Method Description: // - Triggers the Print action to indicate that the listener should render the // string of characters given. // Arguments: -// - rgwch - string to dispatch. -// - cch - length of rgwch +// - string - string to dispatch. // Return Value: // - true iff we successfully dispatched the sequence. -bool InputStateMachineEngine::ActionPassThroughString(const wchar_t* const rgwch, - _In_ size_t const cch) +bool InputStateMachineEngine::ActionPassThroughString(const std::wstring_view string) { - return ActionPrintString(rgwch, cch); + return ActionPrintString(string); } // Method Description: @@ -247,36 +339,34 @@ bool InputStateMachineEngine::ActionPassThroughString(const wchar_t* const rgwch // and a simple letter. No complicated parameters. // Arguments: // - wch - Character to dispatch. -// - cIntermediate - Number of "Intermediate" characters found - such as '!', '?' -// - wchIntermediate - Intermediate character in the sequence, if there was one. +// - intermediates - Intermediate characters in the sequence // Return Value: // - true iff we successfully dispatched the sequence. bool InputStateMachineEngine::ActionEscDispatch(const wchar_t wch, - const unsigned short /*cIntermediate*/, - const wchar_t /*wchIntermediate*/) + const std::basic_string_view /*intermediates*/) { - bool fSuccess = false; + bool success = false; // 0x7f is DEL, which we treat effectively the same as a ctrl character. if (wch == 0x7f) { - fSuccess = _DoControlCharacter(wch, true); + success = _DoControlCharacter(wch, true); } else { - DWORD dwModifierState = 0; + DWORD modifierState = 0; short vk = 0; - fSuccess = _GenerateKeyFromChar(wch, &vk, &dwModifierState); - if (fSuccess) + success = _GenerateKeyFromChar(wch, vk, modifierState); + if (success) { // Alt is definitely pressed in the esc+key case. - dwModifierState = WI_SetFlag(dwModifierState, LEFT_ALT_PRESSED); + modifierState = WI_SetFlag(modifierState, LEFT_ALT_PRESSED); - fSuccess = _WriteSingleKey(wch, vk, dwModifierState); + success = _WriteSingleKey(wch, vk, modifierState); } } - return fSuccess; + return success; } // Method Description: @@ -285,34 +375,29 @@ bool InputStateMachineEngine::ActionEscDispatch(const wchar_t wch, // that can include many parameters. // Arguments: // - wch - Character to dispatch. -// - cIntermediate - Number of "Intermediate" characters found - such as '!', '?' -// - wchIntermediate - Intermediate character in the sequence, if there was one. -// - rgusParams - set of numeric parameters collected while pasring the sequence. -// - cParams - number of parameters found. +// - intermediates - Intermediate characters in the sequence +// - parameters - set of numeric parameters collected while pasring the sequence. // Return Value: // - true iff we successfully dispatched the sequence. bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, - const unsigned short /*cIntermediate*/, - const wchar_t /*wchIntermediate*/, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) + const std::basic_string_view /*intermediates*/, + const std::basic_string_view parameters) { - DWORD dwModifierState = 0; + DWORD modifierState = 0; short vkey = 0; - unsigned int uiFunction = 0; - unsigned int col = 0; - unsigned int row = 0; + unsigned int function = 0; + size_t col = 0; + size_t row = 0; // This is all the args after the first arg, and the count of args not including the first one. - const unsigned short* const rgusRemainingArgs = (cParams > 1) ? rgusParams + 1 : rgusParams; - const unsigned short cRemainingArgs = (cParams >= 1) ? cParams - 1 : 0; + const auto remainingArgs = parameters.size() > 1 ? parameters.substr(1) : std::basic_string_view{}; - bool fSuccess = false; - switch (wch) + bool success = false; + switch ((CsiActionCodes)wch) { case CsiActionCodes::Generic: - dwModifierState = _GetGenericKeysModifierState(rgusParams, cParams); - fSuccess = _GetGenericVkey(rgusParams, cParams, &vkey); + modifierState = _GetGenericKeysModifierState(parameters); + success = _GetGenericVkey(parameters, vkey); break; // case CsiActionCodes::DSR_DeviceStatusReportResponse: case CsiActionCodes::CSI_F3: @@ -321,8 +406,8 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, // Else, fall though to the _GetCursorKeysModifierState handler. if (_lookingForDSR) { - fSuccess = true; - fSuccess = _GetXYPosition(rgusParams, cParams, &row, &col); + success = true; + success = _GetXYPosition(parameters, row, col); break; } case CsiActionCodes::ArrowUp: @@ -334,27 +419,25 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, case CsiActionCodes::CSI_F1: case CsiActionCodes::CSI_F2: case CsiActionCodes::CSI_F4: - dwModifierState = _GetCursorKeysModifierState(rgusParams, cParams); - fSuccess = _GetCursorKeysVkey(wch, &vkey); + modifierState = _GetCursorKeysModifierState(parameters); + success = _GetCursorKeysVkey(wch, vkey); break; case CsiActionCodes::CursorBackTab: - dwModifierState = SHIFT_PRESSED; + modifierState = SHIFT_PRESSED; vkey = VK_TAB; - fSuccess = true; + success = true; break; case CsiActionCodes::DTTERM_WindowManipulation: - fSuccess = _GetWindowManipulationType(rgusParams, - cParams, - &uiFunction); + success = _GetWindowManipulationType(parameters, function); break; default: - fSuccess = false; + success = false; break; } - if (fSuccess) + if (success) { - switch (wch) + switch ((CsiActionCodes)wch) { // case CsiActionCodes::DSR_DeviceStatusReportResponse: case CsiActionCodes::CSI_F3: @@ -363,7 +446,7 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, // Else, fall though to the _GetCursorKeysModifierState handler. if (_lookingForDSR) { - fSuccess = _pDispatch->MoveCursor(row, col); + success = _pDispatch->MoveCursor(row, col); // Right now we're only looking for on initial cursor // position response. After that, only look for F3. _lookingForDSR = false; @@ -381,20 +464,19 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, case CsiActionCodes::CSI_F2: case CsiActionCodes::CSI_F4: case CsiActionCodes::CursorBackTab: - fSuccess = _WriteSingleKey(vkey, dwModifierState); + success = _WriteSingleKey(vkey, modifierState); break; case CsiActionCodes::DTTERM_WindowManipulation: - fSuccess = _pDispatch->WindowManipulation(static_cast(uiFunction), - rgusRemainingArgs, - cRemainingArgs); + success = _pDispatch->WindowManipulation(static_cast(function), + remainingArgs); break; default: - fSuccess = false; + success = false; break; } } - return fSuccess; + return success; } // Routine Description: @@ -403,27 +485,25 @@ bool InputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, // that can include many parameters. // Arguments: // - wch - Character to dispatch. -// - rgusParams - set of numeric parameters collected while pasring the sequence. -// - cParams - number of parameters found. +// - parameters - set of numeric parameters collected while pasring the sequence. // Return Value: // - true iff we successfully dispatched the sequence. bool InputStateMachineEngine::ActionSs3Dispatch(const wchar_t wch, - _In_reads_(_Param_(3)) const unsigned short* const /*rgusParams*/, - const unsigned short /*cParams*/) + const std::basic_string_view /*parameters*/) { // Ss3 sequence keys aren't modified. // When F1-F4 *are* modified, they're sent as CSI sequences, not SS3's. DWORD dwModifierState = 0; short vkey = 0; - bool fSuccess = _GetSs3KeysVkey(wch, &vkey); + bool success = _GetSs3KeysVkey(wch, vkey); - if (fSuccess) + if (success) { - fSuccess = _WriteSingleKey(vkey, dwModifierState); + success = _WriteSingleKey(vkey, dwModifierState); } - return fSuccess; + return success; } // Method Description: @@ -455,15 +535,13 @@ bool InputStateMachineEngine::ActionIgnore() // These sequences perform various API-type commands that can include many parameters. // Arguments: // - wch - Character to dispatch. This will be a BEL or ST char. -// - sOscParam - identifier of the OSC action to perform -// - pwchOscStringBuffer - OSC string we've collected. NOT null terminated. -// - cchOscString - length of pwchOscStringBuffer +// - parameter - identifier of the OSC action to perform +// - string - OSC string we've collected. NOT null terminated. // Return Value: // - true if we handled the dsipatch. bool InputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, - const unsigned short /*sOscParam*/, - _Inout_updates_(_Param_(4)) wchar_t* const /*pwchOscStringBuffer*/, - const unsigned short /*cchOscString*/) + const size_t /*parameter*/, + const std::wstring_view /*string*/) { return false; } @@ -477,127 +555,105 @@ bool InputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, // Arguments: // - wch - the character to write to the input callback. // - vkey - the VKEY of the key to write to the input callback. -// - dwModifierState - the modifier state to write with the key. -// - rgInput - the buffer of characters to write the keypresses to. Can write +// - modifierState - the modifier state to write with the key. +// - input - the buffer of characters to write the keypresses to. Can write // up to 8 records to this buffer. -// - cInput - the size of rgInput. This should be at least WRAPPED_SEQUENCE_MAX_LENGTH // Return Value: // - the number of records written, or 0 if the buffer wasn't big enough. -size_t InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch, - const short vkey, - const DWORD dwModifierState, - _Inout_updates_(cInput) INPUT_RECORD* rgInput, - const size_t cInput) +void InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch, + const short vkey, + const DWORD modifierState, + std::vector& input) { + input.reserve(input.size() + 8); + // TODO: Reuse the clipboard functions for generating input for characters // that aren't on the current keyboard. // MSFT:13994942 - if (cInput < WRAPPED_SEQUENCE_MAX_LENGTH) + + const bool shift = WI_IsFlagSet(modifierState, SHIFT_PRESSED); + const bool ctrl = WI_IsFlagSet(modifierState, LEFT_CTRL_PRESSED); + const bool alt = WI_IsFlagSet(modifierState, LEFT_ALT_PRESSED); + + INPUT_RECORD next; + + DWORD currentModifiers = 0; + + if (shift) { - return 0; + WI_SetFlag(currentModifiers, SHIFT_PRESSED); + next.EventType = KEY_EVENT; + next.Event.KeyEvent.bKeyDown = TRUE; + next.Event.KeyEvent.dwControlKeyState = currentModifiers; + next.Event.KeyEvent.wRepeatCount = 1; + next.Event.KeyEvent.wVirtualKeyCode = VK_SHIFT; + next.Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC)); + next.Event.KeyEvent.uChar.UnicodeChar = 0x0; + input.push_back(next); + } + if (alt) + { + WI_SetFlag(currentModifiers, LEFT_ALT_PRESSED); + next.EventType = KEY_EVENT; + next.Event.KeyEvent.bKeyDown = TRUE; + next.Event.KeyEvent.dwControlKeyState = currentModifiers; + next.Event.KeyEvent.wRepeatCount = 1; + next.Event.KeyEvent.wVirtualKeyCode = VK_MENU; + next.Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC)); + next.Event.KeyEvent.uChar.UnicodeChar = 0x0; + input.push_back(next); + } + if (ctrl) + { + WI_SetFlag(currentModifiers, LEFT_CTRL_PRESSED); + next.EventType = KEY_EVENT; + next.Event.KeyEvent.bKeyDown = TRUE; + next.Event.KeyEvent.dwControlKeyState = currentModifiers; + next.Event.KeyEvent.wRepeatCount = 1; + next.Event.KeyEvent.wVirtualKeyCode = VK_CONTROL; + next.Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC)); + next.Event.KeyEvent.uChar.UnicodeChar = 0x0; + input.push_back(next); } - const bool fShift = WI_IsFlagSet(dwModifierState, SHIFT_PRESSED); - const bool fCtrl = WI_IsFlagSet(dwModifierState, LEFT_CTRL_PRESSED); - const bool fAlt = WI_IsFlagSet(dwModifierState, LEFT_ALT_PRESSED); + _GetSingleKeypress(wch, vkey, currentModifiers, input); - size_t index = 0; - INPUT_RECORD* next = &rgInput[0]; - - DWORD dwCurrentModifiers = 0; - - if (fShift) + if (ctrl) { - WI_SetFlag(dwCurrentModifiers, SHIFT_PRESSED); - next->EventType = KEY_EVENT; - next->Event.KeyEvent.bKeyDown = TRUE; - next->Event.KeyEvent.dwControlKeyState = dwCurrentModifiers; - next->Event.KeyEvent.wRepeatCount = 1; - next->Event.KeyEvent.wVirtualKeyCode = VK_SHIFT; - next->Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC)); - next->Event.KeyEvent.uChar.UnicodeChar = 0x0; - next++; - index++; + WI_ClearFlag(currentModifiers, LEFT_CTRL_PRESSED); + next.EventType = KEY_EVENT; + next.Event.KeyEvent.bKeyDown = FALSE; + next.Event.KeyEvent.dwControlKeyState = currentModifiers; + next.Event.KeyEvent.wRepeatCount = 1; + next.Event.KeyEvent.wVirtualKeyCode = VK_CONTROL; + next.Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC)); + next.Event.KeyEvent.uChar.UnicodeChar = 0x0; + input.push_back(next); } - if (fAlt) + if (alt) { - WI_SetFlag(dwCurrentModifiers, LEFT_ALT_PRESSED); - next->EventType = KEY_EVENT; - next->Event.KeyEvent.bKeyDown = TRUE; - next->Event.KeyEvent.dwControlKeyState = dwCurrentModifiers; - next->Event.KeyEvent.wRepeatCount = 1; - next->Event.KeyEvent.wVirtualKeyCode = VK_MENU; - next->Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC)); - next->Event.KeyEvent.uChar.UnicodeChar = 0x0; - next++; - index++; + WI_ClearFlag(currentModifiers, LEFT_ALT_PRESSED); + next.EventType = KEY_EVENT; + next.Event.KeyEvent.bKeyDown = FALSE; + next.Event.KeyEvent.dwControlKeyState = currentModifiers; + next.Event.KeyEvent.wRepeatCount = 1; + next.Event.KeyEvent.wVirtualKeyCode = VK_MENU; + next.Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC)); + next.Event.KeyEvent.uChar.UnicodeChar = 0x0; + input.push_back(next); } - if (fCtrl) + if (shift) { - WI_SetFlag(dwCurrentModifiers, LEFT_CTRL_PRESSED); - next->EventType = KEY_EVENT; - next->Event.KeyEvent.bKeyDown = TRUE; - next->Event.KeyEvent.dwControlKeyState = dwCurrentModifiers; - next->Event.KeyEvent.wRepeatCount = 1; - next->Event.KeyEvent.wVirtualKeyCode = VK_CONTROL; - next->Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC)); - next->Event.KeyEvent.uChar.UnicodeChar = 0x0; - next++; - index++; + WI_ClearFlag(currentModifiers, SHIFT_PRESSED); + next.EventType = KEY_EVENT; + next.Event.KeyEvent.bKeyDown = FALSE; + next.Event.KeyEvent.dwControlKeyState = currentModifiers; + next.Event.KeyEvent.wRepeatCount = 1; + next.Event.KeyEvent.wVirtualKeyCode = VK_SHIFT; + next.Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC)); + next.Event.KeyEvent.uChar.UnicodeChar = 0x0; + input.push_back(next); } - - size_t added = _GetSingleKeypress(wch, vkey, dwCurrentModifiers, next, cInput - index); - - // if _GetSingleKeypress added more than two events we might overflow the buffer - if (added > 2) - { - return index; - } - - next += added; - index += added; - - if (fCtrl) - { - WI_ClearFlag(dwCurrentModifiers, LEFT_CTRL_PRESSED); - next->EventType = KEY_EVENT; - next->Event.KeyEvent.bKeyDown = FALSE; - next->Event.KeyEvent.dwControlKeyState = dwCurrentModifiers; - next->Event.KeyEvent.wRepeatCount = 1; - next->Event.KeyEvent.wVirtualKeyCode = VK_CONTROL; - next->Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_CONTROL, MAPVK_VK_TO_VSC)); - next->Event.KeyEvent.uChar.UnicodeChar = 0x0; - next++; - index++; - } - if (fAlt) - { - WI_ClearFlag(dwCurrentModifiers, LEFT_ALT_PRESSED); - next->EventType = KEY_EVENT; - next->Event.KeyEvent.bKeyDown = FALSE; - next->Event.KeyEvent.dwControlKeyState = dwCurrentModifiers; - next->Event.KeyEvent.wRepeatCount = 1; - next->Event.KeyEvent.wVirtualKeyCode = VK_MENU; - next->Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_MENU, MAPVK_VK_TO_VSC)); - next->Event.KeyEvent.uChar.UnicodeChar = 0x0; - next++; - index++; - } - if (fShift) - { - WI_ClearFlag(dwCurrentModifiers, SHIFT_PRESSED); - next->EventType = KEY_EVENT; - next->Event.KeyEvent.bKeyDown = FALSE; - next->Event.KeyEvent.dwControlKeyState = dwCurrentModifiers; - next->Event.KeyEvent.wRepeatCount = 1; - next->Event.KeyEvent.wVirtualKeyCode = VK_SHIFT; - next->Event.KeyEvent.wVirtualScanCode = static_cast(MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC)); - next->Event.KeyEvent.uChar.UnicodeChar = 0x0; - next++; - index++; - } - - return index; } // Method Description: @@ -606,36 +662,31 @@ size_t InputStateMachineEngine::_GenerateWrappedSequence(const wchar_t wch, // Arguments: // - wch - the character to write to the buffer. // - vkey - the VKEY of the key to write to the buffer. -// - dwModifierState - the modifier state to write with the key. -// - rgInput - the buffer of characters to write the keypress to. Will always +// - modifierState - the modifier state to write with the key. +// - input - the buffer of characters to write the keypress to. Will always // write to the first two positions in the buffer. -// - cRecords - the size of rgInput // Return Value: // - the number of input records written. -size_t InputStateMachineEngine::_GetSingleKeypress(const wchar_t wch, - const short vkey, - const DWORD dwModifierState, - _Inout_updates_(cRecords) INPUT_RECORD* const rgInput, - const size_t cRecords) +void InputStateMachineEngine::_GetSingleKeypress(const wchar_t wch, + const short vkey, + const DWORD modifierState, + std::vector& input) { - FAIL_FAST_IF(!(cRecords >= 2)); - if (cRecords < 2) - { - return 0; - } + input.reserve(input.size() + 2); - rgInput[0].EventType = KEY_EVENT; - rgInput[0].Event.KeyEvent.bKeyDown = TRUE; - rgInput[0].Event.KeyEvent.dwControlKeyState = dwModifierState; - rgInput[0].Event.KeyEvent.wRepeatCount = 1; - rgInput[0].Event.KeyEvent.wVirtualKeyCode = vkey; - rgInput[0].Event.KeyEvent.wVirtualScanCode = (WORD)MapVirtualKey(vkey, MAPVK_VK_TO_VSC); - rgInput[0].Event.KeyEvent.uChar.UnicodeChar = wch; + INPUT_RECORD rec; - rgInput[1] = rgInput[0]; - rgInput[1].Event.KeyEvent.bKeyDown = FALSE; + rec.EventType = KEY_EVENT; + rec.Event.KeyEvent.bKeyDown = TRUE; + rec.Event.KeyEvent.dwControlKeyState = modifierState; + rec.Event.KeyEvent.wRepeatCount = 1; + rec.Event.KeyEvent.wVirtualKeyCode = vkey; + rec.Event.KeyEvent.wVirtualScanCode = (WORD)MapVirtualKey(vkey, MAPVK_VK_TO_VSC); + rec.Event.KeyEvent.uChar.UnicodeChar = wch; + input.push_back(rec); - return 2; + rec.Event.KeyEvent.bKeyDown = FALSE; + input.push_back(rec); } // Method Description: @@ -646,16 +697,15 @@ size_t InputStateMachineEngine::_GetSingleKeypress(const wchar_t wch, // Arguments: // - wch - the character to write to the input callback. // - vkey - the VKEY of the key to write to the input callback. -// - dwModifierState - the modifier state to write with the key. +// - modifierState - the modifier state to write with the key. // Return Value: // - true iff we successfully wrote the keypress to the input callback. -bool InputStateMachineEngine::_WriteSingleKey(const wchar_t wch, const short vkey, const DWORD dwModifierState) +bool InputStateMachineEngine::_WriteSingleKey(const wchar_t wch, const short vkey, const DWORD modifierState) { // At most 8 records - 2 for each of shift,ctrl,alt up and down, and 2 for the actual key up and down. - INPUT_RECORD rgInput[WRAPPED_SEQUENCE_MAX_LENGTH]; - size_t cInput = _GenerateWrappedSequence(wch, vkey, dwModifierState, rgInput, WRAPPED_SEQUENCE_MAX_LENGTH); - - std::deque> inputEvents = IInputEvent::Create(gsl::make_span(rgInput, cInput)); + std::vector input; + _GenerateWrappedSequence(wch, vkey, modifierState, input); + std::deque> inputEvents = IInputEvent::Create(gsl::make_span(input)); return _pDispatch->WriteInput(inputEvents); } @@ -682,10 +732,10 @@ bool InputStateMachineEngine::_WriteSingleKey(const short vkey, const DWORD dwMo // - cParams - the number of elements in rgusParams // Return Value: // - the INPUT_RECORD comaptible modifier state. -DWORD InputStateMachineEngine::_GetCursorKeysModifierState(_In_reads_(cParams) const unsigned short* const rgusParams, const unsigned short cParams) +DWORD InputStateMachineEngine::_GetCursorKeysModifierState(const std::basic_string_view parameters) { // Both Cursor keys and generic keys keep their modifiers in the same index. - return _GetGenericKeysModifierState(rgusParams, cParams); + return _GetGenericKeysModifierState(parameters); } // Method Description: @@ -696,28 +746,28 @@ DWORD InputStateMachineEngine::_GetCursorKeysModifierState(_In_reads_(cParams) c // - cParams - the number of elements in rgusParams // Return Value: // - the INPUT_RECORD compatible modifier state. -DWORD InputStateMachineEngine::_GetGenericKeysModifierState(_In_reads_(cParams) const unsigned short* const rgusParams, const unsigned short cParams) +DWORD InputStateMachineEngine::_GetGenericKeysModifierState(const std::basic_string_view parameters) { - DWORD dwModifiers = 0; - if (_IsModified(cParams) && cParams >= 2) + DWORD modifiers = 0; + if (_IsModified(parameters.size()) && parameters.size() >= 2) { - dwModifiers = _GetModifier(rgusParams[1]); + modifiers = _GetModifier(parameters.at(1)); } - return dwModifiers; + return modifiers; } // Method Description: // - Determines if a set of parameters indicates a modified keypress // Arguments: -// - cParams - the nummber of parameters we've collected in this sequence +// - paramCount - the nummber of parameters we've collected in this sequence // Return Value: // - true iff the sequence is a modified sequence. -bool InputStateMachineEngine::_IsModified(const unsigned short cParams) +bool InputStateMachineEngine::_IsModified(const size_t paramCount) { // modified input either looks like // \x1b[1;mA or \x1b[17;m~ // Both have two parameters - return cParams == 2; + return paramCount == 2; } // Method Description: @@ -726,46 +776,44 @@ bool InputStateMachineEngine::_IsModified(const unsigned short cParams) // - modifierParam - the VT modifier value to convert // Return Value: // - The equivalent INPUT_RECORD modifier value. -DWORD InputStateMachineEngine::_GetModifier(const unsigned short modifierParam) +DWORD InputStateMachineEngine::_GetModifier(const size_t modifierParam) { // VT Modifiers are 1+(modifier flags) - unsigned short vtParam = modifierParam - 1; - DWORD modifierState = modifierParam > 0 ? ENHANCED_KEY : 0; - - bool fShift = WI_IsFlagSet(vtParam, VT_SHIFT); - bool fAlt = WI_IsFlagSet(vtParam, VT_ALT); - bool fCtrl = WI_IsFlagSet(vtParam, VT_CTRL); - return modifierState | (fShift ? SHIFT_PRESSED : 0) | (fAlt ? LEFT_ALT_PRESSED : 0) | (fCtrl ? LEFT_CTRL_PRESSED : 0); + const auto vtParam = modifierParam - 1; + DWORD modifierState = 0; + WI_SetFlagIf(modifierState, ENHANCED_KEY, modifierParam > 0); + WI_SetFlagIf(modifierState, SHIFT_PRESSED, WI_IsFlagSet(vtParam, VT_SHIFT)); + WI_SetFlagIf(modifierState, LEFT_ALT_PRESSED, WI_IsFlagSet(vtParam, VT_ALT)); + WI_SetFlagIf(modifierState, LEFT_CTRL_PRESSED, WI_IsFlagSet(vtParam, VT_CTRL)); + return modifierState; } // Method Description: // - Gets the Vkey form the generic keys table associated with a particular // identifier code. The identifier code will be the first param in rgusParams. // Arguments: -// - rgusParams: an array of shorts where the first is the identifier of the key +// - parameters: an array of shorts where the first is the identifier of the key // we're looking for. -// - cParams: number of params in rgusParams -// - pVkey: Recieves the vkey +// - vkey: Recieves the vkey // Return Value: // true iff we found the key -bool InputStateMachineEngine::_GetGenericVkey(_In_reads_(cParams) const unsigned short* const rgusParams, const unsigned short cParams, _Out_ short* const pVkey) const +bool InputStateMachineEngine::_GetGenericVkey(const std::basic_string_view parameters, short& vkey) const { - *pVkey = 0; - if (cParams < 1) + vkey = 0; + if (parameters.empty()) { return false; } - const unsigned short identifier = rgusParams[0]; - for (int i = 0; i < ARRAYSIZE(s_rgGenericMap); i++) + const auto identifier = (GenericKeyIdentifiers)parameters[0]; + + const auto mapping = std::find(s_genericMap.cbegin(), s_genericMap.cend(), identifier); + if (mapping != s_genericMap.end()) { - GENERIC_TO_VKEY mapping = s_rgGenericMap[i]; - if (mapping.Identifier == identifier) - { - *pVkey = mapping.vkey; - return true; - } + vkey = mapping->vkey; + return true; } + return false; } @@ -773,20 +821,18 @@ bool InputStateMachineEngine::_GetGenericVkey(_In_reads_(cParams) const unsigned // - Gets the Vkey from the CSI codes table associated with a particular character. // Arguments: // - wch: the wchar_t to get the mapped vkey of. -// - pVkey: Recieves the vkey +// - vkey: Recieves the vkey // Return Value: // true iff we found the key -bool InputStateMachineEngine::_GetCursorKeysVkey(const wchar_t wch, _Out_ short* const pVkey) const +bool InputStateMachineEngine::_GetCursorKeysVkey(const wchar_t wch, short& vkey) const { - *pVkey = 0; - for (int i = 0; i < ARRAYSIZE(s_rgCsiMap); i++) + vkey = 0; + + const auto mapping = std::find(s_csiMap.cbegin(), s_csiMap.cend(), (CsiActionCodes)wch); + if (mapping != s_csiMap.end()) { - CSI_TO_VKEY mapping = s_rgCsiMap[i]; - if (mapping.Action == wch) - { - *pVkey = mapping.vkey; - return true; - } + vkey = mapping->vkey; + return true; } return false; @@ -799,17 +845,15 @@ bool InputStateMachineEngine::_GetCursorKeysVkey(const wchar_t wch, _Out_ short* // - pVkey: Recieves the vkey // Return Value: // true iff we found the key -bool InputStateMachineEngine::_GetSs3KeysVkey(const wchar_t wch, _Out_ short* const pVkey) const +bool InputStateMachineEngine::_GetSs3KeysVkey(const wchar_t wch, short& vkey) const { - *pVkey = 0; - for (int i = 0; i < ARRAYSIZE(s_rgSs3Map); i++) + vkey = 0; + + const auto mapping = std::find(s_ss3Map.cbegin(), s_ss3Map.cend(), (Ss3ActionCodes)wch); + if (mapping != s_ss3Map.end()) { - SS3_TO_VKEY mapping = s_rgSs3Map[i]; - if (mapping.Action == wch) - { - *pVkey = mapping.vkey; - return true; - } + vkey = mapping->vkey; + return true; } return false; @@ -819,40 +863,35 @@ bool InputStateMachineEngine::_GetSs3KeysVkey(const wchar_t wch, _Out_ short* co // - Gets the Vkey and modifier state that's associated with a particular char. // Arguments: // - wch: the wchar_t to get the vkey and modifier state of. -// - pVkey: Recieves the vkey -// - pdwModifierState: Recieves the modifier state +// - vkey: Recieves the vkey +// - modifierState: Recieves the modifier state // Return Value: // bool InputStateMachineEngine::_GenerateKeyFromChar(const wchar_t wch, - _Out_ short* const pVkey, - _Out_ DWORD* const pdwModifierState) + short& vkey, + DWORD& modifierState) { // Low order byte is key, high order is modifiers short keyscan = VkKeyScanW(wch); - short vkey = LOBYTE(keyscan); + short key = LOBYTE(keyscan); short keyscanModifiers = HIBYTE(keyscan); - if (vkey == -1 && keyscanModifiers == -1) + if (key == -1 && keyscanModifiers == -1) { return false; } // Because of course, these are not the same flags. - short dwModifierState = 0 | - (WI_IsFlagSet(keyscanModifiers, KEYSCAN_SHIFT) ? SHIFT_PRESSED : 0) | - (WI_IsFlagSet(keyscanModifiers, KEYSCAN_CTRL) ? LEFT_CTRL_PRESSED : 0) | - (WI_IsFlagSet(keyscanModifiers, KEYSCAN_ALT) ? LEFT_ALT_PRESSED : 0); + short modifierFlags = 0 | + (WI_IsFlagSet(keyscanModifiers, KEYSCAN_SHIFT) ? SHIFT_PRESSED : 0) | + (WI_IsFlagSet(keyscanModifiers, KEYSCAN_CTRL) ? LEFT_CTRL_PRESSED : 0) | + (WI_IsFlagSet(keyscanModifiers, KEYSCAN_ALT) ? LEFT_ALT_PRESSED : 0); + + vkey = key; + modifierState = modifierFlags; - if (pVkey != nullptr) - { - *pVkey = vkey; - } - if (pdwModifierState != nullptr) - { - *pdwModifierState = dwModifierState; - } return true; } @@ -902,84 +941,82 @@ bool InputStateMachineEngine::DispatchIntermediatesFromEscape() const // This is kept seperate from the output version, as there may be // codes that are supported in one direction but not the other. // Arguments: -// - rgusParams - Array of parameters collected -// - cParams - Number of parameters we've collected -// - puiFunction - Memory location to receive the function type +// - parameters - Array of parameters collected +// - function - Receives the function type // Return Value: // - True iff we successfully pulled the function type from the parameters -bool InputStateMachineEngine::_GetWindowManipulationType(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiFunction) const +bool InputStateMachineEngine::_GetWindowManipulationType(const std::basic_string_view parameters, + unsigned int& function) const { - bool fSuccess = false; - *puiFunction = DispatchTypes::WindowManipulationType::Invalid; + bool success = false; + function = DispatchTypes::WindowManipulationType::Invalid; - if (cParams > 0) + if (!parameters.empty()) { - switch (rgusParams[0]) + switch (parameters[0]) { case DispatchTypes::WindowManipulationType::RefreshWindow: - *puiFunction = DispatchTypes::WindowManipulationType::RefreshWindow; - fSuccess = true; + function = DispatchTypes::WindowManipulationType::RefreshWindow; + success = true; break; case DispatchTypes::WindowManipulationType::ResizeWindowInCharacters: - *puiFunction = DispatchTypes::WindowManipulationType::ResizeWindowInCharacters; - fSuccess = true; + function = DispatchTypes::WindowManipulationType::ResizeWindowInCharacters; + success = true; break; default: - fSuccess = false; + success = false; } } - return fSuccess; + return success; } // Routine Description: // - Retrieves an X/Y coordinate pair for a cursor operation from the parameter pool stored during Param actions. // Arguments: -// - puiLine - Memory location to receive the Y/Line/Row position -// - puiColumn - Memory location to receive the X/Column position +// - parameters - set of numeric parameters collected while pasring the sequence. +// - line - Receives the Y/Line/Row position +// - column - Receives the X/Column position // Return Value: // - True if we successfully pulled the cursor coordinates from the parameters we've stored. False otherwise. -_Success_(return ) bool InputStateMachineEngine::_GetXYPosition(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiLine, - _Out_ unsigned int* const puiColumn) const +bool InputStateMachineEngine::_GetXYPosition(const std::basic_string_view parameters, + size_t& line, + size_t& column) const { - bool fSuccess = true; - *puiLine = s_uiDefaultLine; - *puiColumn = s_uiDefaultColumn; + bool success = true; + line = DefaultLine; + column = DefaultColumn; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's only one param, leave the default for the column, and retrieve the specified row. - *puiLine = rgusParams[0]; + line = parameters[0]; } - else if (cParams == 2) + else if (parameters.size() == 2) { // If there are exactly two parameters, use them. - *puiLine = rgusParams[0]; - *puiColumn = rgusParams[1]; + line = parameters[0]; + column = parameters[1]; } else { - fSuccess = false; + success = false; } // Distances of 0 should be changed to 1. - if (*puiLine == 0) + if (line == 0) { - *puiLine = s_uiDefaultLine; + line = DefaultLine; } - if (*puiColumn == 0) + if (column == 0) { - *puiColumn = s_uiDefaultColumn; + column = DefaultColumn; } - return fSuccess; + return success; } diff --git a/src/terminal/parser/InputStateMachineEngine.hpp b/src/terminal/parser/InputStateMachineEngine.hpp index cbb8d0acf6..67bc8ecc48 100644 --- a/src/terminal/parser/InputStateMachineEngine.hpp +++ b/src/terminal/parser/InputStateMachineEngine.hpp @@ -26,8 +26,8 @@ namespace Microsoft::Console::VirtualTerminal class InputStateMachineEngine : public IStateMachineEngine { public: - InputStateMachineEngine(IInteractDispatch* const pDispatch); - InputStateMachineEngine(IInteractDispatch* const pDispatch, + InputStateMachineEngine(std::unique_ptr pDispatch); + InputStateMachineEngine(std::unique_ptr pDispatch, const bool lookingForDSR); bool ActionExecute(const wchar_t wch) override; @@ -35,34 +35,27 @@ namespace Microsoft::Console::VirtualTerminal bool ActionPrint(const wchar_t wch) override; - bool ActionPrintString(const wchar_t* const rgwch, - const size_t cch) override; + bool ActionPrintString(const std::wstring_view string) override; - bool ActionPassThroughString(const wchar_t* const rgwch, - size_t const cch) override; + bool ActionPassThroughString(const std::wstring_view string) override; bool ActionEscDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate) override; + const std::basic_string_view intermediates) override; bool ActionCsiDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams); + const std::basic_string_view intermediates, + const std::basic_string_view parameters) override; bool ActionClear() override; bool ActionIgnore() override; bool ActionOscDispatch(const wchar_t wch, - const unsigned short sOscParam, - _Inout_updates_(cchOscString) wchar_t* const pwchOscStringBuffer, - const unsigned short cchOscString) override; + const size_t parameter, + const std::wstring_view string) override; bool ActionSs3Dispatch(const wchar_t wch, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) override; + const std::basic_string_view parameters) override; bool FlushAtEndOfString() const override; bool DispatchControlCharsFromEscape() const override; @@ -72,121 +65,39 @@ namespace Microsoft::Console::VirtualTerminal const std::unique_ptr _pDispatch; bool _lookingForDSR; - enum CsiActionCodes : wchar_t - { - ArrowUp = L'A', - ArrowDown = L'B', - ArrowRight = L'C', - ArrowLeft = L'D', - Home = L'H', - End = L'F', - Generic = L'~', // Used for a whole bunch of possible keys - CSI_F1 = L'P', - CSI_F2 = L'Q', - CSI_F3 = L'R', // Both F3 and DSR are on R. - // DSR_DeviceStatusReportResponse = L'R', - CSI_F4 = L'S', - DTTERM_WindowManipulation = L't', - CursorBackTab = L'Z', - }; + DWORD _GetCursorKeysModifierState(const std::basic_string_view parameters); + DWORD _GetGenericKeysModifierState(const std::basic_string_view parameters); + bool _GenerateKeyFromChar(const wchar_t wch, short& vkey, DWORD& modifierState); - enum Ss3ActionCodes : wchar_t - { - // The "Cursor Keys" are sometimes sent as a SS3 in "application mode" - // But for now we'll only accept them as Normal Mode sequences, as CSI's. - // ArrowUp = L'A', - // ArrowDown = L'B', - // ArrowRight = L'C', - // ArrowLeft = L'D', - // Home = L'H', - // End = L'F', - SS3_F1 = L'P', - SS3_F2 = L'Q', - SS3_F3 = L'R', - SS3_F4 = L'S', - }; + bool _IsModified(const size_t paramCount); + DWORD _GetModifier(const size_t parameter); - // Sequences ending in '~' use these numbers as identifiers. - enum GenericKeyIdentifiers : unsigned short - { - GenericHome = 1, - Insert = 2, - Delete = 3, - GenericEnd = 4, - Prior = 5, //PgUp - Next = 6, //PgDn - F5 = 15, - F6 = 17, - F7 = 18, - F8 = 19, - F9 = 20, - F10 = 21, - F11 = 23, - F12 = 24, - }; + bool _GetGenericVkey(const std::basic_string_view parameters, + short& vkey) const; + bool _GetCursorKeysVkey(const wchar_t wch, short& vkey) const; + bool _GetSs3KeysVkey(const wchar_t wch, short& vkey) const; - struct CSI_TO_VKEY - { - CsiActionCodes Action; - short vkey; - }; + bool _WriteSingleKey(const short vkey, const DWORD modifierState); + bool _WriteSingleKey(const wchar_t wch, const short vkey, const DWORD modifierState); - struct GENERIC_TO_VKEY - { - GenericKeyIdentifiers Identifier; - short vkey; - }; + void _GenerateWrappedSequence(const wchar_t wch, + const short vkey, + const DWORD modifierState, + std::vector& input); - struct SS3_TO_VKEY - { - Ss3ActionCodes Action; - short vkey; - }; + void _GetSingleKeypress(const wchar_t wch, + const short vkey, + const DWORD modifierState, + std::vector& input); - static const CSI_TO_VKEY s_rgCsiMap[]; - static const GENERIC_TO_VKEY s_rgGenericMap[]; - static const SS3_TO_VKEY s_rgSs3Map[]; + bool _GetWindowManipulationType(const std::basic_string_view parameters, + unsigned int& function) const; - DWORD _GetCursorKeysModifierState(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams); - DWORD _GetGenericKeysModifierState(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams); - bool _GenerateKeyFromChar(const wchar_t wch, _Out_ short* const pVkey, _Out_ DWORD* const pdwModifierState); - - bool _IsModified(const unsigned short cParams); - DWORD _GetModifier(const unsigned short modifierParam); - - bool _GetGenericVkey(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ short* const pVkey) const; - bool _GetCursorKeysVkey(const wchar_t wch, _Out_ short* const pVkey) const; - bool _GetSs3KeysVkey(const wchar_t wch, _Out_ short* const pVkey) const; - - bool _WriteSingleKey(const short vkey, const DWORD dwModifierState); - bool _WriteSingleKey(const wchar_t wch, const short vkey, const DWORD dwModifierState); - - size_t _GenerateWrappedSequence(const wchar_t wch, - const short vkey, - const DWORD dwModifierState, - _Inout_updates_(cInput) INPUT_RECORD* rgInput, - const size_t cInput); - - size_t _GetSingleKeypress(const wchar_t wch, - const short vkey, - const DWORD dwModifierState, - _Inout_updates_(cRecords) INPUT_RECORD* const rgInput, - const size_t cRecords); - - bool _GetWindowManipulationType(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiFunction) const; - - static const unsigned int s_uiDefaultLine = 1; - static const unsigned int s_uiDefaultColumn = 1; - bool _GetXYPosition(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiLine, - _Out_ unsigned int* const puiColumn) const; + static constexpr size_t DefaultLine = 1; + static constexpr size_t DefaultColumn = 1; + bool _GetXYPosition(const std::basic_string_view parameters, + size_t& line, + size_t& column) const; bool _DoControlCharacter(const wchar_t wch, const bool writeAlt); }; diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index c21a2bc1f0..538c7a0fcc 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -11,8 +11,8 @@ using namespace Microsoft::Console; using namespace Microsoft::Console::VirtualTerminal; // takes ownership of pDispatch -OutputStateMachineEngine::OutputStateMachineEngine(ITermDispatch* const pDispatch) : - _dispatch(pDispatch), +OutputStateMachineEngine::OutputStateMachineEngine(std::unique_ptr pDispatch) : + _dispatch(std::move(pDispatch)), _pfnFlushToTerminal(nullptr), _pTtyConnection(nullptr), _lastPrintedChar(AsciiChars::NUL) @@ -105,24 +105,23 @@ bool OutputStateMachineEngine::ActionPrint(const wchar_t wch) // - Triggers the Print action to indicate that the listener should render the // string of characters given. // Arguments: -// - rgwch - string to dispatch. -// - cch - length of rgwch +// - string - string to dispatch. // Return Value: // - true iff we successfully dispatched the sequence. -bool OutputStateMachineEngine::ActionPrintString(const wchar_t* const rgwch, const size_t cch) +bool OutputStateMachineEngine::ActionPrintString(const std::wstring_view string) { - if (cch == 0) + if (string.empty()) { return true; } // Stash the last character of the string, if it's a graphical character - const wchar_t wch = rgwch[cch - 1]; + const wchar_t wch = string.back(); if (wch >= AsciiChars::SPC) { _lastPrintedChar = wch; } - _dispatch->PrintString(rgwch, cch); // call print + _dispatch->PrintString(string); // call print return true; } @@ -136,24 +135,21 @@ bool OutputStateMachineEngine::ActionPrintString(const wchar_t* const rgwch, con // Otherwise, we're the terminal device, and we'll eat the string (because // we don't know what to do with it) // Arguments: -// - rgwch - string to dispatch. -// - cch - length of rgwch +// - string - string to dispatch. // Return Value: // - true iff we successfully dispatched the sequence. -bool OutputStateMachineEngine::ActionPassThroughString(const wchar_t* const rgwch, - _In_ size_t const cch) +bool OutputStateMachineEngine::ActionPassThroughString(const std::wstring_view string) { - bool fSuccess = true; + bool success = true; if (_pTtyConnection != nullptr) { - std::wstring wstr = std::wstring(rgwch, cch); - auto hr = _pTtyConnection->WriteTerminalW(wstr); + const auto hr = _pTtyConnection->WriteTerminalW(string); LOG_IF_FAILED(hr); - fSuccess = SUCCEEDED(hr); + success = SUCCEEDED(hr); } // If there's not a TTY connection, our previous behavior was to eat the string. - return fSuccess; + return success; } // Routine Description: @@ -162,112 +158,111 @@ bool OutputStateMachineEngine::ActionPassThroughString(const wchar_t* const rgwc // and a simple letter. No complicated parameters. // Arguments: // - wch - Character to dispatch. -// - cIntermediate - Number of "Intermediate" characters found - such as '!', '?' -// - wchIntermediate - Intermediate character in the sequence, if there was one. +// - intermediates - Intermediate characters in the sequence // Return Value: // - true iff we successfully dispatched the sequence. bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate) + const std::basic_string_view intermediates) { - bool fSuccess = false; + bool success = false; // no intermediates. - if (cIntermediate == 0) + if (intermediates.empty()) { switch (wch) { case VTActionCodes::CUU_CursorUp: - fSuccess = _dispatch->CursorUp(1); + success = _dispatch->CursorUp(1); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUU); break; case VTActionCodes::CUD_CursorDown: - fSuccess = _dispatch->CursorDown(1); + success = _dispatch->CursorDown(1); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUD); break; case VTActionCodes::CUF_CursorForward: - fSuccess = _dispatch->CursorForward(1); + success = _dispatch->CursorForward(1); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUF); break; case VTActionCodes::CUB_CursorBackward: - fSuccess = _dispatch->CursorBackward(1); + success = _dispatch->CursorBackward(1); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUB); break; case VTActionCodes::DECSC_CursorSave: - fSuccess = _dispatch->CursorSaveState(); + success = _dispatch->CursorSaveState(); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSC); break; case VTActionCodes::DECRC_CursorRestore: - fSuccess = _dispatch->CursorRestoreState(); + success = _dispatch->CursorRestoreState(); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECRC); break; case VTActionCodes::DECKPAM_KeypadApplicationMode: - fSuccess = _dispatch->SetKeypadMode(true); + success = _dispatch->SetKeypadMode(true); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECKPAM); break; case VTActionCodes::DECKPNM_KeypadNumericMode: - fSuccess = _dispatch->SetKeypadMode(false); + success = _dispatch->SetKeypadMode(false); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECKPNM); break; case VTActionCodes::RI_ReverseLineFeed: - fSuccess = _dispatch->ReverseLineFeed(); + success = _dispatch->ReverseLineFeed(); TermTelemetry::Instance().Log(TermTelemetry::Codes::RI); break; case VTActionCodes::HTS_HorizontalTabSet: - fSuccess = _dispatch->HorizontalTabSet(); + success = _dispatch->HorizontalTabSet(); TermTelemetry::Instance().Log(TermTelemetry::Codes::HTS); break; case VTActionCodes::RIS_ResetToInitialState: - fSuccess = _dispatch->HardReset(); + success = _dispatch->HardReset(); TermTelemetry::Instance().Log(TermTelemetry::Codes::RIS); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } - else if (cIntermediate == 1) + else if (intermediates.size() == 1) { - DesignateCharsetTypes designateType = s_DefaultDesignateCharsetType; - fSuccess = _GetDesignateType(wchIntermediate, &designateType); - if (fSuccess) + const auto value = intermediates[0]; + DesignateCharsetTypes designateType = DefaultDesignateCharsetType; + success = _GetDesignateType(value, designateType); + if (success) { switch (designateType) { case DesignateCharsetTypes::G0: - fSuccess = _dispatch->DesignateCharset(wch); + success = _dispatch->DesignateCharset(wch); TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG0); break; case DesignateCharsetTypes::G1: - fSuccess = false; + success = false; TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1); break; case DesignateCharsetTypes::G2: - fSuccess = false; + success = false; TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2); break; case DesignateCharsetTypes::G3: - fSuccess = false; + success = false; TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } - else if (wchIntermediate == L'#') + else if (value == L'#') { switch (wch) { case VTActionCodes::DECALN_ScreenAlignmentPattern: - fSuccess = _dispatch->ScreenAlignmentPattern(); + success = _dispatch->ScreenAlignmentPattern(); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECALN); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } @@ -275,7 +270,7 @@ bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch, _ClearLastChar(); - return fSuccess; + return success; } // Routine Description: @@ -284,37 +279,31 @@ bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch, // that can include many parameters. // Arguments: // - wch - Character to dispatch. -// - cIntermediate - Number of "Intermediate" characters found - such as '!', '?' -// - wchIntermediate - Intermediate character in the sequence, if there was one. -// - rgusParams - set of numeric parameters collected while pasring the sequence. -// - cParams - number of parameters found. +// - intermediates - Intermediate characters in the sequence +// - parameters - set of numeric parameters collected while pasring the sequence. // Return Value: // - true iff we successfully dispatched the sequence. bool OutputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) + const std::basic_string_view intermediates, + std::basic_string_view parameters) { - bool fSuccess = false; - unsigned int uiDistance = 0; - unsigned int uiLine = 0; - unsigned int uiColumn = 0; - SHORT sTopMargin = 0; - SHORT sBottomMargin = 0; - SHORT sNumTabs = 0; - SHORT sClearType = 0; - unsigned int uiFunction = 0; + bool success = false; + size_t distance = 0; + size_t line = 0; + size_t column = 0; + size_t topMargin = 0; + size_t bottomMargin = 0; + size_t numTabs = 0; + size_t clearType = 0; + unsigned int function = 0; DispatchTypes::EraseType eraseType = DispatchTypes::EraseType::ToEnd; - DispatchTypes::GraphicsOptions rgGraphicsOptions[StateMachine::s_cParamsMax]; - size_t cOptions = StateMachine::s_cParamsMax; + std::vector graphicsOptions; DispatchTypes::AnsiStatusType deviceStatusType = (DispatchTypes::AnsiStatusType)-1; // there is no default status type. - unsigned int repeatCount = 0; + size_t repeatCount = 0; // This is all the args after the first arg, and the count of args not including the first one. - const unsigned short* const rgusRemainingArgs = (cParams > 1) ? rgusParams + 1 : rgusParams; - const unsigned short cRemainingArgs = (cParams >= 1) ? cParams - 1 : 0; + const auto remainingParams = parameters.size() > 1 ? parameters.substr(1) : std::basic_string_view{}; - if (cIntermediate == 0) + if (intermediates.empty()) { // fill params switch (wch) @@ -331,178 +320,177 @@ bool OutputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, case VTActionCodes::ICH_InsertCharacter: case VTActionCodes::DCH_DeleteCharacter: case VTActionCodes::ECH_EraseCharacters: - fSuccess = _GetCursorDistance(rgusParams, cParams, &uiDistance); + success = _GetCursorDistance(parameters, distance); break; case VTActionCodes::HVP_HorizontalVerticalPosition: case VTActionCodes::CUP_CursorPosition: - fSuccess = _GetXYPosition(rgusParams, cParams, &uiLine, &uiColumn); + success = _GetXYPosition(parameters, line, column); break; case VTActionCodes::DECSTBM_SetScrollingRegion: - fSuccess = _GetTopBottomMargins(rgusParams, cParams, &sTopMargin, &sBottomMargin); + success = _GetTopBottomMargins(parameters, topMargin, bottomMargin); break; case VTActionCodes::ED_EraseDisplay: case VTActionCodes::EL_EraseLine: - fSuccess = _GetEraseOperation(rgusParams, cParams, &eraseType); + success = _GetEraseOperation(parameters, eraseType); break; case VTActionCodes::SGR_SetGraphicsRendition: - fSuccess = _GetGraphicsOptions(rgusParams, cParams, rgGraphicsOptions, &cOptions); + success = _GetGraphicsOptions(parameters, graphicsOptions); break; case VTActionCodes::DSR_DeviceStatusReport: - fSuccess = _GetDeviceStatusOperation(rgusParams, cParams, &deviceStatusType); + success = _GetDeviceStatusOperation(parameters, deviceStatusType); break; case VTActionCodes::DA_DeviceAttributes: - fSuccess = _VerifyDeviceAttributesParams(rgusParams, cParams); + success = _VerifyDeviceAttributesParams(parameters); break; case VTActionCodes::SU_ScrollUp: case VTActionCodes::SD_ScrollDown: - fSuccess = _GetScrollDistance(rgusParams, cParams, &uiDistance); + success = _GetScrollDistance(parameters, distance); break; case VTActionCodes::ANSISYSSC_CursorSave: case VTActionCodes::ANSISYSRC_CursorRestore: - fSuccess = _VerifyHasNoParameters(cParams); + success = _VerifyHasNoParameters(parameters); break; case VTActionCodes::IL_InsertLine: case VTActionCodes::DL_DeleteLine: - fSuccess = _GetScrollDistance(rgusParams, cParams, &uiDistance); + success = _GetScrollDistance(parameters, distance); break; case VTActionCodes::CHT_CursorForwardTab: case VTActionCodes::CBT_CursorBackTab: - fSuccess = _GetTabDistance(rgusParams, cParams, &sNumTabs); + success = _GetTabDistance(parameters, numTabs); break; case VTActionCodes::TBC_TabClear: - fSuccess = _GetTabClearType(rgusParams, cParams, &sClearType); + success = _GetTabClearType(parameters, clearType); break; case VTActionCodes::DTTERM_WindowManipulation: - fSuccess = _GetWindowManipulationType(rgusParams, cParams, &uiFunction); + success = _GetWindowManipulationType(parameters, function); break; case VTActionCodes::REP_RepeatCharacter: - fSuccess = _GetRepeatCount(rgusParams, cParams, &repeatCount); + success = _GetRepeatCount(parameters, repeatCount); break; default: // If no params to fill, param filling was successful. - fSuccess = true; + success = true; break; } // if param filling successful, try to dispatch - if (fSuccess) + if (success) { switch (wch) { case VTActionCodes::CUU_CursorUp: - fSuccess = _dispatch->CursorUp(uiDistance); + success = _dispatch->CursorUp(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUU); break; case VTActionCodes::CUD_CursorDown: - fSuccess = _dispatch->CursorDown(uiDistance); + success = _dispatch->CursorDown(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUD); break; case VTActionCodes::CUF_CursorForward: - fSuccess = _dispatch->CursorForward(uiDistance); + success = _dispatch->CursorForward(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUF); break; case VTActionCodes::CUB_CursorBackward: - fSuccess = _dispatch->CursorBackward(uiDistance); + success = _dispatch->CursorBackward(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUB); break; case VTActionCodes::CNL_CursorNextLine: - fSuccess = _dispatch->CursorNextLine(uiDistance); + success = _dispatch->CursorNextLine(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::CNL); break; case VTActionCodes::CPL_CursorPrevLine: - fSuccess = _dispatch->CursorPrevLine(uiDistance); + success = _dispatch->CursorPrevLine(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::CPL); break; case VTActionCodes::CHA_CursorHorizontalAbsolute: case VTActionCodes::HPA_HorizontalPositionAbsolute: - fSuccess = _dispatch->CursorHorizontalPositionAbsolute(uiDistance); + success = _dispatch->CursorHorizontalPositionAbsolute(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::CHA); break; case VTActionCodes::VPA_VerticalLinePositionAbsolute: - fSuccess = _dispatch->VerticalLinePositionAbsolute(uiDistance); + success = _dispatch->VerticalLinePositionAbsolute(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::VPA); break; case VTActionCodes::CUP_CursorPosition: case VTActionCodes::HVP_HorizontalVerticalPosition: - fSuccess = _dispatch->CursorPosition(uiLine, uiColumn); + success = _dispatch->CursorPosition(line, column); TermTelemetry::Instance().Log(TermTelemetry::Codes::CUP); break; case VTActionCodes::DECSTBM_SetScrollingRegion: - fSuccess = _dispatch->SetTopBottomScrollingMargins(sTopMargin, sBottomMargin); + success = _dispatch->SetTopBottomScrollingMargins(topMargin, bottomMargin); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSTBM); break; case VTActionCodes::ICH_InsertCharacter: - fSuccess = _dispatch->InsertCharacter(uiDistance); + success = _dispatch->InsertCharacter(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::ICH); break; case VTActionCodes::DCH_DeleteCharacter: - fSuccess = _dispatch->DeleteCharacter(uiDistance); + success = _dispatch->DeleteCharacter(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::DCH); break; case VTActionCodes::ED_EraseDisplay: - fSuccess = _dispatch->EraseInDisplay(eraseType); + success = _dispatch->EraseInDisplay(eraseType); TermTelemetry::Instance().Log(TermTelemetry::Codes::ED); break; case VTActionCodes::EL_EraseLine: - fSuccess = _dispatch->EraseInLine(eraseType); + success = _dispatch->EraseInLine(eraseType); TermTelemetry::Instance().Log(TermTelemetry::Codes::EL); break; case VTActionCodes::SGR_SetGraphicsRendition: - fSuccess = _dispatch->SetGraphicsRendition(rgGraphicsOptions, cOptions); + success = _dispatch->SetGraphicsRendition({ graphicsOptions.data(), graphicsOptions.size() }); TermTelemetry::Instance().Log(TermTelemetry::Codes::SGR); break; case VTActionCodes::DSR_DeviceStatusReport: - fSuccess = _dispatch->DeviceStatusReport(deviceStatusType); + success = _dispatch->DeviceStatusReport(deviceStatusType); TermTelemetry::Instance().Log(TermTelemetry::Codes::DSR); break; case VTActionCodes::DA_DeviceAttributes: - fSuccess = _dispatch->DeviceAttributes(); + success = _dispatch->DeviceAttributes(); TermTelemetry::Instance().Log(TermTelemetry::Codes::DA); break; case VTActionCodes::SU_ScrollUp: - fSuccess = _dispatch->ScrollUp(uiDistance); + success = _dispatch->ScrollUp(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::SU); break; case VTActionCodes::SD_ScrollDown: - fSuccess = _dispatch->ScrollDown(uiDistance); + success = _dispatch->ScrollDown(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::SD); break; case VTActionCodes::ANSISYSSC_CursorSave: - fSuccess = _dispatch->CursorSaveState(); + success = _dispatch->CursorSaveState(); TermTelemetry::Instance().Log(TermTelemetry::Codes::ANSISYSSC); break; case VTActionCodes::ANSISYSRC_CursorRestore: - fSuccess = _dispatch->CursorRestoreState(); + success = _dispatch->CursorRestoreState(); TermTelemetry::Instance().Log(TermTelemetry::Codes::ANSISYSRC); break; case VTActionCodes::IL_InsertLine: - fSuccess = _dispatch->InsertLine(uiDistance); + success = _dispatch->InsertLine(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::IL); break; case VTActionCodes::DL_DeleteLine: - fSuccess = _dispatch->DeleteLine(uiDistance); + success = _dispatch->DeleteLine(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::DL); break; case VTActionCodes::CHT_CursorForwardTab: - fSuccess = _dispatch->ForwardTab(sNumTabs); + success = _dispatch->ForwardTab(numTabs); TermTelemetry::Instance().Log(TermTelemetry::Codes::CHT); break; case VTActionCodes::CBT_CursorBackTab: - fSuccess = _dispatch->BackwardsTab(sNumTabs); + success = _dispatch->BackwardsTab(numTabs); TermTelemetry::Instance().Log(TermTelemetry::Codes::CBT); break; case VTActionCodes::TBC_TabClear: - fSuccess = _dispatch->TabClear(sClearType); + success = _dispatch->TabClear(clearType); TermTelemetry::Instance().Log(TermTelemetry::Codes::TBC); break; case VTActionCodes::ECH_EraseCharacters: - fSuccess = _dispatch->EraseCharacters(uiDistance); + success = _dispatch->EraseCharacters(distance); TermTelemetry::Instance().Log(TermTelemetry::Codes::ECH); break; case VTActionCodes::DTTERM_WindowManipulation: - fSuccess = _dispatch->WindowManipulation(static_cast(uiFunction), - rgusRemainingArgs, - cRemainingArgs); + success = _dispatch->WindowManipulation(static_cast(function), + remainingParams); TermTelemetry::Instance().Log(TermTelemetry::Codes::DTTERM_WM); break; case VTActionCodes::REP_RepeatCharacter: @@ -514,96 +502,96 @@ bool OutputStateMachineEngine::ActionCsiDispatch(const wchar_t wch, if (_lastPrintedChar != AsciiChars::NUL) { std::wstring wstr(repeatCount, _lastPrintedChar); - _dispatch->PrintString(wstr.c_str(), wstr.length()); + _dispatch->PrintString(wstr); } - fSuccess = true; + success = true; TermTelemetry::Instance().Log(TermTelemetry::Codes::REP); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } } - else if (cIntermediate == 1) + else if (intermediates.size() == 1) { - switch (wchIntermediate) + const auto value = intermediates[0]; + switch (value) { case L'?': - fSuccess = _IntermediateQuestionMarkDispatch(wch, rgusParams, cParams); + success = _IntermediateQuestionMarkDispatch(wch, parameters); break; case L'!': - fSuccess = _IntermediateExclamationDispatch(wch); + success = _IntermediateExclamationDispatch(wch); break; case L' ': - fSuccess = _IntermediateSpaceDispatch(wch, rgusParams, cParams); + success = _IntermediateSpaceDispatch(wch, parameters); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } // If we were unable to process the string, and there's a TTY attached to us, // trigger the state machine to flush the string to the terminal. - if (_pfnFlushToTerminal != nullptr && !fSuccess) + if (_pfnFlushToTerminal != nullptr && !success) { - fSuccess = _pfnFlushToTerminal(); + success = _pfnFlushToTerminal(); } _ClearLastChar(); - return fSuccess; + return success; } // Routine Description: // - Handles actions that have postfix params on an intermediate '?', such as DECTCEM, DECCOLM, ATT610 // Arguments: // - wch - Character to dispatch. +// - parameters - set of numeric parameters collected while parsing the sequence. // Return Value: // - True if handled successfully. False otherwise. bool OutputStateMachineEngine::_IntermediateQuestionMarkDispatch(const wchar_t wchAction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) + const std::basic_string_view parameters) { - bool fSuccess = false; + bool success = false; - DispatchTypes::PrivateModeParams rgPrivateModeParams[StateMachine::s_cParamsMax]; - size_t cOptions = StateMachine::s_cParamsMax; + std::vector privateModeParams; // Ensure that there was the right number of params switch (wchAction) { case VTActionCodes::DECSET_PrivateModeSet: case VTActionCodes::DECRST_PrivateModeReset: - fSuccess = _GetPrivateModeParams(rgusParams, cParams, rgPrivateModeParams, &cOptions); + success = _GetPrivateModeParams(parameters, privateModeParams); break; default: // If no params to fill, param filling was successful. - fSuccess = true; + success = true; break; } - if (fSuccess) + if (success) { switch (wchAction) { case VTActionCodes::DECSET_PrivateModeSet: - fSuccess = _dispatch->SetPrivateModes(rgPrivateModeParams, cOptions); + success = _dispatch->SetPrivateModes({ privateModeParams.data(), privateModeParams.size() }); //TODO: MSFT:6367459 Add specific logging for each of the DECSET/DECRST codes TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSET); break; case VTActionCodes::DECRST_PrivateModeReset: - fSuccess = _dispatch->ResetPrivateModes(rgPrivateModeParams, cOptions); + success = _dispatch->ResetPrivateModes({ privateModeParams.data(), privateModeParams.size() }); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECRST); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } - return fSuccess; + return success; } // Routine Description: @@ -614,64 +602,64 @@ bool OutputStateMachineEngine::_IntermediateQuestionMarkDispatch(const wchar_t w // - True if handled successfully. False otherwise. bool OutputStateMachineEngine::_IntermediateExclamationDispatch(const wchar_t wchAction) { - bool fSuccess = false; + bool success = false; switch (wchAction) { case VTActionCodes::DECSTR_SoftReset: - fSuccess = _dispatch->SoftReset(); + success = _dispatch->SoftReset(); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSTR); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } - return fSuccess; + return success; } // Routine Description: // - Handles actions that have an intermediate ' ' (0x20), such as DECSCUSR // Arguments: // - wch - Character to dispatch. +// - parameters - set of numeric parameters collected while parsing the sequence. // Return Value: // - True if handled successfully. False otherwise. bool OutputStateMachineEngine::_IntermediateSpaceDispatch(const wchar_t wchAction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) + const std::basic_string_view parameters) { - bool fSuccess = false; - DispatchTypes::CursorStyle cursorStyle = s_defaultCursorStyle; + bool success = false; + DispatchTypes::CursorStyle cursorStyle = DefaultCursorStyle; // Parse params switch (wchAction) { case VTActionCodes::DECSCUSR_SetCursorStyle: - fSuccess = _GetCursorStyle(rgusParams, cParams, &cursorStyle); + success = _GetCursorStyle(parameters, cursorStyle); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } // if param filling successful, try to dispatch - if (fSuccess) + if (success) { switch (wchAction) { case VTActionCodes::DECSCUSR_SetCursorStyle: - fSuccess = _dispatch->SetCursorStyle(cursorStyle); + success = _dispatch->SetCursorStyle(cursorStyle); TermTelemetry::Instance().Log(TermTelemetry::Codes::DECSCUSR); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } - return fSuccess; + return success; } // Routine Description: @@ -705,94 +693,91 @@ bool OutputStateMachineEngine::ActionIgnore() // These sequences perform various API-type commands that can include many parameters. // Arguments: // - wch - Character to dispatch. This will be a BEL or ST char. -// - sOscParam - identifier of the OSC action to perform -// - pwchOscStringBuffer - OSC string we've collected. NOT null terminated. -// - cchOscString - length of pwchOscStringBuffer +// - parameter - identifier of the OSC action to perform +// - string - OSC string we've collected. NOT null terminated. // Return Value: // - true if we handled the dsipatch. bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, - const unsigned short sOscParam, - _Inout_updates_(cchOscString) wchar_t* const pwchOscStringBuffer, - const unsigned short cchOscString) + const size_t parameter, + const std::wstring_view string) { - bool fSuccess = false; - wchar_t* pwchTitle = nullptr; - unsigned short sCchTitleLength = 0; + bool success = false; + std::wstring title; size_t tableIndex = 0; - DWORD dwColor = 0; + DWORD color = 0; - switch (sOscParam) + switch (parameter) { case OscActionCodes::SetIconAndWindowTitle: case OscActionCodes::SetWindowIcon: case OscActionCodes::SetWindowTitle: - fSuccess = _GetOscTitle(pwchOscStringBuffer, cchOscString, &pwchTitle, &sCchTitleLength); + success = _GetOscTitle(string, title); break; case OscActionCodes::SetColor: - fSuccess = _GetOscSetColorTable(pwchOscStringBuffer, cchOscString, &tableIndex, &dwColor); + success = _GetOscSetColorTable(string, tableIndex, color); break; case OscActionCodes::SetForegroundColor: case OscActionCodes::SetBackgroundColor: case OscActionCodes::SetCursorColor: - fSuccess = _GetOscSetColor(pwchOscStringBuffer, cchOscString, &dwColor); + success = _GetOscSetColor(string, color); break; case OscActionCodes::ResetCursorColor: // the console uses 0xffffffff as an "invalid color" value - dwColor = 0xffffffff; - fSuccess = true; + color = 0xffffffff; + success = true; break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } - if (fSuccess) + if (success) { - switch (sOscParam) + switch (parameter) { case OscActionCodes::SetIconAndWindowTitle: case OscActionCodes::SetWindowIcon: case OscActionCodes::SetWindowTitle: - fSuccess = _dispatch->SetWindowTitle({ pwchTitle, sCchTitleLength }); + success = _dispatch->SetWindowTitle(title); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCWT); break; case OscActionCodes::SetColor: - fSuccess = _dispatch->SetColorTableEntry(tableIndex, dwColor); + success = _dispatch->SetColorTableEntry(tableIndex, color); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCCT); break; case OscActionCodes::SetForegroundColor: - fSuccess = _dispatch->SetDefaultForeground(dwColor); + success = _dispatch->SetDefaultForeground(color); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCFG); break; case OscActionCodes::SetBackgroundColor: - fSuccess = _dispatch->SetDefaultBackground(dwColor); + success = _dispatch->SetDefaultBackground(color); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCBG); break; case OscActionCodes::SetCursorColor: - fSuccess = _dispatch->SetCursorColor(dwColor); + success = _dispatch->SetCursorColor(color); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCSCC); break; case OscActionCodes::ResetCursorColor: - fSuccess = _dispatch->SetCursorColor(dwColor); + success = _dispatch->SetCursorColor(color); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCRCC); break; default: // If no functions to call, overall dispatch was a failure. - fSuccess = false; + success = false; break; } } // If we were unable to process the string, and there's a TTY attached to us, // trigger the state machine to flush the string to the terminal. - if (_pfnFlushToTerminal != nullptr && !fSuccess) + if (_pfnFlushToTerminal != nullptr && !success) { - fSuccess = _pfnFlushToTerminal(); + success = _pfnFlushToTerminal(); } _ClearLastChar(); - return fSuccess; + return success; } // Routine Description: @@ -801,13 +786,11 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, // that can include many parameters. // Arguments: // - wch - Character to dispatch. -// - rgusParams - set of numeric parameters collected while pasring the sequence. -// - cParams - number of parameters found. +// - parameters - set of numeric parameters collected while parsing the sequence. // Return Value: // - true iff we successfully dispatched the sequence. bool OutputStateMachineEngine::ActionSs3Dispatch(const wchar_t /*wch*/, - _In_reads_(_Param_(3)) const unsigned short* const /*rgusParams*/, - const unsigned short /*cParams*/) + const std::basic_string_view /*parameters*/) { // The output engine doesn't handle any SS3 sequences. _ClearLastChar(); @@ -817,260 +800,240 @@ bool OutputStateMachineEngine::ActionSs3Dispatch(const wchar_t /*wch*/, // Routine Description: // - Retrieves the listed graphics options to be applied in order to the "font style" of the next characters inserted into the buffer. // Arguments: -// - rgGraphicsOptions - Pointer to array space (expected 16 max, the max number of params this can generate) that will be filled with valid options from the GraphicsOptions enum -// - pcOptions - Pointer to the length of rgGraphicsOptions on the way in, and the count of the array used on the way out. +// - parameters - The parameters to parse +// - options - Space that will be filled with valid options from the GraphicsOptions enum // Return Value: // - True if we successfully retrieved an array of valid graphics options from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetGraphicsOptions(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_writes_(*pcOptions) DispatchTypes::GraphicsOptions* const rgGraphicsOptions, - _Inout_ size_t* const pcOptions) const +bool OutputStateMachineEngine::_GetGraphicsOptions(const std::basic_string_view parameters, + std::vector& options) const { - bool fSuccess = false; + bool success = false; - if (cParams == 0) + if (parameters.empty()) { - if (*pcOptions >= 1) - { - rgGraphicsOptions[0] = s_defaultGraphicsOption; - *pcOptions = 1; - fSuccess = true; - } - else - { - fSuccess = false; // not enough space in buffer to hold response. - } + options.push_back(DefaultGraphicsOption); + success = true; } else { - if (*pcOptions >= cParams) + for (const auto& p : parameters) { - for (size_t i = 0; i < cParams; i++) - { - // No memcpy. The parameters are shorts. The graphics options are unsigned ints. - rgGraphicsOptions[i] = (DispatchTypes::GraphicsOptions)rgusParams[i]; - } - - *pcOptions = cParams; - fSuccess = true; - } - else - { - fSuccess = false; // not enough space in buffer to hold response. + options.push_back((DispatchTypes::GraphicsOptions)p); } + success = true; } // If we were unable to process the string, and there's a TTY attached to us, // trigger the state machine to flush the string to the terminal. - if (_pfnFlushToTerminal != nullptr && !fSuccess) + if (_pfnFlushToTerminal != nullptr && !success) { - fSuccess = _pfnFlushToTerminal(); + success = _pfnFlushToTerminal(); } - return fSuccess; + return success; } // Routine Description: // - Retrieves the erase type parameter for an upcoming operation. // Arguments: -// - pEraseType - Memory location to receive the erase type parameter +// - parameters - The parameters to parse +// - eraseType - Receives the erase type parameter // Return Value: // - True if we successfully pulled an erase type from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetEraseOperation(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ DispatchTypes::EraseType* const pEraseType) const +bool OutputStateMachineEngine::_GetEraseOperation(const std::basic_string_view parameters, + DispatchTypes::EraseType& eraseType) const { - bool fSuccess = false; // If we have too many parameters or don't know what to do with the given value, return false. - *pEraseType = s_defaultEraseType; // if we fail, just put the default type in. + bool success = false; // If we have too many parameters or don't know what to do with the given value, return false. + eraseType = DefaultEraseType; // if we fail, just put the default type in. - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - *pEraseType = s_defaultEraseType; - fSuccess = true; + eraseType = DefaultEraseType; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, attempt to match it to the values we accept. - unsigned short const usParam = rgusParams[0]; + const auto param = static_cast(parameters[0]); - switch (static_cast(usParam)) + switch (param) { case DispatchTypes::EraseType::ToEnd: case DispatchTypes::EraseType::FromBeginning: case DispatchTypes::EraseType::All: case DispatchTypes::EraseType::Scrollback: - *pEraseType = (DispatchTypes::EraseType)usParam; - fSuccess = true; + eraseType = param; + success = true; break; } } - return fSuccess; + return success; } // Routine Description: // - Retrieves a distance for a cursor operation from the parameter pool stored during Param actions. // Arguments: -// - puiDistance - Memory location to receive the distance +// - parameters - The parameters to parse +// - distance - Receives the distance // Return Value: // - True if we successfully pulled the cursor distance from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetCursorDistance(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiDistance) const +bool OutputStateMachineEngine::_GetCursorDistance(const std::basic_string_view parameters, + size_t& distance) const { - bool fSuccess = false; - *puiDistance = s_uiDefaultCursorDistance; + bool success = false; + distance = DefaultCursorDistance; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, use it. - *puiDistance = rgusParams[0]; - fSuccess = true; + distance = parameters[0]; + success = true; } // Distances of 0 should be changed to 1. - if (*puiDistance == 0) + if (distance == 0) { - *puiDistance = s_uiDefaultCursorDistance; + distance = DefaultCursorDistance; } - return fSuccess; + return success; } // Routine Description: // - Retrieves a distance for a scroll operation from the parameter pool stored during Param actions. // Arguments: -// - puiDistance - Memory location to receive the distance +// - parameters - The parameters to parse +// - distance - Receives the distance // Return Value: // - True if we successfully pulled the scroll distance from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetScrollDistance(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiDistance) const +bool OutputStateMachineEngine::_GetScrollDistance(const std::basic_string_view parameters, + size_t& distance) const { - bool fSuccess = false; - *puiDistance = s_uiDefaultScrollDistance; + bool success = false; + distance = DefaultScrollDistance; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, use it. - *puiDistance = rgusParams[0]; - fSuccess = true; + distance = parameters[0]; + success = true; } // Distances of 0 should be changed to 1. - if (*puiDistance == 0) + if (distance == 0) { - *puiDistance = s_uiDefaultScrollDistance; + distance = DefaultScrollDistance; } - return fSuccess; + return success; } // Routine Description: // - Retrieves a width for the console window from the parameter pool stored during Param actions. // Arguments: -// - puiConsoleWidth - Memory location to receive the width +// - parameters - The parameters to parse +// - consoleWidth - Receives the width // Return Value: // - True if we successfully pulled the width from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetConsoleWidth(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiConsoleWidth) const +bool OutputStateMachineEngine::_GetConsoleWidth(const std::basic_string_view parameters, + size_t& consoleWidth) const { - bool fSuccess = false; - *puiConsoleWidth = s_uiDefaultConsoleWidth; + bool success = false; + consoleWidth = DefaultConsoleWidth; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, use it. - *puiConsoleWidth = rgusParams[0]; - fSuccess = true; + consoleWidth = parameters[0]; + success = true; } // Distances of 0 should be changed to 80. - if (*puiConsoleWidth == 0) + if (consoleWidth == 0) { - *puiConsoleWidth = s_uiDefaultConsoleWidth; + consoleWidth = DefaultConsoleWidth; } - return fSuccess; + return success; } // Routine Description: // - Retrieves an X/Y coordinate pair for a cursor operation from the parameter pool stored during Param actions. // Arguments: -// - puiLine - Memory location to receive the Y/Line/Row position -// - puiColumn - Memory location to receive the X/Column position +// - parameters - The parameters to parse +// - line - Receives the Y/Line/Row position +// - column - Receives the X/Column position // Return Value: // - True if we successfully pulled the cursor coordinates from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetXYPosition(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiLine, - _Out_ unsigned int* const puiColumn) const +bool OutputStateMachineEngine::_GetXYPosition(const std::basic_string_view parameters, + size_t& line, + size_t& column) const { - bool fSuccess = false; - *puiLine = s_uiDefaultLine; - *puiColumn = s_uiDefaultColumn; + bool success = false; + line = DefaultLine; + column = DefaultColumn; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's only one param, leave the default for the column, and retrieve the specified row. - *puiLine = rgusParams[0]; - fSuccess = true; + line = parameters[0]; + success = true; } - else if (cParams == 2) + else if (parameters.size() == 2) { // If there are exactly two parameters, use them. - *puiLine = rgusParams[0]; - *puiColumn = rgusParams[1]; - fSuccess = true; + line = parameters[0]; + column = parameters[1]; + success = true; } // Distances of 0 should be changed to 1. - if (*puiLine == 0) + if (line == 0) { - *puiLine = s_uiDefaultLine; + line = DefaultLine; } - if (*puiColumn == 0) + if (column == 0) { - *puiColumn = s_uiDefaultColumn; + column = DefaultColumn; } - return fSuccess; + return success; } // Routine Description: // - Retrieves a top and bottom pair for setting the margins from the parameter pool stored during Param actions // Arguments: -// - psTopMargin - Memory location to receive the top margin -// - psBottomMargin - Memory location to receive the bottom margin +// - parameters - The parameters to parse +// - topMargin - Receives the top margin +// - bottomMargin - Receives the bottom margin // Return Value: // - True if we successfully pulled the margin settings from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetTopBottomMargins(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ SHORT* const psTopMargin, - _Out_ SHORT* const psBottomMargin) const +bool OutputStateMachineEngine::_GetTopBottomMargins(const std::basic_string_view parameters, + size_t& topMargin, + size_t& bottomMargin) const { // Notes: (input -> state machine out) // having only a top param is legal ([3;r -> 3,0) @@ -1078,251 +1041,237 @@ _Success_(return ) bool OutputStateMachineEngine::_GetTopBottomMargins(_In_reads // having neither uses the defaults ([;r [r -> 0,0) // an illegal combo (eg, 3;2r) is ignored - bool fSuccess = false; - *psTopMargin = s_sDefaultTopMargin; - *psBottomMargin = s_sDefaultBottomMargin; + bool success = false; + topMargin = DefaultTopMargin; + bottomMargin = DefaultBottomMargin; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { - *psTopMargin = rgusParams[0]; - fSuccess = true; + topMargin = parameters[0]; + success = true; } - else if (cParams == 2) + else if (parameters.size() == 2) { // If there are exactly two parameters, use them. - *psTopMargin = rgusParams[0]; - *psBottomMargin = rgusParams[1]; - fSuccess = true; + topMargin = parameters[0]; + bottomMargin = parameters[1]; + success = true; } - if (*psBottomMargin > 0 && *psBottomMargin < *psTopMargin) + if (bottomMargin > 0 && bottomMargin < topMargin) { - fSuccess = false; + success = false; } - return fSuccess; + return success; } // Routine Description: // - Retrieves the status type parameter for an upcoming device query operation // Arguments: -// - pStatusType - Memory location to receive the Status Type parameter +// - parameters - The parameters to parse +// - statusType - Receives the Status Type parameter // Return Value: // - True if we successfully found a device operation in the parameters stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetDeviceStatusOperation(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ DispatchTypes::AnsiStatusType* const pStatusType) const +bool OutputStateMachineEngine::_GetDeviceStatusOperation(const std::basic_string_view parameters, + DispatchTypes::AnsiStatusType& statusType) const { - bool fSuccess = false; - *pStatusType = (DispatchTypes::AnsiStatusType)0; + bool success = false; + statusType = (DispatchTypes::AnsiStatusType)0; - if (cParams == 1) + if (parameters.size() == 1) { // If there's one parameter, attempt to match it to the values we accept. - unsigned short const usParam = rgusParams[0]; + const auto param = parameters[0]; - switch (usParam) + switch (param) { - // This looks kinda silly, but I want the parser to reject (fSuccess = false) any status types we haven't put here. + // This looks kinda silly, but I want the parser to reject (success = false) any status types we haven't put here. case (unsigned short)DispatchTypes::AnsiStatusType::CPR_CursorPositionReport: - *pStatusType = DispatchTypes::AnsiStatusType::CPR_CursorPositionReport; - fSuccess = true; + statusType = DispatchTypes::AnsiStatusType::CPR_CursorPositionReport; + success = true; break; } } - return fSuccess; + return success; } // Routine Description: // - Retrieves the listed private mode params be set/reset by DECSET/DECRST // Arguments: -// - rPrivateModeParams - Pointer to array space (expected 16 max, the max number of params this can generate) that will be filled with valid params from the PrivateModeParams enum -// - pcParams - Pointer to the length of rPrivateModeParams on the way in, and the count of the array used on the way out. +// - parameters - The parameters to parse +// - privateModes - Space that will be filled with valid params from the PrivateModeParams enum // Return Value: // - True if we successfully retrieved an array of private mode params from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetPrivateModeParams(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_writes_(*pcParams) DispatchTypes::PrivateModeParams* const rgPrivateModeParams, - _Inout_ size_t* const pcParams) const +bool OutputStateMachineEngine::_GetPrivateModeParams(const std::basic_string_view parameters, + std::vector& privateModes) const { - bool fSuccess = false; + bool success = false; // Can't just set nothing at all - if (cParams > 0) + if (parameters.size() > 0) { - if (*pcParams >= cParams) + for (const auto& p : parameters) { - for (size_t i = 0; i < cParams; i++) - { - // No memcpy. The parameters are shorts. The graphics options are unsigned ints. - rgPrivateModeParams[i] = (DispatchTypes::PrivateModeParams)rgusParams[i]; - } - *pcParams = cParams; - fSuccess = true; - } - else - { - fSuccess = false; // not enough space in buffer to hold response. + privateModes.push_back((DispatchTypes::PrivateModeParams)p); } + success = true; } - return fSuccess; + return success; } // - Verifies that no parameters were parsed for the current CSI sequence // Arguments: -// - +// - parameters - The parameters to parse // Return Value: // - True if there were no parameters. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_VerifyHasNoParameters(const unsigned short cParams) const +bool OutputStateMachineEngine::_VerifyHasNoParameters(const std::basic_string_view parameters) const { - return cParams == 0; + return parameters.empty(); } // Routine Description: // - Validates that we received the correct parameter sequence for the Device Attributes command. // - For DA, we should have received either NO parameters or just one 0 parameter. Anything else is not acceptable. // Arguments: -// - +// - parameters - The parameters to parse // Return Value: // - True if the DA params were valid. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_VerifyDeviceAttributesParams(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) const +bool OutputStateMachineEngine::_VerifyDeviceAttributesParams(const std::basic_string_view parameters) const { - bool fSuccess = false; + bool success = false; - if (cParams == 0) + if (parameters.empty()) { - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { - if (rgusParams[0] == 0) + if (parameters[0] == 0) { - fSuccess = true; + success = true; } } - return fSuccess; + return success; } // Routine Description: // - Null terminates, then returns, the string that we've collected as part of the OSC string. // Arguments: -// - ppwchTitle - a pointer to point to the Osc String to use as a title. -// - pcchTitle - a pointer place the length of ppwchTitle into. +// - string - Osc String input +// - title - Where to place the Osc String to use as a title. // Return Value: // - True if there was a title to output. (a title with length=0 is still valid) -_Success_(return ) bool OutputStateMachineEngine::_GetOscTitle(_Inout_updates_(cchOscString) wchar_t* const pwchOscStringBuffer, - const unsigned short cchOscString, - _Outptr_result_buffer_(*pcchTitle) wchar_t** const ppwchTitle, - _Out_ unsigned short* pcchTitle) const +bool OutputStateMachineEngine::_GetOscTitle(const std::wstring_view string, + std::wstring& title) const { - *ppwchTitle = pwchOscStringBuffer; - *pcchTitle = cchOscString; + title = string; - return pwchOscStringBuffer != nullptr; + return !string.empty(); } // Routine Description: // - Retrieves a distance for a tab operation from the parameter pool stored during Param actions. // Arguments: -// - psDistance - Memory location to receive the distance +// - parameters - The parameters to parse +// - distance - Receives the distance // Return Value: // - True if we successfully pulled the tab distance from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetTabDistance(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ SHORT* const psDistance) const +bool OutputStateMachineEngine::_GetTabDistance(const std::basic_string_view parameters, + size_t& distance) const { - bool fSuccess = false; - *psDistance = s_sDefaultTabDistance; + bool success = false; + distance = DefaultTabDistance; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, use it. - *psDistance = rgusParams[0]; - fSuccess = true; + distance = parameters[0]; + success = true; } // Distances of 0 should be changed to 1. - if (*psDistance == 0) + if (distance == 0) { - *psDistance = s_sDefaultTabDistance; + distance = DefaultTabDistance; } - return fSuccess; + return success; } // Routine Description: // - Retrieves the type of tab clearing operation from the parameter pool stored during Param actions. // Arguments: -// - psClearType - Memory location to receive the clear type +// - parameters - The parameters to parse +// - clearType - Receives the clear type // Return Value: // - True if we successfully pulled the tab clear type from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetTabClearType(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ SHORT* const psClearType) const +bool OutputStateMachineEngine::_GetTabClearType(const std::basic_string_view parameters, + size_t& clearType) const { - bool fSuccess = false; - *psClearType = s_sDefaultTabClearType; + bool success = false; + clearType = DefaultTabClearType; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, use it. - *psClearType = rgusParams[0]; - fSuccess = true; + clearType = parameters[0]; + success = true; } - return fSuccess; + return success; } // Routine Description: // - Retrieves a designate charset type from the intermediate we've stored. False otherwise. // Arguments: -// - pDesignateType - Memory location to receive the designate type. +// - intermediate - Intermediate character in the sequence +// - designateType - Receives the designate type. // Return Value: // - True if we successfully pulled the designate type from the intermediate we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetDesignateType(const wchar_t wchIntermediate, - _Out_ DesignateCharsetTypes* const pDesignateType) const +bool OutputStateMachineEngine::_GetDesignateType(const wchar_t intermediate, + DesignateCharsetTypes& designateType) const { - bool fSuccess = false; - *pDesignateType = s_DefaultDesignateCharsetType; + bool success = false; + designateType = DefaultDesignateCharsetType; - switch (wchIntermediate) + switch (intermediate) { case '(': - *pDesignateType = DesignateCharsetTypes::G0; - fSuccess = true; + designateType = DesignateCharsetTypes::G0; + success = true; break; case ')': case '-': - *pDesignateType = DesignateCharsetTypes::G1; - fSuccess = true; + designateType = DesignateCharsetTypes::G1; + success = true; break; case '*': case '.': - *pDesignateType = DesignateCharsetTypes::G2; - fSuccess = true; + designateType = DesignateCharsetTypes::G2; + success = true; break; case '+': case '/': - *pDesignateType = DesignateCharsetTypes::G3; - fSuccess = true; + designateType = DesignateCharsetTypes::G3; + success = true; break; } - return fSuccess; + return success; } // Routine Description: @@ -1368,30 +1317,30 @@ bool OutputStateMachineEngine::DispatchIntermediatesFromEscape() const // - Converts a hex character to its equivalent integer value. // Arguments: // - wch - Character to convert. -// - puiValue - recieves the int value of the char +// - value - recieves the int value of the char // Return Value: // - true iff the character is a hex character. bool OutputStateMachineEngine::s_HexToUint(const wchar_t wch, - _Out_ unsigned int* const puiValue) + unsigned int& value) { - *puiValue = 0; - bool fSuccess = false; + value = 0; + bool success = false; if (wch >= L'0' && wch <= L'9') { - *puiValue = wch - L'0'; - fSuccess = true; + value = wch - L'0'; + success = true; } else if (wch >= L'A' && wch <= L'F') { - *puiValue = (wch - L'A') + 10; - fSuccess = true; + value = (wch - L'A') + 10; + success = true; } else if (wch >= L'a' && wch <= L'f') { - *puiValue = (wch - L'a') + 10; - fSuccess = true; + value = (wch - L'a') + 10; + success = true; } - return fSuccess; + return success; } // Routine Description: @@ -1425,28 +1374,24 @@ bool OutputStateMachineEngine::s_IsHexNumber(const wchar_t wch) // "rgb://" // where is one or two hex digits, upper or lower case. // Arguments: -// - pwchBuffer - The string containing the color spec string to parse. -// - cchBuffer - a the length of the pwchBuffer -// - pRgb - recieves the color that we parsed +// - string - The string containing the color spec string to parse. +// - rgb - recieves the color that we parsed // Return Value: // - True if a color was successfully parsed -bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wchar_t* const pwchBuffer, - const size_t cchBuffer, - _Out_ DWORD* const pRgb) +bool OutputStateMachineEngine::s_ParseColorSpec(const std::wstring_view string, + DWORD& rgb) { - const wchar_t* pwchCurr = pwchBuffer; - const wchar_t* const pwchEnd = pwchBuffer + cchBuffer; bool foundRGB = false; bool foundValidColorSpec = false; unsigned int rguiColorValues[3] = { 0 }; - bool fSuccess = false; + bool success = false; // We can have anywhere between [11,15] characters // 9 "rgb:h/h/h" // 12 "rgb:hh/hh/hh" // Any fewer cannot be valid, and any more will be too many. // Return early in this case. // We'll still have to bounds check when parsing the hh/hh/hh values - if (cchBuffer < 9 || cchBuffer > 12) + if (string.size() < 9 || string.size() > 12) { return false; } @@ -1454,14 +1399,14 @@ bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wcha // Now we look for "rgb:" // Other colorspaces are theoretically possible, but we don't support them. - if ((pwchCurr[0] == L'r') && - (pwchCurr[1] == L'g') && - (pwchCurr[2] == L'b') && - (pwchCurr[3] == L':')) + auto curr = string.cbegin(); + if ((*curr++ == L'r') && + (*curr++ == L'g') && + (*curr++ == L'b') && + (*curr++ == L':')) { foundRGB = true; } - pwchCurr += 4; if (foundRGB) { @@ -1472,14 +1417,13 @@ bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wcha unsigned int* const pValue = &(rguiColorValues[component]); for (size_t i = 0; i < 3; i++) { - const wchar_t wch = *pwchCurr; - pwchCurr++; + const wchar_t wch = *curr++; if (s_IsHexNumber(wch)) { *pValue *= 16; unsigned int intVal = 0; - if (s_HexToUint(wch, &intVal)) + if (s_HexToUint(wch, intVal)) { *pValue += intVal; } @@ -1491,7 +1435,7 @@ bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wcha } // If we're on the blue component, we're not going to see a /. // Break out once we hit the end. - if (component == 2 && pwchCurr == pwchEnd) + if (component == 2 && curr >= string.cend()) { foundValidColorSpec = true; break; @@ -1510,7 +1454,7 @@ bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wcha break; } } - if (!foundColor || pwchCurr == pwchEnd) + if (!foundColor || curr >= string.cend()) { // Indicates there was a some error parsing color // or we're at the end of the string. @@ -1525,10 +1469,10 @@ bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wcha LOBYTE(rguiColorValues[1]), LOBYTE(rguiColorValues[2])); - *pRgb = color; - fSuccess = true; + rgb = color; + success = true; } - return fSuccess; + return success; } // Routine Description: @@ -1538,52 +1482,49 @@ bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wcha // "rgb://" // where is two hex digits // Arguments: -// - pwchOscStringBuffer - a pointer to the Osc String to parse -// - cchOscString - the length of the Osc String -// - pTableIndex - a pointer that recieves the table index -// - pRgb - a pointer that recieves the color that we parsed in the format: 0x00BBGGRR +// - string - the Osc String to parse +// - tableIndex - recieves the table index +// - rgb - recieves the color that we parsed in the format: 0x00BBGGRR // Return Value: // - True if a table index and color was parsed successfully. False otherwise. -bool OutputStateMachineEngine::_GetOscSetColorTable(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, - const size_t cchOscString, - _Out_ size_t* const pTableIndex, - _Out_ DWORD* const pRgb) const +bool OutputStateMachineEngine::_GetOscSetColorTable(const std::wstring_view string, + size_t& tableIndex, + DWORD& rgb) const { - *pTableIndex = 0; - *pRgb = 0; - const wchar_t* pwchCurr = pwchOscStringBuffer; - const wchar_t* const pwchEnd = pwchOscStringBuffer + cchOscString; + tableIndex = 0; + rgb = 0; size_t _TableIndex = 0; bool foundTableIndex = false; - bool fSuccess = false; + bool success = false; // We can have anywhere between [11,16] characters // 11 "#;rgb:h/h/h" // 16 "###;rgb:hh/hh/hh" // Any fewer cannot be valid, and any more will be too many. // Return early in this case. // We'll still have to bounds check when parsing the hh/hh/hh values - if (cchOscString < 11 || cchOscString > 16) + if (string.size() < 11 || string.size() > 16) { return false; } // First try to get the table index, a number between [0,256] + size_t current = 0; for (size_t i = 0; i < 4; i++) { - const wchar_t wch = *pwchCurr; + const wchar_t wch = string.at(current); if (s_IsNumber(wch)) { _TableIndex *= 10; _TableIndex += wch - L'0'; - pwchCurr++; + ++current; } else if (wch == L';' && i > 0) { // We need to explicitly pass in a number, we can't default to 0 if // there's no param - pwchCurr++; + ++current; foundTableIndex = true; break; } @@ -1598,16 +1539,16 @@ bool OutputStateMachineEngine::_GetOscSetColorTable(_In_reads_(cchOscString) con if (foundTableIndex) { DWORD color = 0; - fSuccess = s_ParseColorSpec(pwchCurr, pwchEnd - pwchCurr, &color); + success = s_ParseColorSpec(string.substr(current), color); - if (fSuccess) + if (success) { - *pTableIndex = _TableIndex; - *pRgb = color; + tableIndex = _TableIndex; + rgb = color; } } - return fSuccess; + return success; } // Routine Description: @@ -1616,30 +1557,26 @@ bool OutputStateMachineEngine::_GetOscSetColorTable(_In_reads_(cchOscString) con // "rgb://" // where is two hex digits // Arguments: -// - pwchOscStringBuffer - a pointer to the Osc String to parse -// - cchOscString - the length of the Osc String -// - pRgb - a pointer that recieves the color that we parsed in the format: 0x00BBGGRR +// - string - the Osc String to parse +// - rgb - recieves the color that we parsed in the format: 0x00BBGGRR // Return Value: // - True if a table index and color was parsed successfully. False otherwise. -bool OutputStateMachineEngine::_GetOscSetColor(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, - const size_t cchOscString, - _Out_ DWORD* const pRgb) const +bool OutputStateMachineEngine::_GetOscSetColor(const std::wstring_view string, + DWORD& rgb) const { - *pRgb = 0; - const wchar_t* pwchCurr = pwchOscStringBuffer; - const wchar_t* const pwchEnd = pwchOscStringBuffer + cchOscString; + rgb = 0; - bool fSuccess = false; + bool success = false; DWORD color = 0; - fSuccess = s_ParseColorSpec(pwchCurr, pwchEnd - pwchCurr, &color); + success = s_ParseColorSpec(string, color); - if (fSuccess) + if (success) { - *pRgb = color; + rgb = color; } - return fSuccess; + return success; } // Method Description: @@ -1648,65 +1585,63 @@ bool OutputStateMachineEngine::_GetOscSetColor(_In_reads_(cchOscString) const wc // This is kept seperate from the input version, as there may be // codes that are supported in one direction but not the other. // Arguments: -// - rgusParams - Array of parameters collected -// - cParams - Number of parameters we've collected -// - puiFunction - Memory location to receive the function type +// - parameters - The parameters to parse +// - function - Receives the function type // Return Value: // - True iff we successfully pulled the function type from the parameters -bool OutputStateMachineEngine::_GetWindowManipulationType(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiFunction) const +bool OutputStateMachineEngine::_GetWindowManipulationType(const std::basic_string_view parameters, + unsigned int& function) const { - bool fSuccess = false; - *puiFunction = s_DefaultWindowManipulationType; + bool success = false; + function = DefaultWindowManipulationType; - if (cParams > 0) + if (parameters.size() > 0) { - switch (rgusParams[0]) + switch (parameters[0]) { case DispatchTypes::WindowManipulationType::RefreshWindow: - *puiFunction = DispatchTypes::WindowManipulationType::RefreshWindow; - fSuccess = true; + function = DispatchTypes::WindowManipulationType::RefreshWindow; + success = true; break; case DispatchTypes::WindowManipulationType::ResizeWindowInCharacters: - *puiFunction = DispatchTypes::WindowManipulationType::ResizeWindowInCharacters; - fSuccess = true; + function = DispatchTypes::WindowManipulationType::ResizeWindowInCharacters; + success = true; break; default: - fSuccess = false; + success = false; break; } } - return fSuccess; + return success; } // Routine Description: -// - Retrieves a distance for a scroll operation from the parameter pool stored during Param actions. +// - Retrieves the cursor style from the parameter list // Arguments: -// - puiDistance - Memory location to receive the distance +// - parameters - The parameters to parse +// - cursorStyle - Receives the cursorStyle // Return Value: -// - True if we successfully pulled the scroll distance from the parameters we've stored. False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetCursorStyle(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ DispatchTypes::CursorStyle* const pCursorStyle) const +// - True if we successfully pulled the cursor style from the parameters we've stored. False otherwise. +bool OutputStateMachineEngine::_GetCursorStyle(const std::basic_string_view parameters, + DispatchTypes::CursorStyle& cursorStyle) const { - bool fSuccess = false; - *pCursorStyle = s_defaultCursorStyle; + bool success = false; + cursorStyle = DefaultCursorStyle; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, use it. - *pCursorStyle = (DispatchTypes::CursorStyle)rgusParams[0]; - fSuccess = true; + cursorStyle = (DispatchTypes::CursorStyle)parameters[0]; + success = true; } - return fSuccess; + return success; } // Method Description: @@ -1732,36 +1667,36 @@ void OutputStateMachineEngine::SetTerminalConnection(ITerminalOutputConnection* // Routine Description: // - Retrieves a number of times to repeat the last graphical character // Arguments: -// - puiRepeatCount - Memory location to receive the repeat count +// - parameters - The parameters to parse +// - repeatCount - Receives the repeat count // Return Value: // - True if we successfully pulled the repeat count from the parameters. // False otherwise. -_Success_(return ) bool OutputStateMachineEngine::_GetRepeatCount(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiRepeatCount) const noexcept +bool OutputStateMachineEngine::_GetRepeatCount(std::basic_string_view parameters, + size_t& repeatCount) const noexcept { - bool fSuccess = false; - *puiRepeatCount = s_uiDefaultRepeatCount; + bool success = false; + repeatCount = DefaultRepeatCount; - if (cParams == 0) + if (parameters.empty()) { // Empty parameter sequences should use the default - fSuccess = true; + success = true; } - else if (cParams == 1) + else if (parameters.size() == 1) { // If there's one parameter, use it. - *puiRepeatCount = rgusParams[0]; - fSuccess = true; + repeatCount = parameters[0]; + success = true; } // Distances of 0 should be changed to 1. - if (*puiRepeatCount == 0) + if (repeatCount == 0) { - *puiRepeatCount = s_uiDefaultRepeatCount; + repeatCount = DefaultRepeatCount; } - return fSuccess; + return success; } // Method Description: diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index 1126c9d622..ab3df05104 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -22,7 +22,7 @@ namespace Microsoft::Console::VirtualTerminal class OutputStateMachineEngine : public IStateMachineEngine { public: - OutputStateMachineEngine(ITermDispatch* const pDispatch); + OutputStateMachineEngine(std::unique_ptr pDispatch); ~OutputStateMachineEngine(); bool ActionExecute(const wchar_t wch) override; @@ -30,33 +30,27 @@ namespace Microsoft::Console::VirtualTerminal bool ActionPrint(const wchar_t wch) override; - bool ActionPrintString(const wchar_t* const rgwch, const size_t cch) override; + bool ActionPrintString(const std::wstring_view string) override; - bool ActionPassThroughString(const wchar_t* const rgwch, - size_t const cch) override; + bool ActionPassThroughString(const std::wstring_view string) override; bool ActionEscDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate) override; + const std::basic_string_view intermediates) override; bool ActionCsiDispatch(const wchar_t wch, - const unsigned short cIntermediate, - const wchar_t wchIntermediate, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams); + const std::basic_string_view intermediates, + const std::basic_string_view parameters) override; bool ActionClear() override; bool ActionIgnore() override; bool ActionOscDispatch(const wchar_t wch, - const unsigned short sOscParam, - _Inout_updates_(cchOscString) wchar_t* const pwchOscStringBuffer, - const unsigned short cchOscString) override; + const size_t parameter, + const std::wstring_view string) override; bool ActionSs3Dispatch(const wchar_t wch, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) override; + const std::basic_string_view parameters) override; bool FlushAtEndOfString() const override; bool DispatchControlCharsFromEscape() const override; @@ -75,12 +69,10 @@ namespace Microsoft::Console::VirtualTerminal wchar_t _lastPrintedChar; bool _IntermediateQuestionMarkDispatch(const wchar_t wchAction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams); + const std::basic_string_view parameters); bool _IntermediateExclamationDispatch(const wchar_t wch); bool _IntermediateSpaceDispatch(const wchar_t wchAction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams); + const std::basic_string_view parameters); enum VTActionCodes : wchar_t { @@ -154,110 +146,88 @@ namespace Microsoft::Console::VirtualTerminal G3 }; - static const DispatchTypes::GraphicsOptions s_defaultGraphicsOption = DispatchTypes::GraphicsOptions::Off; - _Success_(return ) bool _GetGraphicsOptions(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_writes_(*pcOptions) DispatchTypes::GraphicsOptions* const rgGraphicsOptions, - _Inout_ size_t* const pcOptions) const; + static constexpr DispatchTypes::GraphicsOptions DefaultGraphicsOption = DispatchTypes::GraphicsOptions::Off; + bool _GetGraphicsOptions(const std::basic_string_view parameters, + std::vector& options) const; - static const DispatchTypes::EraseType s_defaultEraseType = DispatchTypes::EraseType::ToEnd; - _Success_(return ) bool _GetEraseOperation(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ DispatchTypes::EraseType* const pEraseType) const; + static constexpr DispatchTypes::EraseType DefaultEraseType = DispatchTypes::EraseType::ToEnd; + bool _GetEraseOperation(const std::basic_string_view parameters, + DispatchTypes::EraseType& eraseType) const; - static const unsigned int s_uiDefaultCursorDistance = 1; - _Success_(return ) bool _GetCursorDistance(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiDistance) const; + static constexpr size_t DefaultCursorDistance = 1; + bool _GetCursorDistance(const std::basic_string_view parameters, + size_t& distance) const; - static const unsigned int s_uiDefaultScrollDistance = 1; - _Success_(return ) bool _GetScrollDistance(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiDistance) const; + static constexpr size_t DefaultScrollDistance = 1; + bool _GetScrollDistance(const std::basic_string_view parameters, + size_t& distance) const; - static const unsigned int s_uiDefaultConsoleWidth = 80; - _Success_(return ) bool _GetConsoleWidth(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiConsoleWidth) const; + static constexpr size_t DefaultConsoleWidth = 80; + bool _GetConsoleWidth(const std::basic_string_view parameters, + size_t& consoleWidth) const; - static const unsigned int s_uiDefaultLine = 1; - static const unsigned int s_uiDefaultColumn = 1; - _Success_(return ) bool _GetXYPosition(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiLine, - _Out_ unsigned int* const puiColumn) const; + static constexpr size_t DefaultLine = 1; + static constexpr size_t DefaultColumn = 1; + bool _GetXYPosition(const std::basic_string_view parameters, + size_t& line, + size_t& column) const; - _Success_(return ) bool _GetDeviceStatusOperation(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ DispatchTypes::AnsiStatusType* const pStatusType) const; + bool _GetDeviceStatusOperation(const std::basic_string_view parameters, + DispatchTypes::AnsiStatusType& statusType) const; - _Success_(return ) bool _VerifyHasNoParameters(const unsigned short cParams) const; + bool _VerifyHasNoParameters(const std::basic_string_view parameters) const; - _Success_(return ) bool _VerifyDeviceAttributesParams(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) const; + bool _VerifyDeviceAttributesParams(const std::basic_string_view parameters) const; - _Success_(return ) bool _GetPrivateModeParams(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_writes_(*pcParams) DispatchTypes::PrivateModeParams* const rgPrivateModeParams, - _Inout_ size_t* const pcParams) const; + bool _GetPrivateModeParams(const std::basic_string_view parameters, + std::vector& privateModes) const; - static const SHORT s_sDefaultTopMargin = 0; - static const SHORT s_sDefaultBottomMargin = 0; - _Success_(return ) bool _GetTopBottomMargins(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ SHORT* const psTopMargin, - _Out_ SHORT* const psBottomMargin) const; + static constexpr size_t DefaultTopMargin = 0; + static constexpr size_t DefaultBottomMargin = 0; + bool _GetTopBottomMargins(const std::basic_string_view parameters, + size_t& topMargin, + size_t& bottomMargin) const; - _Success_(return ) bool _GetOscTitle(_Inout_updates_(cchOscString) wchar_t* const pwchOscStringBuffer, - const unsigned short cchOscString, - _Outptr_result_buffer_(*pcchTitle) wchar_t** const ppwchTitle, - _Out_ unsigned short* pcchTitle) const; + bool _GetOscTitle(const std::wstring_view string, + std::wstring& title) const; - static const SHORT s_sDefaultTabDistance = 1; - _Success_(return ) bool _GetTabDistance(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ SHORT* const psDistance) const; + static constexpr size_t DefaultTabDistance = 1; + bool _GetTabDistance(const std::basic_string_view parameters, + size_t& distance) const; - static const SHORT s_sDefaultTabClearType = 0; - _Success_(return ) bool _GetTabClearType(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ SHORT* const psClearType) const; + static constexpr size_t DefaultTabClearType = 0; + bool _GetTabClearType(const std::basic_string_view parameters, + size_t& clearType) const; - static const DesignateCharsetTypes s_DefaultDesignateCharsetType = DesignateCharsetTypes::G0; - _Success_(return ) bool _GetDesignateType(const wchar_t wchIntermediate, - _Out_ DesignateCharsetTypes* const pDesignateType) const; + static constexpr DesignateCharsetTypes DefaultDesignateCharsetType = DesignateCharsetTypes::G0; + bool _GetDesignateType(const wchar_t intermediate, + DesignateCharsetTypes& designateType) const; - static const DispatchTypes::WindowManipulationType s_DefaultWindowManipulationType = DispatchTypes::WindowManipulationType::Invalid; - _Success_(return ) bool _GetWindowManipulationType(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiFunction) const; + static constexpr DispatchTypes::WindowManipulationType DefaultWindowManipulationType = DispatchTypes::WindowManipulationType::Invalid; + bool _GetWindowManipulationType(const std::basic_string_view parameters, + unsigned int& function) const; static bool s_HexToUint(const wchar_t wch, - _Out_ unsigned int* const puiValue); + unsigned int& value); static bool s_IsNumber(const wchar_t wch); static bool s_IsHexNumber(const wchar_t wch); - bool _GetOscSetColorTable(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, - const size_t cchOscString, - _Out_ size_t* const pTableIndex, - _Out_ DWORD* const pRgb) const; + bool _GetOscSetColorTable(const std::wstring_view string, + size_t& tableIndex, + DWORD& rgb) const; - static bool s_ParseColorSpec(_In_reads_(cchBuffer) const wchar_t* const pwchBuffer, - const size_t cchBuffer, - _Out_ DWORD* const pRgb); + static bool s_ParseColorSpec(const std::wstring_view string, + DWORD& rgb); - bool _GetOscSetColor(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, - const size_t cchOscString, - _Out_ DWORD* const pRgb) const; + bool _GetOscSetColor(const std::wstring_view string, + DWORD& rgb) const; - static const DispatchTypes::CursorStyle s_defaultCursorStyle = DispatchTypes::CursorStyle::BlinkingBlockDefault; - _Success_(return ) bool _GetCursorStyle(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ DispatchTypes::CursorStyle* const pCursorStyle) const; + static constexpr DispatchTypes::CursorStyle DefaultCursorStyle = DispatchTypes::CursorStyle::BlinkingBlockDefault; + bool _GetCursorStyle(const std::basic_string_view parameters, + DispatchTypes::CursorStyle& cursorStyle) const; - static const unsigned int s_uiDefaultRepeatCount = 1; - _Success_(return ) bool _GetRepeatCount(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ unsigned int* const puiRepeatCount) const noexcept; + static constexpr size_t DefaultRepeatCount = 1; + bool _GetRepeatCount(const std::basic_string_view parameters, + size_t& repeatCount) const noexcept; void _ClearLastChar() noexcept; }; diff --git a/src/terminal/parser/ft_fuzzwrapper/echoDispatch.cpp b/src/terminal/parser/ft_fuzzwrapper/echoDispatch.cpp index 34a8d872ba..a72c7b80fb 100644 --- a/src/terminal/parser/ft_fuzzwrapper/echoDispatch.cpp +++ b/src/terminal/parser/ft_fuzzwrapper/echoDispatch.cpp @@ -12,9 +12,10 @@ void EchoDispatch::Print(const wchar_t wchPrintable) wprintf(L"Print: %c (0x%x)\r\n", wchPrintable, wchPrintable); } -void EchoDispatch::PrintString(const wchar_t* const rgwch, const size_t cch) +void EchoDispatch::PrintString(const std::wstring_view string) { - wprintf(L"PrintString: \"%s\" (%zd chars)\r\n", rgwch, cch); + const std::wstring nullTermString(string); // string_view not guaranteed null terminated, but wprintf needs it. + wprintf(L"PrintString: \"%s\" (%zd chars)\r\n", nullTermString.data(), nullTermString.size()); } void EchoDispatch::Execute(const wchar_t wchControl) diff --git a/src/terminal/parser/ft_fuzzwrapper/echoDispatch.hpp b/src/terminal/parser/ft_fuzzwrapper/echoDispatch.hpp index 48b9255350..ac144a31ad 100644 --- a/src/terminal/parser/ft_fuzzwrapper/echoDispatch.hpp +++ b/src/terminal/parser/ft_fuzzwrapper/echoDispatch.hpp @@ -13,7 +13,7 @@ namespace Microsoft { public: void Print(const wchar_t wchPrintable) override; - void PrintString(const wchar_t* const rgwch, const size_t cch) override; + void PrintString(const std::wstring_view string) override; void Execute(const wchar_t wchControl) override; }; } diff --git a/src/terminal/parser/ft_fuzzwrapper/main.cpp b/src/terminal/parser/ft_fuzzwrapper/main.cpp index dff5fea97e..ca5a297d5d 100644 --- a/src/terminal/parser/ft_fuzzwrapper/main.cpp +++ b/src/terminal/parser/ft_fuzzwrapper/main.cpp @@ -60,8 +60,10 @@ int __cdecl wmain(int argc, wchar_t* argv[]) hFile = _wfopen(argv[1], L"r"); wchar_t wch; bool fGotChar = GetChar(&wch); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); - StateMachine machine(new OutputStateMachineEngine(new EchoDispatch)); + StateMachine machine(std::move(engine)); wprintf(L"Sending characters to state machine...\r\n"); while (fGotChar) diff --git a/src/terminal/parser/stateMachine.cpp b/src/terminal/parser/stateMachine.cpp index 0a656342b7..681996d049 100644 --- a/src/terminal/parser/stateMachine.cpp +++ b/src/terminal/parser/stateMachine.cpp @@ -10,37 +10,26 @@ using namespace Microsoft::Console::VirtualTerminal; //Takes ownership of the pEngine. -StateMachine::StateMachine(IStateMachineEngine* const pEngine) : - _pEngine(THROW_IF_NULL_ALLOC(pEngine)), +StateMachine::StateMachine(std::unique_ptr engine) : + _engine(std::move(engine)), _state(VTStates::Ground), _trace(Microsoft::Console::VirtualTerminal::ParserTracing()), - _cParams(0), - _pusActiveParam(nullptr), - _cIntermediate(0), - _wchIntermediate(UNICODE_NULL), - _pwchCurr(nullptr), - _iParamAccumulatePos(0), - // pwchOscStringBuffer Initialized below - _pwchSequenceStart(nullptr), - // rgusParams Initialized below - _sOscNextChar(0), - _sOscParam(0), - _currRunLength(0), - _fProcessingIndividually(false) + _intermediates{}, + _parameters{}, + _oscString{}, + _processingIndividually(false) { - ZeroMemory(_pwchOscStringBuffer, sizeof(_pwchOscStringBuffer)); - ZeroMemory(_rgusParams, sizeof(_rgusParams)); _ActionClear(); } const IStateMachineEngine& StateMachine::Engine() const noexcept { - return *_pEngine; + return *_engine; } IStateMachineEngine& StateMachine::Engine() noexcept { - return *_pEngine; + return *_engine; } // Routine Description: @@ -299,7 +288,7 @@ bool StateMachine::s_IsNumber(const wchar_t wch) void StateMachine::_ActionExecute(const wchar_t wch) { _trace.TraceOnExecute(wch); - _pEngine->ActionExecute(wch); + _engine->ActionExecute(wch); } // Routine Description: @@ -313,7 +302,7 @@ void StateMachine::_ActionExecute(const wchar_t wch) void StateMachine::_ActionExecuteFromEscape(const wchar_t wch) { _trace.TraceOnExecuteFromEscape(wch); - _pEngine->ActionExecuteFromEscape(wch); + _engine->ActionExecuteFromEscape(wch); } // Routine Description: @@ -325,7 +314,7 @@ void StateMachine::_ActionExecuteFromEscape(const wchar_t wch) void StateMachine::_ActionPrint(const wchar_t wch) { _trace.TraceOnAction(L"Print"); - _pEngine->ActionPrint(wch); + _engine->ActionPrint(wch); } // Routine Description: @@ -339,12 +328,12 @@ void StateMachine::_ActionEscDispatch(const wchar_t wch) { _trace.TraceOnAction(L"EscDispatch"); - bool fSuccess = _pEngine->ActionEscDispatch(wch, _cIntermediate, _wchIntermediate); + bool success = _engine->ActionEscDispatch(wch, { _intermediates.data(), _intermediates.size() }); // Trace the result. - _trace.DispatchSequenceTrace(fSuccess); + _trace.DispatchSequenceTrace(success); - if (!fSuccess) + if (!success) { // Suppress it and log telemetry on failed cases TermTelemetry::Instance().LogFailed(wch); @@ -362,12 +351,14 @@ void StateMachine::_ActionCsiDispatch(const wchar_t wch) { _trace.TraceOnAction(L"CsiDispatch"); - bool fSuccess = _pEngine->ActionCsiDispatch(wch, _cIntermediate, _wchIntermediate, _rgusParams, _cParams); + bool success = _engine->ActionCsiDispatch(wch, + { _intermediates.data(), _intermediates.size() }, + { _parameters.data(), _parameters.size() }); // Trace the result. - _trace.DispatchSequenceTrace(fSuccess); + _trace.DispatchSequenceTrace(success); - if (!fSuccess) + if (!success) { // Suppress it and log telemetry on failed cases TermTelemetry::Instance().LogFailed(wch); @@ -385,12 +376,7 @@ void StateMachine::_ActionCollect(const wchar_t wch) _trace.TraceOnAction(L"Collect"); // store collect data - if (_cIntermediate < s_cIntermediateMax) - { - _wchIntermediate = wch; - } - - _cIntermediate++; + _intermediates.push_back(wch); } // Routine Description: @@ -404,70 +390,24 @@ void StateMachine::_ActionParam(const wchar_t wch) { _trace.TraceOnAction(L"Param"); - // Verify both the count and that the pointer didn't run off the end of the - // array. If we're past the end, this param is just ignored. - if (_cParams <= s_cParamsMax && _pusActiveParam < &_rgusParams[s_cParamsMax]) + // If we have no parameters and we're about to add one, get the 0 value ready here. + if (_parameters.empty()) { - // If we're adding a character to the first parameter, - // then we now have one parameter. - if (_iParamAccumulatePos == 0 && _cParams == 0) - { - _cParams++; - } + _parameters.push_back(0); + } - // On a delimiter, increase the number of params we've seen. - // "Empty" params should still count as a param - - // eg "\x1b[0;;m" should be three "0" params - if (wch == L';') - { - // Move to next param. - // If we're on the last param (_cParams == s_cParamsMax), - // then _pusActiveParam will now be past the end of _rgusParams, - // and any future params will be ignored. - _pusActiveParam++; - - // clear out the accumulator count to prepare for the next one - _iParamAccumulatePos = 0; - - // Don't increment the _cParams to be greater than s_cParamsMax. - // We're using _pusActiveParam to make sure we don't fill too - // many params. - if (_cParams < s_cParamsMax) - { - _cParams++; - } - } - else - { - // don't bother accumulating if we're storing more than 4 digits (since we're putting it into a short) - if (_iParamAccumulatePos < 5) - { - // convert character into digit. - unsigned short const usDigit = wch - L'0'; // convert character into value - - // multiply existing values by 10 to make space in the 1s digit - *_pusActiveParam *= 10; - - // store the digit in the 1s place. - *_pusActiveParam += usDigit; - - // if the total is zero, it must be a leading zero digit, so we don't count it. - if (*_pusActiveParam != 0) - { - // otherwise mark that we've now stored another digit. - _iParamAccumulatePos++; - } - - if (*_pusActiveParam > SHORT_MAX) - { - *_pusActiveParam = SHORT_MAX; - } - } - else - { - *_pusActiveParam = SHORT_MAX; - } - } + // On a delimiter, increase the number of params we've seen. + // "Empty" params should still count as a param - + // eg "\x1b[0;;m" should be three "0" params + if (wch == L';') + { + // Move to next param. + _parameters.push_back(0); + } + else + { + // Accumulate the character given into the last (current) parameter + _AccumulateTo(wch, _parameters.back()); } } @@ -482,22 +422,14 @@ void StateMachine::_ActionClear() _trace.TraceOnAction(L"Clear"); // clear all internal stored state. - _wchIntermediate = 0; - _cIntermediate = 0; + _intermediates.clear(); - for (unsigned short i = 0; i < s_cParamsMax; i++) - { - _rgusParams[i] = 0; - } + _parameters.clear(); - _cParams = 0; - _iParamAccumulatePos = 0; - _pusActiveParam = _rgusParams; // set pointer back to beginning of array + _oscString.clear(); + _oscParameter = 0; - _sOscParam = 0; - _sOscNextChar = 0; - - _pEngine->ActionClear(); + _engine->ActionClear(); } // Routine Description: @@ -522,34 +454,7 @@ void StateMachine::_ActionOscParam(const wchar_t wch) { _trace.TraceOnAction(L"OscParamCollect"); - // don't bother accumulating if we're storing more than 4 digits (since we're putting it into a short) - if (_iParamAccumulatePos < 5) - { - // convert character into digit. - unsigned short const usDigit = wch - L'0'; // convert character into value - - // multiply existing values by 10 to make space in the 1s digit - _sOscParam *= 10; - - // store the digit in the 1s place. - _sOscParam += usDigit; - - // if the total is zero, it must be a leading zero digit, so we don't count it. - if (_sOscParam != 0) - { - // otherwise mark that we've now stored another digit. - _iParamAccumulatePos++; - } - - if (_sOscParam > SHORT_MAX) - { - _sOscParam = SHORT_MAX; - } - } - else - { - _sOscParam = SHORT_MAX; - } + _AccumulateTo(wch, _oscParameter); } // Routine Description: @@ -562,14 +467,7 @@ void StateMachine::_ActionOscPut(const wchar_t wch) { _trace.TraceOnAction(L"OscPut"); - // if we're past the end, this param is just ignored. - // need to leave one char for \0 at end - if (_sOscNextChar < s_cOscStringMaxLength - 1) - { - _pwchOscStringBuffer[_sOscNextChar] = wch; - _sOscNextChar++; - //we'll place the null at the end of the string when we send the actual action. - } + _oscString.push_back(wch); } // Routine Description: @@ -583,12 +481,12 @@ void StateMachine::_ActionOscDispatch(const wchar_t wch) { _trace.TraceOnAction(L"OscDispatch"); - bool fSuccess = _pEngine->ActionOscDispatch(wch, _sOscParam, _pwchOscStringBuffer, _sOscNextChar); + bool success = _engine->ActionOscDispatch(wch, _oscParameter, _oscString); // Trace the result. - _trace.DispatchSequenceTrace(fSuccess); + _trace.DispatchSequenceTrace(success); - if (!fSuccess) + if (!success) { // Suppress it and log telemetry on failed cases TermTelemetry::Instance().LogFailed(wch); @@ -606,12 +504,12 @@ void StateMachine::_ActionSs3Dispatch(const wchar_t wch) { _trace.TraceOnAction(L"Ss3Dispatch"); - bool fSuccess = _pEngine->ActionSs3Dispatch(wch, _rgusParams, _cParams); + bool success = _engine->ActionSs3Dispatch(wch, { _parameters.data(), _parameters.size() }); // Trace the result. - _trace.DispatchSequenceTrace(fSuccess); + _trace.DispatchSequenceTrace(success); - if (!fSuccess) + if (!success) { // Suppress it and log telemetry on failed cases TermTelemetry::Instance().LogFailed(wch); @@ -838,7 +736,7 @@ void StateMachine::_EventEscape(const wchar_t wch) _trace.TraceOnEvent(L"Escape"); if (s_IsC0Code(wch)) { - if (_pEngine->DispatchControlCharsFromEscape()) + if (_engine->DispatchControlCharsFromEscape()) { _ActionExecuteFromEscape(wch); _EnterGround(); @@ -854,7 +752,7 @@ void StateMachine::_EventEscape(const wchar_t wch) } else if (s_IsIntermediate(wch)) { - if (_pEngine->DispatchIntermediatesFromEscape()) + if (_engine->DispatchIntermediatesFromEscape()) { _ActionEscDispatch(wch); _EnterGround(); @@ -1327,8 +1225,7 @@ bool StateMachine::FlushToTerminal() // that pwchCurr was processed. // However, if we're here, then the processing of pwchChar triggered the // engine to request the entire sequence get passed through, including pwchCurr. - return _pEngine->ActionPassThroughString(_pwchSequenceStart, - _pwchCurr - _pwchSequenceStart + 1); + return _engine->ActionPassThroughString(_run); } // Routine Description: @@ -1337,64 +1234,56 @@ bool StateMachine::FlushToTerminal() // a escape sequence, then feed characters into the state machine one at a // time until we return to the ground state. // Arguments: -// - rgwch - Array of new characters to operate upon -// - cch - Count of characters in array +// - string - Characters to operate upon // Return Value: // - -void StateMachine::ProcessString(const wchar_t* const rgwch, const size_t cch) +void StateMachine::ProcessString(const std::wstring_view string) { - _pwchCurr = rgwch; - _pwchSequenceStart = rgwch; - _currRunLength = 0; + size_t start = 0; + size_t current = start; - for (size_t cchCharsRemaining = cch; cchCharsRemaining > 0; cchCharsRemaining--) + while (current < string.size()) { - if (_fProcessingIndividually) + _run = string.substr(start, current - start); + + if (_processingIndividually) { // If we're processing characters individually, send it to the state machine. - ProcessCharacter(*_pwchCurr); - _pwchCurr++; + ProcessCharacter(string.at(current)); + ++current; if (_state == VTStates::Ground) // Then check if we're back at ground. If we are, the next character (pwchCurr) { // is the start of the next run of characters that might be printable. - _fProcessingIndividually = false; - _pwchSequenceStart = _pwchCurr; - _currRunLength = 0; + _processingIndividually = false; + start = current; } } else { - if (s_IsActionableFromGround(*_pwchCurr)) // If the current char is the start of an escape sequence, or should be executed in ground state... + if (s_IsActionableFromGround(string.at(current))) // If the current char is the start of an escape sequence, or should be executed in ground state... { - FAIL_FAST_IF(!(_pwchSequenceStart + _currRunLength <= rgwch + cch)); - _pEngine->ActionPrintString(_pwchSequenceStart, _currRunLength); // ... print all the chars leading up to it as part of the run... - _trace.DispatchPrintRunTrace(_pwchSequenceStart, _currRunLength); - _fProcessingIndividually = true; // begin processing future characters individually... - _currRunLength = 0; - _pwchSequenceStart = _pwchCurr; - ProcessCharacter(*_pwchCurr); // ... Then process the character individually. - if (_state == VTStates::Ground) // If the character took us right back to ground, start another run after it. - { - _fProcessingIndividually = false; - _pwchSequenceStart = _pwchCurr + 1; - _currRunLength = 0; - } + _engine->ActionPrintString(_run); // ... print all the chars leading up to it as part of the run... + _trace.DispatchPrintRunTrace(_run); + _processingIndividually = true; // begin processing future characters individually... + start = current; + continue; } else { - _currRunLength++; // Otherwise, add this char to the current run to be printed. + ++current; // Otherwise, add this char to the current run to be printed. } - _pwchCurr++; } } + _run = string.substr(start, current - start); + // If we're at the end of the string and have remaining un-printed characters, - if (!_fProcessingIndividually && _currRunLength > 0) + if (!_processingIndividually && !_run.empty()) { // print the rest of the characters in the string - _pEngine->ActionPrintString(_pwchSequenceStart, _currRunLength); - _trace.DispatchPrintRunTrace(_pwchSequenceStart, _currRunLength); + _engine->ActionPrintString(_run); + _trace.DispatchPrintRunTrace(_run); } - else if (_fProcessingIndividually) + else if (_processingIndividually) { // One of the "weird things" in VT input is the case of something like // alt+[. In VT, that's encoded as `\x1b[`. However, that's @@ -1415,40 +1304,41 @@ void StateMachine::ProcessString(const wchar_t* const rgwch, const size_t cch) // means we'll make sure to call `_ActionEscDispatch('[')`., which will // properly decode the string as alt+[. - if (_pEngine->FlushAtEndOfString()) + if (_engine->FlushAtEndOfString()) { // Reset our state, and put all but the last char in again. ResetState(); // Chars to flush are [pwchSequenceStart, pwchCurr) - const wchar_t* pwch = _pwchSequenceStart; - for (; pwch < _pwchCurr - 1; pwch++) + auto wchIter = _run.cbegin(); + while (wchIter < _run.cend() - 1) { - ProcessCharacter(*pwch); + ProcessCharacter(*wchIter); + wchIter++; } // Manually execute the last char [pwchCurr] switch (_state) { case VTStates::Ground: - _ActionExecute(*pwch); + _ActionExecute(*wchIter); break; case VTStates::Escape: case VTStates::EscapeIntermediate: - _ActionEscDispatch(*pwch); + _ActionEscDispatch(*wchIter); break; case VTStates::CsiEntry: case VTStates::CsiIntermediate: case VTStates::CsiIgnore: case VTStates::CsiParam: - _ActionCsiDispatch(*pwch); + _ActionCsiDispatch(*wchIter); break; case VTStates::OscParam: case VTStates::OscString: case VTStates::OscTermination: - _ActionOscDispatch(*pwch); + _ActionOscDispatch(*wchIter); break; case VTStates::Ss3Entry: case VTStates::Ss3Param: - _ActionSs3Dispatch(*pwch); + _ActionSs3Dispatch(*wchIter); break; } // microsoft/terminal#2746: Make sure to return to the ground state @@ -1458,11 +1348,6 @@ void StateMachine::ProcessString(const wchar_t* const rgwch, const size_t cch) } } -void StateMachine::ProcessString(const std::wstring& wstr) -{ - return ProcessString(wstr.c_str(), wstr.length()); -} - // Routine Description: // - Wherever the state machine is, whatever it's going, go back to ground. // This is used by conhost to "jiggle the handle" - when VT support is @@ -1475,3 +1360,26 @@ void StateMachine::ResetState() { _EnterGround(); } + +// Routine Description: +// - Takes the given printable character and accumulates it as the new ones digit +// into the given size_t. All existing value is moved up by 10. +// - For example, if your value had 437 and you put in the printable number 2, +// this function will update value to 4372. +// - Clamps to size_t max if it gets too big. +// Arguments: +// - wch - Printable character to accumulate into the value (after conversion to number, of course) +// - value - The value to update with the printable character. See example above. +// Return Value: +// - - But really it's the update to the given value parameter. +void StateMachine::_AccumulateTo(const wchar_t wch, size_t& value) +{ + const size_t digit = wch - L'0'; + + // If we overflow while multiplying and adding, the value is just size_t max. + if (FAILED(SizeTMult(value, 10, &value)) || + FAILED(SizeTAdd(value, digit, &value))) + { + value = std::numeric_limits().max(); + } +} diff --git a/src/terminal/parser/stateMachine.hpp b/src/terminal/parser/stateMachine.hpp index a4e71a69bd..e6c9a34daa 100644 --- a/src/terminal/parser/stateMachine.hpp +++ b/src/terminal/parser/stateMachine.hpp @@ -29,11 +29,10 @@ namespace Microsoft::Console::VirtualTerminal #endif public: - StateMachine(IStateMachineEngine* const pEngine); + StateMachine(std::unique_ptr engine); void ProcessCharacter(const wchar_t wch); - void ProcessString(const wchar_t* const rgwch, const size_t cch); - void ProcessString(const std::wstring& wstr); + void ProcessString(const std::wstring_view string); void ResetState(); @@ -42,10 +41,6 @@ namespace Microsoft::Console::VirtualTerminal const IStateMachineEngine& Engine() const noexcept; IStateMachineEngine& Engine() noexcept; - static const short s_cIntermediateMax = 1; - static const short s_cParamsMax = 16; - static const short s_cOscStringMaxLength = 256; - private: static bool s_IsActionableFromGround(const wchar_t wch); static bool s_IsC0Code(const wchar_t wch); @@ -64,8 +59,6 @@ namespace Microsoft::Console::VirtualTerminal static bool s_IsOscInvalid(const wchar_t wch); static bool s_IsOscTerminator(const wchar_t wch); static bool s_IsOscTerminationInitiator(const wchar_t wch); - static bool s_IsDesignateCharsetIndicator(const wchar_t wch); - static bool s_IsCharsetCode(const wchar_t wch); static bool s_IsNumber(const wchar_t wch); static bool s_IsSs3Indicator(const wchar_t wch); @@ -110,6 +103,8 @@ namespace Microsoft::Console::VirtualTerminal void _EventSs3Entry(const wchar_t wch); void _EventSs3Param(const wchar_t wch); + void _AccumulateTo(const wchar_t wch, size_t& value); + enum class VTStates { Ground, @@ -128,31 +123,20 @@ namespace Microsoft::Console::VirtualTerminal Microsoft::Console::VirtualTerminal::ParserTracing _trace; - std::unique_ptr _pEngine; + std::unique_ptr _engine; VTStates _state; - wchar_t _wchIntermediate; - unsigned short _cIntermediate; + std::wstring_view _run; - unsigned short _rgusParams[s_cParamsMax]; - unsigned short _cParams; - unsigned short* _pusActiveParam; - unsigned short _iParamAccumulatePos; + std::vector _intermediates; + std::vector _parameters; - unsigned short _sOscParam; - unsigned short _sOscNextChar; - wchar_t _pwchOscStringBuffer[s_cOscStringMaxLength]; - - // These members track out state in the parsing of a single string. - // FlushToTerminal uses these, so that an engine can force a string - // we're parsing to go straight through to the engine's ActionPassThroughString - const wchar_t* _pwchCurr; - const wchar_t* _pwchSequenceStart; - size_t _currRunLength; + std::wstring _oscString; + size_t _oscParameter; // This is tracked per state machine instance so that separate calls to Process* // can start and finish a sequence. - bool _fProcessingIndividually; + bool _processingIndividually; }; } diff --git a/src/terminal/parser/tracing.cpp b/src/terminal/parser/tracing.cpp index 78feed1e6b..cbdbf8cee0 100644 --- a/src/terminal/parser/tracing.cpp +++ b/src/terminal/parser/tracing.cpp @@ -15,19 +15,19 @@ ParserTracing::~ParserTracing() { } -void ParserTracing::TraceStateChange(_In_ PCWSTR const pwszName) const +void ParserTracing::TraceStateChange(const std::wstring_view name) const { TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, "StateMachine_EnterState", - TraceLoggingWideString(pwszName), + TraceLoggingCountedWideString(name.data(), gsl::narrow_cast(name.size())), TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); } -void ParserTracing::TraceOnAction(_In_ PCWSTR const pwszName) const +void ParserTracing::TraceOnAction(const std::wstring_view name) const { TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, "StateMachine_Action", - TraceLoggingWideString(pwszName), + TraceLoggingCountedWideString(name.data(), gsl::narrow_cast(name.size())), TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); } @@ -51,11 +51,11 @@ void ParserTracing::TraceOnExecuteFromEscape(const wchar_t wch) const TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); } -void ParserTracing::TraceOnEvent(_In_ PCWSTR const pwszName) const +void ParserTracing::TraceOnEvent(const std::wstring_view name) const { TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, "StateMachine_Event", - TraceLoggingWideString(pwszName), + TraceLoggingCountedWideString(name.data(), gsl::narrow_cast(name.size())), TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); } @@ -73,12 +73,7 @@ void ParserTracing::TraceCharInput(const wchar_t wch) void ParserTracing::AddSequenceTrace(const wchar_t wch) { - // -1 to always leave the last character as null/0. - if (_cchSequenceTrace < s_cMaxSequenceTrace - 1) - { - _rgwchSequenceTrace[_cchSequenceTrace] = wch; - _cchSequenceTrace++; - } + _sequenceTrace.push_back(wch); } void ParserTracing::DispatchSequenceTrace(const bool fSuccess) @@ -87,14 +82,14 @@ void ParserTracing::DispatchSequenceTrace(const bool fSuccess) { TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, "StateMachine_Sequence_OK", - TraceLoggingWideString(_rgwchSequenceTrace), + TraceLoggingWideString(_sequenceTrace.c_str()), TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); } else { TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, "StateMachine_Sequence_FAIL", - TraceLoggingWideString(_rgwchSequenceTrace), + TraceLoggingWideString(_sequenceTrace.c_str()), TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); } @@ -103,19 +98,15 @@ void ParserTracing::DispatchSequenceTrace(const bool fSuccess) void ParserTracing::ClearSequenceTrace() { - ZeroMemory(_rgwchSequenceTrace, sizeof(_rgwchSequenceTrace)); - _cchSequenceTrace = 0; + _sequenceTrace.clear(); } // NOTE: I'm expecting this to not be null terminated -void ParserTracing::DispatchPrintRunTrace(const wchar_t* const pwsString, const size_t cchString) const +void ParserTracing::DispatchPrintRunTrace(const std::wstring_view string) const { - size_t charsRemaining = cchString; - wchar_t str[BYTE_MAX + 4 + sizeof(wchar_t) + sizeof('\0')]; - - if (cchString == 1) + if (string.size() == 1) { - wchar_t wch = *pwsString; + wchar_t wch = string.front(); INT16 sch = (INT16)wch; TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, "StateMachine_PrintRun", @@ -125,27 +116,12 @@ void ParserTracing::DispatchPrintRunTrace(const wchar_t* const pwsString, const } else { - while (charsRemaining > 0) - { - size_t strLen = 0; - if (charsRemaining > ARRAYSIZE(str) - 1) - { - strLen = ARRAYSIZE(str) - 1; - } - else - { - strLen = charsRemaining; - } - charsRemaining -= strLen; + const auto length = gsl::narrow_cast(string.size()); - memcpy(str, pwsString, sizeof(wchar_t) * strLen); - str[strLen] = '\0'; - - TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, - "StateMachine_PrintRun", - TraceLoggingWideString(str), - TraceLoggingValue(strLen), - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); - } + TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, + "StateMachine_PrintRun", + TraceLoggingCountedWideString(string.data(), length), + TraceLoggingValue(length), + TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); } } diff --git a/src/terminal/parser/tracing.hpp b/src/terminal/parser/tracing.hpp index 772b2abedb..2547d047ad 100644 --- a/src/terminal/parser/tracing.hpp +++ b/src/terminal/parser/tracing.hpp @@ -24,22 +24,19 @@ namespace Microsoft::Console::VirtualTerminal ParserTracing(); ~ParserTracing(); - void TraceStateChange(_In_ PCWSTR const pwszName) const; - void TraceOnAction(_In_ PCWSTR const pwszName) const; + void TraceStateChange(const std::wstring_view name) const; + void TraceOnAction(const std::wstring_view name) const; void TraceOnExecute(const wchar_t wch) const; void TraceOnExecuteFromEscape(const wchar_t wch) const; - void TraceOnEvent(_In_ PCWSTR const pwszName) const; + void TraceOnEvent(const std::wstring_view name) const; void TraceCharInput(const wchar_t wch); void AddSequenceTrace(const wchar_t wch); void DispatchSequenceTrace(const bool fSuccess); void ClearSequenceTrace(); - void DispatchPrintRunTrace(const wchar_t* const pwsString, const size_t cchString) const; + void DispatchPrintRunTrace(const std::wstring_view string) const; private: - static const size_t s_cMaxSequenceTrace = 32; - - wchar_t _rgwchSequenceTrace[s_cMaxSequenceTrace]; - size_t _cchSequenceTrace; + std::wstring _sequenceTrace; }; } diff --git a/src/terminal/parser/ut_parser/InputEngineTest.cpp b/src/terminal/parser/ut_parser/InputEngineTest.cpp index 27fbd25cb3..8518720d28 100644 --- a/src/terminal/parser/ut_parser/InputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/InputEngineTest.cpp @@ -94,7 +94,7 @@ public: Log::Comment( NoThrowString().Format(L"\tvtseq: \"%s\"(%zu)", vtseq.c_str(), vtseq.length())); - _stateMachine->ProcessString(&vtseq[0], vtseq.length()); + _stateMachine->ProcessString(vtseq); Log::Comment(L"String processed"); } @@ -242,14 +242,12 @@ public: _In_ TestState* testState); virtual bool WriteInput(_In_ std::deque>& inputEvents) override; virtual bool WriteCtrlC() override; - virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) override; // DTTERM_WindowManipulation - virtual bool WriteString(_In_reads_(cch) const wchar_t* const pws, - const size_t cch) override; + virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) override; // DTTERM_WindowManipulation + virtual bool WriteString(const std::wstring_view string) override; - virtual bool MoveCursor(const unsigned int row, - const unsigned int col) override; + virtual bool MoveCursor(const size_t row, + const size_t col) override; private: std::function>&)> _pfnWriteInputCallback; @@ -278,27 +276,26 @@ bool TestInteractDispatch::WriteCtrlC() return WriteInput(inputEvents); } -bool TestInteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) +bool TestInteractDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType function, + const std::basic_string_view parameters) { VERIFY_ARE_EQUAL(true, _testState->_expectedToCallWindowManipulation); - VERIFY_ARE_EQUAL(_testState->_expectedWindowManipulation, uiFunction); - for (size_t i = 0; i < cParams; i++) + VERIFY_ARE_EQUAL(_testState->_expectedWindowManipulation, function); + for (size_t i = 0; i < parameters.size(); i++) { - VERIFY_ARE_EQUAL(_testState->_expectedParams[i], rgusParams[i]); + unsigned short actual; + VERIFY_SUCCEEDED(SizeTToUShort(parameters.at(i), &actual)); + VERIFY_ARE_EQUAL(_testState->_expectedParams[i], actual); } return true; } -bool TestInteractDispatch::WriteString(_In_reads_(cch) const wchar_t* const pws, - const size_t cch) +bool TestInteractDispatch::WriteString(const std::wstring_view string) { std::deque> keyEvents; - for (size_t i = 0; i < cch; ++i) + for (const auto& wch : string) { - const wchar_t wch = pws[i]; // We're forcing the translation to CP_USA, so that it'll be constant // regardless of the CP the test is running in std::deque> convertedEvents = CharToKeyEvents(wch, CP_USA); @@ -310,8 +307,7 @@ bool TestInteractDispatch::WriteString(_In_reads_(cch) const wchar_t* const pws, return WriteInput(keyEvents); } -bool TestInteractDispatch::MoveCursor(const unsigned int row, - const unsigned int col) +bool TestInteractDispatch::MoveCursor(const size_t row, const size_t col) { VERIFY_IS_TRUE(_testState->_expectCursorPosition); COORD received = { static_cast(col), static_cast(row) }; @@ -324,8 +320,9 @@ void InputEngineTest::C0Test() TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); @@ -412,7 +409,7 @@ void InputEngineTest::C0Test() testState.vExpectedInput.push_back(inputRec); - _stateMachine->ProcessString(&inputSeq[0], inputSeq.length()); + _stateMachine->ProcessString(inputSeq); } } @@ -420,9 +417,9 @@ void InputEngineTest::AlphanumericTest() { TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); @@ -457,7 +454,7 @@ void InputEngineTest::AlphanumericTest() testState.vExpectedInput.push_back(inputRec); - _stateMachine->ProcessString(&inputSeq[0], inputSeq.length()); + _stateMachine->ProcessString(inputSeq); } } @@ -465,8 +462,9 @@ void InputEngineTest::RoundTripTest() { TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); @@ -525,9 +523,9 @@ void InputEngineTest::WindowManipulationTest() { TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine.get()); testState._stateMachine = _stateMachine.get(); @@ -584,7 +582,7 @@ void InputEngineTest::WindowManipulationTest() std::wstring seq = seqBuilder.str(); Log::Comment(NoThrowString().Format( L"Processing \"%s\"", seq.c_str())); - _stateMachine->ProcessString(&seq[0], seq.length()); + _stateMachine->ProcessString(seq); } } @@ -592,9 +590,9 @@ void InputEngineTest::NonAsciiTest() { TestState testState; auto pfn = std::bind(&TestState::TestInputStringCallback, &testState, std::placeholders::_1); - - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine.get()); testState._stateMachine = _stateMachine.get(); Log::Comment(L"Sending various non-ascii strings, and seeing what we get out"); @@ -625,7 +623,7 @@ void InputEngineTest::NonAsciiTest() testState.vExpectedInput.push_back(test); test.Event.KeyEvent.bKeyDown = FALSE; testState.vExpectedInput.push_back(test); - _stateMachine->ProcessString(&utf8Input[0], utf8Input.length()); + _stateMachine->ProcessString(utf8Input); // "æ—…", UTF-16: 0x65C5, utf8: "0xE6 0x97 0x85" utf8Input = L"\u65C5"; @@ -639,7 +637,7 @@ void InputEngineTest::NonAsciiTest() testState.vExpectedInput.push_back(test); test.Event.KeyEvent.bKeyDown = FALSE; testState.vExpectedInput.push_back(test); - _stateMachine->ProcessString(&utf8Input[0], utf8Input.length()); + _stateMachine->ProcessString(utf8Input); } void InputEngineTest::CursorPositioningTest() @@ -649,9 +647,9 @@ void InputEngineTest::CursorPositioningTest() auto dispatch = std::make_unique(pfn, &testState); VERIFY_IS_NOT_NULL(dispatch.get()); - auto inputEngine = std::make_unique(dispatch.release(), true); + auto inputEngine = std::make_unique(std::move(dispatch), true); VERIFY_IS_NOT_NULL(inputEngine.get()); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); @@ -667,7 +665,7 @@ void InputEngineTest::CursorPositioningTest() Log::Comment(NoThrowString().Format( L"Processing \"%s\"", seq.c_str())); - _stateMachine->ProcessString(&seq[0], seq.length()); + _stateMachine->ProcessString(seq); testState._expectCursorPosition = false; @@ -683,16 +681,16 @@ void InputEngineTest::CursorPositioningTest() testState.vExpectedInput.push_back(inputRec); Log::Comment(NoThrowString().Format( L"Processing \"%s\"", seq.c_str())); - _stateMachine->ProcessString(&seq[0], seq.length()); + _stateMachine->ProcessString(seq); } void InputEngineTest::CSICursorBackTabTest() { TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); @@ -711,16 +709,16 @@ void InputEngineTest::CSICursorBackTabTest() const std::wstring seq = L"\x1b[Z"; Log::Comment(NoThrowString().Format( L"Processing \"%s\"", seq.c_str())); - _stateMachine->ProcessString(&seq[0], seq.length()); + _stateMachine->ProcessString(seq); } void InputEngineTest::AltBackspaceTest() { TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); @@ -745,9 +743,9 @@ void InputEngineTest::AltCtrlDTest() { TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); @@ -809,8 +807,9 @@ void InputEngineTest::AltIntermediateTest() terminalInput.HandleKey(ev.get()); } }; - auto inputEngine = std::make_unique(new TestInteractDispatch(pfnInputStateMachineCallback, &testState)); - auto stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfnInputStateMachineCallback, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(stateMachine); testState._stateMachine = stateMachine.get(); @@ -837,9 +836,9 @@ void InputEngineTest::AltBackspaceEnterTest() TestState testState; auto pfn = std::bind(&TestState::TestInputCallback, &testState, std::placeholders::_1); - - auto inputEngine = std::make_unique(new TestInteractDispatch(pfn, &testState)); - auto _stateMachine = std::make_unique(inputEngine.release()); + auto dispatch = std::make_unique(pfn, &testState); + auto inputEngine = std::make_unique(std::move(dispatch)); + auto _stateMachine = std::make_unique(std::move(inputEngine)); VERIFY_IS_NOT_NULL(_stateMachine); testState._stateMachine = _stateMachine.get(); diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index 0b1d430e29..54e1b0377b 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -44,7 +44,7 @@ public: { } - virtual void PrintString(const wchar_t* const /*rgwch*/, const size_t /*cch*/) override + virtual void PrintString(const std::wstring_view /*string*/) override { } }; @@ -59,10 +59,11 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD_PROPERTY(L"Data:uiTest", L"{0,1,2,3,4,5,6,7,8,9,10,11}") // one value for each type of state test below. END_TEST_METHOD_PROPERTIES() - unsigned int uiTest; + size_t uiTest; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiTest", uiTest)); - - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); // The OscString state shouldn't escape out after an ESC. bool shouldEscapeOut = true; @@ -153,7 +154,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestEscapeImmediatePath) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -172,7 +175,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestEscapeThenC0Path) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -194,7 +199,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestGroundPrint) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(L'a'); @@ -203,7 +210,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestCsiEntry) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -216,7 +225,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestC1CsiEntry) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(L'\x9b'); @@ -227,7 +238,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestCsiImmediate) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -246,7 +259,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestCsiParam) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -273,7 +288,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestLeadingZeroCsiParam) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -290,14 +307,16 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach.ProcessCharacter((wchar_t)(L'1' + i)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::CsiParam); } - VERIFY_ARE_EQUAL(*mach._pusActiveParam, 12345); + VERIFY_ARE_EQUAL(mach._parameters.back(), 12345u); mach.ProcessCharacter(L'J'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); } TEST_METHOD(TestCsiIgnore) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -344,7 +363,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestOscStringSimple) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -409,7 +430,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final } TEST_METHOD(TestLongOscString) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -419,19 +442,21 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach.ProcessCharacter(L'0'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscParam); mach.ProcessCharacter(L';'); - for (int i = 0; i < MAX_PATH; i++) // The buffer is only 256 long, so any longer value should work :P + for (int i = 0; i < 260u; i++) // The buffer is only 256 long, so any longer value should work :P { mach.ProcessCharacter(L's'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscString); } - VERIFY_ARE_EQUAL(mach._sOscNextChar, mach.s_cOscStringMaxLength - 1); + VERIFY_ARE_EQUAL(mach._oscString.size(), 260u); mach.ProcessCharacter(AsciiChars::BEL); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); } TEST_METHOD(NormalTestOscParam) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -443,7 +468,7 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach.ProcessCharacter((wchar_t)(L'1' + i)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscParam); } - VERIFY_ARE_EQUAL(mach._sOscParam, 12345); + VERIFY_ARE_EQUAL(mach._oscParameter, 12345u); mach.ProcessCharacter(L';'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscString); mach.ProcessCharacter(L's'); @@ -454,7 +479,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestLeadingZeroOscParam) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -471,7 +498,7 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach.ProcessCharacter((wchar_t)(L'1' + i)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscParam); } - VERIFY_ARE_EQUAL(mach._sOscParam, 12345); + VERIFY_ARE_EQUAL(mach._oscParameter, 12345u); mach.ProcessCharacter(L';'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscString); mach.ProcessCharacter(L's'); @@ -482,19 +509,23 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestLongOscParam) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); mach.ProcessCharacter(L']'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscParam); - for (int i = 0; i < 6; i++) // We're only expecting to be able to keep 5 digits max + constexpr auto sizeMax = std::numeric_limits::max(); + const auto sizeMaxStr = wil::str_printf(L"%zu", sizeMax); + for (auto& wch : sizeMaxStr) { - mach.ProcessCharacter((wchar_t)(L'1' + i)); + mach.ProcessCharacter(wch); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscParam); } - VERIFY_ARE_EQUAL(mach._sOscParam, SHORT_MAX); + VERIFY_ARE_EQUAL(mach._oscParameter, sizeMax); mach.ProcessCharacter(L';'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscString); mach.ProcessCharacter(L's'); @@ -502,17 +533,16 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final mach.ProcessCharacter(AsciiChars::BEL); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); - Log::Comment(L"Make sure we cap the param value to SHORT_MAX"); mach.ProcessCharacter(AsciiChars::ESC); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Escape); mach.ProcessCharacter(L']'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscParam); - for (int i = 0; i < 5; i++) // We're only expecting to be able to keep 5 digits max + for (const auto& wch : sizeMaxStr) { - mach.ProcessCharacter((wchar_t)(L'4' + i)); // 45678 > (SHORT_MAX===32767) + mach.ProcessCharacter(wch); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscParam); } - VERIFY_ARE_EQUAL(mach._sOscParam, SHORT_MAX); + VERIFY_ARE_EQUAL(mach._oscParameter, sizeMax); mach.ProcessCharacter(L';'); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::OscString); mach.ProcessCharacter(L's'); @@ -523,7 +553,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestSs3Entry) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -537,7 +569,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestSs3Immediate) { // Intermediates aren't supported by Ss3 - they just get dispatched - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -571,7 +605,9 @@ class Microsoft::Console::VirtualTerminal::OutputEngineTest final TEST_METHOD(TestSs3Param) { - StateMachine mach(new OutputStateMachineEngine(new DummyDispatch)); + auto dispatch = std::make_unique(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); VERIFY_ARE_EQUAL(mach._state, StateMachine::VTStates::Ground); mach.ProcessCharacter(AsciiChars::ESC); @@ -608,44 +644,43 @@ public: { } - virtual void PrintString(const wchar_t* const /*rgwch*/, const size_t /*cch*/) override + virtual void PrintString(const std::wstring_view /*string*/) override { } StatefulDispatch() : - _uiCursorDistance{ 0 }, - _uiLine{ 0 }, - _uiColumn{ 0 }, - _fCursorUp{ false }, - _fCursorDown{ false }, - _fCursorBackward{ false }, - _fCursorForward{ false }, - _fCursorNextLine{ false }, - _fCursorPreviousLine{ false }, - _fCursorHorizontalPositionAbsolute{ false }, - _fVerticalLinePositionAbsolute{ false }, - _fCursorPosition{ false }, - _fCursorSave{ false }, - _fCursorLoad{ false }, - _fCursorVisible{ true }, - _fEraseDisplay{ false }, - _fEraseLine{ false }, - _fInsertCharacter{ false }, - _fDeleteCharacter{ false }, + _cursorDistance{ 0 }, + _line{ 0 }, + _column{ 0 }, + _cursorUp{ false }, + _cursorDown{ false }, + _cursorBackward{ false }, + _cursorForward{ false }, + _cursorNextLine{ false }, + _cursorPreviousLine{ false }, + _cursorHorizontalPositionAbsolute{ false }, + _verticalLinePositionAbsolute{ false }, + _cursorPosition{ false }, + _cursorSave{ false }, + _cursorLoad{ false }, + _cursorVisible{ true }, + _eraseDisplay{ false }, + _eraseLine{ false }, + _insertCharacter{ false }, + _deleteCharacter{ false }, _eraseType{ (DispatchTypes::EraseType)-1 }, - _fSetGraphics{ false }, + _setGraphics{ false }, _statusReportType{ (DispatchTypes::AnsiStatusType)-1 }, - _fDeviceStatusReport{ false }, - _fDeviceAttributes{ false }, - _cOptions{ 0 }, - _fIsAltBuffer{ false }, - _fCursorKeysMode{ false }, - _fCursorBlinking{ true }, - _fIsOriginModeRelative{ false }, - _fIsDECCOLMAllowed{ false }, - _uiWindowWidth{ 80 } + _deviceStatusReport{ false }, + _deviceAttributes{ false }, + _isAltBuffer{ false }, + _cursorKeysMode{ false }, + _cursorBlinking{ true }, + _isOriginModeRelative{ false }, + _isDECCOLMAllowed{ false }, + _windowWidth{ 80 }, + _options{ s_cMaxOptions, static_cast(s_uiGraphicsCleared) } // fill with cleared option { - memset(_rgOptions, s_uiGraphicsCleared, sizeof(_rgOptions)); } void ClearState() @@ -654,131 +689,127 @@ public: *this = dispatch; } - bool CursorUp(_In_ unsigned int const uiDistance) override + bool CursorUp(_In_ size_t const uiDistance) override { - _fCursorUp = true; - _uiCursorDistance = uiDistance; + _cursorUp = true; + _cursorDistance = uiDistance; return true; } - bool CursorDown(_In_ unsigned int const uiDistance) override + bool CursorDown(_In_ size_t const uiDistance) override { - _fCursorDown = true; - _uiCursorDistance = uiDistance; + _cursorDown = true; + _cursorDistance = uiDistance; return true; } - bool CursorBackward(_In_ unsigned int const uiDistance) override + bool CursorBackward(_In_ size_t const uiDistance) override { - _fCursorBackward = true; - _uiCursorDistance = uiDistance; + _cursorBackward = true; + _cursorDistance = uiDistance; return true; } - bool CursorForward(_In_ unsigned int const uiDistance) override + bool CursorForward(_In_ size_t const uiDistance) override { - _fCursorForward = true; - _uiCursorDistance = uiDistance; + _cursorForward = true; + _cursorDistance = uiDistance; return true; } - bool CursorNextLine(_In_ unsigned int const uiDistance) override + bool CursorNextLine(_In_ size_t const uiDistance) override { - _fCursorNextLine = true; - _uiCursorDistance = uiDistance; + _cursorNextLine = true; + _cursorDistance = uiDistance; return true; } - bool CursorPrevLine(_In_ unsigned int const uiDistance) override + bool CursorPrevLine(_In_ size_t const uiDistance) override { - _fCursorPreviousLine = true; - _uiCursorDistance = uiDistance; + _cursorPreviousLine = true; + _cursorDistance = uiDistance; return true; } - bool CursorHorizontalPositionAbsolute(_In_ unsigned int const uiPosition) override + bool CursorHorizontalPositionAbsolute(_In_ size_t const uiPosition) override { - _fCursorHorizontalPositionAbsolute = true; - _uiCursorDistance = uiPosition; + _cursorHorizontalPositionAbsolute = true; + _cursorDistance = uiPosition; return true; } - bool VerticalLinePositionAbsolute(_In_ unsigned int const uiPosition) override + bool VerticalLinePositionAbsolute(_In_ size_t const uiPosition) override { - _fVerticalLinePositionAbsolute = true; - _uiCursorDistance = uiPosition; + _verticalLinePositionAbsolute = true; + _cursorDistance = uiPosition; return true; } - bool CursorPosition(_In_ unsigned int const uiLine, _In_ unsigned int const uiColumn) override + bool CursorPosition(_In_ size_t const uiLine, _In_ size_t const uiColumn) override { - _fCursorPosition = true; - _uiLine = uiLine; - _uiColumn = uiColumn; + _cursorPosition = true; + _line = uiLine; + _column = uiColumn; return true; } bool CursorSaveState() override { - _fCursorSave = true; + _cursorSave = true; return true; } bool CursorRestoreState() override { - _fCursorLoad = true; + _cursorLoad = true; return true; } bool EraseInDisplay(const DispatchTypes::EraseType eraseType) override { - _fEraseDisplay = true; + _eraseDisplay = true; _eraseType = eraseType; return true; } bool EraseInLine(const DispatchTypes::EraseType eraseType) override { - _fEraseLine = true; + _eraseLine = true; _eraseType = eraseType; return true; } - bool InsertCharacter(_In_ unsigned int const uiCount) override + bool InsertCharacter(_In_ size_t const uiCount) override { - _fInsertCharacter = true; - _uiCursorDistance = uiCount; + _insertCharacter = true; + _cursorDistance = uiCount; return true; } - bool DeleteCharacter(_In_ unsigned int const uiCount) override + bool DeleteCharacter(_In_ size_t const uiCount) override { - _fDeleteCharacter = true; - _uiCursorDistance = uiCount; + _deleteCharacter = true; + _cursorDistance = uiCount; return true; } bool CursorVisibility(const bool fIsVisible) override { - _fCursorVisible = fIsVisible; + _cursorVisible = fIsVisible; return true; } - bool SetGraphicsRendition(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions) override + bool SetGraphicsRendition(const std::basic_string_view options) override { - size_t cCopyLength = std::min(cOptions, s_cMaxOptions); // whichever is smaller, our buffer size or the number given - _cOptions = cCopyLength; - memcpy(_rgOptions, rgOptions, _cOptions * sizeof(DispatchTypes::GraphicsOptions)); - - _fSetGraphics = true; + _options.assign(options.cbegin(), options.cend()); + _setGraphics = true; return true; } bool DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType) override { - _fDeviceStatusReport = true; + _deviceStatusReport = true; _statusReportType = statusType; return true; @@ -786,7 +817,7 @@ public: bool DeviceAttributes() override { - _fDeviceAttributes = true; + _deviceAttributes = true; return true; } @@ -801,7 +832,7 @@ public: fSuccess = SetVirtualTerminalInputMode(fEnable); break; case DispatchTypes::PrivateModeParams::DECCOLM_SetNumberOfColumns: - fSuccess = SetColumns(static_cast(fEnable ? DispatchTypes::s_sDECCOLMSetColumns : DispatchTypes::s_sDECCOLMResetColumns)); + fSuccess = SetColumns(static_cast(fEnable ? DispatchTypes::s_sDECCOLMSetColumns : DispatchTypes::s_sDECCOLMResetColumns)); break; case DispatchTypes::PrivateModeParams::DECOM_OriginMode: // The cursor is also moved to the new home position when the origin mode is set or reset. @@ -827,107 +858,103 @@ public: return fSuccess; } - bool _SetResetPrivateModesHelper(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, - const size_t cParams, - const bool fEnable) + bool _SetResetPrivateModesHelper(const std::basic_string_view params, + const bool enable) { size_t cFailures = 0; - for (size_t i = 0; i < cParams; i++) + for (const auto& p : params) { - cFailures += _PrivateModeParamsHelper(rParams[i], fEnable) ? 0 : 1; // increment the number of failures if we fail. + cFailures += _PrivateModeParamsHelper(p, enable) ? 0 : 1; // increment the number of failures if we fail. } return cFailures == 0; } - bool SetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, - const size_t cParams) override + bool SetPrivateModes(const std::basic_string_view params) override { - return _SetResetPrivateModesHelper(rParams, cParams, true); + return _SetResetPrivateModesHelper(params, true); } - bool ResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, - const size_t cParams) override + bool ResetPrivateModes(const std::basic_string_view params) override { - return _SetResetPrivateModesHelper(rParams, cParams, false); + return _SetResetPrivateModesHelper(params, false); } - bool SetColumns(_In_ unsigned int const uiColumns) override + bool SetColumns(_In_ size_t const uiColumns) override { - _uiWindowWidth = uiColumns; + _windowWidth = uiColumns; return true; } bool SetVirtualTerminalInputMode(const bool fApplicationMode) { - _fCursorKeysMode = fApplicationMode; + _cursorKeysMode = fApplicationMode; return true; } bool EnableCursorBlinking(const bool bEnable) override { - _fCursorBlinking = bEnable; + _cursorBlinking = bEnable; return true; } bool SetOriginMode(const bool fRelativeMode) override { - _fIsOriginModeRelative = fRelativeMode; + _isOriginModeRelative = fRelativeMode; return true; } bool EnableDECCOLMSupport(const bool fEnabled) override { - _fIsDECCOLMAllowed = fEnabled; + _isDECCOLMAllowed = fEnabled; return true; } bool UseAlternateScreenBuffer() override { - _fIsAltBuffer = true; + _isAltBuffer = true; return true; } bool UseMainScreenBuffer() override { - _fIsAltBuffer = false; + _isAltBuffer = false; return true; } - unsigned int _uiCursorDistance; - unsigned int _uiLine; - unsigned int _uiColumn; - bool _fCursorUp; - bool _fCursorDown; - bool _fCursorBackward; - bool _fCursorForward; - bool _fCursorNextLine; - bool _fCursorPreviousLine; - bool _fCursorHorizontalPositionAbsolute; - bool _fVerticalLinePositionAbsolute; - bool _fCursorPosition; - bool _fCursorSave; - bool _fCursorLoad; - bool _fCursorVisible; - bool _fEraseDisplay; - bool _fEraseLine; - bool _fInsertCharacter; - bool _fDeleteCharacter; + size_t _cursorDistance; + size_t _line; + size_t _column; + bool _cursorUp; + bool _cursorDown; + bool _cursorBackward; + bool _cursorForward; + bool _cursorNextLine; + bool _cursorPreviousLine; + bool _cursorHorizontalPositionAbsolute; + bool _verticalLinePositionAbsolute; + bool _cursorPosition; + bool _cursorSave; + bool _cursorLoad; + bool _cursorVisible; + bool _eraseDisplay; + bool _eraseLine; + bool _insertCharacter; + bool _deleteCharacter; DispatchTypes::EraseType _eraseType; - bool _fSetGraphics; + bool _setGraphics; DispatchTypes::AnsiStatusType _statusReportType; - bool _fDeviceStatusReport; - bool _fDeviceAttributes; - bool _fIsAltBuffer; - bool _fCursorKeysMode; - bool _fCursorBlinking; - bool _fIsOriginModeRelative; - bool _fIsDECCOLMAllowed; - unsigned int _uiWindowWidth; + bool _deviceStatusReport; + bool _deviceAttributes; + bool _isAltBuffer; + bool _cursorKeysMode; + bool _cursorBlinking; + bool _isOriginModeRelative; + bool _isDECCOLMAllowed; + size_t _windowWidth; static const size_t s_cMaxOptions = 16; - static const unsigned int s_uiGraphicsCleared = UINT_MAX; - DispatchTypes::GraphicsOptions _rgOptions[s_cMaxOptions]; - size_t _cOptions; + static const size_t s_uiGraphicsCleared = UINT_MAX; + std::vector _options; }; class StateMachineExternalTest final @@ -948,27 +975,27 @@ class StateMachineExternalTest final mach.ProcessCharacter(wchCommand); VERIFY_IS_TRUE(*pfFlag); - VERIFY_ARE_EQUAL(dispatch._uiCursorDistance, 1u); + VERIFY_ARE_EQUAL(dispatch._cursorDistance, 1u); } TEST_METHOD(TestEscCursorMovement) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); - - TestEscCursorMovement(L'A', &pDispatch->_fCursorUp, mach, *pDispatch); - TestEscCursorMovement(L'B', &pDispatch->_fCursorDown, mach, *pDispatch); - TestEscCursorMovement(L'C', &pDispatch->_fCursorForward, mach, *pDispatch); - TestEscCursorMovement(L'D', &pDispatch->_fCursorBackward, mach, *pDispatch); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + TestEscCursorMovement(L'A', &pDispatch->_cursorUp, mach, *pDispatch); + TestEscCursorMovement(L'B', &pDispatch->_cursorDown, mach, *pDispatch); + TestEscCursorMovement(L'C', &pDispatch->_cursorForward, mach, *pDispatch); + TestEscCursorMovement(L'D', &pDispatch->_cursorBackward, mach, *pDispatch); } - void InsertNumberToMachine(StateMachine* const pMachine, unsigned int uiNumber) + void InsertNumberToMachine(StateMachine* const pMachine, size_t number) { static const size_t cchBufferMax = 20; wchar_t pwszDistance[cchBufferMax]; - int cchDistance = swprintf_s(pwszDistance, cchBufferMax, L"%d", uiNumber); + int cchDistance = swprintf_s(pwszDistance, cchBufferMax, L"%zu", number); if (cchDistance > 0 && cchDistance < cchBufferMax) { @@ -979,27 +1006,22 @@ class StateMachineExternalTest final } } - void ApplyParameterBoundary(unsigned int* uiExpected, unsigned int uiGiven) + void ApplyParameterBoundary(size_t* uiExpected, size_t uiGiven) { // 0 and 1 should be 1. Use the preset value. - // 1-SHORT_MAX should be what we set. - // > SHORT_MAX should be SHORT_MAX. + // 2019-12: No longer bound by SHORT_MAX. Goes all the way to size_t. if (uiGiven <= 1) { *uiExpected = 1u; } - else if (uiGiven > 1 && uiGiven <= SHORT_MAX) + else if (uiGiven > 1) { *uiExpected = uiGiven; } - else if (uiGiven > SHORT_MAX) - { - *uiExpected = SHORT_MAX; // 16383 is our max value. - } } void TestCsiCursorMovement(wchar_t const wchCommand, - unsigned int const uiDistance, + size_t const uiDistance, const bool fUseDistance, const bool* const pfFlag, StateMachine& mach, @@ -1017,14 +1039,14 @@ class StateMachineExternalTest final VERIFY_IS_TRUE(*pfFlag); - unsigned int uiExpectedDistance = 1u; + size_t uiExpectedDistance = 1u; if (fUseDistance) { ApplyParameterBoundary(&uiExpectedDistance, uiDistance); } - VERIFY_ARE_EQUAL(dispatch._uiCursorDistance, uiExpectedDistance); + VERIFY_ARE_EQUAL(dispatch._cursorDistance, uiExpectedDistance); } TEST_METHOD(TestCsiCursorMovementWithValues) @@ -1033,64 +1055,66 @@ class StateMachineExternalTest final TEST_METHOD_PROPERTY(L"Data:uiDistance", PARAM_VALUES) END_TEST_METHOD_PROPERTIES() - unsigned int uiDistance; + size_t uiDistance; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiDistance", uiDistance)); - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - TestCsiCursorMovement(L'A', uiDistance, true, &pDispatch->_fCursorUp, mach, *pDispatch); + TestCsiCursorMovement(L'A', uiDistance, true, &pDispatch->_cursorUp, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'B', uiDistance, true, &pDispatch->_fCursorDown, mach, *pDispatch); + TestCsiCursorMovement(L'B', uiDistance, true, &pDispatch->_cursorDown, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'C', uiDistance, true, &pDispatch->_fCursorForward, mach, *pDispatch); + TestCsiCursorMovement(L'C', uiDistance, true, &pDispatch->_cursorForward, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'D', uiDistance, true, &pDispatch->_fCursorBackward, mach, *pDispatch); + TestCsiCursorMovement(L'D', uiDistance, true, &pDispatch->_cursorBackward, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'E', uiDistance, true, &pDispatch->_fCursorNextLine, mach, *pDispatch); + TestCsiCursorMovement(L'E', uiDistance, true, &pDispatch->_cursorNextLine, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'F', uiDistance, true, &pDispatch->_fCursorPreviousLine, mach, *pDispatch); + TestCsiCursorMovement(L'F', uiDistance, true, &pDispatch->_cursorPreviousLine, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'G', uiDistance, true, &pDispatch->_fCursorHorizontalPositionAbsolute, mach, *pDispatch); + TestCsiCursorMovement(L'G', uiDistance, true, &pDispatch->_cursorHorizontalPositionAbsolute, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'`', uiDistance, true, &pDispatch->_fCursorHorizontalPositionAbsolute, mach, *pDispatch); + TestCsiCursorMovement(L'`', uiDistance, true, &pDispatch->_cursorHorizontalPositionAbsolute, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'd', uiDistance, true, &pDispatch->_fVerticalLinePositionAbsolute, mach, *pDispatch); + TestCsiCursorMovement(L'd', uiDistance, true, &pDispatch->_verticalLinePositionAbsolute, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'@', uiDistance, true, &pDispatch->_fInsertCharacter, mach, *pDispatch); + TestCsiCursorMovement(L'@', uiDistance, true, &pDispatch->_insertCharacter, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'P', uiDistance, true, &pDispatch->_fDeleteCharacter, mach, *pDispatch); + TestCsiCursorMovement(L'P', uiDistance, true, &pDispatch->_deleteCharacter, mach, *pDispatch); } TEST_METHOD(TestCsiCursorMovementWithoutValues) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - unsigned int uiDistance = 9999; // this value should be ignored with the false below. - TestCsiCursorMovement(L'A', uiDistance, false, &pDispatch->_fCursorUp, mach, *pDispatch); + size_t uiDistance = 9999; // this value should be ignored with the false below. + TestCsiCursorMovement(L'A', uiDistance, false, &pDispatch->_cursorUp, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'B', uiDistance, false, &pDispatch->_fCursorDown, mach, *pDispatch); + TestCsiCursorMovement(L'B', uiDistance, false, &pDispatch->_cursorDown, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'C', uiDistance, false, &pDispatch->_fCursorForward, mach, *pDispatch); + TestCsiCursorMovement(L'C', uiDistance, false, &pDispatch->_cursorForward, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'D', uiDistance, false, &pDispatch->_fCursorBackward, mach, *pDispatch); + TestCsiCursorMovement(L'D', uiDistance, false, &pDispatch->_cursorBackward, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'E', uiDistance, false, &pDispatch->_fCursorNextLine, mach, *pDispatch); + TestCsiCursorMovement(L'E', uiDistance, false, &pDispatch->_cursorNextLine, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'F', uiDistance, false, &pDispatch->_fCursorPreviousLine, mach, *pDispatch); + TestCsiCursorMovement(L'F', uiDistance, false, &pDispatch->_cursorPreviousLine, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'G', uiDistance, false, &pDispatch->_fCursorHorizontalPositionAbsolute, mach, *pDispatch); + TestCsiCursorMovement(L'G', uiDistance, false, &pDispatch->_cursorHorizontalPositionAbsolute, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'`', uiDistance, false, &pDispatch->_fCursorHorizontalPositionAbsolute, mach, *pDispatch); + TestCsiCursorMovement(L'`', uiDistance, false, &pDispatch->_cursorHorizontalPositionAbsolute, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'd', uiDistance, false, &pDispatch->_fVerticalLinePositionAbsolute, mach, *pDispatch); + TestCsiCursorMovement(L'd', uiDistance, false, &pDispatch->_verticalLinePositionAbsolute, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'@', uiDistance, false, &pDispatch->_fInsertCharacter, mach, *pDispatch); + TestCsiCursorMovement(L'@', uiDistance, false, &pDispatch->_insertCharacter, mach, *pDispatch); pDispatch->ClearState(); - TestCsiCursorMovement(L'P', uiDistance, false, &pDispatch->_fDeleteCharacter, mach, *pDispatch); + TestCsiCursorMovement(L'P', uiDistance, false, &pDispatch->_deleteCharacter, mach, *pDispatch); } TEST_METHOD(TestCsiCursorPosition) @@ -1100,14 +1124,15 @@ class StateMachineExternalTest final TEST_METHOD_PROPERTY(L"Data:uiCol", PARAM_VALUES) END_TEST_METHOD_PROPERTIES() - unsigned int uiRow; + size_t uiRow; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiRow", uiRow)); - unsigned int uiCol; + size_t uiCol; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiCol", uiCol)); - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); @@ -1121,9 +1146,9 @@ class StateMachineExternalTest final ApplyParameterBoundary(&uiRow, uiRow); ApplyParameterBoundary(&uiCol, uiCol); - VERIFY_IS_TRUE(pDispatch->_fCursorPosition); - VERIFY_ARE_EQUAL(pDispatch->_uiLine, uiRow); - VERIFY_ARE_EQUAL(pDispatch->_uiColumn, uiCol); + VERIFY_IS_TRUE(pDispatch->_cursorPosition); + VERIFY_ARE_EQUAL(pDispatch->_line, uiRow); + VERIFY_ARE_EQUAL(pDispatch->_column, uiCol); } TEST_METHOD(TestCsiCursorPositionWithOnlyRow) @@ -1132,12 +1157,13 @@ class StateMachineExternalTest final TEST_METHOD_PROPERTY(L"Data:uiRow", PARAM_VALUES) END_TEST_METHOD_PROPERTIES() - unsigned int uiRow; + size_t uiRow; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiRow", uiRow)); - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); @@ -1148,188 +1174,196 @@ class StateMachineExternalTest final // bound the row/col values by the max we expect ApplyParameterBoundary(&uiRow, uiRow); - VERIFY_IS_TRUE(pDispatch->_fCursorPosition); - VERIFY_ARE_EQUAL(pDispatch->_uiLine, uiRow); - VERIFY_ARE_EQUAL(pDispatch->_uiColumn, (unsigned int)1); // Without the second param, the column should always be the default + VERIFY_IS_TRUE(pDispatch->_cursorPosition); + VERIFY_ARE_EQUAL(pDispatch->_line, uiRow); + VERIFY_ARE_EQUAL(pDispatch->_column, (size_t)1); // Without the second param, the column should always be the default } TEST_METHOD(TestCursorSaveLoad) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'7'); - VERIFY_IS_TRUE(pDispatch->_fCursorSave); + VERIFY_IS_TRUE(pDispatch->_cursorSave); pDispatch->ClearState(); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'8'); - VERIFY_IS_TRUE(pDispatch->_fCursorLoad); + VERIFY_IS_TRUE(pDispatch->_cursorLoad); pDispatch->ClearState(); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); mach.ProcessCharacter(L's'); - VERIFY_IS_TRUE(pDispatch->_fCursorSave); + VERIFY_IS_TRUE(pDispatch->_cursorSave); pDispatch->ClearState(); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); mach.ProcessCharacter(L'u'); - VERIFY_IS_TRUE(pDispatch->_fCursorLoad); + VERIFY_IS_TRUE(pDispatch->_cursorLoad); pDispatch->ClearState(); } TEST_METHOD(TestCursorKeysMode) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - mach.ProcessString(L"\x1b[?1h", 5); - VERIFY_IS_TRUE(pDispatch->_fCursorKeysMode); + mach.ProcessString(L"\x1b[?1h"); + VERIFY_IS_TRUE(pDispatch->_cursorKeysMode); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?1l", 5); - VERIFY_IS_FALSE(pDispatch->_fCursorKeysMode); + mach.ProcessString(L"\x1b[?1l"); + VERIFY_IS_FALSE(pDispatch->_cursorKeysMode); pDispatch->ClearState(); } TEST_METHOD(TestSetNumberOfColumns) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - mach.ProcessString(L"\x1b[?3h", 5); - VERIFY_ARE_EQUAL(pDispatch->_uiWindowWidth, static_cast(DispatchTypes::s_sDECCOLMSetColumns)); + mach.ProcessString(L"\x1b[?3h"); + VERIFY_ARE_EQUAL(pDispatch->_windowWidth, static_cast(DispatchTypes::s_sDECCOLMSetColumns)); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?3l", 5); - VERIFY_ARE_EQUAL(pDispatch->_uiWindowWidth, static_cast(DispatchTypes::s_sDECCOLMResetColumns)); + mach.ProcessString(L"\x1b[?3l"); + VERIFY_ARE_EQUAL(pDispatch->_windowWidth, static_cast(DispatchTypes::s_sDECCOLMResetColumns)); pDispatch->ClearState(); } TEST_METHOD(TestOriginMode) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - mach.ProcessString(L"\x1b[?6h", 5); - VERIFY_IS_TRUE(pDispatch->_fIsOriginModeRelative); - VERIFY_IS_TRUE(pDispatch->_fCursorPosition); - VERIFY_ARE_EQUAL(pDispatch->_uiLine, 1u); - VERIFY_ARE_EQUAL(pDispatch->_uiColumn, 1u); + mach.ProcessString(L"\x1b[?6h"); + VERIFY_IS_TRUE(pDispatch->_isOriginModeRelative); + VERIFY_IS_TRUE(pDispatch->_cursorPosition); + VERIFY_ARE_EQUAL(pDispatch->_line, 1u); + VERIFY_ARE_EQUAL(pDispatch->_column, 1u); pDispatch->ClearState(); - pDispatch->_fIsOriginModeRelative = true; + pDispatch->_isOriginModeRelative = true; - mach.ProcessString(L"\x1b[?6l", 5); - VERIFY_IS_FALSE(pDispatch->_fIsOriginModeRelative); - VERIFY_IS_TRUE(pDispatch->_fCursorPosition); - VERIFY_ARE_EQUAL(pDispatch->_uiLine, 1u); - VERIFY_ARE_EQUAL(pDispatch->_uiColumn, 1u); + mach.ProcessString(L"\x1b[?6l"); + VERIFY_IS_FALSE(pDispatch->_isOriginModeRelative); + VERIFY_IS_TRUE(pDispatch->_cursorPosition); + VERIFY_ARE_EQUAL(pDispatch->_line, 1u); + VERIFY_ARE_EQUAL(pDispatch->_column, 1u); pDispatch->ClearState(); } TEST_METHOD(TestCursorBlinking) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - mach.ProcessString(L"\x1b[?12h", 6); - VERIFY_IS_TRUE(pDispatch->_fCursorBlinking); + mach.ProcessString(L"\x1b[?12h"); + VERIFY_IS_TRUE(pDispatch->_cursorBlinking); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?12l", 6); - VERIFY_IS_FALSE(pDispatch->_fCursorBlinking); + mach.ProcessString(L"\x1b[?12l"); + VERIFY_IS_FALSE(pDispatch->_cursorBlinking); pDispatch->ClearState(); } TEST_METHOD(TestCursorVisibility) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - mach.ProcessString(L"\x1b[?25h", 6); - VERIFY_IS_TRUE(pDispatch->_fCursorVisible); + mach.ProcessString(L"\x1b[?25h"); + VERIFY_IS_TRUE(pDispatch->_cursorVisible); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?25l", 6); - VERIFY_IS_FALSE(pDispatch->_fCursorVisible); + mach.ProcessString(L"\x1b[?25l"); + VERIFY_IS_FALSE(pDispatch->_cursorVisible); pDispatch->ClearState(); } TEST_METHOD(TestAltBufferSwapping) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - mach.ProcessString(L"\x1b[?1049h", 8); - VERIFY_IS_TRUE(pDispatch->_fIsAltBuffer); + mach.ProcessString(L"\x1b[?1049h"); + VERIFY_IS_TRUE(pDispatch->_isAltBuffer); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?1049h", 8); - VERIFY_IS_TRUE(pDispatch->_fIsAltBuffer); - mach.ProcessString(L"\x1b[?1049h", 8); - VERIFY_IS_TRUE(pDispatch->_fIsAltBuffer); + mach.ProcessString(L"\x1b[?1049h"); + VERIFY_IS_TRUE(pDispatch->_isAltBuffer); + mach.ProcessString(L"\x1b[?1049h"); + VERIFY_IS_TRUE(pDispatch->_isAltBuffer); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?1049l", 8); - VERIFY_IS_FALSE(pDispatch->_fIsAltBuffer); + mach.ProcessString(L"\x1b[?1049l"); + VERIFY_IS_FALSE(pDispatch->_isAltBuffer); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?1049h", 8); - VERIFY_IS_TRUE(pDispatch->_fIsAltBuffer); - mach.ProcessString(L"\x1b[?1049l", 8); - VERIFY_IS_FALSE(pDispatch->_fIsAltBuffer); + mach.ProcessString(L"\x1b[?1049h"); + VERIFY_IS_TRUE(pDispatch->_isAltBuffer); + mach.ProcessString(L"\x1b[?1049l"); + VERIFY_IS_FALSE(pDispatch->_isAltBuffer); pDispatch->ClearState(); - mach.ProcessString(L"\x1b[?1049l", 8); - VERIFY_IS_FALSE(pDispatch->_fIsAltBuffer); - mach.ProcessString(L"\x1b[?1049l", 8); - VERIFY_IS_FALSE(pDispatch->_fIsAltBuffer); + mach.ProcessString(L"\x1b[?1049l"); + VERIFY_IS_FALSE(pDispatch->_isAltBuffer); + mach.ProcessString(L"\x1b[?1049l"); + VERIFY_IS_FALSE(pDispatch->_isAltBuffer); pDispatch->ClearState(); } TEST_METHOD(TestEnableDECCOLMSupport) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); mach.ProcessString(L"\x1b[?40h"); - VERIFY_IS_TRUE(pDispatch->_fIsDECCOLMAllowed); + VERIFY_IS_TRUE(pDispatch->_isDECCOLMAllowed); pDispatch->ClearState(); - pDispatch->_fIsDECCOLMAllowed = true; + pDispatch->_isDECCOLMAllowed = true; mach.ProcessString(L"\x1b[?40l"); - VERIFY_IS_FALSE(pDispatch->_fIsDECCOLMAllowed); + VERIFY_IS_FALSE(pDispatch->_isDECCOLMAllowed); pDispatch->ClearState(); } @@ -1341,27 +1375,28 @@ class StateMachineExternalTest final TEST_METHOD_PROPERTY(L"Data:uiDispatchTypes::EraseType", L"{0, 1, 2, 10}") // maps to DispatchTypes::EraseType enum class options. END_TEST_METHOD_PROPERTIES() - unsigned int uiEraseOperation; + size_t uiEraseOperation; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiEraseOperation", uiEraseOperation)); - unsigned int uiDispatchTypes; + size_t uiDispatchTypes; VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"uiDispatchTypes::EraseType", uiDispatchTypes)); WCHAR wchOp = L'\0'; bool* pfOperationCallback = nullptr; - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); switch (uiEraseOperation) { case 0: wchOp = L'J'; - pfOperationCallback = &pDispatch->_fEraseDisplay; + pfOperationCallback = &pDispatch->_eraseDisplay; break; case 1: wchOp = L'K'; - pfOperationCallback = &pDispatch->_fEraseLine; + pfOperationCallback = &pDispatch->_eraseLine; break; default: VERIFY_FAIL(L"Unknown erase operation permutation."); @@ -1401,50 +1436,50 @@ class StateMachineExternalTest final VERIFY_ARE_EQUAL(expectedDispatchTypes, pDispatch->_eraseType); } - void VerifyDispatchTypes(_In_reads_(cExpectedOptions) const DispatchTypes::GraphicsOptions* const rgExpectedOptions, - const size_t cExpectedOptions, + void VerifyDispatchTypes(const std::basic_string_view expectedOptions, const StatefulDispatch& dispatch) { - VERIFY_ARE_EQUAL(cExpectedOptions, dispatch._cOptions); - bool fOptionsValid = true; + VERIFY_ARE_EQUAL(expectedOptions.size(), dispatch._options.size()); + bool optionsValid = true; - for (size_t i = 0; i < dispatch.s_cMaxOptions; i++) + for (size_t i = 0; i < dispatch._options.size(); i++) { auto expectedOption = (DispatchTypes::GraphicsOptions)dispatch.s_uiGraphicsCleared; - if (i < cExpectedOptions) + if (i < expectedOptions.size()) { - expectedOption = rgExpectedOptions[i]; + expectedOption = expectedOptions.at(i); } - fOptionsValid = expectedOption == dispatch._rgOptions[i]; + optionsValid = expectedOption == dispatch._options.at(i); - if (!fOptionsValid) + if (!optionsValid) { - Log::Comment(NoThrowString().Format(L"Graphics option match failed, index [%zu]. Expected: '%d' Actual: '%d'", i, expectedOption, dispatch._rgOptions[i])); + Log::Comment(NoThrowString().Format(L"Graphics option match failed, index [%zu]. Expected: '%d' Actual: '%d'", i, expectedOption, dispatch._options.at(i))); break; } } - VERIFY_IS_TRUE(fOptionsValid); + VERIFY_IS_TRUE(optionsValid); } TEST_METHOD(TestSetGraphicsRendition) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); - DispatchTypes::GraphicsOptions rgExpected[16]; + DispatchTypes::GraphicsOptions rgExpected[17]; Log::Comment(L"Test 1: Check default case."); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); mach.ProcessCharacter(L'm'); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + VERIFY_IS_TRUE(pDispatch->_setGraphics); rgExpected[0] = DispatchTypes::GraphicsOptions::Off; - VerifyDispatchTypes(rgExpected, 1, *pDispatch); + VerifyDispatchTypes({ rgExpected, 1 }, *pDispatch); pDispatch->ClearState(); @@ -1454,10 +1489,10 @@ class StateMachineExternalTest final mach.ProcessCharacter(L'['); mach.ProcessCharacter(L'0'); mach.ProcessCharacter(L'm'); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + VERIFY_IS_TRUE(pDispatch->_setGraphics); rgExpected[0] = DispatchTypes::GraphicsOptions::Off; - VerifyDispatchTypes(rgExpected, 1, *pDispatch); + VerifyDispatchTypes({ rgExpected, 1 }, *pDispatch); pDispatch->ClearState(); @@ -1477,18 +1512,18 @@ class StateMachineExternalTest final mach.ProcessCharacter(L'4'); mach.ProcessCharacter(L'5'); mach.ProcessCharacter(L'm'); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + VERIFY_IS_TRUE(pDispatch->_setGraphics); rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::Underline; rgExpected[2] = DispatchTypes::GraphicsOptions::Negative; rgExpected[3] = DispatchTypes::GraphicsOptions::ForegroundBlack; rgExpected[4] = DispatchTypes::GraphicsOptions::BackgroundMagenta; - VerifyDispatchTypes(rgExpected, 5, *pDispatch); + VerifyDispatchTypes({ rgExpected, 5 }, *pDispatch); pDispatch->ClearState(); - Log::Comment(L"Test 4: Check 'too many options' (>16) case."); + Log::Comment(L"Test 4: Check 'many options' (>16) case."); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); @@ -1526,7 +1561,7 @@ class StateMachineExternalTest final mach.ProcessCharacter(L';'); mach.ProcessCharacter(L'1'); mach.ProcessCharacter(L'm'); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + VERIFY_IS_TRUE(pDispatch->_setGraphics); rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::Underline; @@ -1544,61 +1579,63 @@ class StateMachineExternalTest final rgExpected[13] = DispatchTypes::GraphicsOptions::Underline; rgExpected[14] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[15] = DispatchTypes::GraphicsOptions::Underline; - VerifyDispatchTypes(rgExpected, 16, *pDispatch); + rgExpected[16] = DispatchTypes::GraphicsOptions::BoldBright; + VerifyDispatchTypes({ rgExpected, 17 }, *pDispatch); pDispatch->ClearState(); Log::Comment(L"Test 5.a: Test an empty param at the end of a sequence"); std::wstring sequence = L"\x1b[1;m"; - mach.ProcessString(&sequence[0], sequence.length()); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + mach.ProcessString(sequence); + VERIFY_IS_TRUE(pDispatch->_setGraphics); rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::Off; - VerifyDispatchTypes(rgExpected, 2, *pDispatch); + VerifyDispatchTypes({ rgExpected, 2 }, *pDispatch); pDispatch->ClearState(); Log::Comment(L"Test 5.b: Test an empty param in the middle of a sequence"); sequence = L"\x1b[1;;1m"; - mach.ProcessString(&sequence[0], sequence.length()); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + mach.ProcessString(sequence); + VERIFY_IS_TRUE(pDispatch->_setGraphics); rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::Off; rgExpected[2] = DispatchTypes::GraphicsOptions::BoldBright; - VerifyDispatchTypes(rgExpected, 3, *pDispatch); + VerifyDispatchTypes({ rgExpected, 3 }, *pDispatch); pDispatch->ClearState(); Log::Comment(L"Test 5.c: Test an empty param at the start of a sequence"); sequence = L"\x1b[;31;1m"; - mach.ProcessString(&sequence[0], sequence.length()); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + mach.ProcessString(sequence); + VERIFY_IS_TRUE(pDispatch->_setGraphics); rgExpected[0] = DispatchTypes::GraphicsOptions::Off; rgExpected[1] = DispatchTypes::GraphicsOptions::ForegroundRed; rgExpected[2] = DispatchTypes::GraphicsOptions::BoldBright; - VerifyDispatchTypes(rgExpected, 3, *pDispatch); + VerifyDispatchTypes({ rgExpected, 3 }, *pDispatch); pDispatch->ClearState(); } TEST_METHOD(TestDeviceStatusReport) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); Log::Comment(L"Test 1: Check empty case. Should fail."); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); mach.ProcessCharacter(L'n'); - VERIFY_IS_FALSE(pDispatch->_fDeviceStatusReport); + VERIFY_IS_FALSE(pDispatch->_deviceStatusReport); pDispatch->ClearState(); @@ -1608,7 +1645,7 @@ class StateMachineExternalTest final mach.ProcessCharacter(L'6'); mach.ProcessCharacter(L'n'); - VERIFY_IS_TRUE(pDispatch->_fDeviceStatusReport); + VERIFY_IS_TRUE(pDispatch->_deviceStatusReport); VERIFY_ARE_EQUAL(DispatchTypes::AnsiStatusType::CPR_CursorPositionReport, pDispatch->_statusReportType); pDispatch->ClearState(); @@ -1619,23 +1656,24 @@ class StateMachineExternalTest final mach.ProcessCharacter(L'1'); mach.ProcessCharacter(L'n'); - VERIFY_IS_FALSE(pDispatch->_fDeviceStatusReport); + VERIFY_IS_FALSE(pDispatch->_deviceStatusReport); pDispatch->ClearState(); } TEST_METHOD(TestDeviceAttributes) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); Log::Comment(L"Test 1: Check default case, no params."); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'['); mach.ProcessCharacter(L'c'); - VERIFY_IS_TRUE(pDispatch->_fDeviceAttributes); + VERIFY_IS_TRUE(pDispatch->_deviceAttributes); pDispatch->ClearState(); @@ -1645,7 +1683,7 @@ class StateMachineExternalTest final mach.ProcessCharacter(L'0'); mach.ProcessCharacter(L'c'); - VERIFY_IS_TRUE(pDispatch->_fDeviceAttributes); + VERIFY_IS_TRUE(pDispatch->_deviceAttributes); pDispatch->ClearState(); @@ -1655,25 +1693,26 @@ class StateMachineExternalTest final mach.ProcessCharacter(L'1'); mach.ProcessCharacter(L'c'); - VERIFY_IS_FALSE(pDispatch->_fDeviceAttributes); + VERIFY_IS_FALSE(pDispatch->_deviceAttributes); pDispatch->ClearState(); } TEST_METHOD(TestStrings) { - StatefulDispatch* pDispatch = new StatefulDispatch; - VERIFY_IS_NOT_NULL(pDispatch); - StateMachine mach(new OutputStateMachineEngine(pDispatch)); + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); DispatchTypes::GraphicsOptions rgExpected[16]; DispatchTypes::EraseType expectedDispatchTypes; /////////////////////////////////////////////////////////////////////// Log::Comment(L"Test 1: Basic String processing. One sequence in a string."); - mach.ProcessString(L"\x1b[0m", 4); + mach.ProcessString(L"\x1b[0m"); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); + VERIFY_IS_TRUE(pDispatch->_setGraphics); pDispatch->ClearState(); @@ -1681,9 +1720,9 @@ class StateMachineExternalTest final Log::Comment(L"Test 2: A couple of sequences all in one string"); - mach.ProcessString(L"\x1b[1;4;7;30;45m\x1b[2J", 18); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); - VERIFY_IS_TRUE(pDispatch->_fEraseDisplay); + mach.ProcessString(L"\x1b[1;4;7;30;45m\x1b[2J"); + VERIFY_IS_TRUE(pDispatch->_setGraphics); + VERIFY_IS_TRUE(pDispatch->_eraseDisplay); rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::Underline; @@ -1691,7 +1730,7 @@ class StateMachineExternalTest final rgExpected[3] = DispatchTypes::GraphicsOptions::ForegroundBlack; rgExpected[4] = DispatchTypes::GraphicsOptions::BackgroundMagenta; expectedDispatchTypes = DispatchTypes::EraseType::All; - VerifyDispatchTypes(rgExpected, 5, *pDispatch); + VerifyDispatchTypes({ rgExpected, 5 }, *pDispatch); VERIFY_ARE_EQUAL(expectedDispatchTypes, pDispatch->_eraseType); pDispatch->ClearState(); @@ -1699,36 +1738,36 @@ class StateMachineExternalTest final /////////////////////////////////////////////////////////////////////// Log::Comment(L"Test 3: Two sequences seperated by a non-sequence of characters"); - mach.ProcessString(L"\x1b[1;30mHello World\x1b[2J", 22); + mach.ProcessString(L"\x1b[1;30mHello World\x1b[2J"); rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::ForegroundBlack; expectedDispatchTypes = DispatchTypes::EraseType::All; - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); - VERIFY_IS_TRUE(pDispatch->_fEraseDisplay); + VERIFY_IS_TRUE(pDispatch->_setGraphics); + VERIFY_IS_TRUE(pDispatch->_eraseDisplay); - VerifyDispatchTypes(rgExpected, 2, *pDispatch); + VerifyDispatchTypes({ rgExpected, 2 }, *pDispatch); VERIFY_ARE_EQUAL(expectedDispatchTypes, pDispatch->_eraseType); pDispatch->ClearState(); /////////////////////////////////////////////////////////////////////// Log::Comment(L"Test 4: An entire sequence broke into multiple strings"); - mach.ProcessString(L"\x1b[1;", 4); - VERIFY_IS_FALSE(pDispatch->_fSetGraphics); - VERIFY_IS_FALSE(pDispatch->_fEraseDisplay); + mach.ProcessString(L"\x1b[1;"); + VERIFY_IS_FALSE(pDispatch->_setGraphics); + VERIFY_IS_FALSE(pDispatch->_eraseDisplay); - mach.ProcessString(L"30mHello World\x1b[2J", 18); + mach.ProcessString(L"30mHello World\x1b[2J"); rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::ForegroundBlack; expectedDispatchTypes = DispatchTypes::EraseType::All; - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); - VERIFY_IS_TRUE(pDispatch->_fEraseDisplay); + VERIFY_IS_TRUE(pDispatch->_setGraphics); + VERIFY_IS_TRUE(pDispatch->_eraseDisplay); - VerifyDispatchTypes(rgExpected, 2, *pDispatch); + VerifyDispatchTypes({ rgExpected, 2 }, *pDispatch); VERIFY_ARE_EQUAL(expectedDispatchTypes, pDispatch->_eraseType); pDispatch->ClearState(); @@ -1739,29 +1778,29 @@ class StateMachineExternalTest final rgExpected[0] = DispatchTypes::GraphicsOptions::BoldBright; rgExpected[1] = DispatchTypes::GraphicsOptions::ForegroundBlack; - mach.ProcessString(L"\x1b[1;", 4); - VERIFY_IS_FALSE(pDispatch->_fSetGraphics); - VERIFY_IS_FALSE(pDispatch->_fEraseDisplay); + mach.ProcessString(L"\x1b[1;"); + VERIFY_IS_FALSE(pDispatch->_setGraphics); + VERIFY_IS_FALSE(pDispatch->_eraseDisplay); mach.ProcessCharacter(L'3'); - VERIFY_IS_FALSE(pDispatch->_fSetGraphics); - VERIFY_IS_FALSE(pDispatch->_fEraseDisplay); + VERIFY_IS_FALSE(pDispatch->_setGraphics); + VERIFY_IS_FALSE(pDispatch->_eraseDisplay); mach.ProcessCharacter(L'0'); - VERIFY_IS_FALSE(pDispatch->_fSetGraphics); - VERIFY_IS_FALSE(pDispatch->_fEraseDisplay); + VERIFY_IS_FALSE(pDispatch->_setGraphics); + VERIFY_IS_FALSE(pDispatch->_eraseDisplay); mach.ProcessCharacter(L'm'); - VERIFY_IS_TRUE(pDispatch->_fSetGraphics); - VERIFY_IS_FALSE(pDispatch->_fEraseDisplay); - VerifyDispatchTypes(rgExpected, 2, *pDispatch); + VERIFY_IS_TRUE(pDispatch->_setGraphics); + VERIFY_IS_FALSE(pDispatch->_eraseDisplay); + VerifyDispatchTypes({ rgExpected, 2 }, *pDispatch); - mach.ProcessString(L"Hello World\x1b[2J", 15); + mach.ProcessString(L"Hello World\x1b[2J"); expectedDispatchTypes = DispatchTypes::EraseType::All; - VERIFY_IS_TRUE(pDispatch->_fEraseDisplay); + VERIFY_IS_TRUE(pDispatch->_eraseDisplay); VERIFY_ARE_EQUAL(expectedDispatchTypes, pDispatch->_eraseType); diff --git a/src/terminal/parser/ut_parser/StateMachineTest.cpp b/src/terminal/parser/ut_parser/StateMachineTest.cpp index 7235b1ecce..046855d9ba 100644 --- a/src/terminal/parser/ut_parser/StateMachineTest.cpp +++ b/src/terminal/parser/ut_parser/StateMachineTest.cpp @@ -31,46 +31,39 @@ public: bool ActionExecute(const wchar_t /* wch */) override { return true; }; bool ActionExecuteFromEscape(const wchar_t /* wch */) override { return true; }; bool ActionPrint(const wchar_t /* wch */) override { return true; }; - bool ActionPrintString(const wchar_t* const /* rgwch */, - size_t const /* cch */) override { return true; }; + bool ActionPrintString(const std::wstring_view /* string */) override { return true; }; - bool ActionPassThroughString(const wchar_t* const /* rgwch */, - size_t const /* cch */) override { return true; }; + bool ActionPassThroughString(const std::wstring_view /* string */) override { return true; }; bool ActionEscDispatch(const wchar_t /* wch */, - const unsigned short /* cIntermediate */, - const wchar_t /* wchIntermediate */) override { return true; }; + const std::basic_string_view /* intermediates */) override { return true; }; bool ActionClear() override { return true; }; bool ActionIgnore() override { return true; }; bool ActionOscDispatch(const wchar_t /* wch */, - const unsigned short /* sOscParam */, - wchar_t* const /* pwchOscStringBuffer */, - const unsigned short /* cchOscString */) override { return true; }; + const size_t /* parameter */, + const std::wstring_view /* string */) override { return true; }; bool ActionSs3Dispatch(const wchar_t /* wch */, - const unsigned short* const /* rgusParams */, - const unsigned short /* cParams */) override { return true; }; + const std::basic_string_view /* parameters */) override { return true; }; bool FlushAtEndOfString() const override { return false; }; bool DispatchControlCharsFromEscape() const override { return false; }; bool DispatchIntermediatesFromEscape() const override { return false; }; // ActionCsiDispatch is the only method that's actually implemented. - bool ActionCsiDispatch(const wchar_t /* wch */, - const unsigned short /* cIntermediate */, - const wchar_t /* wchIntermediate */, - _In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) override + bool ActionCsiDispatch(const wchar_t /*wch*/, + const std::basic_string_view /*intermediates*/, + const std::basic_string_view parameters) override { - csiParams.emplace(rgusParams, rgusParams + cParams); + csiParams.emplace(parameters.cbegin(), parameters.cend()); return true; } // This will only be populated if ActionCsiDispatch is called. - std::optional> csiParams; + std::optional> csiParams; }; class Microsoft::Console::VirtualTerminal::StateMachineTest @@ -95,18 +88,18 @@ void StateMachineTest::TwoStateMachinesDoNotInterfereWithEachother() auto firstEnginePtr{ std::make_unique() }; // this dance is required because StateMachine presumes to take ownership of its engine. const auto& firstEngine{ *firstEnginePtr.get() }; - StateMachine firstStateMachine{ firstEnginePtr.release() }; + StateMachine firstStateMachine{ std::move(firstEnginePtr) }; auto secondEnginePtr{ std::make_unique() }; const auto& secondEngine{ *secondEnginePtr.get() }; - StateMachine secondStateMachine{ secondEnginePtr.release() }; + StateMachine secondStateMachine{ std::move(secondEnginePtr) }; firstStateMachine.ProcessString(L"\x1b[12"); // partial sequence secondStateMachine.ProcessString(L"\x1b[3C"); // full sequence on second parser firstStateMachine.ProcessString(L";34m"); // completion to previous partial sequence on first parser - std::vector expectedFirstCsi{ 12u, 34u }; - std::vector expectedSecondCsi{ 3u }; + std::vector expectedFirstCsi{ 12u, 34u }; + std::vector expectedSecondCsi{ 3u }; VERIFY_ARE_EQUAL(expectedFirstCsi, firstEngine.csiParams); VERIFY_ARE_EQUAL(expectedSecondCsi, secondEngine.csiParams);