Skip to content

Commit

Permalink
Add support for character sets with two character ids in the designat…
Browse files Browse the repository at this point in the history
…ion sequence.
  • Loading branch information
j4james committed Feb 9, 2020
1 parent 1abeaaa commit 8e46c7f
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 46 deletions.
4 changes: 2 additions & 2 deletions src/terminal/adapter/ITermDispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ class Microsoft::Console::VirtualTerminal::ITermDispatch
virtual bool DeviceAttributes() = 0; // DA

virtual bool DesignateCodingSystem(const wchar_t codingSystem) = 0; // DOCS
virtual bool Designate94Charset(const size_t gsetNumber, const wchar_t newCharset) = 0; // SCS
virtual bool Designate96Charset(const size_t gsetNumber, const wchar_t newCharset) = 0; // SCS
virtual bool Designate94Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset) = 0; // SCS
virtual bool Designate96Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset) = 0; // SCS
virtual bool LockingShift(const size_t gsetNumber) = 0; // LSx
virtual bool LockingShiftRight(const size_t gsetNumber) = 0; // LSxR
virtual bool SingleShift(const size_t gsetNumber) = 0; // SSx
Expand Down
8 changes: 4 additions & 4 deletions src/terminal/adapter/adaptDispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1429,10 +1429,10 @@ bool AdaptDispatch::DesignateCodingSystem(const wchar_t codingSystem)
// If the specified charset is unsupported, we do nothing (remain on the current one)
//Arguments:
// - gsetNumber - The G-set into which the charset will be selected.
// - newCharset - The character indicating the charset that will be used.
// - newCharset - The characters indicating the charset that will be used.
// Return value:
// True if handled successfully. False otherwise.
bool AdaptDispatch::Designate94Charset(const size_t gsetNumber, const wchar_t newCharset)
bool AdaptDispatch::Designate94Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset)
{
return _termOutput.Designate94Charset(gsetNumber, newCharset);
}
Expand All @@ -1445,10 +1445,10 @@ bool AdaptDispatch::Designate94Charset(const size_t gsetNumber, const wchar_t ne
//Arguments:
// - gsetNumber - The G-set into which the charset will be selected.
// - setSize - The size of the selected charset - 94 or 96.
// - newCharset - The character indicating the charset that will be used.
// - newCharset - The characters indicating the charset that will be used.
// Return value:
// True if handled successfully. False otherwise.
bool AdaptDispatch::Designate96Charset(const size_t gsetNumber, const wchar_t newCharset)
bool AdaptDispatch::Designate96Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset)
{
return _termOutput.Designate96Charset(gsetNumber, newCharset);
}
Expand Down
4 changes: 2 additions & 2 deletions src/terminal/adapter/adaptDispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ namespace Microsoft::Console::VirtualTerminal
bool BackwardsTab(const size_t numTabs) override; // CBT
bool TabClear(const size_t clearType) override; // TBC
bool DesignateCodingSystem(const wchar_t codingSystem) override; // DOCS
bool Designate94Charset(const size_t gsetNumber, const wchar_t newCharset) override; // SCS
bool Designate96Charset(const size_t gsetNumber, const wchar_t newCharset) override; // SCS
bool Designate94Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset) override; // SCS
bool Designate96Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset) override; // SCS
bool LockingShift(const size_t gsetNumber) override; // LSx
bool LockingShiftRight(const size_t gsetNumber) override; // LSxR
bool SingleShift(const size_t gsetNumber) override; // SSx
Expand Down
4 changes: 2 additions & 2 deletions src/terminal/adapter/termDispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Cons
bool DeviceAttributes() noexcept override { return false; } // DA

bool DesignateCodingSystem(const wchar_t /*codingSystem*/) noexcept override { return false; } // DOCS
bool Designate94Charset(const size_t /*gsetNumber*/, const wchar_t /*newCharset*/) noexcept override { return false; } // SCS
bool Designate96Charset(const size_t /*gsetNumber*/, const wchar_t /*newCharset*/) noexcept override { return false; } // SCS
bool Designate94Charset(const size_t /*gsetNumber*/, const std::pair<wchar_t, wchar_t> /*newCharset*/) noexcept override { return false; } // SCS
bool Designate96Charset(const size_t /*gsetNumber*/, const std::pair<wchar_t, wchar_t> /*newCharset*/) noexcept override { return false; } // SCS
bool LockingShift(const size_t /*gsetNumber*/) noexcept override { return false; } // LSx
bool LockingShiftRight(const size_t /*gsetNumber*/) noexcept override { return false; } // LSxR
bool SingleShift(const size_t /*gsetNumber*/) noexcept override { return false; } // SSx
Expand Down
15 changes: 11 additions & 4 deletions src/terminal/adapter/terminalOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,9 @@ TerminalOutput::TerminalOutput() noexcept
_gsetTranslationTables.at(3) = Latin1;
}

