Repository: microsoft/terminal (language: cpp)

Issue:
Update the Device Attributes report
# Description of the new feature/enhancement

Up to now, we've been identifying as a VT100, since we haven't fully met the conformance requirements for any of the higher level devices. But with the recent support that's been added for several VT extensions, I think it's time to consider an updated `DA` response.

The structure of a `DA` report is as follows: the first parameter value indicates the conformance level with a number in the range 61 to 69 (representing levels 1 to 9); subsequent parameters indicate the supported feature extensions. The early VT terminals didn't follow this standard, but their initial `DA` parameter would have always been below 60.

We still don't meet the requirements for level 2, so the first parameter in our `DA` response will have to be 61. But we do now support a number of feature extensions, which we can indicate with additional parameter values. Some of the more useful ones include:

7 = Soft Fonts (since PR #13965)
28 = Rectangular Editing (since PR #14285)
32 = Text Macros (since PR #14402, if accepted)

Applications that wish to take advantage of these features would be able to do so automatically if they could tell from the `DA` report that the terminal supported the necessary extensions.

# Proposed technical implementation details (optional)

Updating the `DA` report seems like it ought to be a trivial change. However, the complication for us is this it's handled on the conhost side, but it needs to take into account the capabilities of the conpty client. For example, conhost supports _Soft Fonts_, but they won't work over conpty unless the conpty client also supports them (and for Terminal that's dependent on the configured renderer).

My proposed solution for this is that we fire off a `DA` request to the conpty client on startup (similar to the way we sometimes send a `CPR` request on startup). We then save the relevant information from the client's response (for now just the _Soft Font_ support), and use that to determine what features we can include in our `DA` response.

Does that seem like a reasonable approach to take?


Discussion / hints:

Fix patch:
diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp
index 32c06d67bff..4225057355f 100644
--- a/src/terminal/adapter/adaptDispatch.cpp
+++ b/src/terminal/adapter/adaptDispatch.cpp
@@ -1373,16 +1373,36 @@ bool AdaptDispatch::DeviceStatusReport(const DispatchTypes::StatusType statusTyp
 }
 
 // Routine Description:
-// - DA - Reports the identity of this Virtual Terminal machine to the caller.
-//      - In our case, we'll report back to acknowledge we understand, but reveal no "hardware" upgrades like physical terminals of old.
+// - DA - Reports the service class or conformance level that the terminal
+//   supports, and the set of implemented extensions.
 // Arguments:
 // - <none>
 // Return Value:
 // - True.
 bool AdaptDispatch::DeviceAttributes()
 {
-    // See: http://vt100.net/docs/vt100-ug/chapter3.html#DA
-    _api.ReturnResponse(L"\x1b[?1;0c");
+    // This first parameter of the response is 61, representing a conformance
+    // level of 1. The subsequent parameters identify the supported feature
+    // extensions.
+    //
+    // 1 = 132 column mode (ConHost only)
+    // 6 = Selective erase
+    // 7 = Soft fonts
+    // 22 = Color text
+    // 23 = Greek character sets
+    // 24 = Turkish character sets
+    // 28 = Rectangular area operations
+    // 32 = Text macros
+    // 42 = ISO Latin - 2 character set
+
+    if (_api.IsConsolePty())
+    {
+        _api.ReturnResponse(L"\x1b[?61;6;7;22;23;24;28;32;42c");
+    }
+    else
+    {
+        _api.ReturnResponse(L"\x1b[?61;1;6;7;22;23;24;28;32;42c");
+    }
     return true;
 }
 
diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp
index 862d449031b..dd7b1e0964e 100644
--- a/src/terminal/adapter/ut_adapter/adapterTest.cpp
+++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp
@@ -1534,7 +1534,7 @@ class AdapterTest
         _testGetSet->PrepData();
         VERIFY_IS_TRUE(_pDispatch->DeviceAttributes());
 
-        auto pwszExpectedResponse = L"\x1b[?1;0c";
+        auto pwszExpectedResponse = L"\x1b[?61;1;6;7;22;23;24;28;32;42c";
         _testGetSet->ValidateInputEvent(pwszExpectedResponse);
 
         Log::Comment(L"Test 2: Verify failure when ReturnResponse doesn't work.");


Test patch: