diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index 2bf09bf7b31..867699ceb86 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 e903607d58d..3ae05c0937c 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 8391f39f8e9..6a776f8a59d 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -75,16 +75,16 @@ class Microsoft::Terminal::Core::Terminal final : 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 b54a22581f5..fafb6972f8b 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 d5b061d2913..6b8e6215a08 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 5fa9758856e..df418ad886d 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -11,29 +11,28 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc 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 @@ class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatc 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 b73b9adee1b..4e2d4ece6d7 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 e7e968204b0..7abe5258c1d 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 cfc80868a24..363eb4427ad 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 dd9bb35a59f..f27d4bcbcae 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; - - if (pwAttributes == nullptr) - { - Status = STATUS_INVALID_PARAMETER; - } + attributes = screenInfo.GetActiveBuffer().GetAttributes().GetLegacyAttributes(); - 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 0971b435192..0199a7660f0 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 f69fa961be9..ff713ae4156 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 244ce172ac4..f7f6d720f43 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -29,14 +29,14 @@ class WriteBuffer : public Microsoft::Console::VirtualTerminal::AdaptDefaults // 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 bed6d12b608..21c589c2f82 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 07ac3527bd4..fa6fd102900 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 226b4ced32d..7ad1fa874e9 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 3b1875d14a2..0d7569e63e7 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 b27e84f805d..fb65e0a8a47 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 a2a9283808e..b9e48c166fc 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 bbaeb6aea6f..179697a5ab9 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 88eda0389a7..2c1d8a08ed1 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 6be72d6c78a..dc64a8c1a18 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 31cca05d4a2..11131d39215 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 c4629585840..5adf1cd1d9c 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 6d022299d58..a7ef93f38f1 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 5f06a6559b9..f7af1e28d03 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 954f75094d4..d974e93b060 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 d76e2f65774..c5bbd81494d 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -25,63 +25,60 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch 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 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch 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 74c918bffe1..a78db37b18c 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 6914194c85c..503c5cd980b 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 a97ae829de8..63a7b0eb864 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 fb60da09929..63402b2dda8 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); - - if (fSuccess) + // 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 (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 77a5ded263c..ce7b948d09b 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 _DoSetTopBottomScrollingMargins(const SHORT sTopMargin, - const SHORT sBottomMargin); + 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 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; - - bool _fIsOriginModeRelative; + SMALL_RECT _scrollMargins; - bool _fIsSetColumnsEnabled; + bool _isOriginModeRelative; - bool _fIsDECCOLMAllowed; + bool _isDECCOLMAllowed; - bool _fChangedForeground; - bool _fChangedBackground; - bool _fChangedMetaAttrs; + bool _changedForeground; + bool _changedBackground; + bool _changedMetaAttrs; - 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 85076d08238..088f80f4954 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 59c391872ff..6b6f9e0b8e6 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 PrivateSetLegacyAttributes(const WORD wAttr, - const bool fForeground, - const bool fBackground, - const bool fMeta) = 0; - - virtual BOOL PrivateSetDefaultAttributes(const bool fForeground, const bool fBackground) = 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 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 PrivateShowCursor(const bool show) = 0; - virtual BOOL PrivateAllowCursorBlinking(const bool fEnable) = 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 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 GetConsoleOutputCP(_Out_ unsigned int* const puiOutputCP) = 0; - - virtual BOOL PrivateSuppressResizeRepaint() = 0; - virtual BOOL IsConsolePty(_Out_ bool* const pIsPty) const = 0; - - virtual BOOL MoveCursorVertically(const short lines) = 0; - - virtual BOOL DeleteLines(const unsigned int count) = 0; - virtual BOOL InsertLines(const unsigned int count) = 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 PrivateFillRegion(const COORD startPosition, + 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 attr, + const bool foreground, + const bool background, + const bool meta) = 0; + + virtual bool PrivateSetDefaultAttributes(const bool foreground, const bool background) = 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(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 enable) = 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 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(unsigned int& codepage) = 0; + + virtual bool PrivateSuppressResizeRepaint() = 0; + virtual bool IsConsolePty(bool& isPty) const = 0; + + virtual bool MoveCursorVertically(const ptrdiff_t lines) = 0; + + virtual bool DeleteLines(const size_t count) = 0; + virtual bool InsertLines(const size_t count) = 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 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 39850028e73..4ac7cc4b7b9 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 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons 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 4328a876e67..99d8600729b 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 @@ class TestGetSet final : public ConGetSet 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 @@ class TestGetSet final : public ConGetSet 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 @@ class TestGetSet final : public ConGetSet 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 @@ class TestGetSet final : public ConGetSet 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 @@ class TestGetSet final : public ConGetSet 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; - - _coordBufferSize.X = 100; - _coordBufferSize.Y = 600; + _setConsoleCursorPositionResult = TRUE; + _getConsoleScreenBufferInfoExResult = TRUE; + _getConsoleCursorInfoResult = TRUE; + _setConsoleCursorInfoResult = TRUE; + _setConsoleTextAttributeResult = TRUE; + _privateWriteConsoleInputWResult = TRUE; + _privatePrependConsoleInputResult = TRUE; + _privateWriteConsoleControlInputResult = TRUE; + _setConsoleWindowInfoResult = TRUE; + _privateGetConsoleScreenBufferAttributesResult = TRUE; + _moveToBottomResult = true; + + _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 @@ class TestGetSet final : public ConGetSet { 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 @@ class TestGetSet final : public ConGetSet { 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 @@ class TestGetSet final : public ConGetSet 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 @@ class TestGetSet final : public ConGetSet 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 _fSetConsoleWindowInfoResult = false; - BOOL _fExpectedWindowAbsolute = false; - BOOL _fSetConsoleScreenBufferInfoExResult = 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; - - 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 _fPrivateSetColorTableEntryResult = 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 _setConsoleWindowInfoResult = false; + bool _expectedWindowAbsolute = false; + bool _setConsoleScreenBufferInfoExResult = 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 _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 _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 @@ class AdapterTest { 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 @@ class AdapterTest TEST_METHOD_CLEANUP(CleanupMethods) { - delete _pDispatch; + _pDispatch.reset(); _testGetSet = nullptr; return true; } @@ -988,12 +993,12 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest { 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest // 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 @@ class AdapterTest { 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 @@ class AdapterTest *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 @@ class AdapterTest *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 @@ class AdapterTest *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 @@ class AdapterTest // 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest // 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 @@ class AdapterTest 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 @@ class AdapterTest _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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest _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 @@ class AdapterTest 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 @@ class AdapterTest // 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 @@ class AdapterTest // 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 @@ class AdapterTest // 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest 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 @@ class AdapterTest 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 691d0e92adb..2c75e7ec8e2 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 0720e79ccd6..88e948517ea 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', +}; + +struct CsiToVkey +{ + CsiActionCodes action; + short vkey; +}; + +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 } +}; + +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, }; -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 GenericToVkey +{ + GenericKeyIdentifiers identifier; + 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_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 }, }; -InputStateMachineEngine::InputStateMachineEngine(IInteractDispatch* const pDispatch) : - InputStateMachineEngine(pDispatch, false) +static bool operator==(const GenericToVkey& pair, const GenericKeyIdentifiers identifier) noexcept { + return pair.identifier == identifier; } -InputStateMachineEngine::InputStateMachineEngine(IInteractDispatch* const pDispatch, const bool lookingForDSR) : - _pDispatch(THROW_IF_NULL_ALLOC(pDispatch)), +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(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) - { - return 0; - } - - 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); - - size_t index = 0; - INPUT_RECORD* next = &rgInput[0]; - - DWORD dwCurrentModifiers = 0; - - if (fShift) - { - 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++; - } - if (fAlt) - { - 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++; - } - if (fCtrl) - { - 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++; - } - - 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++; + 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) + { + 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); + } + + _GetSingleKeypress(wch, vkey, currentModifiers, input); + + if (ctrl) + { + 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 (alt) + { + 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 (shift) + { + 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); } - - 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) -{ - FAIL_FAST_IF(!(cRecords >= 2)); - if (cRecords < 2) - { - return 0; - } +void InputStateMachineEngine::_GetSingleKeypress(const wchar_t wch, + const short vkey, + const DWORD modifierState, + std::vector& input) +{ + 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 cbb8d0acf6e..67bc8ecc48d 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', - }; - - 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', - }; - - // 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, - }; - - struct CSI_TO_VKEY - { - CsiActionCodes Action; - short vkey; - }; - - struct GENERIC_TO_VKEY - { - GenericKeyIdentifiers Identifier; - short vkey; - }; - - struct SS3_TO_VKEY - { - Ss3ActionCodes Action; - short vkey; - }; - - static const CSI_TO_VKEY s_rgCsiMap[]; - static const GENERIC_TO_VKEY s_rgGenericMap[]; - static const SS3_TO_VKEY s_rgSs3Map[]; - - 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; + 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); + + bool _IsModified(const size_t paramCount); + DWORD _GetModifier(const size_t parameter); + + 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; + + bool _WriteSingleKey(const short vkey, const DWORD modifierState); + bool _WriteSingleKey(const wchar_t wch, const short vkey, const DWORD modifierState); + + void _GenerateWrappedSequence(const wchar_t wch, + const short vkey, + const DWORD modifierState, + std::vector& input); + + void _GetSingleKeypress(const wchar_t wch, + const short vkey, + const DWORD modifierState, + std::vector& input); + + bool _GetWindowManipulationType(const std::basic_string_view parameters, + unsigned int& function) 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 c21a2bc1f04..538c7a0fccb 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 (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 + for (const auto& p : parameters) { - 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 1126c9d622c..ab3df051045 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 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 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 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 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 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; - - _Success_(return ) bool _GetDeviceStatusOperation(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams, - _Out_ DispatchTypes::AnsiStatusType* const pStatusType) const; - - _Success_(return ) bool _VerifyHasNoParameters(const unsigned short cParams) const; - - _Success_(return ) bool _VerifyDeviceAttributesParams(_In_reads_(cParams) const unsigned short* const rgusParams, - const unsigned short cParams) 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; - - 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; - - _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; - - 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 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 const DesignateCharsetTypes s_DefaultDesignateCharsetType = DesignateCharsetTypes::G0; - _Success_(return ) bool _GetDesignateType(const wchar_t wchIntermediate, - _Out_ DesignateCharsetTypes* const pDesignateType) 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::GraphicsOptions DefaultGraphicsOption = DispatchTypes::GraphicsOptions::Off; + bool _GetGraphicsOptions(const std::basic_string_view parameters, + std::vector& options) const; + + static constexpr DispatchTypes::EraseType DefaultEraseType = DispatchTypes::EraseType::ToEnd; + bool _GetEraseOperation(const std::basic_string_view parameters, + DispatchTypes::EraseType& eraseType) const; + + static constexpr size_t DefaultCursorDistance = 1; + bool _GetCursorDistance(const std::basic_string_view parameters, + size_t& distance) const; + + static constexpr size_t DefaultScrollDistance = 1; + bool _GetScrollDistance(const std::basic_string_view parameters, + size_t& distance) const; + + static constexpr size_t DefaultConsoleWidth = 80; + bool _GetConsoleWidth(const std::basic_string_view parameters, + size_t& consoleWidth) 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 _GetDeviceStatusOperation(const std::basic_string_view parameters, + DispatchTypes::AnsiStatusType& statusType) const; + + bool _VerifyHasNoParameters(const std::basic_string_view parameters) const; + + bool _VerifyDeviceAttributesParams(const std::basic_string_view parameters) const; + + bool _GetPrivateModeParams(const std::basic_string_view parameters, + std::vector& privateModes) 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; + + bool _GetOscTitle(const std::wstring_view string, + std::wstring& title) const; + + static constexpr size_t DefaultTabDistance = 1; + bool _GetTabDistance(const std::basic_string_view parameters, + size_t& distance) const; + + static constexpr size_t DefaultTabClearType = 0; + bool _GetTabClearType(const std::basic_string_view parameters, + size_t& clearType) const; + + static constexpr DesignateCharsetTypes DefaultDesignateCharsetType = DesignateCharsetTypes::G0; + bool _GetDesignateType(const wchar_t intermediate, + DesignateCharsetTypes& designateType) 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; - - static bool s_ParseColorSpec(_In_reads_(cchBuffer) const wchar_t* const pwchBuffer, - const size_t cchBuffer, - _Out_ DWORD* const pRgb); - - bool _GetOscSetColor(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, - const size_t cchOscString, - _Out_ DWORD* const pRgb) 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 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; + bool _GetOscSetColorTable(const std::wstring_view string, + size_t& tableIndex, + DWORD& rgb) const; + + static bool s_ParseColorSpec(const std::wstring_view string, + DWORD& rgb); + + bool _GetOscSetColor(const std::wstring_view string, + DWORD& rgb) const; + + static constexpr DispatchTypes::CursorStyle DefaultCursorStyle = DispatchTypes::CursorStyle::BlinkingBlockDefault; + bool _GetCursorStyle(const std::basic_string_view parameters, + DispatchTypes::CursorStyle& cursorStyle) const; + + 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 34a8d872bae..a72c7b80fb3 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 48b92553500..ac144a31ade 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 dff5fea97e7..ca5a297d5d7 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 0a656342b7f..681996d0491 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) -{ - ZeroMemory(_pwchOscStringBuffer, sizeof(_pwchOscStringBuffer)); - ZeroMemory(_rgusParams, sizeof(_rgusParams)); + _intermediates{}, + _parameters{}, + _oscString{}, + _processingIndividually(false) +{ _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 a4e71a69bd9..e6c9a34daaf 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; - - unsigned short _rgusParams[s_cParamsMax]; - unsigned short _cParams; - unsigned short* _pusActiveParam; - unsigned short _iParamAccumulatePos; + std::wstring_view _run; - unsigned short _sOscParam; - unsigned short _sOscNextChar; - wchar_t _pwchOscStringBuffer[s_cOscStringMaxLength]; + std::vector _intermediates; + std::vector _parameters; - // 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 78feed1e6b0..cbdbf8cee06 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; - - memcpy(str, pwsString, sizeof(wchar_t) * strLen); - str[strLen] = '\0'; - - TraceLoggingWrite(g_hConsoleVirtTermParserEventTraceProvider, - "StateMachine_PrintRun", - TraceLoggingWideString(str), - TraceLoggingValue(strLen), - TraceLoggingLevel(WINEVENT_LEVEL_VERBOSE)); - } + const auto length = gsl::narrow_cast(string.size()); + + 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 772b2abedb3..2547d047ad4 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 27fbd25cb3e..8518720d287 100644 --- a/src/terminal/parser/ut_parser/InputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/InputEngineTest.cpp @@ -94,7 +94,7 @@ class TestState 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 @@ class Microsoft::Console::VirtualTerminal::TestInteractDispatch final : public I _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 0b1d430e291..54e1b0377ba 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -44,7 +44,7 @@ class DummyDispatch final : public TermDispatch { } - 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 @@ class StatefulDispatch final : public TermDispatch { } - 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 @@ class StatefulDispatch final : public TermDispatch *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 @@ class StatefulDispatch final : public TermDispatch bool DeviceAttributes() override { - _fDeviceAttributes = true; + _deviceAttributes = true; return true; } @@ -801,7 +832,7 @@ class StatefulDispatch final : public TermDispatch 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 @@ class StatefulDispatch final : public TermDispatch 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 7235b1ecce0..046855d9ba3 100644 --- a/src/terminal/parser/ut_parser/StateMachineTest.cpp +++ b/src/terminal/parser/ut_parser/StateMachineTest.cpp @@ -31,46 +31,39 @@ class Microsoft::Console::VirtualTerminal::TestStateMachineEngine : public IStat 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);