bool TerminalOutput::Designate94Charset(size_t gsetNumber, const wchar_t newCharset)
bool TerminalOutput::Designate94Charset(size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset)
{
switch (newCharset)
switch (newCharset.first)
{
case L'B': // US ASCII
case L'1': // Alternate Character ROM
Expand Down Expand Up @@ -302,14 +302,21 @@ bool TerminalOutput::Designate94Charset(size_t gsetNumber, const wchar_t newChar
return _SetTranslationTable(gsetNumber, SwedishNrcs);
case L'=': // Swiss NRCS
return _SetTranslationTable(gsetNumber, SwissNrcs);
case L'%':
switch (newCharset.second)
{
case L'5': // DEC Supplemental
return _SetTranslationTable(gsetNumber, DecSupplemental);
}
return false;
default:
return false;
}
}

bool TerminalOutput::Designate96Charset(size_t gsetNumber, const wchar_t newCharset)
bool TerminalOutput::Designate96Charset(size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset)
{
switch (newCharset)
switch (newCharset.first)
{
case L'A': // ISO Latin-1 Supplemental
return _SetTranslationTable(gsetNumber, Latin1);
Expand Down
4 changes: 2 additions & 2 deletions src/terminal/adapter/terminalOutput.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ namespace Microsoft::Console::VirtualTerminal
TerminalOutput() noexcept;

wchar_t TranslateKey(const wchar_t wch) const noexcept;
bool Designate94Charset(const size_t gsetNumber, const wchar_t newCharset);
bool Designate96Charset(const size_t gsetNumber, const wchar_t newCharset);
bool Designate94Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset);
bool Designate96Charset(const size_t gsetNumber, const std::pair<wchar_t, wchar_t> newCharset);
bool LockingShift(const size_t gsetNumber);
bool LockingShiftRight(const size_t gsetNumber);
bool SingleShift(const size_t gsetNumber);
Expand Down
86 changes: 56 additions & 30 deletions src/terminal/parser/OutputStateMachineEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,34 +265,6 @@ bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch,
{
switch (til::at(intermediates, 0))
{
case L'(':
success = _dispatch->Designate94Charset(0, wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG0);
break;
case L')':
success = _dispatch->Designate94Charset(1, wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1);
break;
case L'*':
success = _dispatch->Designate94Charset(2, wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2);
break;
case L'+':
success = _dispatch->Designate94Charset(3, wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3);
break;
case L'-':
success = _dispatch->Designate96Charset(1, wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1);
break;
case L'.':
success = _dispatch->Designate96Charset(2, wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2);
break;
case L'/':
success = _dispatch->Designate96Charset(3, wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3);
break;
case L'%':
success = _dispatch->DesignateCodingSystem(wch);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DOCS);
Expand All @@ -311,17 +283,71 @@ bool OutputStateMachineEngine::ActionEscDispatch(const wchar_t wch,
}
break;
default:
// If no functions to call, overall dispatch was a failure.
success = false;
success = _IntermediateScsDispatch(wch, intermediates);
break;
}
}
else if (intermediates.size() == 2)
{
success = _IntermediateScsDispatch(wch, intermediates);
}

_ClearLastChar();

return success;
}

// Routine Description:
// - Handles SCS charset designation actions that can have one or two possible intermediates.
// Arguments:
// - wch - Character to dispatch.
// - intermediates - Intermediate characters in the sequence
// Return Value:
// - True if handled successfully. False otherwise.
bool OutputStateMachineEngine::_IntermediateScsDispatch(const wchar_t wch,
const std::basic_string_view<wchar_t> intermediates)
{
bool success = false;

// If we have more than one intermediate, the second intermediate forms part of
// the charset identifier. Otherwise it's identified by just the final character.
const auto newCharset = intermediates.size() > 1 ? std::make_pair(intermediates.at(1), wch) : std::make_pair(wch, L'\0');

switch (intermediates.at(0))
{
case L'(':
success = _dispatch->Designate94Charset(0, newCharset);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG0);
break;
case L')':
success = _dispatch->Designate94Charset(1, newCharset);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1);
break;
case L'*':
success = _dispatch->Designate94Charset(2, newCharset);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2);
break;
case L'+':
success = _dispatch->Designate94Charset(3, newCharset);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3);
break;
case L'-':
success = _dispatch->Designate96Charset(1, newCharset);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG1);
break;
case L'.':
success = _dispatch->Designate96Charset(2, newCharset);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG2);
break;
case L'/':
success = _dispatch->Designate96Charset(3, newCharset);
TermTelemetry::Instance().Log(TermTelemetry::Codes::DesignateG3);
break;
}

return success;
}

// Routine Description:
// - Triggers the CsiDispatch action to indicate that the listener should handle
// a control sequence. These sequences perform various API-type commands
Expand Down
2 changes: 2 additions & 0 deletions src/terminal/parser/OutputStateMachineEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ namespace Microsoft::Console::VirtualTerminal
std::function<bool()> _pfnFlushToTerminal;
wchar_t _lastPrintedChar;

bool _IntermediateScsDispatch(const wchar_t wch,
const std::basic_string_view<wchar_t> intermediates);
bool _IntermediateQuestionMarkDispatch(const wchar_t wchAction,
const std::basic_string_view<size_t> parameters);
bool _IntermediateExclamationDispatch(const wchar_t wch);
Expand Down

0 comments on commit 8e46c7f

Please sign in to comment.