diff --git a/.github/actions/spelling/allow/apis.txt b/.github/actions/spelling/allow/apis.txt index 83ca55178..572acd023 100644 --- a/.github/actions/spelling/allow/apis.txt +++ b/.github/actions/spelling/allow/apis.txt @@ -169,6 +169,7 @@ toupper TTask TVal UChar +UFIELD ULARGE UPDATEINIFILE userenv diff --git a/src/buffer/out/TextAttribute.cpp b/src/buffer/out/TextAttribute.cpp index b99c3121d..cefc7b6bc 100644 --- a/src/buffer/out/TextAttribute.cpp +++ b/src/buffer/out/TextAttribute.cpp @@ -128,22 +128,22 @@ bool TextAttribute::IsLegacy() const noexcept // - Calculates rgb colors based off of current color table and active modification attributes. // Arguments: // - colorTable: the current color table rgb values. -// - defaultFgColor: the default foreground color rgb value. -// - defaultBgColor: the default background color rgb value. +// - defaultFgIndex: the color table index of the default foreground color. +// - defaultBgIndex: the color table index of the default background color. // - reverseScreenMode: true if the screen mode is reversed. // - blinkingIsFaint: true if blinking should be interpreted as faint. (defaults to false) // - boldIsBright: true if "bold" should be interpreted as bright. (defaults to true) // Return Value: // - the foreground and background colors that should be displayed. -std::pair TextAttribute::CalculateRgbColors(const std::array& colorTable, - const COLORREF defaultFgColor, - const COLORREF defaultBgColor, +std::pair TextAttribute::CalculateRgbColors(const std::array& colorTable, + const size_t defaultFgIndex, + const size_t defaultBgIndex, const bool reverseScreenMode, const bool blinkingIsFaint, const bool boldIsBright) const noexcept { - auto fg = _foreground.GetColor(colorTable, defaultFgColor, boldIsBright && IsBold()); - auto bg = _background.GetColor(colorTable, defaultBgColor); + auto fg = _foreground.GetColor(colorTable, defaultFgIndex, boldIsBright && IsBold()); + auto bg = _background.GetColor(colorTable, defaultBgIndex); if (IsFaint() || (IsBlinking() && blinkingIsFaint)) { fg = (fg >> 1) & 0x7F7F7F; // Divide foreground color components by two. diff --git a/src/buffer/out/TextAttribute.hpp b/src/buffer/out/TextAttribute.hpp index e973a9cd3..54e143d14 100644 --- a/src/buffer/out/TextAttribute.hpp +++ b/src/buffer/out/TextAttribute.hpp @@ -64,9 +64,9 @@ public: static TextAttribute StripErroneousVT16VersionsOfLegacyDefaults(const TextAttribute& attribute) noexcept; WORD GetLegacyAttributes() const noexcept; - std::pair CalculateRgbColors(const std::array& colorTable, - const COLORREF defaultFgColor, - const COLORREF defaultBgColor, + std::pair CalculateRgbColors(const std::array& colorTable, + const size_t defaultFgIndex, + const size_t defaultBgIndex, const bool reverseScreenMode = false, const bool blinkingIsFaint = false, const bool boldIsBright = true) const noexcept; diff --git a/src/buffer/out/TextColor.cpp b/src/buffer/out/TextColor.cpp index 88bc8657f..e20195cea 100644 --- a/src/buffer/out/TextColor.cpp +++ b/src/buffer/out/TextColor.cpp @@ -139,14 +139,16 @@ void TextColor::SetDefault() noexcept // Arguments: // - colorTable: The table of colors we should use to look up the value of // an indexed attribute from. -// - defaultColor: The color value to use if we're a default attribute. +// - defaultIndex: The color table index to use if we're a default attribute. // - brighten: if true, we'll brighten a dark color table index. // Return Value: // - a COLORREF containing the real value of this TextColor. -COLORREF TextColor::GetColor(const std::array& colorTable, const COLORREF defaultColor, bool brighten) const noexcept +COLORREF TextColor::GetColor(const std::array& colorTable, const size_t defaultIndex, bool brighten) const noexcept { if (IsDefault()) { + const auto defaultColor = til::at(colorTable, defaultIndex); + if (brighten) { // See MSFT:20266024 for context on this fix. diff --git a/src/buffer/out/TextColor.h b/src/buffer/out/TextColor.h index 35b62ff65..75a8e7ae2 100644 --- a/src/buffer/out/TextColor.h +++ b/src/buffer/out/TextColor.h @@ -65,6 +65,11 @@ public: static constexpr BYTE BRIGHT_CYAN = 14; static constexpr BYTE BRIGHT_WHITE = 15; + static constexpr size_t DEFAULT_FOREGROUND = 256; + static constexpr size_t DEFAULT_BACKGROUND = 257; + static constexpr size_t CURSOR_COLOR = 258; + static constexpr size_t TABLE_SIZE = 259; + constexpr TextColor() noexcept : _meta{ ColorType::IsDefault }, _red{ 0 }, @@ -103,7 +108,7 @@ public: void SetIndex(const BYTE index, const bool isIndex256) noexcept; void SetDefault() noexcept; - COLORREF GetColor(const std::array& colorTable, const COLORREF defaultColor, bool brighten = false) const noexcept; + COLORREF GetColor(const std::array& colorTable, const size_t defaultIndex, bool brighten = false) const noexcept; BYTE GetLegacyIndex(const BYTE defaultIndex) const noexcept; constexpr BYTE GetIndex() const noexcept diff --git a/src/buffer/out/cursor.cpp b/src/buffer/out/cursor.cpp index 1d050a215..4a3aba783 100644 --- a/src/buffer/out/cursor.cpp +++ b/src/buffer/out/cursor.cpp @@ -27,9 +27,7 @@ Cursor::Cursor(const ULONG ulSize, TextBuffer& parentBuffer) noexcept : _fDeferCursorRedraw(false), _fHaveDeferredCursorRedraw(false), _ulSize(ulSize), - _cursorType(CursorType::Legacy), - _fUseColor(false), - _color(s_InvertCursorColor) + _cursorType(CursorType::Legacy) { } @@ -143,10 +141,9 @@ void Cursor::SetSize(const ULONG ulSize) noexcept _RedrawCursor(); } -void Cursor::SetStyle(const ULONG ulSize, const COLORREF color, const CursorType type) noexcept +void Cursor::SetStyle(const ULONG ulSize, const CursorType type) noexcept { _ulSize = ulSize; - _color = color; _cursorType = type; _RedrawCursor(); @@ -285,7 +282,6 @@ void Cursor::CopyProperties(const Cursor& OtherCursor) noexcept // Size will be handled separately in the resize operation. //_ulSize = OtherCursor._ulSize; _cursorType = OtherCursor._cursorType; - _color = OtherCursor._color; } void Cursor::DelayEOLWrap(const COORD coordDelayedAt) noexcept @@ -335,21 +331,6 @@ const CursorType Cursor::GetType() const noexcept return _cursorType; } -const bool Cursor::IsUsingColor() const noexcept -{ - return GetColor() != INVALID_COLOR; -} - -const COLORREF Cursor::GetColor() const noexcept -{ - return _color; -} - -void Cursor::SetColor(const unsigned int color) noexcept -{ - _color = gsl::narrow_cast(color); -} - void Cursor::SetType(const CursorType type) noexcept { _cursorType = type; diff --git a/src/buffer/out/cursor.h b/src/buffer/out/cursor.h index dbd05f535..ec0caa018 100644 --- a/src/buffer/out/cursor.h +++ b/src/buffer/out/cursor.h @@ -24,7 +24,6 @@ class TextBuffer; class Cursor final { public: - static const unsigned int s_InvertCursorColor = INVALID_COLOR; // the following values are used to create the textmode cursor. static constexpr unsigned int CURSOR_SMALL_SIZE = 25; // large enough to be one pixel on a six pixel font @@ -51,8 +50,6 @@ public: COORD GetPosition() const noexcept; const CursorType GetType() const noexcept; - const bool IsUsingColor() const noexcept; - const COLORREF GetColor() const noexcept; void StartDeferDrawing() noexcept; bool IsDeferDrawing() noexcept; @@ -67,7 +64,7 @@ public: void SetIsPopupShown(const bool fIsPopupShown) noexcept; void SetDelay(const bool fDelay) noexcept; void SetSize(const ULONG ulSize) noexcept; - void SetStyle(const ULONG ulSize, const COLORREF color, const CursorType type) noexcept; + void SetStyle(const ULONG ulSize, const CursorType type) noexcept; void SetPosition(const COORD cPosition) noexcept; void SetXPosition(const int NewX) noexcept; @@ -84,7 +81,6 @@ public: COORD GetDelayedAtPosition() const noexcept; bool IsDelayedEOLWrap() const noexcept; - void SetColor(const unsigned int color) noexcept; void SetType(const CursorType type) noexcept; private: @@ -117,6 +113,4 @@ private: void _RedrawCursorAlways() noexcept; CursorType _cursorType; - bool _fUseColor; - COLORREF _color; }; diff --git a/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp b/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp index 1b61955bb..e5153618e 100644 --- a/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp +++ b/src/buffer/out/ut_textbuffer/TextAttributeTests.cpp @@ -24,9 +24,11 @@ class TextAttributeTests TEST_METHOD(TestRoundtripDefaultColors); TEST_METHOD(TestBoldAsBright); - std::array _colorTable; - COLORREF _defaultFg = RGB(1, 2, 3); - COLORREF _defaultBg = RGB(4, 5, 6); + std::array _colorTable; + const COLORREF _defaultFg = RGB(1, 2, 3); + const COLORREF _defaultBg = RGB(4, 5, 6); + const size_t _defaultFgIndex = TextColor::DEFAULT_FOREGROUND; + const size_t _defaultBgIndex = TextColor::DEFAULT_BACKGROUND; }; bool TextAttributeTests::ClassSetup() @@ -47,6 +49,8 @@ bool TextAttributeTests::ClassSetup() _colorTable[13] = RGB(180, 0, 158); // Bright Magenta _colorTable[14] = RGB(249, 241, 165); // Bright Yellow _colorTable[15] = RGB(242, 242, 242); // White + _colorTable[_defaultFgIndex] = _defaultFg; + _colorTable[_defaultBgIndex] = _defaultBg; return true; } @@ -132,17 +136,17 @@ void TextAttributeTests::TestTextAttributeColorGetters() // values when reverse video is not set VERIFY_IS_FALSE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(red, green), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(red, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); // with reverse video set, calculated foreground/background values should be // switched while getters stay the same attr.SetReverseVideo(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(green, red), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(green, red), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); // reset the reverse video attr.SetReverseVideo(false); @@ -151,17 +155,17 @@ void TextAttributeTests::TestTextAttributeColorGetters() // while the background and getters stay the same attr.SetFaint(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(faintRed, green), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(faintRed, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); // with reverse video set, calculated foreground/background values should be // switched, and the background fainter, while getters stay the same attr.SetReverseVideo(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(green, faintRed), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(green, faintRed), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); // reset the reverse video and faint attributes attr.SetReverseVideo(false); @@ -171,17 +175,17 @@ void TextAttributeTests::TestTextAttributeColorGetters() // background, while getters stay the same attr.SetInvisible(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(green, green), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(green, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); // with reverse video set, the calculated background value should match // the foreground, while getters stay the same attr.SetReverseVideo(true); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(red, red), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(red, red), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); } void TextAttributeTests::TestReverseDefaultColors() @@ -194,34 +198,34 @@ void TextAttributeTests::TestReverseDefaultColors() // values when reverse video is not set VERIFY_IS_FALSE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); // with reverse video set, calculated foreground/background values should be // switched while getters stay the same attr.SetReverseVideo(true); VERIFY_IS_TRUE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, _defaultFg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, _defaultFg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); attr.SetForeground(red); VERIFY_IS_TRUE(attr.IsReverseVideo()); - VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, red), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(red, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultBg, red), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); attr.Invert(); VERIFY_IS_FALSE(attr.IsReverseVideo()); attr.SetDefaultForeground(); attr.SetBackground(green); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, green), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(green, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, green), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex)); } void TextAttributeTests::TestRoundtripDefaultColors() @@ -277,43 +281,43 @@ void TextAttributeTests::TestBoldAsBright() // values when not bold VERIFY_IS_FALSE(attr.IsBold()); - VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFg)); - VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBg)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); + VERIFY_ARE_EQUAL(_defaultFg, attr.GetForeground().GetColor(_colorTable, _defaultFgIndex)); + VERIFY_ARE_EQUAL(_defaultBg, attr.GetBackground().GetColor(_colorTable, _defaultBgIndex)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); // with bold set, calculated foreground/background values shouldn't change for the default colors. attr.SetBold(true); VERIFY_IS_TRUE(attr.IsBold()); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); + VERIFY_ARE_EQUAL(std::make_pair(_defaultFg, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); attr.SetIndexedForeground(TextColor::DARK_BLACK); VERIFY_IS_TRUE(attr.IsBold()); Log::Comment(L"Foreground should be bright black when bold is bright is enabled"); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); Log::Comment(L"Foreground should be dark black when bold is bright is disabled"); - VERIFY_ARE_EQUAL(std::make_pair(darkBlack, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, _defaultBg), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); attr.SetIndexedBackground(TextColor::DARK_GREEN); VERIFY_IS_TRUE(attr.IsBold()); Log::Comment(L"background should be unaffected by 'bold is bright'"); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); attr.SetBold(false); VERIFY_IS_FALSE(attr.IsBold()); Log::Comment(L"when not bold, 'bold is bright' changes nothing"); - VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); + VERIFY_ARE_EQUAL(std::make_pair(darkBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); Log::Comment(L"When set to a bright color, and bold, 'bold is bright' changes nothing"); attr.SetBold(true); attr.SetIndexedForeground(TextColor::BRIGHT_BLACK); VERIFY_IS_TRUE(attr.IsBold()); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, true)); - VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFg, _defaultBg, false, false, false)); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, true)); + VERIFY_ARE_EQUAL(std::make_pair(brightBlack, darkGreen), attr.CalculateRgbColors(_colorTable, _defaultFgIndex, _defaultBgIndex, false, false, false)); } diff --git a/src/buffer/out/ut_textbuffer/TextColorTests.cpp b/src/buffer/out/ut_textbuffer/TextColorTests.cpp index d419bfc33..829daf9d2 100644 --- a/src/buffer/out/ut_textbuffer/TextColorTests.cpp +++ b/src/buffer/out/ut_textbuffer/TextColorTests.cpp @@ -23,9 +23,11 @@ class TextColorTests TEST_METHOD(TestRgbColor); TEST_METHOD(TestChangeColor); - std::array _colorTable; - COLORREF _defaultFg = RGB(1, 2, 3); - COLORREF _defaultBg = RGB(4, 5, 6); + std::array _colorTable; + const COLORREF _defaultFg = RGB(1, 2, 3); + const COLORREF _defaultBg = RGB(4, 5, 6); + const size_t _defaultFgIndex = TextColor::DEFAULT_FOREGROUND; + const size_t _defaultBgIndex = TextColor::DEFAULT_BACKGROUND; }; bool TextColorTests::ClassSetup() @@ -46,6 +48,8 @@ bool TextColorTests::ClassSetup() _colorTable[13] = RGB(180, 0, 158); // Bright Magenta _colorTable[14] = RGB(249, 241, 165); // Bright Yellow _colorTable[15] = RGB(242, 242, 242); // White + _colorTable[_defaultFgIndex] = _defaultFg; + _colorTable[_defaultBgIndex] = _defaultBg; return true; } @@ -57,16 +61,16 @@ void TextColorTests::TestDefaultColor() VERIFY_IS_FALSE(defaultColor.IsLegacy()); VERIFY_IS_FALSE(defaultColor.IsRgb()); - auto color = defaultColor.GetColor(_colorTable, _defaultFg, false); + auto color = defaultColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(_defaultFg, color); - color = defaultColor.GetColor(_colorTable, _defaultFg, true); + color = defaultColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(_defaultFg, color); - color = defaultColor.GetColor(_colorTable, _defaultBg, false); + color = defaultColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(_defaultBg, color); - color = defaultColor.GetColor(_colorTable, _defaultBg, true); + color = defaultColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(_defaultBg, color); } @@ -78,16 +82,16 @@ void TextColorTests::TestDarkIndexColor() VERIFY_IS_TRUE(indexColor.IsLegacy()); VERIFY_IS_FALSE(indexColor.IsRgb()); - auto color = indexColor.GetColor(_colorTable, _defaultFg, false); + auto color = indexColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(_colorTable[7], color); - color = indexColor.GetColor(_colorTable, _defaultFg, true); + color = indexColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = indexColor.GetColor(_colorTable, _defaultBg, false); + color = indexColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(_colorTable[7], color); - color = indexColor.GetColor(_colorTable, _defaultBg, true); + color = indexColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); } @@ -99,16 +103,16 @@ void TextColorTests::TestBrightIndexColor() VERIFY_IS_TRUE(indexColor.IsLegacy()); VERIFY_IS_FALSE(indexColor.IsRgb()); - auto color = indexColor.GetColor(_colorTable, _defaultFg, false); + auto color = indexColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = indexColor.GetColor(_colorTable, _defaultFg, true); + color = indexColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = indexColor.GetColor(_colorTable, _defaultBg, false); + color = indexColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = indexColor.GetColor(_colorTable, _defaultBg, true); + color = indexColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); } @@ -121,16 +125,16 @@ void TextColorTests::TestRgbColor() VERIFY_IS_FALSE(rgbColor.IsLegacy()); VERIFY_IS_TRUE(rgbColor.IsRgb()); - auto color = rgbColor.GetColor(_colorTable, _defaultFg, false); + auto color = rgbColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(myColor, color); - color = rgbColor.GetColor(_colorTable, _defaultFg, true); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(myColor, color); - color = rgbColor.GetColor(_colorTable, _defaultBg, false); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(myColor, color); - color = rgbColor.GetColor(_colorTable, _defaultBg, true); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(myColor, color); } @@ -143,55 +147,55 @@ void TextColorTests::TestChangeColor() VERIFY_IS_FALSE(rgbColor.IsLegacy()); VERIFY_IS_TRUE(rgbColor.IsRgb()); - auto color = rgbColor.GetColor(_colorTable, _defaultFg, false); + auto color = rgbColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(myColor, color); - color = rgbColor.GetColor(_colorTable, _defaultFg, true); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(myColor, color); - color = rgbColor.GetColor(_colorTable, _defaultBg, false); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(myColor, color); - color = rgbColor.GetColor(_colorTable, _defaultBg, true); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(myColor, color); rgbColor.SetDefault(); - color = rgbColor.GetColor(_colorTable, _defaultFg, false); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(_defaultFg, color); - color = rgbColor.GetColor(_colorTable, _defaultFg, true); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(_defaultFg, color); - color = rgbColor.GetColor(_colorTable, _defaultBg, false); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(_defaultBg, color); - color = rgbColor.GetColor(_colorTable, _defaultBg, true); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(_defaultBg, color); rgbColor.SetIndex(7, false); - color = rgbColor.GetColor(_colorTable, _defaultFg, false); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(_colorTable[7], color); - color = rgbColor.GetColor(_colorTable, _defaultFg, true); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = rgbColor.GetColor(_colorTable, _defaultBg, false); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(_colorTable[7], color); - color = rgbColor.GetColor(_colorTable, _defaultBg, true); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); rgbColor.SetIndex(15, false); - color = rgbColor.GetColor(_colorTable, _defaultFg, false); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, false); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = rgbColor.GetColor(_colorTable, _defaultFg, true); + color = rgbColor.GetColor(_colorTable, _defaultFgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = rgbColor.GetColor(_colorTable, _defaultBg, false); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, false); VERIFY_ARE_EQUAL(_colorTable[15], color); - color = rgbColor.GetColor(_colorTable, _defaultBg, true); + color = rgbColor.GetColor(_colorTable, _defaultBgIndex, true); VERIFY_ARE_EQUAL(_colorTable[15], color); } diff --git a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp index 6a1a8282c..389d2ac76 100644 --- a/src/cascadia/PublicTerminalCore/HwndTerminal.cpp +++ b/src/cascadia/PublicTerminalCore/HwndTerminal.cpp @@ -239,8 +239,8 @@ HRESULT HwndTerminal::Initialize() _terminal->SetBackgroundCallback([](auto) {}); _terminal->Create(COORD{ 80, 25 }, 1000, *_renderer); - _terminal->SetDefaultBackground(RGB(12, 12, 12)); - _terminal->SetDefaultForeground(RGB(204, 204, 204)); + _terminal->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, RGB(12, 12, 12)); + _terminal->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, RGB(204, 204, 204)); _terminal->SetWriteInputCallback([=](std::wstring& input) noexcept { _WriteTextToConnection(input); }); localPointerToThread->EnablePainting(); @@ -781,8 +781,8 @@ void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR font { auto lock = publicTerminal->_terminal->LockForWriting(); - publicTerminal->_terminal->SetDefaultForeground(theme.DefaultForeground); - publicTerminal->_terminal->SetDefaultBackground(theme.DefaultBackground); + publicTerminal->_terminal->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, theme.DefaultForeground); + publicTerminal->_terminal->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, theme.DefaultBackground); publicTerminal->_renderEngine->SetSelectionBackground(theme.DefaultSelectionBackground, theme.SelectionBackgroundAlpha); // Set the font colors diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index b08e4c474..5f4dcb915 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1089,7 +1089,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation til::color ControlCore::BackgroundColor() const { - return _terminal->GetDefaultBackground(); + return _terminal->GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); } // Method Description: diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index 3f09cea8f..f8943c5cb 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -40,13 +40,10 @@ namespace Microsoft::Terminal::Core virtual bool WarningBell() noexcept = 0; virtual bool SetWindowTitle(std::wstring_view title) noexcept = 0; - virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept = 0; + virtual COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept = 0; + virtual bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept = 0; virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept = 0; - virtual bool SetCursorColor(const DWORD color) noexcept = 0; - - virtual bool SetDefaultForeground(const DWORD color) noexcept = 0; - virtual bool SetDefaultBackground(const DWORD color) noexcept = 0; virtual bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept = 0; diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 6f8d06453..b622e40e9 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -41,8 +41,6 @@ Terminal::Terminal() : _mutableViewport{ Viewport::Empty() }, _title{}, _colorTable{}, - _defaultFg{ RGB(255, 255, 255) }, - _defaultBg{ ARGB(0, 0, 0, 0) }, _screenReversed{ false }, _pfnWriteInput{ nullptr }, _scrollOffset{ 0 }, @@ -81,6 +79,10 @@ Terminal::Terminal() : _terminalInput = std::make_unique(passAlongInput); _InitializeColorTable(); + + _colorTable.at(TextColor::DEFAULT_FOREGROUND) = RGB(255, 255, 255); + _colorTable.at(TextColor::DEFAULT_BACKGROUND) = ARGB(0, 0, 0, 0); + _colorTable.at(TextColor::CURSOR_COLOR) = INVALID_COLOR; } void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, IRenderTarget& renderTarget) @@ -180,9 +182,13 @@ void Terminal::UpdateAppearance(const ICoreAppearance& appearance) { // Set the default background as transparent to prevent the // DX layer from overwriting the background image or acrylic effect - til::color newBackgroundColor{ appearance.DefaultBackground() }; - _defaultBg = newBackgroundColor.with_alpha(0); - _defaultFg = appearance.DefaultForeground(); + const til::color newBackgroundColor{ appearance.DefaultBackground() }; + _colorTable.at(TextColor::DEFAULT_BACKGROUND) = newBackgroundColor.with_alpha(0); + const til::color newForegroundColor{ appearance.DefaultForeground() }; + _colorTable.at(TextColor::DEFAULT_FOREGROUND) = newForegroundColor; + const til::color newCursorColor{ appearance.CursorColor() }; + _colorTable.at(TextColor::CURSOR_COLOR) = newCursorColor; + _intenseIsBright = appearance.IntenseIsBright(); _adjustIndistinguishableColors = appearance.AdjustIndistinguishableColors(); @@ -221,9 +227,7 @@ void Terminal::UpdateAppearance(const ICoreAppearance& appearance) if (_buffer) { - _buffer->GetCursor().SetStyle(appearance.CursorHeight(), - til::color{ appearance.CursorColor() }, - cursorShape); + _buffer->GetCursor().SetStyle(appearance.CursorHeight(), cursorShape); } _defaultCursorShape = cursorShape; diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 5a7b08751..1f8a67447 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -106,11 +106,9 @@ public: bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override; bool WarningBell() noexcept override; bool SetWindowTitle(std::wstring_view title) noexcept override; + COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept override; bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override; - bool SetCursorColor(const COLORREF color) noexcept override; - bool SetDefaultForeground(const COLORREF color) noexcept override; - bool SetDefaultBackground(const COLORREF color) noexcept override; bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept override; @@ -212,7 +210,6 @@ public: void ClearPatternTree() noexcept; const std::optional GetTabColor() const noexcept; - til::color GetDefaultBackground() const noexcept; Microsoft::Console::Render::BlinkingState& GetBlinkingState() const noexcept; @@ -281,9 +278,7 @@ private: std::optional _startingTabColor; // This is still stored as a COLORREF because it interacts with some code in ConTypes - std::array _colorTable; - til::color _defaultFg; - til::color _defaultBg; + std::array _colorTable; CursorType _defaultCursorShape; bool _screenReversed; mutable Microsoft::Console::Render::BlinkingState _blinkingState; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 455851ac8..52463987a 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -69,14 +69,6 @@ COORD Terminal::GetCursorPosition() noexcept return newPos; } -bool Terminal::SetCursorColor(const COLORREF color) noexcept -try -{ - _buffer->GetCursor().SetColor(color); - return true; -} -CATCH_RETURN_FALSE() - // Method Description: // - Moves the cursor down one line, and possibly also to the leftmost column. // Arguments: @@ -370,6 +362,22 @@ try } CATCH_RETURN_FALSE() +// Method Description: +// - Retrieves the value in the colortable at the specified index. +// Arguments: +// - tableIndex: the index of the color table to retrieve. +// Return Value: +// - the COLORREF value for the color at that index in the table. +COLORREF Terminal::GetColorTableEntry(const size_t tableIndex) const noexcept +try +{ + return _colorTable.at(tableIndex); +} +catch (...) +{ + return INVALID_COLOR; +} + // Method Description: // - Updates the value in the colortable at index tableIndex to the new color // color. color is a COLORREF, format 0x00BBGGRR. @@ -383,6 +391,11 @@ try { _colorTable.at(tableIndex) = color; + if (tableIndex == TextColor::DEFAULT_BACKGROUND) + { + _pfnBackgroundColorChanged(color); + } + // Repaint everything - the colors might have changed _buffer->GetRenderTarget().TriggerRedrawAll(); return true; @@ -442,46 +455,6 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) noex return true; } -// Method Description: -// - Updates the default foreground color from a COLORREF, format 0x00BBGGRR. -// Arguments: -// - color: the new COLORREF to use as the default foreground color -// Return Value: -// - true -bool Terminal::SetDefaultForeground(const COLORREF color) noexcept -try -{ - _defaultFg = color; - - // Repaint everything - the colors might have changed - _buffer->GetRenderTarget().TriggerRedrawAll(); - return true; -} -CATCH_RETURN_FALSE() - -// Method Description: -// - Updates the default background color from a COLORREF, format 0x00BBGGRR. -// Arguments: -// - color: the new COLORREF to use as the default background color -// Return Value: -// - true -bool Terminal::SetDefaultBackground(const COLORREF color) noexcept -try -{ - _defaultBg = color; - _pfnBackgroundColorChanged(color); - - // Repaint everything - the colors might have changed - _buffer->GetRenderTarget().TriggerRedrawAll(); - return true; -} -CATCH_RETURN_FALSE() - -til::color Terminal::GetDefaultBackground() const noexcept -{ - return _defaultBg; -} - bool Terminal::SetInputMode(const TerminalInput::Mode mode, const bool enabled) noexcept try { diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 414291cb0..215e495da 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -227,7 +227,7 @@ CATCH_LOG_RETURN_FALSE() bool TerminalDispatch::SetCursorColor(const DWORD color) noexcept try { - return _terminalApi.SetCursorColor(color); + return _terminalApi.SetColorTableEntry(TextColor::CURSOR_COLOR, color); } CATCH_LOG_RETURN_FALSE() @@ -247,7 +247,7 @@ CATCH_LOG_RETURN_FALSE() bool TerminalDispatch::SetDefaultForeground(const DWORD color) noexcept try { - return _terminalApi.SetDefaultForeground(color); + return _terminalApi.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, color); } CATCH_LOG_RETURN_FALSE() @@ -260,7 +260,7 @@ CATCH_LOG_RETURN_FALSE() bool TerminalDispatch::SetDefaultBackground(const DWORD color) noexcept try { - return _terminalApi.SetDefaultBackground(color); + return _terminalApi.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, color); } CATCH_LOG_RETURN_FALSE() diff --git a/src/cascadia/TerminalCore/terminalrenderdata.cpp b/src/cascadia/TerminalCore/terminalrenderdata.cpp index df3483ab0..4396f8d8a 100644 --- a/src/cascadia/TerminalCore/terminalrenderdata.cpp +++ b/src/cascadia/TerminalCore/terminalrenderdata.cpp @@ -73,19 +73,19 @@ std::pair Terminal::GetAttributeColors(const TextAttribute& if (attr.IsReverseVideo() ^ _screenReversed) { colors.first = _adjustedForegroundColors[fgIndex][bgIndex]; - colors.second = fgTextColor.GetColor(_colorTable, _defaultFg); + colors.second = fgTextColor.GetColor(_colorTable, TextColor::DEFAULT_FOREGROUND); } else { colors.first = _adjustedForegroundColors[bgIndex][fgIndex]; - colors.second = bgTextColor.GetColor(_colorTable, _defaultBg); + colors.second = bgTextColor.GetColor(_colorTable, TextColor::DEFAULT_BACKGROUND); } } else { colors = attr.CalculateRgbColors(_colorTable, - _defaultFg, - _defaultBg, + TextColor::DEFAULT_FOREGROUND, + TextColor::DEFAULT_BACKGROUND, _screenReversed, _blinkingState.IsBlinkingFaint(), _intenseIsBright); @@ -135,7 +135,7 @@ CursorType Terminal::GetCursorStyle() const noexcept COLORREF Terminal::GetCursorColor() const noexcept { - return _buffer->GetCursor().GetColor(); + return _colorTable.at(TextColor::CURSOR_COLOR); } bool Terminal::IsCursorDoubleWidth() const @@ -312,8 +312,8 @@ void Terminal::_MakeAdjustedColorArray() // to include the default background and default foreground colors std::array colorTableWithDefaults; std::copy_n(std::begin(_colorTable), 16, std::begin(colorTableWithDefaults)); - colorTableWithDefaults[DefaultBgIndex] = _defaultBg; - colorTableWithDefaults[DefaultFgIndex] = _defaultFg; + colorTableWithDefaults[DefaultBgIndex] = _colorTable.at(TextColor::DEFAULT_BACKGROUND); + colorTableWithDefaults[DefaultFgIndex] = _colorTable.at(TextColor::DEFAULT_FOREGROUND); for (auto fgIndex = 0; fgIndex < 18; ++fgIndex) { const auto fg = til::at(colorTableWithDefaults, fgIndex); diff --git a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp index 2145032fd..ae063f193 100644 --- a/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp +++ b/src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp @@ -96,9 +96,10 @@ class TerminalCoreUnitTests::ConptyRoundtripTests final auto& g = ServiceLocator::LocateGlobals(); auto& gci = g.getConsoleInformation(); - gci.SetDefaultForegroundColor(INVALID_COLOR); - gci.SetDefaultBackgroundColor(INVALID_COLOR); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, INVALID_COLOR); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, INVALID_COLOR); gci.SetFillAttribute(0x07); // DARK_WHITE on DARK_BLACK + gci.CalculateDefaultColorIndices(); m_state->PrepareNewTextBufferInfo(true, TerminalViewWidth, TerminalViewHeight); auto& currentBuffer = gci.GetActiveOutputBuffer(); diff --git a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp index acb85c492..8606be708 100644 --- a/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp @@ -59,7 +59,6 @@ void TerminalApiTest::SetColorTableEntry() VERIFY_IS_TRUE(term.SetColorTableEntry(128, 100)); VERIFY_IS_TRUE(term.SetColorTableEntry(255, 100)); - VERIFY_IS_FALSE(term.SetColorTableEntry(256, 100)); VERIFY_IS_FALSE(term.SetColorTableEntry(512, 100)); } diff --git a/src/host/consoleInformation.cpp b/src/host/consoleInformation.cpp index 51ed7de9b..8ace24178 100644 --- a/src/host/consoleInformation.cpp +++ b/src/host/consoleInformation.cpp @@ -219,36 +219,6 @@ InputBuffer* const CONSOLE_INFORMATION::GetActiveInputBuffer() const return pInputBuffer; } -// Method Description: -// - Return the default foreground color of the console. If the settings are -// configured to have a default foreground color (separate from the color -// table), this will return that value. Otherwise it will return the value -// from the colortable corresponding to our default attributes. -// Arguments: -// - -// Return Value: -// - the default foreground color of the console. -COLORREF CONSOLE_INFORMATION::GetDefaultForeground() const noexcept -{ - const auto fg = GetDefaultForegroundColor(); - return fg != INVALID_COLOR ? fg : GetLegacyColorTableEntry(LOBYTE(GetFillAttribute()) & FG_ATTRS); -} - -// Method Description: -// - Return the default background color of the console. If the settings are -// configured to have a default background color (separate from the color -// table), this will return that value. Otherwise it will return the value -// from the colortable corresponding to our default attributes. -// Arguments: -// - -// Return Value: -// - the default background color of the console. -COLORREF CONSOLE_INFORMATION::GetDefaultBackground() const noexcept -{ - const auto bg = GetDefaultBackgroundColor(); - return bg != INVALID_COLOR ? bg : GetLegacyColorTableEntry((LOBYTE(GetFillAttribute()) & BG_ATTRS) >> 4); -} - // Method Description: // - Get the colors of a particular text attribute, using our color table, // and our configured default attributes. @@ -257,26 +227,12 @@ COLORREF CONSOLE_INFORMATION::GetDefaultBackground() const noexcept // Return Value: // - The color values of the attribute's foreground and background. std::pair CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr) const noexcept -{ - return LookupAttributeColors(attr, GetDefaultForeground(), GetDefaultBackground()); -} - -// Method Description: -// - Get the colors of a particular text attribute, using our color table, -// and the given default color values. -// Arguments: -// - attr: the TextAttribute to retrieve the foreground and background color of. -// - defaultFg: the COLORREF to use for a default foreground color. -// - defaultBg: the COLORREF to use for a default background color. -// Return Value: -// - The color values of the attribute's foreground and background. -std::pair CONSOLE_INFORMATION::LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept { _blinkingState.RecordBlinkingUsage(attr); return attr.CalculateRgbColors( GetColorTable(), - defaultFg, - defaultBg, + GetDefaultForegroundIndex(), + GetDefaultBackgroundIndex(), IsScreenReversed(), _blinkingState.IsBlinkingFaint()); } diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 4f85d4a5b..7e894c161 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -1499,12 +1499,6 @@ void DoSrvSetCursorStyle(SCREEN_INFORMATION& screenInfo, screenInfo.GetActiveBuffer().GetTextBuffer().GetCursor().SetType(cursorType); } -void DoSrvSetCursorColor(SCREEN_INFORMATION& screenInfo, - const COLORREF cursorColor) -{ - screenInfo.GetActiveBuffer().GetTextBuffer().GetCursor().SetColor(cursorColor); -} - void DoSrvAddHyperlink(SCREEN_INFORMATION& screenInfo, const std::wstring_view uri, const std::wstring_view params) @@ -1963,115 +1957,6 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo) screenInfo.GetActiveBuffer().MoveToBottom(); } -// Method Description: -// - Retrieve the color table value at the specified index. -// Arguments: -// - index: the index in the table to retrieve. -// - value: receives the RGB value for the color at that index in the table. -// Return Value: -// - E_INVALIDARG if index is >= 256, else S_OK -[[nodiscard]] HRESULT DoSrvPrivateGetColorTableEntry(const size_t index, COLORREF& value) noexcept -{ - RETURN_HR_IF(E_INVALIDARG, index >= 256); - try - { - Globals& g = ServiceLocator::LocateGlobals(); - CONSOLE_INFORMATION& gci = g.getConsoleInformation(); - - value = gci.GetColorTableEntry(index); - - return S_OK; - } - CATCH_RETURN(); -} - -// Method Description: -// - Sets the color table value in index to the color specified in value. -// Can be used to set the 256-color table as well as the 16-color table. -// Arguments: -// - index: the index in the table to change. -// - value: the new RGB value to use for that index in the color table. -// Return Value: -// - E_INVALIDARG if index is >= 256, else S_OK -// Notes: -// Does not take a buffer parameter. The color table for a console and for -// terminals as well is global, not per-screen-buffer. -[[nodiscard]] HRESULT DoSrvPrivateSetColorTableEntry(const size_t index, const COLORREF value) noexcept -{ - RETURN_HR_IF(E_INVALIDARG, index >= 256); - try - { - Globals& g = ServiceLocator::LocateGlobals(); - CONSOLE_INFORMATION& gci = g.getConsoleInformation(); - - gci.SetColorTableEntry(index, value); - - // Update the screen colors if we're not a pty - // No need to force a redraw in pty mode. - if (g.pRender && !gci.IsInVtIoMode()) - { - g.pRender->TriggerRedrawAll(); - } - - return S_OK; - } - CATCH_RETURN(); -} - -// Method Description: -// - Sets the default foreground color to the color specified in value. -// Arguments: -// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. -// Return Value: -// - S_OK -[[nodiscard]] HRESULT DoSrvPrivateSetDefaultForegroundColor(const COLORREF value) noexcept -{ - try - { - Globals& g = ServiceLocator::LocateGlobals(); - CONSOLE_INFORMATION& gci = g.getConsoleInformation(); - - gci.SetDefaultForegroundColor(value); - - // Update the screen colors if we're not a pty - // No need to force a redraw in pty mode. - if (g.pRender && !gci.IsInVtIoMode()) - { - g.pRender->TriggerRedrawAll(); - } - - return S_OK; - } - CATCH_RETURN(); -} - -// Method Description: -// - Sets the default background color to the color specified in value. -// Arguments: -// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. -// Return Value: -// - S_OK -[[nodiscard]] HRESULT DoSrvPrivateSetDefaultBackgroundColor(const COLORREF value) noexcept -{ - try - { - Globals& g = ServiceLocator::LocateGlobals(); - CONSOLE_INFORMATION& gci = g.getConsoleInformation(); - - gci.SetDefaultBackgroundColor(value); - - // Update the screen colors if we're not a pty - // No need to force a redraw in pty mode. - if (g.pRender && !gci.IsInVtIoMode()) - { - g.pRender->TriggerRedrawAll(); - } - - return S_OK; - } - CATCH_RETURN(); -} - // Routine Description: // - A private API call for filling a region of the screen buffer. // Arguments: diff --git a/src/host/getset.h b/src/host/getset.h index 5a084d206..3ffe0a561 100644 --- a/src/host/getset.h +++ b/src/host/getset.h @@ -36,8 +36,6 @@ void DoSrvPrivateUseMainScreenBuffer(SCREEN_INFORMATION& screenInfo); void DoSrvSetCursorStyle(SCREEN_INFORMATION& screenInfo, const CursorType cursorType); -void DoSrvSetCursorColor(SCREEN_INFORMATION& screenInfo, - const COLORREF cursorColor); void DoSrvAddHyperlink(SCREEN_INFORMATION& screenInfo, const std::wstring_view uri, @@ -63,13 +61,6 @@ void DoSrvPrivateInsertLines(const size_t count); void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo); -[[nodiscard]] HRESULT DoSrvPrivateGetColorTableEntry(const size_t index, COLORREF& value) noexcept; -[[nodiscard]] HRESULT DoSrvPrivateSetColorTableEntry(const size_t index, const COLORREF value) noexcept; - -[[nodiscard]] HRESULT DoSrvPrivateSetDefaultForegroundColor(const COLORREF value) noexcept; - -[[nodiscard]] HRESULT DoSrvPrivateSetDefaultBackgroundColor(const COLORREF value) noexcept; - [[nodiscard]] HRESULT DoSrvPrivateFillRegion(SCREEN_INFORMATION& screenInfo, const COORD startPosition, const size_t fillLength, diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index 8ef3f44b5..cfeaa4245 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -552,21 +552,6 @@ bool ConhostInternalGetSet::PrivateSuppressResizeRepaint() return SUCCEEDED(DoSrvPrivateSuppressResizeRepaint()); } -// Routine Description: -// - Connects the SetCursorStyle call directly into our Driver Message servicing call inside Conhost.exe -// 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: -// - 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) -{ - DoSrvSetCursorColor(_io.GetActiveOutputBuffer(), cursorColor); - return true; -} - // Routine Description: // - Connects the IsConsolePty call directly into our Driver Message servicing call inside Conhost.exe // - NOTE: This ONE method behaves differently! The rest of the methods on this @@ -608,54 +593,61 @@ bool ConhostInternalGetSet::MoveToBottom() const } // Method Description: -// - Connects the PrivateGetColorTableEntry call directly into our Driver Message servicing -// call inside Conhost.exe +// - Retrieves the value in the colortable at the specified index. // Arguments: -// - index: the index in the table to retrieve. -// - value: receives the RGB value for the color at that index in the table. +// - tableIndex: the index of the color table to retrieve. // Return Value: -// - true if successful (see DoSrvPrivateGetColorTableEntry). false otherwise. -bool ConhostInternalGetSet::PrivateGetColorTableEntry(const size_t index, COLORREF& value) const noexcept +// - the COLORREF value for the color at that index in the table. +COLORREF ConhostInternalGetSet::GetColorTableEntry(const size_t tableIndex) const noexcept +try { - return SUCCEEDED(DoSrvPrivateGetColorTableEntry(index, value)); + auto& g = ServiceLocator::LocateGlobals(); + auto& gci = g.getConsoleInformation(); + + return gci.GetColorTableEntry(tableIndex); +} +catch (...) +{ + return INVALID_COLOR; } // Method Description: -// - Connects the PrivateSetColorTableEntry call directly into our Driver Message servicing -// call inside Conhost.exe +// - Updates the value in the colortable at index tableIndex to the new color +// color. color is a COLORREF, format 0x00BBGGRR. // Arguments: -// - index: the index in the table to change. -// - value: the new RGB value to use for that index in the color table. +// - tableIndex: the index of the color table to update. +// - color: the new COLORREF to use as that color table value. // Return Value: -// - true if successful (see DoSrvPrivateSetColorTableEntry). false otherwise. -bool ConhostInternalGetSet::PrivateSetColorTableEntry(const size_t index, const COLORREF value) const noexcept +// - true if successful. false otherwise. +bool ConhostInternalGetSet::SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept +try { - return SUCCEEDED(DoSrvPrivateSetColorTableEntry(index, value)); -} + auto& g = ServiceLocator::LocateGlobals(); + auto& gci = g.getConsoleInformation(); -// Method Description: -// - Connects the PrivateSetDefaultForeground call directly into our Driver Message servicing -// call inside Conhost.exe -// 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 -{ - return SUCCEEDED(DoSrvPrivateSetDefaultForegroundColor(value)); -} + gci.SetColorTableEntry(tableIndex, color); -// Method Description: -// - Connects the PrivateSetDefaultBackground call directly into our Driver Message servicing -// call inside Conhost.exe -// 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 -{ - return SUCCEEDED(DoSrvPrivateSetDefaultBackgroundColor(value)); + // If we're setting the default foreground or background colors + // we need to make sure the index is correctly set as well. + if (tableIndex == TextColor::DEFAULT_FOREGROUND) + { + gci.SetDefaultForegroundIndex(TextColor::DEFAULT_FOREGROUND); + } + if (tableIndex == TextColor::DEFAULT_BACKGROUND) + { + gci.SetDefaultBackgroundIndex(TextColor::DEFAULT_BACKGROUND); + } + + // Update the screen colors if we're not a pty + // No need to force a redraw in pty mode. + if (g.pRender && !gci.IsInVtIoMode()) + { + g.pRender->TriggerRedrawAll(); + } + + return true; } +CATCH_RETURN_FALSE() // Routine Description: // - Connects the PrivateFillRegion call directly into our Driver Message servicing diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index d019e3efa..70d980011 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -101,7 +101,6 @@ public: bool GetUserDefaultCursorStyle(CursorType& style) override; bool SetCursorStyle(CursorType const style) override; - bool SetCursorColor(COLORREF const color) override; bool PrivateRefreshWindow() override; @@ -119,12 +118,8 @@ public: bool MoveToBottom() const override; - bool PrivateGetColorTableEntry(const size_t index, COLORREF& value) const noexcept override; - bool PrivateSetColorTableEntry(const size_t index, const COLORREF value) const noexcept override; - - bool PrivateSetDefaultForeground(const COLORREF value) const noexcept override; - - bool PrivateSetDefaultBackground(const COLORREF value) const noexcept override; + COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept override; + bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override; bool PrivateFillRegion(const COORD startPosition, const size_t fillLength, diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index 1eb6090d7..8bb8f9daf 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -110,8 +110,6 @@ void RenderData::UnlockConsole() noexcept const TextAttribute RenderData::GetDefaultBrushColors() noexcept { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - _defaultForeground = gci.GetDefaultForeground(); - _defaultBackground = gci.GetDefaultBackground(); return gci.GetActiveOutputBuffer().GetAttributes(); } @@ -226,8 +224,7 @@ ULONG RenderData::GetCursorPixelWidth() const noexcept COLORREF RenderData::GetCursorColor() const noexcept { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - const auto& cursor = gci.GetActiveOutputBuffer().GetTextBuffer().GetCursor(); - return cursor.GetColor(); + return gci.GetColorTableEntry(TextColor::CURSOR_COLOR); } // Routine Description: @@ -364,7 +361,7 @@ const std::vector RenderData::GetPatternId(const COORD /*location*/) con std::pair RenderData::GetAttributeColors(const TextAttribute& attr) const noexcept { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - return gci.LookupAttributeColors(attr, _defaultForeground, _defaultBackground); + return gci.LookupAttributeColors(attr); } #pragma endregion diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index 9b5ab7f6d..f75cbb5b6 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -72,8 +72,4 @@ public: void ColorSelection(const COORD coordSelectionStart, const COORD coordSelectionEnd, const TextAttribute attr); const bool IsUiaDataInitialized() const noexcept override { return true; } #pragma endregion - -private: - COLORREF _defaultForeground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 7); - COLORREF _defaultBackground = gsl::at(Microsoft::Console::Utils::CampbellColorTable(), 0); }; diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index cc06df4ca..eb5a8b6e2 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -123,7 +123,6 @@ SCREEN_INFORMATION::~SCREEN_INFORMATION() pScreen->_renderTarget); const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - pScreen->_textBuffer->GetCursor().SetColor(gci.GetCursorColor()); pScreen->_textBuffer->GetCursor().SetType(gci.GetCursorType()); const NTSTATUS status = pScreen->_InitializeOutputStateMachine(); @@ -1630,29 +1629,6 @@ void SCREEN_INFORMATION::SetCursorInformation(const ULONG Size, } } -// Routine Description: -// - This routine sets the cursor color. Also updates the cursor information of -// this buffer's main buffer, if this buffer is an alt buffer. -// Arguments: -// - Color - The new color to set the cursor to -// - setMain - If true, propagate change to main buffer as well. -// Return Value: -// - None -void SCREEN_INFORMATION::SetCursorColor(const unsigned int Color, const bool setMain) noexcept -{ - Cursor& cursor = _textBuffer->GetCursor(); - - cursor.SetColor(Color); - - // If we're an alt buffer, DON'T propagate this setting up to the main buffer. - // We don't want to pollute that buffer with this state, - // UNLESS we're getting called from the propsheet, then we DO want to update this. - if (_psiMainBuffer && setMain) - { - _psiMainBuffer->SetCursorColor(Color); - } -} - // Routine Description: // - This routine sets the cursor shape both in the data // structures and on the screen. Also updates the cursor information of @@ -1908,7 +1884,7 @@ const SCREEN_INFORMATION& SCREEN_INFORMATION::GetMainBuffer() const auto& myCursor = GetTextBuffer().GetCursor(); auto* const createdBuffer = *ppsiNewScreenBuffer; auto& altCursor = createdBuffer->GetTextBuffer().GetCursor(); - altCursor.SetStyle(myCursor.GetSize(), myCursor.GetColor(), myCursor.GetType()); + altCursor.SetStyle(myCursor.GetSize(), myCursor.GetType()); altCursor.SetIsVisible(myCursor.IsVisible()); altCursor.SetBlinkingAllowed(myCursor.IsBlinkingAllowed()); // The new position should match the viewport-relative position of the main buffer. @@ -2006,7 +1982,7 @@ void SCREEN_INFORMATION::UseMainScreenBuffer() // Copy the alt buffer's cursor style and visibility back to the main buffer. const auto& altCursor = psiAlt->GetTextBuffer().GetCursor(); auto& mainCursor = psiMain->GetTextBuffer().GetCursor(); - mainCursor.SetStyle(altCursor.GetSize(), altCursor.GetColor(), altCursor.GetType()); + mainCursor.SetStyle(altCursor.GetSize(), altCursor.GetType()); mainCursor.SetIsVisible(altCursor.IsVisible()); mainCursor.SetBlinkingAllowed(altCursor.IsBlinkingAllowed()); diff --git a/src/host/screenInfo.hpp b/src/host/screenInfo.hpp index e3b1eed4d..740dbb53f 100644 --- a/src/host/screenInfo.hpp +++ b/src/host/screenInfo.hpp @@ -189,8 +189,6 @@ public: void SetCursorInformation(const ULONG Size, const bool Visible) noexcept; - void SetCursorColor(const unsigned int Color, const bool setMain = false) noexcept; - void SetCursorType(const CursorType Type, const bool setMain = false) noexcept; void SetCursorDBMode(const bool DoubleCursor); diff --git a/src/host/selection.cpp b/src/host/selection.cpp index 90bb5668f..0b1e0c5f5 100644 --- a/src/host/selection.cpp +++ b/src/host/selection.cpp @@ -16,7 +16,6 @@ Selection::Selection() : _fSelectionVisible(false), _ulSavedCursorSize(0), _fSavedCursorVisible(false), - _savedCursorColor(INVALID_COLOR), _savedCursorType(CursorType::Legacy), _dwSelectionFlags(0), _fLineSelection(true), diff --git a/src/host/selection.hpp b/src/host/selection.hpp index 34dc872d8..9f7865214 100644 --- a/src/host/selection.hpp +++ b/src/host/selection.hpp @@ -174,7 +174,6 @@ private: COORD _coordSavedCursorPosition; ULONG _ulSavedCursorSize; bool _fSavedCursorVisible; - COLORREF _savedCursorColor; CursorType _savedCursorType; #ifdef UNIT_TESTING diff --git a/src/host/selectionState.cpp b/src/host/selectionState.cpp index af82bd764..8a8705fee 100644 --- a/src/host/selectionState.cpp +++ b/src/host/selectionState.cpp @@ -168,7 +168,6 @@ void Selection::_SaveCursorData(const Cursor& cursor) noexcept _coordSavedCursorPosition = cursor.GetPosition(); _ulSavedCursorSize = cursor.GetSize(); _fSavedCursorVisible = cursor.IsVisible(); - _savedCursorColor = cursor.GetColor(); _savedCursorType = cursor.GetType(); } @@ -182,7 +181,6 @@ void Selection::_RestoreDataToCursor(Cursor& cursor) noexcept { cursor.SetSize(_ulSavedCursorSize); cursor.SetIsVisible(_fSavedCursorVisible); - cursor.SetColor(_savedCursorColor); cursor.SetType(_savedCursorType); cursor.SetIsOn(true); cursor.SetPosition(_coordSavedCursorPosition); diff --git a/src/host/server.h b/src/host/server.h index 2d8fa0d15..cd6baf493 100644 --- a/src/host/server.h +++ b/src/host/server.h @@ -124,10 +124,7 @@ public: COOKED_READ_DATA& CookedReadData() noexcept; void SetCookedReadData(COOKED_READ_DATA* readData) noexcept; - COLORREF GetDefaultForeground() const noexcept; - COLORREF GetDefaultBackground() const noexcept; std::pair LookupAttributeColors(const TextAttribute& attr) const noexcept; - std::pair LookupAttributeColors(const TextAttribute& attr, const COLORREF defaultFg, const COLORREF defaultBg) const noexcept; void SetTitle(const std::wstring_view newTitle); void SetTitlePrefix(const std::wstring_view newTitlePrefix); diff --git a/src/host/settings.cpp b/src/host/settings.cpp index d59181668..cda78119d 100644 --- a/src/host/settings.cpp +++ b/src/host/settings.cpp @@ -56,8 +56,8 @@ Settings::Settings() : _fScreenReversed(false), // window size pixels initialized below _fInterceptCopyPaste(0), - _DefaultForeground(INVALID_COLOR), - _DefaultBackground(INVALID_COLOR), + _defaultForegroundIndex(TextColor::DARK_WHITE), + _defaultBackgroundIndex(TextColor::DARK_BLACK), _fUseDx(UseDx::Disabled), _fCopyColor(false) { @@ -78,11 +78,14 @@ Settings::Settings() : ZeroMemory((void*)&_FaceName, sizeof(_FaceName)); wcscpy_s(_FaceName, DEFAULT_TT_FONT_FACENAME); - _CursorColor = Cursor::s_InvertCursorColor; _CursorType = CursorType::Legacy; gsl::span tableView = { _colorTable.data(), _colorTable.size() }; ::Microsoft::Console::Utils::InitializeColorTable(tableView); + + _colorTable.at(TextColor::DEFAULT_FOREGROUND) = INVALID_COLOR; + _colorTable.at(TextColor::DEFAULT_BACKGROUND) = INVALID_COLOR; + _colorTable.at(TextColor::CURSOR_COLOR) = INVALID_COLOR; } // Routine Description: @@ -229,11 +232,11 @@ void Settings::InitFromStateInfo(_In_ PCONSOLE_STATE_INFO pStateInfo) _fCtrlKeyShortcutsDisabled = pStateInfo->fCtrlKeyShortcutsDisabled; _bLineSelection = pStateInfo->fLineSelection; _bWindowAlpha = pStateInfo->bWindowTransparency; - _CursorColor = pStateInfo->CursorColor; _CursorType = static_cast(pStateInfo->CursorType); _fInterceptCopyPaste = pStateInfo->InterceptCopyPaste; - _DefaultForeground = pStateInfo->DefaultForeground; - _DefaultBackground = pStateInfo->DefaultBackground; + _colorTable.at(TextColor::DEFAULT_FOREGROUND) = pStateInfo->DefaultForeground; + _colorTable.at(TextColor::DEFAULT_BACKGROUND) = pStateInfo->DefaultBackground; + _colorTable.at(TextColor::CURSOR_COLOR) = pStateInfo->CursorColor; _TerminalScrolling = pStateInfo->TerminalScrolling; } @@ -274,11 +277,11 @@ CONSOLE_STATE_INFO Settings::CreateConsoleStateInfo() const csi.fCtrlKeyShortcutsDisabled = _fCtrlKeyShortcutsDisabled; csi.fLineSelection = _bLineSelection; csi.bWindowTransparency = _bWindowAlpha; - csi.CursorColor = _CursorColor; csi.CursorType = static_cast(_CursorType); csi.InterceptCopyPaste = _fInterceptCopyPaste; - csi.DefaultForeground = _DefaultForeground; - csi.DefaultBackground = _DefaultBackground; + csi.DefaultForeground = _colorTable.at(TextColor::DEFAULT_FOREGROUND); + csi.DefaultBackground = _colorTable.at(TextColor::DEFAULT_BACKGROUND); + csi.CursorColor = _colorTable.at(TextColor::CURSOR_COLOR); csi.TerminalScrolling = _TerminalScrolling; return csi; } @@ -330,16 +333,22 @@ void Settings::Validate() WI_ClearAllFlags(_wFillAttribute, ~(FG_ATTRS | BG_ATTRS)); WI_ClearAllFlags(_wPopupFillAttribute, ~(FG_ATTRS | BG_ATTRS)); + const auto defaultForeground = _colorTable.at(TextColor::DEFAULT_FOREGROUND); + const auto defaultBackground = _colorTable.at(TextColor::DEFAULT_BACKGROUND); + const auto cursorColor = _colorTable.at(TextColor::CURSOR_COLOR); + // If the extended color options are set to invalid values (all the same color), reset them. - if (_CursorColor != Cursor::s_InvertCursorColor && _CursorColor == _DefaultBackground) + if (cursorColor != INVALID_COLOR && cursorColor == defaultBackground) { - _CursorColor = Cursor::s_InvertCursorColor; + // INVALID_COLOR is used to represent "Invert Colors" + _colorTable.at(TextColor::CURSOR_COLOR) = INVALID_COLOR; } - if (_DefaultForeground != INVALID_COLOR && _DefaultForeground == _DefaultBackground) + if (defaultForeground != INVALID_COLOR && defaultForeground == defaultBackground) { // INVALID_COLOR is used as an "unset" sentinel in future attribute functions. - _DefaultForeground = _DefaultBackground = INVALID_COLOR; + _colorTable.at(TextColor::DEFAULT_FOREGROUND) = INVALID_COLOR; + _colorTable.at(TextColor::DEFAULT_BACKGROUND) = INVALID_COLOR; // If the damaged settings _further_ propagated to the default fill attribute, fix it. if (_wFillAttribute == 0) { @@ -351,6 +360,8 @@ void Settings::Validate() // At this point the default fill attributes are fully initialized // so we can pass on the final colors to the TextAttribute class. TextAttribute::SetLegacyDefaultAttributes(_wFillAttribute); + // And calculate the position of the default colors in the color table. + CalculateDefaultColorIndices(); FAIL_FAST_IF(!(_dwWindowSize.X > 0)); FAIL_FAST_IF(!(_dwWindowSize.Y > 0)); @@ -760,21 +771,11 @@ COLORREF Settings::GetLegacyColorTableEntry(const size_t index) const return _colorTable.at(TextColor::TransposeLegacyIndex(index)); } -COLORREF Settings::GetCursorColor() const noexcept -{ - return _CursorColor; -} - CursorType Settings::GetCursorType() const noexcept { return _CursorType; } -void Settings::SetCursorColor(const COLORREF CursorColor) noexcept -{ - _CursorColor = CursorColor; -} - void Settings::SetCursorType(const CursorType cursorType) noexcept { _CursorType = cursorType; @@ -790,24 +791,35 @@ void Settings::SetInterceptCopyPaste(const bool interceptCopyPaste) noexcept _fInterceptCopyPaste = interceptCopyPaste; } -COLORREF Settings::GetDefaultForegroundColor() const noexcept +void Settings::CalculateDefaultColorIndices() noexcept { - return _DefaultForeground; + const auto foregroundColor = _colorTable.at(TextColor::DEFAULT_FOREGROUND); + const auto foregroundIndex = TextColor::TransposeLegacyIndex(_wFillAttribute & FG_ATTRS); + _defaultForegroundIndex = foregroundColor != INVALID_COLOR ? TextColor::DEFAULT_FOREGROUND : foregroundIndex; + + const auto backgroundColor = _colorTable.at(TextColor::DEFAULT_BACKGROUND); + const auto backgroundIndex = TextColor::TransposeLegacyIndex((_wFillAttribute & BG_ATTRS) >> 4); + _defaultBackgroundIndex = backgroundColor != INVALID_COLOR ? TextColor::DEFAULT_BACKGROUND : backgroundIndex; } -void Settings::SetDefaultForegroundColor(const COLORREF defaultForeground) noexcept +size_t Settings::GetDefaultForegroundIndex() const noexcept { - _DefaultForeground = defaultForeground; + return _defaultForegroundIndex; } -COLORREF Settings::GetDefaultBackgroundColor() const noexcept +void Settings::SetDefaultForegroundIndex(const size_t index) noexcept { - return _DefaultBackground; + _defaultForegroundIndex = index; } -void Settings::SetDefaultBackgroundColor(const COLORREF defaultBackground) noexcept +size_t Settings::GetDefaultBackgroundIndex() const noexcept { - _DefaultBackground = defaultBackground; + return _defaultBackgroundIndex; +} + +void Settings::SetDefaultBackgroundIndex(const size_t index) noexcept +{ + _defaultBackgroundIndex = index; } bool Settings::IsTerminalScrolling() const noexcept diff --git a/src/host/settings.hpp b/src/host/settings.hpp index 3963be4bc..3929b4df9 100644 --- a/src/host/settings.hpp +++ b/src/host/settings.hpp @@ -167,7 +167,7 @@ public: void SetHistoryNoDup(const bool fHistoryNoDup); // The first 16 items of the color table are the same as the 16-color palette. - inline const std::array& GetColorTable() const noexcept + inline const std::array& GetColorTable() const noexcept { return _colorTable; } @@ -177,20 +177,17 @@ public: void SetLegacyColorTableEntry(const size_t index, const COLORREF ColorValue); COLORREF GetLegacyColorTableEntry(const size_t index) const; - COLORREF GetCursorColor() const noexcept; CursorType GetCursorType() const noexcept; - - void SetCursorColor(const COLORREF CursorColor) noexcept; void SetCursorType(const CursorType cursorType) noexcept; bool GetInterceptCopyPaste() const noexcept; void SetInterceptCopyPaste(const bool interceptCopyPaste) noexcept; - COLORREF GetDefaultForegroundColor() const noexcept; - void SetDefaultForegroundColor(const COLORREF defaultForeground) noexcept; - - COLORREF GetDefaultBackgroundColor() const noexcept; - void SetDefaultBackgroundColor(const COLORREF defaultBackground) noexcept; + void CalculateDefaultColorIndices() noexcept; + size_t GetDefaultForegroundIndex() const noexcept; + void SetDefaultForegroundIndex(const size_t index) noexcept; + size_t GetDefaultBackgroundIndex() const noexcept; + void SetDefaultBackgroundIndex(const size_t index) noexcept; bool IsTerminalScrolling() const noexcept; void SetTerminalScrolling(const bool terminalScrollingEnabled) noexcept; @@ -242,20 +239,19 @@ private: UseDx _fUseDx; bool _fCopyColor; - std::array _colorTable; + std::array _colorTable; // this is used for the special STARTF_USESIZE mode. bool _fUseWindowSizePixels; COORD _dwWindowSizePixels; - // Technically a COLORREF, but using INVALID_COLOR as "Invert Colors" - unsigned int _CursorColor; CursorType _CursorType; bool _fInterceptCopyPaste; - COLORREF _DefaultForeground; - COLORREF _DefaultBackground; + size_t _defaultForegroundIndex; + size_t _defaultBackgroundIndex; + bool _TerminalScrolling; friend class RegistrySerialization; }; diff --git a/src/host/ut_host/ConptyOutputTests.cpp b/src/host/ut_host/ConptyOutputTests.cpp index d412fb562..80ea088ec 100644 --- a/src/host/ut_host/ConptyOutputTests.cpp +++ b/src/host/ut_host/ConptyOutputTests.cpp @@ -67,9 +67,10 @@ class ConptyOutputTests // Set up some sane defaults auto& g = ServiceLocator::LocateGlobals(); auto& gci = g.getConsoleInformation(); - gci.SetDefaultForegroundColor(INVALID_COLOR); - gci.SetDefaultBackgroundColor(INVALID_COLOR); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, INVALID_COLOR); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, INVALID_COLOR); gci.SetFillAttribute(0x07); // DARK_WHITE on DARK_BLACK + gci.CalculateDefaultColorIndices(); m_state->PrepareNewTextBufferInfo(true, TerminalViewWidth, TerminalViewHeight); auto& currentBuffer = gci.GetActiveOutputBuffer(); diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 1b65bfc2a..4d9381309 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -59,9 +59,10 @@ class ScreenBufferTests { // Set up some sane defaults CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.SetDefaultForegroundColor(INVALID_COLOR); - gci.SetDefaultBackgroundColor(INVALID_COLOR); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, INVALID_COLOR); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, INVALID_COLOR); gci.SetFillAttribute(0x07); // DARK_WHITE on DARK_BLACK + gci.CalculateDefaultColorIndices(); m_state->PrepareNewTextBufferInfo(); auto& currentBuffer = gci.GetActiveOutputBuffer(); @@ -359,12 +360,11 @@ void ScreenBufferTests::AlternateBufferCursorInheritanceTest() auto mainCursorPos = COORD{ 3, 5 }; auto mainCursorVisible = false; auto mainCursorSize = 33u; - auto mainCursorColor = RGB(1, 2, 3); auto mainCursorType = CursorType::DoubleUnderscore; auto mainCursorBlinking = false; mainCursor.SetPosition(mainCursorPos); mainCursor.SetIsVisible(mainCursorVisible); - mainCursor.SetStyle(mainCursorSize, mainCursorColor, mainCursorType); + mainCursor.SetStyle(mainCursorSize, mainCursorType); mainCursor.SetBlinkingAllowed(mainCursorBlinking); Log::Comment(L"Switch to the alternate buffer."); @@ -379,7 +379,6 @@ void ScreenBufferTests::AlternateBufferCursorInheritanceTest() VERIFY_ARE_EQUAL(mainCursorVisible, altCursor.IsVisible()); Log::Comment(L"Confirm the cursor style is inherited from the main buffer."); VERIFY_ARE_EQUAL(mainCursorSize, altCursor.GetSize()); - VERIFY_ARE_EQUAL(mainCursorColor, altCursor.GetColor()); VERIFY_ARE_EQUAL(mainCursorType, altCursor.GetType()); VERIFY_ARE_EQUAL(mainCursorBlinking, altCursor.IsBlinkingAllowed()); @@ -387,12 +386,11 @@ void ScreenBufferTests::AlternateBufferCursorInheritanceTest() auto altCursorPos = COORD{ 5, 3 }; auto altCursorVisible = true; auto altCursorSize = 66u; - auto altCursorColor = RGB(3, 2, 1); auto altCursorType = CursorType::EmptyBox; auto altCursorBlinking = true; altCursor.SetPosition(altCursorPos); altCursor.SetIsVisible(altCursorVisible); - altCursor.SetStyle(altCursorSize, altCursorColor, altCursorType); + altCursor.SetStyle(altCursorSize, altCursorType); altCursor.SetBlinkingAllowed(altCursorBlinking); Log::Comment(L"Switch back to the main buffer."); @@ -406,7 +404,6 @@ void ScreenBufferTests::AlternateBufferCursorInheritanceTest() VERIFY_ARE_EQUAL(altCursorVisible, mainCursor.IsVisible()); Log::Comment(L"Confirm the cursor style is inherited from the alt buffer."); VERIFY_ARE_EQUAL(altCursorSize, mainCursor.GetSize()); - VERIFY_ARE_EQUAL(altCursorColor, mainCursor.GetColor()); VERIFY_ARE_EQUAL(altCursorType, mainCursor.GetType()); VERIFY_ARE_EQUAL(altCursorBlinking, mainCursor.IsBlinkingAllowed()); } @@ -1388,8 +1385,9 @@ void ScreenBufferTests::VtScrollMarginsNewlineColor() const COLORREF yellow = RGB(255, 255, 0); const COLORREF magenta = RGB(255, 0, 255); - gci.SetDefaultForegroundColor(yellow); - gci.SetDefaultBackgroundColor(magenta); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, yellow); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, magenta); + gci.CalculateDefaultColorIndices(); const TextAttribute defaultAttrs = {}; si.SetAttributes(defaultAttrs); @@ -1741,7 +1739,6 @@ void ScreenBufferTests::ResizeCursorUnchanged() // Get initial cursor values const CursorType initialType = initialCursor.GetType(); const auto initialSize = initialCursor.GetSize(); - const COLORREF initialColor = initialCursor.GetColor(); // set our wrap mode accordingly - ResizeScreenBuffer will be smart enough // to call the appropriate implementation @@ -1756,10 +1753,8 @@ void ScreenBufferTests::ResizeCursorUnchanged() const auto& finalCursor = si.GetTextBuffer().GetCursor(); const CursorType finalType = finalCursor.GetType(); const auto finalSize = finalCursor.GetSize(); - const COLORREF finalColor = finalCursor.GetColor(); VERIFY_ARE_EQUAL(initialType, finalType); - VERIFY_ARE_EQUAL(initialColor, finalColor); VERIFY_ARE_EQUAL(initialSize, finalSize); } @@ -2122,7 +2117,6 @@ void ScreenBufferTests::TestAltBufferCursorState() // Validate that the cursor state was copied appropriately into the // alternate buffer VERIFY_ARE_EQUAL(mainCursor.GetSize(), altCursor.GetSize()); - VERIFY_ARE_EQUAL(mainCursor.GetColor(), altCursor.GetColor()); VERIFY_ARE_EQUAL(mainCursor.GetType(), altCursor.GetType()); } } @@ -2259,8 +2253,9 @@ void ScreenBufferTests::SetDefaultsIndividuallyBothDefault() COLORREF brightGreen = gci.GetColorTableEntry(TextColor::BRIGHT_GREEN); COLORREF darkBlue = gci.GetColorTableEntry(TextColor::DARK_BLUE); - gci.SetDefaultForegroundColor(yellow); - gci.SetDefaultBackgroundColor(magenta); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, yellow); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, magenta); + gci.CalculateDefaultColorIndices(); si.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); Log::Comment(NoThrowString().Format(L"Write 6 X's:")); @@ -2361,8 +2356,9 @@ void ScreenBufferTests::SetDefaultsTogether() COLORREF yellow = RGB(255, 255, 0); COLORREF color250 = gci.GetColorTableEntry(250); - gci.SetDefaultForegroundColor(yellow); - gci.SetDefaultBackgroundColor(magenta); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, yellow); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, magenta); + gci.CalculateDefaultColorIndices(); si.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); Log::Comment(NoThrowString().Format(L"Write 6 X's:")); @@ -2432,8 +2428,9 @@ void ScreenBufferTests::ReverseResetWithDefaultBackground() COLORREF magenta = RGB(255, 0, 255); - gci.SetDefaultForegroundColor(INVALID_COLOR); - gci.SetDefaultBackgroundColor(magenta); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, INVALID_COLOR); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, magenta); + gci.CalculateDefaultColorIndices(); si.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); Log::Comment(NoThrowString().Format(L"Write 3 X's:")); @@ -2501,7 +2498,8 @@ void ScreenBufferTests::BackspaceDefaultAttrs() COLORREF magenta = RGB(255, 0, 255); - gci.SetDefaultBackgroundColor(magenta); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, magenta); + gci.CalculateDefaultColorIndices(); si.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); Log::Comment(NoThrowString().Format(L"Write 2 X's, then backspace one.")); @@ -2564,7 +2562,8 @@ void ScreenBufferTests::BackspaceDefaultAttrsWriteCharsLegacy() COLORREF magenta = RGB(255, 0, 255); - gci.SetDefaultBackgroundColor(magenta); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, magenta); + gci.CalculateDefaultColorIndices(); si.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); Log::Comment(NoThrowString().Format(L"Write 2 X's, then backspace one.")); @@ -2632,7 +2631,8 @@ void ScreenBufferTests::BackspaceDefaultAttrsInPrompt() COLORREF magenta = RGB(255, 0, 255); - gci.SetDefaultBackgroundColor(magenta); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, magenta); + gci.CalculateDefaultColorIndices(); si.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); TextAttribute expectedDefaults{}; @@ -2889,15 +2889,15 @@ void ScreenBufferTests::SetDefaultForegroundColor() StateMachine& stateMachine = mainBuffer.GetStateMachine(); - COLORREF originalColor = gci.GetDefaultForegroundColor(); - COLORREF newColor = gci.GetDefaultForegroundColor(); + COLORREF originalColor = gci.GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); + COLORREF newColor = gci.GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); COLORREF testColor = RGB(0x33, 0x66, 0x99); VERIFY_ARE_NOT_EQUAL(originalColor, testColor); Log::Comment(L"Valid Hexadecimal Notation"); stateMachine.ProcessString(L"\x1b]10;rgb:33/66/99\x1b\\"); - newColor = gci.GetDefaultForegroundColor(); + newColor = gci.GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); VERIFY_ARE_EQUAL(testColor, newColor); Log::Comment(L"Valid Hexadecimal Notation"); @@ -2905,7 +2905,7 @@ void ScreenBufferTests::SetDefaultForegroundColor() testColor = RGB(0xff, 0xff, 0xff); stateMachine.ProcessString(L"\x1b]10;rgb:ff/ff/ff\x1b\\"); - newColor = gci.GetDefaultForegroundColor(); + newColor = gci.GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); VERIFY_ARE_EQUAL(testColor, newColor); Log::Comment(L"Invalid syntax"); @@ -2913,7 +2913,7 @@ void ScreenBufferTests::SetDefaultForegroundColor() testColor = RGB(153, 102, 51); stateMachine.ProcessString(L"\x1b]10;99/66/33\x1b\\"); - newColor = gci.GetDefaultForegroundColor(); + newColor = gci.GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); VERIFY_ARE_NOT_EQUAL(testColor, newColor); // it will, in fact leave the color the way it was VERIFY_ARE_EQUAL(originalColor, newColor); @@ -2934,15 +2934,15 @@ void ScreenBufferTests::SetDefaultBackgroundColor() StateMachine& stateMachine = mainBuffer.GetStateMachine(); - COLORREF originalColor = gci.GetDefaultBackgroundColor(); - COLORREF newColor = gci.GetDefaultBackgroundColor(); + COLORREF originalColor = gci.GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); + COLORREF newColor = gci.GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); COLORREF testColor = RGB(0x33, 0x66, 0x99); VERIFY_ARE_NOT_EQUAL(originalColor, testColor); Log::Comment(L"Valid Hexadecimal Notation"); stateMachine.ProcessString(L"\x1b]11;rgb:33/66/99\x1b\\"); - newColor = gci.GetDefaultBackgroundColor(); + newColor = gci.GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); VERIFY_ARE_EQUAL(testColor, newColor); Log::Comment(L"Valid Hexadecimal Notation"); @@ -2950,7 +2950,7 @@ void ScreenBufferTests::SetDefaultBackgroundColor() testColor = RGB(0xff, 0xff, 0xff); stateMachine.ProcessString(L"\x1b]11;rgb:ff/ff/ff\x1b\\"); - newColor = gci.GetDefaultBackgroundColor(); + newColor = gci.GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); VERIFY_ARE_EQUAL(testColor, newColor); Log::Comment(L"Invalid Syntax"); @@ -2958,7 +2958,7 @@ void ScreenBufferTests::SetDefaultBackgroundColor() testColor = RGB(153, 102, 51); stateMachine.ProcessString(L"\x1b]11;99/66/33\x1b\\"); - newColor = gci.GetDefaultBackgroundColor(); + newColor = gci.GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); VERIFY_ARE_NOT_EQUAL(testColor, newColor); // it will, in fact leave the color the way it was VERIFY_ARE_EQUAL(originalColor, newColor); diff --git a/src/inc/conattrs.hpp b/src/inc/conattrs.hpp index 8589590d4..0f542e436 100644 --- a/src/inc/conattrs.hpp +++ b/src/inc/conattrs.hpp @@ -37,4 +37,3 @@ enum class CursorType : unsigned int constexpr COLORREF INVALID_COLOR = 0xffffffff; constexpr WORD COLOR_TABLE_SIZE = 16; -constexpr WORD XTERM_COLOR_TABLE_SIZE = 256; diff --git a/src/interactivity/win32/Clipboard.cpp b/src/interactivity/win32/Clipboard.cpp index 8e05e7827..a1ca3bcf3 100644 --- a/src/interactivity/win32/Clipboard.cpp +++ b/src/interactivity/win32/Clipboard.cpp @@ -208,10 +208,8 @@ void Clipboard::StoreSelectionToClipboard(bool const copyFormatting) const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); const auto& buffer = gci.GetActiveOutputBuffer().GetTextBuffer(); - const auto defaultForeground = gci.GetDefaultForeground(); - const auto defaultBackground = gci.GetDefaultBackground(); const auto GetAttributeColors = [=, &gci](const auto& attr) { - return gci.LookupAttributeColors(attr, defaultForeground, defaultBackground); + return gci.LookupAttributeColors(attr); }; bool includeCRLF, trimTrailingWhitespace; @@ -276,9 +274,10 @@ void Clipboard::CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, if (fAlsoCopyFormatting) { - const auto& fontData = ServiceLocator::LocateGlobals().getConsoleInformation().GetActiveOutputBuffer().GetCurrentFont(); + const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + const auto& fontData = gci.GetActiveOutputBuffer().GetCurrentFont(); int const iFontHeightPoints = fontData.GetUnscaledSize().Y * 72 / ServiceLocator::LocateGlobals().dpi; - const COLORREF bgColor = ServiceLocator::LocateGlobals().getConsoleInformation().GetDefaultBackground(); + const COLORREF bgColor = gci.GetColorTableEntry(gci.GetDefaultBackgroundIndex()); std::string HTMLToPlaceOnClip = TextBuffer::GenHTML(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor); CopyToSystemClipboard(HTMLToPlaceOnClip, L"HTML Format"); diff --git a/src/interactivity/win32/menu.cpp b/src/interactivity/win32/menu.cpp index 9364e6364..b09eacf3b 100644 --- a/src/interactivity/win32/menu.cpp +++ b/src/interactivity/win32/menu.cpp @@ -315,7 +315,7 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults) const Cursor& cursor = ScreenInfo.GetTextBuffer().GetCursor(); pStateInfo->CursorSize = cursor.GetSize(); - pStateInfo->CursorColor = cursor.GetColor(); + pStateInfo->CursorColor = gci.GetColorTableEntry(TextColor::CURSOR_COLOR); pStateInfo->CursorType = static_cast(cursor.GetType()); // Retrieve small icon for use in displaying the dialog @@ -376,8 +376,8 @@ void Menu::s_ShowPropertiesDialog(HWND const hwnd, BOOL const Defaults) pStateInfo->InterceptCopyPaste = gci.GetInterceptCopyPaste(); // Get the properties from the settings - pStateInfo->DefaultForeground = gci.GetDefaultForegroundColor(); - pStateInfo->DefaultBackground = gci.GetDefaultBackgroundColor(); + pStateInfo->DefaultForeground = gci.GetColorTableEntry(TextColor::DEFAULT_FOREGROUND); + pStateInfo->DefaultBackground = gci.GetColorTableEntry(TextColor::DEFAULT_BACKGROUND); pStateInfo->TerminalScrolling = gci.IsTerminalScrolling(); // end console v2 properties @@ -461,13 +461,12 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo) // Set the cursor properties in the Settings const auto cursorType = static_cast(pStateInfo->CursorType); - gci.SetCursorColor(pStateInfo->CursorColor); gci.SetCursorType(cursorType); + gci.SetColorTableEntry(TextColor::CURSOR_COLOR, pStateInfo->CursorColor); // Then also apply them to the buffer's cursor ScreenInfo.SetCursorInformation(pStateInfo->CursorSize, ScreenInfo.GetTextBuffer().GetCursor().IsVisible()); - ScreenInfo.SetCursorColor(pStateInfo->CursorColor, true); ScreenInfo.SetCursorType(cursorType, true); gci.SetTerminalScrolling(pStateInfo->TerminalScrolling); @@ -579,11 +578,13 @@ void Menu::s_PropertiesUpdate(PCONSOLE_STATE_INFO pStateInfo) gci.SetFillAttribute(pStateInfo->ScreenAttributes); gci.SetPopupFillAttribute(pStateInfo->PopupAttributes); // Store our updated Default Color values - gci.SetDefaultForegroundColor(pStateInfo->DefaultForeground); - gci.SetDefaultBackgroundColor(pStateInfo->DefaultBackground); + gci.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, pStateInfo->DefaultForeground); + gci.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, pStateInfo->DefaultBackground); // Make sure the updated fill attributes are passed on to the TextAttribute class. TextAttribute::SetLegacyDefaultAttributes(pStateInfo->ScreenAttributes); + // And recalculate the position of the default colors in the color table. + gci.CalculateDefaultColorIndices(); // Set the screen info's default text attributes to defaults - ScreenInfo.SetDefaultAttributes({}, TextAttribute{ gci.GetPopupFillAttribute() }); diff --git a/src/propslib/RegistrySerialization.cpp b/src/propslib/RegistrySerialization.cpp index d9e9bcfbe..4c45ba05c 100644 --- a/src/propslib/RegistrySerialization.cpp +++ b/src/propslib/RegistrySerialization.cpp @@ -7,7 +7,7 @@ #pragma hdrstop -#define SET_FIELD_AND_SIZE(x) FIELD_OFFSET(Settings, x), RTL_FIELD_SIZE(Settings, x) +#define SET_FIELD_AND_SIZE(x) UFIELD_OFFSET(Settings, x), RTL_FIELD_SIZE(Settings, x) #define NT_TESTNULL(var) (((var) == nullptr) ? STATUS_NO_MEMORY : STATUS_SUCCESS) @@ -57,14 +57,14 @@ const RegistrySerialization::_RegPropertyMap RegistrySerialization::s_PropertyMa { _RegPropertyType::Boolean, CONSOLE_REGISTRY_TRIMZEROHEADINGS, SET_FIELD_AND_SIZE(_fTrimLeadingZeros) }, { _RegPropertyType::Boolean, CONSOLE_REGISTRY_ENABLE_COLOR_SELECTION, SET_FIELD_AND_SIZE(_fEnableColorSelection) }, { _RegPropertyType::Coordinate, CONSOLE_REGISTRY_WINDOWPOS, SET_FIELD_AND_SIZE(_dwWindowOrigin) }, - { _RegPropertyType::Dword, CONSOLE_REGISTRY_CURSORCOLOR, SET_FIELD_AND_SIZE(_CursorColor) }, { _RegPropertyType::Dword, CONSOLE_REGISTRY_CURSORTYPE, SET_FIELD_AND_SIZE(_CursorType) }, { _RegPropertyType::Boolean, CONSOLE_REGISTRY_INTERCEPTCOPYPASTE, SET_FIELD_AND_SIZE(_fInterceptCopyPaste) }, - { _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTFOREGROUND, SET_FIELD_AND_SIZE(_DefaultForeground) }, - { _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTBACKGROUND, SET_FIELD_AND_SIZE(_DefaultBackground) }, { _RegPropertyType::Boolean, CONSOLE_REGISTRY_TERMINALSCROLLING, SET_FIELD_AND_SIZE(_TerminalScrolling) }, { _RegPropertyType::Dword, CONSOLE_REGISTRY_USEDX, SET_FIELD_AND_SIZE(_fUseDx) }, - { _RegPropertyType::Boolean, CONSOLE_REGISTRY_COPYCOLOR, SET_FIELD_AND_SIZE(_fCopyColor) } + { _RegPropertyType::Boolean, CONSOLE_REGISTRY_COPYCOLOR, SET_FIELD_AND_SIZE(_fCopyColor) }, + { _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTFOREGROUND, SET_FIELD_AND_SIZE(_colorTable[TextColor::DEFAULT_FOREGROUND]) }, + { _RegPropertyType::Dword, CONSOLE_REGISTRY_DEFAULTBACKGROUND, SET_FIELD_AND_SIZE(_colorTable[TextColor::DEFAULT_BACKGROUND]) }, + { _RegPropertyType::Dword, CONSOLE_REGISTRY_CURSORCOLOR, SET_FIELD_AND_SIZE(_colorTable[TextColor::CURSOR_COLOR]) } }; const size_t RegistrySerialization::s_PropertyMappingsSize = ARRAYSIZE(s_PropertyMappings); diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index eef56cb83..18d81fd56 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -2250,7 +2250,7 @@ bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor) return false; } - return _pConApi->SetCursorColor(cursorColor); + return _pConApi->SetColorTableEntry(TextColor::CURSOR_COLOR, cursorColor); } // Routine Description: @@ -2273,7 +2273,7 @@ bool AdaptDispatch::SetClipboard(const std::wstring_view /*content*/) noexcept // True if handled successfully. False otherwise. bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) { - const bool success = _pConApi->PrivateSetColorTableEntry(tableIndex, dwColor); + const bool success = _pConApi->SetColorTableEntry(tableIndex, 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 @@ -2293,10 +2293,10 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo // - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR. // Return Value: // True if handled successfully. False otherwise. -bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultForeground(const DWORD dwColor) +bool AdaptDispatch::SetDefaultForeground(const DWORD dwColor) { bool success = true; - success = _pConApi->PrivateSetDefaultForeground(dwColor); + success = _pConApi->SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, 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 @@ -2316,10 +2316,10 @@ bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultForeground(co // - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR. // Return Value: // True if handled successfully. False otherwise. -bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultBackground(const DWORD dwColor) +bool AdaptDispatch::SetDefaultBackground(const DWORD dwColor) { bool success = true; - success = _pConApi->PrivateSetDefaultBackground(dwColor); + success = _pConApi->SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, 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 diff --git a/src/terminal/adapter/conGetSet.hpp b/src/terminal/adapter/conGetSet.hpp index 833e84b17..1c975e2d4 100644 --- a/src/terminal/adapter/conGetSet.hpp +++ b/src/terminal/adapter/conGetSet.hpp @@ -72,7 +72,6 @@ namespace Microsoft::Console::VirtualTerminal virtual bool PrivateClearBuffer() = 0; virtual bool GetUserDefaultCursorStyle(CursorType& style) = 0; virtual bool SetCursorStyle(const CursorType style) = 0; - virtual bool SetCursorColor(const COLORREF color) = 0; virtual bool PrivateWriteConsoleControlInput(const KeyEvent key) = 0; virtual bool PrivateRefreshWindow() = 0; @@ -87,10 +86,8 @@ namespace Microsoft::Console::VirtualTerminal virtual bool MoveToBottom() const = 0; - virtual bool PrivateGetColorTableEntry(const size_t index, COLORREF& value) const = 0; - virtual bool PrivateSetColorTableEntry(const size_t index, const COLORREF value) const = 0; - virtual bool PrivateSetDefaultForeground(const COLORREF value) const = 0; - virtual bool PrivateSetDefaultBackground(const COLORREF value) const = 0; + virtual COLORREF GetColorTableEntry(const size_t tableIndex) const = 0; + virtual bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) = 0; virtual bool PrivateFillRegion(const COORD startPosition, const size_t fillLength, diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index 98a1ab2c0..2f45b32a7 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -370,16 +370,6 @@ public: return _setCursorStyleResult; } - bool SetCursorColor(const COLORREF cursorColor) override - { - Log::Comment(L"SetCursorColor MOCK called..."); - if (_setCursorColorResult) - { - VERIFY_ARE_EQUAL(_expectedCursorColor, cursorColor); - } - return _setCursorColorResult; - } - bool PrivateRefreshWindow() override { Log::Comment(L"PrivateRefreshWindow MOCK called..."); @@ -438,53 +428,31 @@ public: return _moveToBottomResult; } - bool PrivateGetColorTableEntry(const size_t index, COLORREF& value) const noexcept override + COLORREF GetColorTableEntry(const size_t tableIndex) const noexcept override { - Log::Comment(L"PrivateGetColorTableEntry MOCK called..."); + Log::Comment(L"GetColorTableEntry MOCK called..."); - if (_privateGetColorTableEntryResult) + if (_getColorTableEntryResult) { - VERIFY_ARE_EQUAL(_expectedColorTableIndex, index); + VERIFY_ARE_EQUAL(_expectedColorTableIndex, tableIndex); // Simply returning the index as the color value makes it easy for // tests to confirm that they've received the color they expected. - value = gsl::narrow_cast(index); + return gsl::narrow_cast(tableIndex); } - return _privateGetColorTableEntryResult; + return INVALID_COLOR; } - bool PrivateSetColorTableEntry(const size_t index, const COLORREF value) const noexcept override + bool SetColorTableEntry(const size_t tableIndex, const COLORREF color) noexcept override { - Log::Comment(L"PrivateSetColorTableEntry MOCK called..."); - if (_privateSetColorTableEntryResult) + Log::Comment(L"SetColorTableEntry MOCK called..."); + if (_setColorTableEntryResult) { - VERIFY_ARE_EQUAL(_expectedColorTableIndex, index); - VERIFY_ARE_EQUAL(_expectedColorValue, value); + VERIFY_ARE_EQUAL(_expectedColorTableIndex, tableIndex); + VERIFY_ARE_EQUAL(_expectedColorValue, color); } - return _privateSetColorTableEntryResult; - } - - bool PrivateSetDefaultForeground(const COLORREF value) const noexcept override - { - Log::Comment(L"PrivateSetDefaultForeground MOCK called..."); - if (_privateSetDefaultForegroundResult) - { - VERIFY_ARE_EQUAL(_expectedDefaultForegroundColorValue, value); - } - - return _privateSetDefaultForegroundResult; - } - - bool PrivateSetDefaultBackground(const COLORREF value) const noexcept override - { - Log::Comment(L"PrivateSetDefaultForeground MOCK called..."); - if (_privateSetDefaultBackgroundResult) - { - VERIFY_ARE_EQUAL(_expectedDefaultBackgroundColorValue, value); - } - - return _privateSetDefaultBackgroundResult; + return _setColorTableEntryResult; } bool PrivateFillRegion(const COORD /*startPosition*/, @@ -739,23 +707,15 @@ public: std::wstring_view _expectedWindowTitle{}; bool _setCursorStyleResult = false; CursorType _expectedCursorStyle; - bool _setCursorColorResult = false; - COLORREF _expectedCursorColor = 0; bool _setConsoleOutputCPResult = false; bool _getConsoleOutputCPResult = false; bool _moveToBottomResult = false; - bool _privateGetColorTableEntryResult = false; - bool _privateSetColorTableEntryResult = false; + bool _getColorTableEntryResult = false; + bool _setColorTableEntryResult = false; size_t _expectedColorTableIndex = SIZE_MAX; COLORREF _expectedColorValue = INVALID_COLOR; - bool _privateSetDefaultForegroundResult = false; - COLORREF _expectedDefaultForegroundColorValue = INVALID_COLOR; - - bool _privateSetDefaultBackgroundResult = false; - COLORREF _expectedDefaultBackgroundColorValue = INVALID_COLOR; - SIZE _expectedCellSize = {}; private: @@ -2306,7 +2266,7 @@ public: VTParameter rgOptions[16]; size_t cOptions = 3; - _testGetSet->_privateGetColorTableEntryResult = true; + _testGetSet->_getColorTableEntryResult = true; _testGetSet->_expectedAttribute = _testGetSet->_attribute; Log::Comment(L"Test 1: Change Foreground"); @@ -2356,7 +2316,7 @@ public: VTParameter rgOptions[16]; - _testGetSet->_privateGetColorTableEntryResult = true; + _testGetSet->_getColorTableEntryResult = true; _testGetSet->_expectedAttribute = _testGetSet->_attribute; Log::Comment(L"Test 1: Change Indexed Foreground with missing index parameter"); @@ -2399,7 +2359,7 @@ public: { _testGetSet->PrepData(); - _testGetSet->_privateSetColorTableEntryResult = true; + _testGetSet->_setColorTableEntryResult = true; const auto testColor = RGB(1, 2, 3); _testGetSet->_expectedColorValue = testColor; @@ -2409,7 +2369,7 @@ public: VERIFY_IS_TRUE(_pDispatch.get()->SetColorTableEntry(i, testColor)); } - // Test in pty mode - we should fail, but PrivateSetColorTableEntry should still be called + // Test in pty mode - we should fail, but SetColorTableEntry should still be called _testGetSet->_isPty = true; _testGetSet->_expectedColorTableIndex = 15; // Windows BRIGHT_WHITE