XTGETTCAP Request Termcap/Terminfo String
Ask the terminal what a key sends, or for one of a few of its capabilities, by its terminfo or termcap name.
DCS + q Pt ST
- xterm
- Device-Control functions
DCS + q Pt ST asks for one or more capabilities by name, so that a program can learn about the terminal it is actually talking to rather than trusting $TERM’s terminfo entry, which may be wrong or on another machine. Pt is the names, each in hexadecimal and separated by ;: kcuu1 is 6B63757531. The answer is DCS 1 + r name=value ST, with the name as it was sent and the value in hexadecimal too, or DCS 0 + r ST if the first name is not one the terminal knows.
It is xterm’s, and what a default xterm knows is a fixed table, not a terminfo entry (xtermcap.c):
- the keys: arrows, editing keys, function keys and the keypad, each by its terminfo name (
kcuu1,khome,kf1) or its termcap name (ku,kh,k1), and shifted ones such askRIT; Coorcolors, the number of colors,256;RGB, the bits per color it can show directly,8on a 24-bit display;TNorname, the terminal name it set$TERMto,xtermunless thetermNameresource says otherwise.
A key is answered by pretending to press it, so the answer is what the key sends now: kcuu1 is CSI A, until DECCKM makes it SS3 A (XTGETTCAP, xtermcapKeycode, cursor keys). Several names in one request get one answer, with the name=value pairs separated by ;; it stops at the first name it does not know, after writing the ;.
libghostty-vt answers from Ghostty’s own terminfo entry instead. Its key strings are fixed, the ones that entry gives, which assume DECCKM is set; it knows terminfo names only; it answers many capabilities xterm does not, such as Smulx and setrgbf, giving those as their terminfo source text; it gives each name its own DCS … ST, writes the names back in upper case, and says nothing about a name it does not know. It does not answer TN. The cases follow a default xterm, and the cases that touch those differences are known differences.
The names in the cases are sent in upper-case hexadecimal, which both write back unchanged, so that a case shows one difference at a time.
Validation
XTGETTCAP-1: Number of colors
\eP+q436F\e\\ # Co
\eP+q636F6C6F7273\e\\ # colors
|______|
reply \eP1+r436F=323536\e\\\eP1+r636F6C6F7273=323536\e\\
XTGETTCAP-2: Direct color
\eP+q524742\e\\ # RGB
|______|
reply \eP1+r524742=38\e\\
XTGETTCAP-3: F1
\eP+q6B6631\e\\ # kf1
|______|
reply \eP1+r6B6631=1B4F50\e\\
XTGETTCAP-4: Up arrow, as it is now
\eP+q6B63757531\e\\ # kcuu1: CSI A
|______|
reply \eP1+r6B63757531=1B5B41\e\\
XTGETTCAP-5: Up arrow, after DECCKM
\e[?1h
\eP+q6B63757531\e\\ # kcuu1: SS3 A
|______|
reply \eP1+r6B63757531=1B4F41\e\\
XTGETTCAP-6: Home
\eP+q6B686F6D65\e\\ # khome: CSI H
\e[?1h
\eP+q6B686F6D65\e\\ # khome: SS3 H
|______|
reply \eP1+r6B686F6D65=1B5B48\e\\\eP1+r6B686F6D65=1B4F48\e\\
XTGETTCAP-7: Shift and right arrow
\eP+q6B524954\e\\ # kRIT: CSI 1 ; 2 C
|______|
reply \eP1+r6B524954=1B5B313B3243\e\\
XTGETTCAP-8: By termcap name
\eP+q6B75\e\\ # ku
|______|
reply \eP1+r6B75=1B5B41\e\\
XTGETTCAP-9: The terminal’s name
\eP+q544E\e\\ # TN
|______|
reply \eP1+r544E=787465726D\e\\
XTGETTCAP-10: Two at once
\eP+q436F;524742\e\\ # Co;RGB
|______|
reply \eP1+r436F=323536;524742=38\e\\
XTGETTCAP-11: A name it does not know
\eP+q536D756C78\e\\ # Smulx
|______|
reply \eP0+r\e\\
XTGETTCAP-12: The name comes back as it was sent
\eP+q436f\e\\ # Co, in lower case
|______|
reply \eP1+r436f=323536\e\\