Add support for querying Xterm dynamic colors and palette (#17729)
This pull request adds support for querying all of the "dynamic resource" colors (foreground, background, cursor) as well as the entire color palette using OSC 4, 10, 11 and 12 with the `?` color specifier. To ease integration and to make it easier to extend later, I have consolidated `SetDefaultForeground`, `SetDefaultBackground` and `SetCursorColor` into one function `SetXtermColorResource`, plus its analog `RequestXtermColorResource`. Those functions will map xterm resource OSC numbers to color table entries and optionally color _alias_ entries using a constant table. The alias mappings are required to support reassigning the default foreground and background to their indexed entries after a `DECAC`. While there are only three real entries in the mapping table right now, I have designs on bringing in selection background (xterm "highlight") and foreground (xterm "highlightText"). We can also extend this to support resetting via OSC 110-119. However, at the adapter layer we do not have the requisite information to restore any of the colors (even the cursor color!) to the user's defaults. `OSC 10` and `OSC 11` queries report the final values of `DECAC`-reassigned entries, under the assumption that an application asking for them wants to make a determination regardless of their internal meaning to us (that is: they read through the aliased color to its final destination in the color palette.) I've tested this with lsix, which detects the background color before generating sixel previews. It works great! ConPTY does not currently pass OSC sequences received on the input handle, so work was required to make it do so. Closes #3718
This commit is contained in:
parent
ce92b18507
commit
3b4ee83ed1
|
@ -22,6 +22,7 @@ vcvars\w*
|
||||||
ROY\sG\.\sBIV
|
ROY\sG\.\sBIV
|
||||||
!(?:(?i)ESC)!\[
|
!(?:(?i)ESC)!\[
|
||||||
!(?:(?i)CSI)!(?:\d+(?:;\d+|)m|[ABCDF])
|
!(?:(?i)CSI)!(?:\d+(?:;\d+|)m|[ABCDF])
|
||||||
|
(?i)rgb:[a-z0-9]{2,4}/[a-z0-9]{2,4}/[a-z0-9]{2,4}
|
||||||
|
|
||||||
# SSE intrinsics like "_mm_subs_epu16"
|
# SSE intrinsics like "_mm_subs_epu16"
|
||||||
\b_mm(?:|256|512)_\w+\b
|
\b_mm(?:|256|512)_\w+\b
|
||||||
|
|
|
@ -76,9 +76,10 @@ public:
|
||||||
virtual bool BackwardsTab(const VTInt numTabs) = 0; // CBT
|
virtual bool BackwardsTab(const VTInt numTabs) = 0; // CBT
|
||||||
virtual bool TabClear(const DispatchTypes::TabClearType clearType) = 0; // TBC
|
virtual bool TabClear(const DispatchTypes::TabClearType clearType) = 0; // TBC
|
||||||
virtual bool TabSet(const VTParameter setType) = 0; // DECST8C
|
virtual bool TabSet(const VTParameter setType) = 0; // DECST8C
|
||||||
virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; // OSCColorTable
|
virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; // OSCSetColorTable
|
||||||
virtual bool SetDefaultForeground(const DWORD color) = 0; // OSCDefaultForeground
|
virtual bool RequestColorTableEntry(const size_t tableIndex) = 0; // OSCGetColorTable
|
||||||
virtual bool SetDefaultBackground(const DWORD color) = 0; // OSCDefaultBackground
|
virtual bool SetXtermColorResource(const size_t resource, const DWORD color) = 0; // OSCSetDefaultForeground, OSCSetDefaultBackground, OSCSetCursorColor, OSCResetCursorColor
|
||||||
|
virtual bool RequestXtermColorResource(const size_t resource) = 0; // OSCGetDefaultForeground, OSCGetDefaultBackground, OSCGetCursorColor
|
||||||
virtual bool AssignColor(const DispatchTypes::ColorItem item, const VTInt fgIndex, const VTInt bgIndex) = 0; // DECAC
|
virtual bool AssignColor(const DispatchTypes::ColorItem item, const VTInt fgIndex, const VTInt bgIndex) = 0; // DECAC
|
||||||
|
|
||||||
virtual bool EraseInDisplay(const DispatchTypes::EraseType eraseType) = 0; // ED
|
virtual bool EraseInDisplay(const DispatchTypes::EraseType eraseType) = 0; // ED
|
||||||
|
@ -128,7 +129,6 @@ public:
|
||||||
virtual bool ScreenAlignmentPattern() = 0; // DECALN
|
virtual bool ScreenAlignmentPattern() = 0; // DECALN
|
||||||
|
|
||||||
virtual bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR
|
virtual bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR
|
||||||
virtual bool SetCursorColor(const COLORREF color) = 0; // OSCSetCursorColor, OSCResetCursorColor
|
|
||||||
|
|
||||||
virtual bool SetClipboard(wil::zwstring_view content) = 0; // OSCSetClipboard
|
virtual bool SetClipboard(wil::zwstring_view content) = 0; // OSCSetClipboard
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,25 @@ using namespace Microsoft::Console::VirtualTerminal;
|
||||||
|
|
||||||
static constexpr std::wstring_view whitespace{ L" " };
|
static constexpr std::wstring_view whitespace{ L" " };
|
||||||
|
|
||||||
|
struct XtermResourceColorTableEntry
|
||||||
|
{
|
||||||
|
int ColorTableIndex;
|
||||||
|
int AliasIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr std::array<XtermResourceColorTableEntry, 10> XtermResourceColorTableMappings{ {
|
||||||
|
/* 10 */ { TextColor::DEFAULT_FOREGROUND, static_cast<int>(ColorAlias::DefaultForeground) },
|
||||||
|
/* 11 */ { TextColor::DEFAULT_BACKGROUND, static_cast<int>(ColorAlias::DefaultBackground) },
|
||||||
|
/* 12 */ { TextColor::CURSOR_COLOR, -1 },
|
||||||
|
/* 13 */ { -1, -1 },
|
||||||
|
/* 14 */ { -1, -1 },
|
||||||
|
/* 15 */ { -1, -1 },
|
||||||
|
/* 16 */ { -1, -1 },
|
||||||
|
/* 17 */ { -1, -1 },
|
||||||
|
/* 18 */ { -1, -1 },
|
||||||
|
/* 19 */ { -1, -1 },
|
||||||
|
} };
|
||||||
|
|
||||||
AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept :
|
AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept :
|
||||||
_api{ api },
|
_api{ api },
|
||||||
_renderer{ renderer },
|
_renderer{ renderer },
|
||||||
|
@ -3446,18 +3465,6 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
|
||||||
// - Sets a single entry of the colortable to a new value
|
|
||||||
// Arguments:
|
|
||||||
// - tableIndex: The VT color table index
|
|
||||||
// - dwColor: The new RGB color value to use.
|
|
||||||
// Return Value:
|
|
||||||
// True if handled successfully. False otherwise.
|
|
||||||
bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor)
|
|
||||||
{
|
|
||||||
return SetColorTableEntry(TextColor::CURSOR_COLOR, cursorColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routine Description:
|
// Routine Description:
|
||||||
// - OSC Copy to Clipboard
|
// - OSC Copy to Clipboard
|
||||||
// Arguments:
|
// Arguments:
|
||||||
|
@ -3498,28 +3505,69 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
bool AdaptDispatch::RequestColorTableEntry(const size_t tableIndex)
|
||||||
// - Sets the default foreground color to a new value
|
|
||||||
// Arguments:
|
|
||||||
// - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR.
|
|
||||||
// Return Value:
|
|
||||||
// True if handled successfully. False otherwise.
|
|
||||||
bool AdaptDispatch::SetDefaultForeground(const DWORD dwColor)
|
|
||||||
{
|
{
|
||||||
_renderSettings.SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND);
|
const auto color = _renderSettings.GetColorTableEntry(tableIndex);
|
||||||
return SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, dwColor);
|
if (color != INVALID_COLOR)
|
||||||
|
{
|
||||||
|
const til::color c{ color };
|
||||||
|
// Scale values up to match xterm's 16-bit color report format.
|
||||||
|
_api.ReturnResponse(fmt::format(FMT_COMPILE(L"\033]4;{};rgb:{:04x}/{:04x}/{:04x}\033\\"), tableIndex, c.r * 0x0101, c.g * 0x0101, c.b * 0x0101));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
// - Sets the default background color to a new value
|
// - Sets one Xterm Color Resource such as Default Foreground, Background, Cursor
|
||||||
// Arguments:
|
|
||||||
// - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR.
|
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// True if handled successfully. False otherwise.
|
// True if handled successfully. False otherwise.
|
||||||
bool AdaptDispatch::SetDefaultBackground(const DWORD dwColor)
|
bool AdaptDispatch::SetXtermColorResource(const size_t resource, const DWORD color)
|
||||||
{
|
{
|
||||||
_renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND);
|
assert(resource >= 10);
|
||||||
return SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, dwColor);
|
const auto mappingIndex = resource - 10;
|
||||||
|
const auto& oscMapping = XtermResourceColorTableMappings.at(mappingIndex);
|
||||||
|
if (oscMapping.ColorTableIndex > 0)
|
||||||
|
{
|
||||||
|
if (oscMapping.AliasIndex >= 0) [[unlikely]]
|
||||||
|
{
|
||||||
|
// If this color change applies to an aliased color, point the alias at the new color
|
||||||
|
_renderSettings.SetColorAliasIndex(static_cast<ColorAlias>(oscMapping.AliasIndex), oscMapping.ColorTableIndex);
|
||||||
|
}
|
||||||
|
return SetColorTableEntry(oscMapping.ColorTableIndex, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Description:
|
||||||
|
// - Reports the value of one Xterm Color Resource, if it is set.
|
||||||
|
// Return Value:
|
||||||
|
// True if handled successfully. False otherwise.
|
||||||
|
bool AdaptDispatch::RequestXtermColorResource(const size_t resource)
|
||||||
|
{
|
||||||
|
assert(resource >= 10);
|
||||||
|
const auto mappingIndex = resource - 10;
|
||||||
|
const auto& oscMapping = XtermResourceColorTableMappings.at(mappingIndex);
|
||||||
|
if (oscMapping.ColorTableIndex > 0)
|
||||||
|
{
|
||||||
|
size_t finalColorIndex = oscMapping.ColorTableIndex;
|
||||||
|
|
||||||
|
if (oscMapping.AliasIndex >= 0) [[unlikely]]
|
||||||
|
{
|
||||||
|
finalColorIndex = _renderSettings.GetColorAliasIndex(static_cast<ColorAlias>(oscMapping.AliasIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto color = _renderSettings.GetColorTableEntry(finalColorIndex);
|
||||||
|
if (color != INVALID_COLOR)
|
||||||
|
{
|
||||||
|
const til::color c{ color };
|
||||||
|
// Scale values up to match xterm's 16-bit color report format.
|
||||||
|
_api.ReturnResponse(fmt::format(FMT_COMPILE(L"\033]{};rgb:{:04x}/{:04x}/{:04x}\033\\"), resource, c.r * 0x0101, c.g * 0x0101, c.b * 0x0101));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method Description:
|
// Method Description:
|
||||||
|
|
|
@ -126,14 +126,14 @@ namespace Microsoft::Console::VirtualTerminal
|
||||||
bool HardReset() override; // RIS
|
bool HardReset() override; // RIS
|
||||||
bool ScreenAlignmentPattern() override; // DECALN
|
bool ScreenAlignmentPattern() override; // DECALN
|
||||||
bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR
|
bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR
|
||||||
bool SetCursorColor(const COLORREF cursorColor) override;
|
|
||||||
|
|
||||||
bool SetClipboard(const wil::zwstring_view content) override; // OSCSetClipboard
|
bool SetClipboard(const wil::zwstring_view content) override; // OSCSetClipboard
|
||||||
|
|
||||||
bool SetColorTableEntry(const size_t tableIndex,
|
bool SetColorTableEntry(const size_t tableIndex,
|
||||||
const DWORD color) override; // OSCColorTable
|
const DWORD color) override; // OSCSetColorTable
|
||||||
bool SetDefaultForeground(const DWORD color) override; // OSCDefaultForeground
|
bool RequestColorTableEntry(const size_t tableIndex) override; // OSCGetColorTable
|
||||||
bool SetDefaultBackground(const DWORD color) override; // OSCDefaultBackground
|
bool SetXtermColorResource(const size_t resource, const DWORD color) override; // OSCSetDefaultForeground, OSCSetDefaultBackground, OSCSetCursorColor, OSCResetCursorColor
|
||||||
|
bool RequestXtermColorResource(const size_t resource) override; // OSCGetDefaultForeground, OSCGetDefaultBackground, OSCGetCursorColor
|
||||||
bool AssignColor(const DispatchTypes::ColorItem item, const VTInt fgIndex, const VTInt bgIndex) override; // DECAC
|
bool AssignColor(const DispatchTypes::ColorItem item, const VTInt fgIndex, const VTInt bgIndex) override; // DECAC
|
||||||
|
|
||||||
bool WindowManipulation(const DispatchTypes::WindowManipulationType function,
|
bool WindowManipulation(const DispatchTypes::WindowManipulationType function,
|
||||||
|
|
|
@ -69,9 +69,10 @@ public:
|
||||||
bool BackwardsTab(const VTInt /*numTabs*/) override { return false; } // CBT
|
bool BackwardsTab(const VTInt /*numTabs*/) override { return false; } // CBT
|
||||||
bool TabClear(const DispatchTypes::TabClearType /*clearType*/) override { return false; } // TBC
|
bool TabClear(const DispatchTypes::TabClearType /*clearType*/) override { return false; } // TBC
|
||||||
bool TabSet(const VTParameter /*setType*/) override { return false; } // DECST8C
|
bool TabSet(const VTParameter /*setType*/) override { return false; } // DECST8C
|
||||||
bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*color*/) override { return false; } // OSCColorTable
|
bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*color*/) override { return false; } // OSCSetColorTable
|
||||||
bool SetDefaultForeground(const DWORD /*color*/) override { return false; } // OSCDefaultForeground
|
bool RequestColorTableEntry(const size_t /*tableIndex*/) override { return false; } // OSCGetColorTable
|
||||||
bool SetDefaultBackground(const DWORD /*color*/) override { return false; } // OSCDefaultBackground
|
bool SetXtermColorResource(const size_t /*resource*/, const DWORD /*color*/) override { return false; } // OSCSetDefaultForeground, OSCSetDefaultBackground, OSCSetCursorColor, OSCResetCursorColor
|
||||||
|
bool RequestXtermColorResource(const size_t /*resource*/) override { return false; } // OSCGetDefaultForeground, OSCGetDefaultBackground, OSCGetCursorColor
|
||||||
bool AssignColor(const DispatchTypes::ColorItem /*item*/, const VTInt /*fgIndex*/, const VTInt /*bgIndex*/) override { return false; } // DECAC
|
bool AssignColor(const DispatchTypes::ColorItem /*item*/, const VTInt /*fgIndex*/, const VTInt /*bgIndex*/) override { return false; } // DECAC
|
||||||
|
|
||||||
bool EraseInDisplay(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // ED
|
bool EraseInDisplay(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // ED
|
||||||
|
@ -121,7 +122,6 @@ public:
|
||||||
bool ScreenAlignmentPattern() override { return false; } // DECALN
|
bool ScreenAlignmentPattern() override { return false; } // DECALN
|
||||||
|
|
||||||
bool SetCursorStyle(const DispatchTypes::CursorStyle /*cursorStyle*/) override { return false; } // DECSCUSR
|
bool SetCursorStyle(const DispatchTypes::CursorStyle /*cursorStyle*/) override { return false; } // DECSCUSR
|
||||||
bool SetCursorColor(const COLORREF /*color*/) override { return false; } // OSCSetCursorColor, OSCResetCursorColor
|
|
||||||
|
|
||||||
bool SetClipboard(wil::zwstring_view /*content*/) override { return false; } // OscSetClipboard
|
bool SetClipboard(wil::zwstring_view /*content*/) override { return false; } // OscSetClipboard
|
||||||
|
|
||||||
|
|
|
@ -2398,6 +2398,232 @@ public:
|
||||||
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(Osc4ColorPaletteReportTests)
|
||||||
|
{
|
||||||
|
_testGetSet->PrepData();
|
||||||
|
|
||||||
|
// The colors below use the same VT525 colors as the other color table report tests.
|
||||||
|
auto& renderSettings = _testGetSet->_renderer._renderSettings;
|
||||||
|
renderSettings.SetColorTableEntry(0, RGB(0, 0, 0));
|
||||||
|
renderSettings.SetColorTableEntry(1, RGB(204, 36, 36));
|
||||||
|
renderSettings.SetColorTableEntry(2, RGB(51, 204, 51));
|
||||||
|
renderSettings.SetColorTableEntry(3, RGB(204, 204, 51));
|
||||||
|
renderSettings.SetColorTableEntry(4, RGB(51, 51, 204));
|
||||||
|
renderSettings.SetColorTableEntry(5, RGB(204, 51, 204));
|
||||||
|
renderSettings.SetColorTableEntry(6, RGB(51, 204, 204));
|
||||||
|
renderSettings.SetColorTableEntry(7, RGB(120, 120, 120));
|
||||||
|
renderSettings.SetColorTableEntry(8, RGB(69, 69, 69));
|
||||||
|
renderSettings.SetColorTableEntry(9, RGB(255, 0, 0));
|
||||||
|
renderSettings.SetColorTableEntry(10, RGB(0, 255, 0));
|
||||||
|
renderSettings.SetColorTableEntry(11, RGB(255, 255, 0));
|
||||||
|
renderSettings.SetColorTableEntry(12, RGB(0, 0, 255));
|
||||||
|
renderSettings.SetColorTableEntry(13, RGB(255, 0, 255));
|
||||||
|
renderSettings.SetColorTableEntry(14, RGB(0, 255, 255));
|
||||||
|
renderSettings.SetColorTableEntry(15, RGB(255, 255, 255));
|
||||||
|
for (size_t i = 16; i < TextColor::TABLE_SIZE; i++)
|
||||||
|
{
|
||||||
|
renderSettings.SetColorTableEntry(i, RGB(0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dynamic color reports begin with an OSC, parameter 4, another parameter for the index, and end with ST.
|
||||||
|
const auto OSC = L"\033]";
|
||||||
|
const auto ST = L"\033\\";
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(0);
|
||||||
|
std::wstring expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;0;rgb:0000/0000/0000";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(1);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;1;rgb:cccc/2424/2424";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(2);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;2;rgb:3333/cccc/3333";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(3);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;3;rgb:cccc/cccc/3333";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(4);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;4;rgb:3333/3333/cccc";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(5);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;5;rgb:cccc/3333/cccc";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(6);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;6;rgb:3333/cccc/cccc";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(7);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;7;rgb:7878/7878/7878";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(8);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;8;rgb:4545/4545/4545";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(9);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;9;rgb:ffff/0000/0000";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(10);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;10;rgb:0000/ffff/0000";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(11);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;11;rgb:ffff/ffff/0000";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(12);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;12;rgb:0000/0000/ffff";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(13);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;13;rgb:ffff/0000/ffff";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(14);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;14;rgb:0000/ffff/ffff";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
_pDispatch->RequestColorTableEntry(15);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"4;15;rgb:ffff/ffff/ffff";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(XtermColorResourceReportTests)
|
||||||
|
{
|
||||||
|
_testGetSet->PrepData();
|
||||||
|
|
||||||
|
// The colors below use the same VT525 colors as the other color table report tests.
|
||||||
|
auto& renderSettings = _testGetSet->_renderer._renderSettings;
|
||||||
|
renderSettings.SetColorTableEntry(0, RGB(0, 0, 0));
|
||||||
|
renderSettings.SetColorTableEntry(1, RGB(204, 36, 36));
|
||||||
|
renderSettings.SetColorTableEntry(2, RGB(51, 204, 51));
|
||||||
|
renderSettings.SetColorTableEntry(3, RGB(204, 204, 51));
|
||||||
|
renderSettings.SetColorTableEntry(4, RGB(51, 51, 204));
|
||||||
|
renderSettings.SetColorTableEntry(5, RGB(204, 51, 204));
|
||||||
|
renderSettings.SetColorTableEntry(6, RGB(51, 204, 204));
|
||||||
|
renderSettings.SetColorTableEntry(7, RGB(120, 120, 120));
|
||||||
|
renderSettings.SetColorTableEntry(8, RGB(69, 69, 69));
|
||||||
|
renderSettings.SetColorTableEntry(9, RGB(255, 0, 0));
|
||||||
|
renderSettings.SetColorTableEntry(10, RGB(0, 255, 0));
|
||||||
|
renderSettings.SetColorTableEntry(11, RGB(255, 255, 0));
|
||||||
|
renderSettings.SetColorTableEntry(12, RGB(0, 0, 255));
|
||||||
|
renderSettings.SetColorTableEntry(13, RGB(255, 0, 255));
|
||||||
|
renderSettings.SetColorTableEntry(14, RGB(0, 255, 255));
|
||||||
|
renderSettings.SetColorTableEntry(15, RGB(255, 255, 255));
|
||||||
|
|
||||||
|
renderSettings.SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, RGB(190, 190, 190));
|
||||||
|
renderSettings.SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, RGB(12, 12, 12));
|
||||||
|
renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, RGB(255, 0, 0));
|
||||||
|
|
||||||
|
// Dynamic color reports begin with an OSC, a parameter matching the requested value, and end with ST.
|
||||||
|
const auto OSC = L"\033]";
|
||||||
|
const auto ST = L"\033\\";
|
||||||
|
|
||||||
|
// Foreground mapped to DARK_WHITE
|
||||||
|
_pDispatch->RequestXtermColorResource(10);
|
||||||
|
std::wstring expectedResponse = OSC;
|
||||||
|
expectedResponse += L"10;rgb:7878/7878/7878";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
// Foreground mapped to independent foreground color
|
||||||
|
renderSettings.SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND);
|
||||||
|
_pDispatch->RequestXtermColorResource(10);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"10;rgb:bebe/bebe/bebe";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
// Background mapped to DARK_BLACK
|
||||||
|
_pDispatch->RequestXtermColorResource(11);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"11;rgb:0000/0000/0000";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
// Background mapped to independent background color
|
||||||
|
renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND);
|
||||||
|
_pDispatch->RequestXtermColorResource(11);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"11;rgb:0c0c/0c0c/0c0c";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
// Foreground and Background mapped to different indices (e.g. via DECAC)
|
||||||
|
{
|
||||||
|
_testGetSet->_response.clear(); // manually clear (since we aren't issuing a call that will empty it)
|
||||||
|
auto retentionScope = _testGetSet->EnableInputRetentionInScope();
|
||||||
|
renderSettings.SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DARK_RED);
|
||||||
|
renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::BRIGHT_GREEN);
|
||||||
|
_pDispatch->RequestXtermColorResource(10);
|
||||||
|
_pDispatch->RequestXtermColorResource(11);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"10;rgb:cccc/2424/2424";
|
||||||
|
expectedResponse += ST;
|
||||||
|
expectedResponse += OSC;
|
||||||
|
expectedResponse += L"11;rgb:0000/ffff/0000";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
_pDispatch->RequestXtermColorResource(12);
|
||||||
|
expectedResponse = OSC;
|
||||||
|
expectedResponse += L"12;rgb:ffff/0000/0000";
|
||||||
|
expectedResponse += ST;
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
// Resource set to unrepresentable color
|
||||||
|
_testGetSet->_response.clear(); // manually clear (since we aren't issuing a call that will empty it)
|
||||||
|
renderSettings.SetColorTableEntry(TextColor::CURSOR_COLOR, INVALID_COLOR);
|
||||||
|
_pDispatch->RequestXtermColorResource(12);
|
||||||
|
expectedResponse = L"";
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
|
||||||
|
// Unsupported resource - no mapped color
|
||||||
|
_testGetSet->_response.clear();
|
||||||
|
_pDispatch->RequestXtermColorResource(13);
|
||||||
|
expectedResponse = L"";
|
||||||
|
_testGetSet->ValidateInputEvent(expectedResponse.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_METHOD(TabulationStopReportTests)
|
TEST_METHOD(TabulationStopReportTests)
|
||||||
{
|
{
|
||||||
_testGetSet->PrepData();
|
_testGetSet->PrepData();
|
||||||
|
|
|
@ -550,8 +550,19 @@ bool InputStateMachineEngine::ActionIgnore() noexcept
|
||||||
// - string - OSC string we've collected. NOT null terminated.
|
// - string - OSC string we've collected. NOT null terminated.
|
||||||
// Return Value:
|
// Return Value:
|
||||||
// - true if we handled the dispatch.
|
// - true if we handled the dispatch.
|
||||||
bool InputStateMachineEngine::ActionOscDispatch(const size_t /*parameter*/, const std::wstring_view /*string*/) noexcept
|
bool InputStateMachineEngine::ActionOscDispatch(const size_t /*parameter*/, const std::wstring_view /*string*/)
|
||||||
{
|
{
|
||||||
|
// Unlike ActionCsiDispatch, we are not checking whether the application has requested
|
||||||
|
// VT input.
|
||||||
|
// Our documentation states that VT reports generated by application requests will be
|
||||||
|
// sent regardless of the state of `ENABLE_VIRTUAL_TERMINAL_INPUT`. We can't easily do
|
||||||
|
// that for CSI reports because we may incidentally pass through non-response VT input;
|
||||||
|
// however, there should be no OSC on the input stream *except* for responses.
|
||||||
|
// It should be safe to pass all OSCs from the input stream through to the application.
|
||||||
|
if (_pfnFlushToInputQueue)
|
||||||
|
{
|
||||||
|
return _pfnFlushToInputQueue();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||||
|
|
||||||
bool ActionIgnore() noexcept override;
|
bool ActionIgnore() noexcept override;
|
||||||
|
|
||||||
bool ActionOscDispatch(const size_t parameter, const std::wstring_view string) noexcept override;
|
bool ActionOscDispatch(const size_t parameter, const std::wstring_view string) override;
|
||||||
|
|
||||||
bool ActionSs3Dispatch(const wchar_t wch, const VTParameters parameters) override;
|
bool ActionSs3Dispatch(const wchar_t wch, const VTParameters parameters) override;
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
using namespace Microsoft::Console;
|
using namespace Microsoft::Console;
|
||||||
using namespace Microsoft::Console::VirtualTerminal;
|
using namespace Microsoft::Console::VirtualTerminal;
|
||||||
|
|
||||||
|
constexpr COLORREF COLOR_INQUIRY_COLOR = 0xfeffffff; // It's like INVALID_COLOR but special
|
||||||
|
|
||||||
// takes ownership of pDispatch
|
// takes ownership of pDispatch
|
||||||
OutputStateMachineEngine::OutputStateMachineEngine(std::unique_ptr<ITermDispatch> pDispatch) :
|
OutputStateMachineEngine::OutputStateMachineEngine(std::unique_ptr<ITermDispatch> pDispatch) :
|
||||||
_dispatch(std::move(pDispatch)),
|
_dispatch(std::move(pDispatch)),
|
||||||
|
@ -788,8 +790,15 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||||
{
|
{
|
||||||
const auto tableIndex = til::at(tableIndexes, i);
|
const auto tableIndex = til::at(tableIndexes, i);
|
||||||
const auto rgb = til::at(colors, i);
|
const auto rgb = til::at(colors, i);
|
||||||
|
if (rgb == COLOR_INQUIRY_COLOR)
|
||||||
|
{
|
||||||
|
success = success && _dispatch->RequestColorTableEntry(tableIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
success = success && _dispatch->SetColorTableEntry(tableIndex, rgb);
|
success = success && _dispatch->SetColorTableEntry(tableIndex, rgb);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OscActionCodes::SetForegroundColor:
|
case OscActionCodes::SetForegroundColor:
|
||||||
|
@ -800,40 +809,18 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||||
success = _GetOscSetColor(string, colors);
|
success = _GetOscSetColor(string, colors);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
auto commandIndex = parameter;
|
auto resource = parameter;
|
||||||
size_t colorIndex = 0;
|
for (auto&& color : colors)
|
||||||
|
|
||||||
if (commandIndex == OscActionCodes::SetForegroundColor && colors.size() > colorIndex)
|
|
||||||
{
|
{
|
||||||
const auto color = til::at(colors, colorIndex);
|
if (color == COLOR_INQUIRY_COLOR)
|
||||||
if (color != INVALID_COLOR)
|
|
||||||
{
|
{
|
||||||
success = success && _dispatch->SetDefaultForeground(color);
|
success = success && _dispatch->RequestXtermColorResource(resource);
|
||||||
}
|
}
|
||||||
commandIndex++;
|
else if (color != INVALID_COLOR)
|
||||||
colorIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commandIndex == OscActionCodes::SetBackgroundColor && colors.size() > colorIndex)
|
|
||||||
{
|
{
|
||||||
const auto color = til::at(colors, colorIndex);
|
success = success && _dispatch->SetXtermColorResource(resource, color);
|
||||||
if (color != INVALID_COLOR)
|
|
||||||
{
|
|
||||||
success = success && _dispatch->SetDefaultBackground(color);
|
|
||||||
}
|
}
|
||||||
commandIndex++;
|
resource++;
|
||||||
colorIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (commandIndex == OscActionCodes::SetCursorColor && colors.size() > colorIndex)
|
|
||||||
{
|
|
||||||
const auto color = til::at(colors, colorIndex);
|
|
||||||
if (color != INVALID_COLOR)
|
|
||||||
{
|
|
||||||
success = success && _dispatch->SetCursorColor(color);
|
|
||||||
}
|
|
||||||
commandIndex++;
|
|
||||||
colorIndex++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -851,7 +838,8 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||||
}
|
}
|
||||||
case OscActionCodes::ResetCursorColor:
|
case OscActionCodes::ResetCursorColor:
|
||||||
{
|
{
|
||||||
success = _dispatch->SetCursorColor(INVALID_COLOR);
|
/* The reset codes for xterm dynamic resources are the set codes + 100 */
|
||||||
|
success = _dispatch->SetXtermColorResource(parameter - 100u, INVALID_COLOR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OscActionCodes::Hyperlink:
|
case OscActionCodes::Hyperlink:
|
||||||
|
@ -938,6 +926,8 @@ bool OutputStateMachineEngine::_GetOscSetColorTable(const std::wstring_view stri
|
||||||
std::vector<size_t>& tableIndexes,
|
std::vector<size_t>& tableIndexes,
|
||||||
std::vector<DWORD>& rgbs) const
|
std::vector<DWORD>& rgbs) const
|
||||||
{
|
{
|
||||||
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
const auto parts = Utils::SplitString(string, L';');
|
const auto parts = Utils::SplitString(string, L';');
|
||||||
if (parts.size() < 2)
|
if (parts.size() < 2)
|
||||||
{
|
{
|
||||||
|
@ -949,15 +939,25 @@ bool OutputStateMachineEngine::_GetOscSetColorTable(const std::wstring_view stri
|
||||||
|
|
||||||
for (size_t i = 0, j = 1; j < parts.size(); i += 2, j += 2)
|
for (size_t i = 0, j = 1; j < parts.size(); i += 2, j += 2)
|
||||||
{
|
{
|
||||||
|
auto&& index = til::at(parts, i);
|
||||||
|
auto&& color = til::at(parts, j);
|
||||||
unsigned int tableIndex = 0;
|
unsigned int tableIndex = 0;
|
||||||
const auto indexSuccess = Utils::StringToUint(til::at(parts, i), tableIndex);
|
const auto indexSuccess = Utils::StringToUint(index, tableIndex);
|
||||||
const auto colorOptional = Utils::ColorFromXTermColor(til::at(parts, j));
|
|
||||||
if (indexSuccess && colorOptional.has_value())
|
if (indexSuccess)
|
||||||
|
{
|
||||||
|
if (color == L"?"sv) [[unlikely]]
|
||||||
|
{
|
||||||
|
newTableIndexes.push_back(tableIndex);
|
||||||
|
newRgbs.push_back(COLOR_INQUIRY_COLOR);
|
||||||
|
}
|
||||||
|
else if (const auto colorOptional = Utils::ColorFromXTermColor(color))
|
||||||
{
|
{
|
||||||
newTableIndexes.push_back(tableIndex);
|
newTableIndexes.push_back(tableIndex);
|
||||||
newRgbs.push_back(colorOptional.value());
|
newRgbs.push_back(colorOptional.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tableIndexes.swap(newTableIndexes);
|
tableIndexes.swap(newTableIndexes);
|
||||||
rgbs.swap(newRgbs);
|
rgbs.swap(newRgbs);
|
||||||
|
@ -1032,6 +1032,8 @@ bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string,
|
||||||
bool OutputStateMachineEngine::_GetOscSetColor(const std::wstring_view string,
|
bool OutputStateMachineEngine::_GetOscSetColor(const std::wstring_view string,
|
||||||
std::vector<DWORD>& rgbs) const
|
std::vector<DWORD>& rgbs) const
|
||||||
{
|
{
|
||||||
|
using namespace std::string_view_literals;
|
||||||
|
|
||||||
const auto parts = Utils::SplitString(string, L';');
|
const auto parts = Utils::SplitString(string, L';');
|
||||||
if (parts.size() < 1)
|
if (parts.size() < 1)
|
||||||
{
|
{
|
||||||
|
@ -1039,10 +1041,14 @@ bool OutputStateMachineEngine::_GetOscSetColor(const std::wstring_view string,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DWORD> newRgbs;
|
std::vector<DWORD> newRgbs;
|
||||||
for (size_t i = 0; i < parts.size(); i++)
|
for (auto&& part : parts)
|
||||||
{
|
{
|
||||||
const auto colorOptional = Utils::ColorFromXTermColor(til::at(parts, i));
|
if (part == L"?"sv) [[unlikely]]
|
||||||
if (colorOptional.has_value())
|
{
|
||||||
|
newRgbs.push_back(COLOR_INQUIRY_COLOR);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (const auto colorOptional = Utils::ColorFromXTermColor(part))
|
||||||
{
|
{
|
||||||
newRgbs.push_back(colorOptional.value());
|
newRgbs.push_back(colorOptional.value());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1158,12 +1158,8 @@ public:
|
||||||
_numTabs{ 0 },
|
_numTabs{ 0 },
|
||||||
_tabClear{ false },
|
_tabClear{ false },
|
||||||
_tabClearTypes{},
|
_tabClearTypes{},
|
||||||
_setDefaultForeground(false),
|
_xtermResourcesChanged{},
|
||||||
_defaultForegroundColor{ RGB(0, 0, 0) },
|
_xtermResourceValues{},
|
||||||
_setDefaultBackground(false),
|
|
||||||
_defaultBackgroundColor{ RGB(0, 0, 0) },
|
|
||||||
_setDefaultCursorColor(false),
|
|
||||||
_defaultCursorColor{ RGB(0, 0, 0) },
|
|
||||||
_hyperlinkMode{ false },
|
_hyperlinkMode{ false },
|
||||||
_options{ s_cMaxOptions, static_cast<DispatchTypes::GraphicsOptions>(s_uiGraphicsCleared) }, // fill with cleared option
|
_options{ s_cMaxOptions, static_cast<DispatchTypes::GraphicsOptions>(s_uiGraphicsCleared) }, // fill with cleared option
|
||||||
_colorTable{},
|
_colorTable{},
|
||||||
|
@ -1432,24 +1428,22 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetDefaultForeground(const DWORD color) noexcept override
|
bool RequestColorTableEntry(const size_t tableIndex) noexcept override
|
||||||
{
|
{
|
||||||
_setDefaultForeground = true;
|
_colorTableEntriesRequested.push_back(tableIndex);
|
||||||
_defaultForegroundColor = color;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetDefaultBackground(const DWORD color) noexcept override
|
bool SetXtermColorResource(const size_t resource, const DWORD color) override
|
||||||
{
|
{
|
||||||
_setDefaultBackground = true;
|
_xtermResourcesChanged.push_back(resource);
|
||||||
_defaultBackgroundColor = color;
|
_xtermResourceValues.push_back(color);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetCursorColor(const DWORD color) noexcept override
|
bool RequestXtermColorResource(const size_t resource) override
|
||||||
{
|
{
|
||||||
_setDefaultCursorColor = true;
|
_xtermResourcesRequested.push_back(resource);
|
||||||
_defaultCursorColor = color;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1529,13 +1523,11 @@ public:
|
||||||
size_t _numTabs;
|
size_t _numTabs;
|
||||||
bool _tabClear;
|
bool _tabClear;
|
||||||
std::vector<DispatchTypes::TabClearType> _tabClearTypes;
|
std::vector<DispatchTypes::TabClearType> _tabClearTypes;
|
||||||
bool _setDefaultForeground;
|
std::vector<size_t> _xtermResourcesChanged;
|
||||||
DWORD _defaultForegroundColor;
|
std::vector<DWORD> _xtermResourceValues;
|
||||||
bool _setDefaultBackground;
|
std::vector<size_t> _xtermResourcesRequested;
|
||||||
DWORD _defaultBackgroundColor;
|
|
||||||
bool _setDefaultCursorColor;
|
|
||||||
DWORD _defaultCursorColor;
|
|
||||||
bool _setColorTableEntry;
|
bool _setColorTableEntry;
|
||||||
|
std::vector<size_t> _colorTableEntriesRequested;
|
||||||
bool _hyperlinkMode;
|
bool _hyperlinkMode;
|
||||||
std::wstring _copyContent;
|
std::wstring _copyContent;
|
||||||
std::wstring _uri;
|
std::wstring _uri;
|
||||||
|
@ -2822,105 +2814,114 @@ class StateMachineExternalTest final
|
||||||
|
|
||||||
// Single param
|
// Single param
|
||||||
mach.ProcessString(L"\033]10;rgb:1/1/1\033\\");
|
mach.ProcessString(L"\033]10;rgb:1/1/1\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;rgb:12/34/56\033\\");
|
mach.ProcessString(L"\033]10;rgb:12/34/56\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#111\033\\");
|
mach.ProcessString(L"\033]10;#111\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#123456\033\\");
|
mach.ProcessString(L"\033]10;#123456\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;DarkOrange\033\\");
|
mach.ProcessString(L"\033]10;DarkOrange\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
// Multiple params
|
// Multiple params
|
||||||
mach.ProcessString(L"\033]10;#111;rgb:2/2/2\033\\");
|
mach.ProcessString(L"\033]10;#111;rgb:2/2/2\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(2u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[1]);
|
||||||
VERIFY_ARE_EQUAL(RGB(0x22, 0x22, 0x22), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x22, 0x22, 0x22), pDispatch->_xtermResourceValues[1]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#111;DarkOrange\033\\");
|
mach.ProcessString(L"\033]10;#111;DarkOrange\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(2u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[1]);
|
||||||
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_xtermResourceValues[1]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#111;DarkOrange;rgb:2/2/2\033\\");
|
mach.ProcessString(L"\033]10;#111;DarkOrange;rgb:2/2/2\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(3u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[1]);
|
||||||
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(12u, pDispatch->_xtermResourcesChanged[2]);
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultCursorColor);
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(0x22, 0x22, 0x22), pDispatch->_defaultCursorColor);
|
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_xtermResourceValues[1]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x22, 0x22, 0x22), pDispatch->_xtermResourceValues[2]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
// Partially valid multi-param sequences.
|
// Partially valid multi-param sequences.
|
||||||
mach.ProcessString(L"\033]10;#111;\033\\");
|
mach.ProcessString(L"\033]10;#111;\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#111;rgb:\033\\");
|
mach.ProcessString(L"\033]10;#111;rgb:\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#111;#2\033\\");
|
mach.ProcessString(L"\033]10;#111;#2\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultForegroundColor);
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;;rgb:1/1/1\033\\");
|
mach.ProcessString(L"\033]10;;rgb:1/1/1\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#1;rgb:1/1/1\033\\");
|
mach.ProcessString(L"\033]10;#1;rgb:1/1/1\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
// Invalid sequences.
|
// Invalid sequences.
|
||||||
mach.ProcessString(L"\033]10;rgb:1/1/\033\\");
|
mach.ProcessString(L"\033]10;rgb:1/1/\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]10;#1\033\\");
|
mach.ProcessString(L"\033]10;#1\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultForeground);
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
}
|
}
|
||||||
|
@ -2933,100 +2934,115 @@ class StateMachineExternalTest final
|
||||||
StateMachine mach(std::move(engine));
|
StateMachine mach(std::move(engine));
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;rgb:1/1/1\033\\");
|
mach.ProcessString(L"\033]11;rgb:1/1/1\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
// Single param
|
// Single param
|
||||||
mach.ProcessString(L"\033]11;rgb:12/34/56\033\\");
|
mach.ProcessString(L"\033]11;rgb:12/34/56\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#111\033\\");
|
mach.ProcessString(L"\033]11;#111\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#123456\033\\");
|
mach.ProcessString(L"\033]11;#123456\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x12, 0x34, 0x56), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;DarkOrange\033\\");
|
mach.ProcessString(L"\033]11;DarkOrange\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
// Multiple params
|
// Multiple params
|
||||||
mach.ProcessString(L"\033]11;#111;rgb:2/2/2\033\\");
|
mach.ProcessString(L"\033]11;#111;rgb:2/2/2\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(2u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(0x22, 0x22, 0x22), pDispatch->_defaultCursorColor);
|
VERIFY_ARE_EQUAL(12u, pDispatch->_xtermResourcesChanged[1]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x22, 0x22, 0x22), pDispatch->_xtermResourceValues[1]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#111;DarkOrange\033\\");
|
mach.ProcessString(L"\033]11;#111;DarkOrange\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(2u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_defaultCursorColor);
|
VERIFY_ARE_EQUAL(12u, pDispatch->_xtermResourcesChanged[1]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_xtermResourceValues[1]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#111;DarkOrange;rgb:2/2/2\033\\");
|
mach.ProcessString(L"\033]11;#111;DarkOrange;rgb:2/2/2\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(3u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_defaultCursorColor);
|
VERIFY_ARE_EQUAL(12u, pDispatch->_xtermResourcesChanged[1]);
|
||||||
// The third param is out of range.
|
VERIFY_ARE_EQUAL(13u, pDispatch->_xtermResourcesChanged[2]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(255, 140, 0), pDispatch->_xtermResourceValues[1]);
|
||||||
|
// The third param is out of range, but it's technically still in compliance to set it
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
// Partially valid multi-param sequences.
|
// Partially valid multi-param sequences.
|
||||||
mach.ProcessString(L"\033]11;#111;\033\\");
|
mach.ProcessString(L"\033]11;#111;\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#111;rgb:\033\\");
|
mach.ProcessString(L"\033]11;#111;rgb:\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#111;#2\033\\");
|
mach.ProcessString(L"\033]11;#111;#2\033\\");
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_defaultBackgroundColor);
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x10, 0x10, 0x10), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;;rgb:1/1/1\033\\");
|
mach.ProcessString(L"\033]11;;rgb:1/1/1\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultCursorColor);
|
VERIFY_ARE_EQUAL(12u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_defaultCursorColor);
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#1;rgb:1/1/1\033\\");
|
mach.ProcessString(L"\033]11;#1;rgb:1/1/1\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
VERIFY_IS_TRUE(pDispatch->_setDefaultCursorColor);
|
VERIFY_ARE_EQUAL(12u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_defaultCursorColor);
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x11, 0x11), pDispatch->_xtermResourceValues[0]);
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
// Invalid sequences.
|
// Invalid sequences.
|
||||||
mach.ProcessString(L"\033]11;rgb:1/1/\033\\");
|
mach.ProcessString(L"\033]11;rgb:1/1/\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
|
|
||||||
mach.ProcessString(L"\033]11;#1\033\\");
|
mach.ProcessString(L"\033]11;#1\033\\");
|
||||||
VERIFY_IS_FALSE(pDispatch->_setDefaultBackground);
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
}
|
}
|
||||||
|
@ -3178,6 +3194,88 @@ class StateMachineExternalTest final
|
||||||
pDispatch->ClearState();
|
pDispatch->ClearState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(TestOscGetColorTableEntry)
|
||||||
|
{
|
||||||
|
auto dispatch = std::make_unique<StatefulDispatch>();
|
||||||
|
auto pDispatch = dispatch.get();
|
||||||
|
auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch));
|
||||||
|
StateMachine mach(std::move(engine));
|
||||||
|
|
||||||
|
mach.ProcessString(L"\033]4;0;?;1;?;2;;3;?;4;?\033\\"); // Inquire about 0-4 skipping 2
|
||||||
|
VERIFY_ARE_EQUAL((std::vector<size_t>{ 0u, 1u, 3u, 4u }), pDispatch->_colorTableEntriesRequested);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
|
||||||
|
mach.ProcessString(L"\033]4;0;rgb:00/00/00;1;rgb:00/00/01;2;?;3;rgb:00/00/03;4;rgb:00/00/04\033\\"); // Set 0-4, except 2 (inquire)
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0, 0, 0), pDispatch->_colorTable.at(0));
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0, 0, 1), pDispatch->_colorTable.at(1));
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0, 0, 3), pDispatch->_colorTable.at(3));
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0, 0, 4), pDispatch->_colorTable.at(4));
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_colorTableEntriesRequested.size()); // note: (1u, 2u) constructs a 1-length vector containing 2
|
||||||
|
VERIFY_ARE_EQUAL(2u, pDispatch->_colorTableEntriesRequested[0]);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
|
||||||
|
pDispatch->_colorTable.at(3) = RGB(0xfe, 0xed, 0xfa);
|
||||||
|
mach.ProcessString(L"\033]4;0;rgb:f0/00/00;1;?;3\033\\"); // Set 0, inquire 1, truncated 3
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0xf0, 0, 0), pDispatch->_colorTable.at(0));
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0xfe, 0xed, 0xfa), pDispatch->_colorTable.at(3)); // unchanged from before ProcessString
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_colorTableEntriesRequested.size()); // note: (1u, 2u) constructs a 1-length vector containing 2
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_colorTableEntriesRequested[0]);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(TestOscXtermResourceReport)
|
||||||
|
{
|
||||||
|
auto dispatch = std::make_unique<StatefulDispatch>();
|
||||||
|
auto pDispatch = dispatch.get();
|
||||||
|
auto engine = std::make_unique<OutputStateMachineEngine>(std::move(dispatch));
|
||||||
|
StateMachine mach(std::move(engine));
|
||||||
|
|
||||||
|
mach.ProcessString(L"\033]10;?\033\\");
|
||||||
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesRequested.size());
|
||||||
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesRequested[0]);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
|
||||||
|
// Two params, skip first
|
||||||
|
mach.ProcessString(L"\033]10;;?\033\\");
|
||||||
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesRequested.size());
|
||||||
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesRequested[0]);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
|
||||||
|
// Two params, set first
|
||||||
|
mach.ProcessString(L"\033]10;rgb:11/22/33;?\033\\");
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
VERIFY_ARE_EQUAL(10u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x22, 0x33), pDispatch->_xtermResourceValues[0]);
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesRequested.size());
|
||||||
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesRequested[0]);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
|
||||||
|
// Two params, set first, starting at 12
|
||||||
|
mach.ProcessString(L"\033]12;rgb:11/22/33;?\033\\");
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
VERIFY_ARE_EQUAL(12u, pDispatch->_xtermResourcesChanged[0]);
|
||||||
|
VERIFY_ARE_EQUAL(RGB(0x11, 0x22, 0x33), pDispatch->_xtermResourceValues[0]);
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesRequested.size());
|
||||||
|
VERIFY_ARE_EQUAL(13u, pDispatch->_xtermResourcesRequested[0]);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
|
||||||
|
// Request all 10
|
||||||
|
mach.ProcessString(L"\033]10;?;?;?;?;?;?;?;?;?;?\033\\");
|
||||||
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
std::vector<size_t> expected{ 10u, 11u, 12u, 13u, 14u, 15u, 16u, 17u, 18u, 19u };
|
||||||
|
VERIFY_ARE_EQUAL(expected, pDispatch->_xtermResourcesRequested);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
|
||||||
|
// Request out of range
|
||||||
|
mach.ProcessString(L"\033]10;;?\033\\");
|
||||||
|
VERIFY_ARE_EQUAL(0u, pDispatch->_xtermResourcesChanged.size());
|
||||||
|
VERIFY_ARE_EQUAL(1u, pDispatch->_xtermResourcesRequested.size());
|
||||||
|
VERIFY_ARE_EQUAL(11u, pDispatch->_xtermResourcesRequested[0]);
|
||||||
|
pDispatch->ClearState();
|
||||||
|
}
|
||||||
|
|
||||||
TEST_METHOD(TestOscSetWindowTitle)
|
TEST_METHOD(TestOscSetWindowTitle)
|
||||||
{
|
{
|
||||||
BEGIN_TEST_METHOD_PROPERTIES()
|
BEGIN_TEST_METHOD_PROPERTIES()
|
||||||
|
|
Loading…
Reference in New Issue