Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for querying Xterm dynamic colors and palette #17729

Merged
merged 18 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/patterns/patterns.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ vcvars\w*
ROY\sG\.\sBIV
!(?:(?i)ESC)!\[
!(?:(?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"
\b_mm(?:|256|512)_\w+\b
Expand Down
8 changes: 4 additions & 4 deletions src/terminal/adapter/ITermDispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
virtual bool BackwardsTab(const VTInt numTabs) = 0; // CBT
virtual bool TabClear(const DispatchTypes::TabClearType clearType) = 0; // TBC
virtual bool TabSet(const VTParameter setType) = 0; // DECST8C
virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; // OSCColorTable
virtual bool SetDefaultForeground(const DWORD color) = 0; // OSCDefaultForeground
virtual bool SetDefaultBackground(const DWORD color) = 0; // OSCDefaultBackground
virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD color) = 0; // OSCSetColorTable
virtual bool RequestColorTableEntry(const size_t tableIndex) = 0; // OSCGetColorTable
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 EraseInDisplay(const DispatchTypes::EraseType eraseType) = 0; // ED
Expand Down Expand Up @@ -128,7 +129,6 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
virtual bool ScreenAlignmentPattern() = 0; // DECALN

virtual bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) = 0; // DECSCUSR
virtual bool SetCursorColor(const COLORREF color) = 0; // OSCSetCursorColor, OSCResetCursorColor

virtual bool SetClipboard(wil::zwstring_view content) = 0; // OSCSetClipboard

Expand Down
96 changes: 72 additions & 24 deletions src/terminal/adapter/adaptDispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ using namespace Microsoft::Console::VirtualTerminal;

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 },
Comment on lines +31 to +37
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will not be filling all of these in, but are technically part of Xterm's supported color complement. We could put TEKTRONIX colors in here if we ever support it (OSC 15, 16, 18). We may never support pointer colors (OSC 13, 14). I intend to support selection colors (OSC 17, 19).

} };

AdaptDispatch::AdaptDispatch(ITerminalApi& api, Renderer* renderer, RenderSettings& renderSettings, TerminalInput& terminalInput) noexcept :
_api{ api },
_renderer{ renderer },
Expand Down Expand Up @@ -3439,18 +3458,6 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle)
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:
// - OSC Copy to Clipboard
// Arguments:
Expand Down Expand Up @@ -3491,28 +3498,69 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwCo
return true;
}

bool AdaptDispatch::RequestColorTableEntry(const size_t tableIndex)
{
const auto color = _renderSettings.GetColorTableEntry(tableIndex);
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:
// - Sets the default foreground color to a new value
// Arguments:
// - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR.
// - Sets one Xterm Color Resource such as Default Foreground, Background, Cursor
// Return Value:
// True if handled successfully. False otherwise.
bool AdaptDispatch::SetDefaultForeground(const DWORD dwColor)
bool AdaptDispatch::SetXtermColorResource(const size_t resource, const DWORD color)
{
_renderSettings.SetColorAliasIndex(ColorAlias::DefaultForeground, TextColor::DEFAULT_FOREGROUND);
return SetColorTableEntry(TextColor::DEFAULT_FOREGROUND, dwColor);
assert(resource >= 10);
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:
// - Sets the default background color to a new value
// Arguments:
// - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR.
// - Reports the value of one Xterm Color Resource, if it is set.
// Return Value:
// True if handled successfully. False otherwise.
bool AdaptDispatch::SetDefaultBackground(const DWORD dwColor)
bool AdaptDispatch::RequestXtermColorResource(const size_t resource)
{
_renderSettings.SetColorAliasIndex(ColorAlias::DefaultBackground, TextColor::DEFAULT_BACKGROUND);
return SetColorTableEntry(TextColor::DEFAULT_BACKGROUND, dwColor);
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:
Expand Down
8 changes: 4 additions & 4 deletions src/terminal/adapter/adaptDispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,14 @@ namespace Microsoft::Console::VirtualTerminal
bool HardReset() override; // RIS
bool ScreenAlignmentPattern() override; // DECALN
bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR
bool SetCursorColor(const COLORREF cursorColor) override;

bool SetClipboard(const wil::zwstring_view content) override; // OSCSetClipboard

bool SetColorTableEntry(const size_t tableIndex,
const DWORD color) override; // OSCColorTable
bool SetDefaultForeground(const DWORD color) override; // OSCDefaultForeground
bool SetDefaultBackground(const DWORD color) override; // OSCDefaultBackground
const DWORD color) override; // OSCSetColorTable
bool RequestColorTableEntry(const size_t tableIndex) override; // OSCGetColorTable
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 WindowManipulation(const DispatchTypes::WindowManipulationType function,
Expand Down
8 changes: 4 additions & 4 deletions src/terminal/adapter/termDispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons
bool BackwardsTab(const VTInt /*numTabs*/) override { return false; } // CBT
bool TabClear(const DispatchTypes::TabClearType /*clearType*/) override { return false; } // TBC
bool TabSet(const VTParameter /*setType*/) override { return false; } // DECST8C
bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*color*/) override { return false; } // OSCColorTable
bool SetDefaultForeground(const DWORD /*color*/) override { return false; } // OSCDefaultForeground
bool SetDefaultBackground(const DWORD /*color*/) override { return false; } // OSCDefaultBackground
bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*color*/) override { return false; } // OSCSetColorTable
bool RequestColorTableEntry(const size_t /*tableIndex*/) override { return false; } // OSCGetColorTable
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 EraseInDisplay(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // ED
Expand Down Expand Up @@ -121,7 +122,6 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons
bool ScreenAlignmentPattern() override { return false; } // DECALN

bool SetCursorStyle(const DispatchTypes::CursorStyle /*cursorStyle*/) override { return false; } // DECSCUSR
bool SetCursorColor(const COLORREF /*color*/) override { return false; } // OSCSetCursorColor, OSCResetCursorColor

bool SetClipboard(wil::zwstring_view /*content*/) override { return false; } // OscSetClipboard

Expand Down
Loading
Loading