From bd0d7646bf0b54659370b5eb38bf240ea70821b7 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Mon, 25 Jan 2021 18:11:33 +0000 Subject: [PATCH] Add support for the DECID report (#8864) This PR adds support for the `DECID` (Identify Device) escape sequence, which allows for querying the terminal type in a way that is backwards compatible with VT52 terminals. This simply checks for the `ESC Z` sequence in the `ActionEscDispatch` method of output state machine, and forwards the query to the existing `DeviceAttributes` dispatch method, since the expected response is identical to a `DA` report. ## Validation Steps Performed I've added an output engine test that verifies that the `ESC Z` sequence is correctly interpreted as a `DA` query when in ANSI mode, and as a VT52 identification query when in VT52 mode. Closes #8857 --- .../parser/OutputStateMachineEngine.cpp | 4 ++++ .../parser/OutputStateMachineEngine.hpp | 1 + .../parser/ut_parser/OutputEngineTest.cpp | 23 ++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index b97045cdc1ec..5383cc4713c0 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -226,6 +226,10 @@ bool OutputStateMachineEngine::ActionEscDispatch(const VTID id) success = _dispatch->HorizontalTabSet(); TermTelemetry::Instance().Log(TermTelemetry::Codes::HTS); break; + case EscActionCodes::DECID_IdentifyDevice: + success = _dispatch->DeviceAttributes(); + TermTelemetry::Instance().Log(TermTelemetry::Codes::DA); + break; case EscActionCodes::RIS_ResetToInitialState: success = _dispatch->HardReset(); TermTelemetry::Instance().Log(TermTelemetry::Codes::RIS); diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index b1ebd19b87fb..69436840ca5c 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -78,6 +78,7 @@ namespace Microsoft::Console::VirtualTerminal RI_ReverseLineFeed = VTID("M"), SS2_SingleShift = VTID("N"), SS3_SingleShift = VTID("O"), + DECID_IdentifyDevice = VTID("Z"), ST_StringTerminator = VTID("\\"), RIS_ResetToInitialState = VTID("c"), LS2_LockingShift = VTID("n"), diff --git a/src/terminal/parser/ut_parser/OutputEngineTest.cpp b/src/terminal/parser/ut_parser/OutputEngineTest.cpp index 2dbe9e287558..fcc438ca5295 100644 --- a/src/terminal/parser/ut_parser/OutputEngineTest.cpp +++ b/src/terminal/parser/ut_parser/OutputEngineTest.cpp @@ -2811,11 +2811,32 @@ class StateMachineExternalTest final VERIFY_ARE_EQUAL(5u, pDispatch->_column - 1); // so are 1 more than the expected values. pDispatch->ClearState(); + } - Log::Comment(L"Identify Device"); + TEST_METHOD(TestIdentifyDeviceReport) + { + auto dispatch = std::make_unique(); + auto pDispatch = dispatch.get(); + auto engine = std::make_unique(std::move(dispatch)); + StateMachine mach(std::move(engine)); + + Log::Comment(L"Identify Device in VT52 mode."); + mach.SetAnsiMode(false); mach.ProcessCharacter(AsciiChars::ESC); mach.ProcessCharacter(L'Z'); VERIFY_IS_TRUE(pDispatch->_vt52DeviceAttributes); + VERIFY_IS_FALSE(pDispatch->_deviceAttributes); + + pDispatch->ClearState(); + + Log::Comment(L"Identify Device in ANSI mode."); + mach.SetAnsiMode(true); + mach.ProcessCharacter(AsciiChars::ESC); + mach.ProcessCharacter(L'Z'); + VERIFY_IS_TRUE(pDispatch->_deviceAttributes); + VERIFY_IS_FALSE(pDispatch->_vt52DeviceAttributes); + + pDispatch->ClearState(); } TEST_METHOD(TestOscSetDefaultForeground)