[hackers] [dvtm][PATCH] Reply to primary DA query

From: Johannes Altmanninger <aclopte_AT_gmail.com>
Date: Sun, 9 Feb 2025 10:42:22 +0100

TUI programs that want to use features that are not
backwards-compatible can do so by querying for support (via XTGETTCAP
for example) and awaiting the terminals reply.

A terminal that doesn't support a certain feature may fail to reply.
A good workaround is to follow-up the initial query with another
query that is expected to get a reply.

Primary DA is the de-facto standard query to use. It is implemented
by every terminal I know, including Terminal.app, st, Putty.

In absence of a reply,
- TUI framework [notcurses] will hang forever
- TUI framwork [libvaxis] will block with a 1 second timeout
- fish shell will do either (currently hangs until ctrl-c is pressed)

So far, among relevant terminal-like programs, I found only dvtm
(and pexpect) to be missing Primary DA.

Pretend we are a VT102 (see
https://invisible-island.net/xterm/ctlseqs/ctlseqs.html) because
that's what st uses. I believe this should be fine in practice but
if there are concerns that programs might make invalid assumptions
based on that, we can invent a new user agent.

st allows to configure this string; that would be fine too although
I have not found out why one would want to.

Alternatively, we could forward the request to stdout (i.e. do
"printf '\033[0c'") which would cause dvtm's parent terminal to reply.
I think this would be more technically-correct, but since it doesn't
look like we directly forward any other query, I'd stick to this
safer option for now.

[notcurses]: https://github.com/dankamongmen/notcurses/blob/da7151929d9f87a73cabb4c5b54668b3a42cfcaf/TERMINALS.md?plain=1#L35-L37
[libvaxis]: https://github.com/rockorager/libvaxis
---
 vt.c | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/vt.c b/vt.c
index 15dabc1..3a2afe3 100644
--- a/vt.c
+++ b/vt.c
_AT_@ -1078,6 +1078,13 @@ static void interpret_csi(Vt *t)
 	case 'Z': /* CBT: cursor backward tabulation */
 		puttab(t, param_count ? -csiparam[0] : -1);
 		break;
+	case 'c':
+		if (param_count == 0 || (param_count == 1 && csiparam[0] == 0)) {
+			// Primary Device Attribute.
+			const char* vtiden = "\033[?6c";
+			vt_write(t, vtiden, strlen(vtiden));
+		}
+		break;
 	case 'g': /* TBC: tabulation clear */
 		switch (param_count ? csiparam[0] : 0) {
 		case 0:
-- 
2.48.1
Received on Sun Feb 09 2025 - 10:42:22 CET

This archive was generated by hypermail 2.3.0 : Sun Feb 09 2025 - 11:00:39 CET