^[control-codes live in libghostty-vt
View as Markdown

Private status requests: DEC's extended cursor position, printer, keyboard and macro space, and newer ones for dark or light colors and visibility.

CSI ? Ps n

DECXCPR Extended Cursor Position Report

CSI ? Pl ; Pc ; Pp R

DECMSR Macro Space Report

CSI Pn * {
DEC STD 070
§5.4.4 Extended Cursor Position Report, p. 5-55
VT220
§4.17.2 Device Status Report (DSR)
VT510
DSR—Device Status Reports

With a ? before the parameter, a device status report asks one of DEC’s own questions, or one of the few that newer terminals have added in the same form. Each has its own answer:

PsAsks forPossible answersxterm, as a VT420, answers
5the operating status, in the private formCSI ? 0 n, readyCSI ? 0 n
6the cursor position, with the page: DECXCPRCSI ? Pl ; Pc ; Pp RCSI ? Pl ; Pc ; 1 R
15the printer’s statusCSI ? 10 n ready, 11 not ready, 13 no printer, 18 busy, 19 assigned to the other sessionCSI ? 13 n, no printer
25whether the user-defined keys are lockedCSI ? 20 n unlocked, 21 lockedCSI ? 20 n, unlocked
26the keyboardCSI ? 27 ; Pn ; Pst ; Ptyp n: language, status and typeCSI ? 27 ; 1 ; 0 ; 0 n: North American, ready, an LK201
55the locator’s statusCSI ? 50 n ready, 53 no locatorCSI ? 53 n, no locator
56the locator’s typeCSI ? 57 ; 0 n unknown, 57 ; 1 a mouseCSI ? 57 ; 0 n, unknown
62the space left for macros: DECMSRCSI Pn * {CSI 0000 * {, none
63 ; Pida checksum of the macros: DECCKSRDCS Pid ! ~ D…D STDCS Pid ! ~ 0000 ST
75the data integrity flagCSI ? 70 n no errors, 71 an error, 73 no report since power-upCSI ? 70 n, no errors
85the multiple-session configurationCSI ? 83 n not configured, among othersCSI ? 83 n, not configured
996whether the colors are dark or lightCSI ? 997 ; 1 n dark, 997 ; 2 lightnothing
998whether the view is visibleCSI ? 999 ; 1 n potentially visible, 999 ; 2 not visiblenothing

?996 is from Contour’s Dark and Light Mode detection, and ?998 from Private Mode for Terminal Visibility Reports; each answer is sent unasked as well, while its private mode, 2031 or 2033, is set. The rest are DEC’s. The possible answers are the VT510 manual’s, for the locator xterm’s control sequences, and for multiple sessions only the one xterm sends.

Most answers take the same form, CSI ? Ps n, so a host reading one back can tell from the number what it answers:

Answer PsAnswersMeans
0?5ready
10, 11, 13, 18, 19?15the printer is ready, not ready, missing, busy, or assigned to the other session
20, 21?25the user-defined keys are unlocked, or locked
27?26the keyboard: its language, status and type follow
50, 53?55the locator is ready, or missing
57?56the locator: its type follows
70, 71, 73?75no errors, an error, or no report since power-up
83?85not configured for multiple sessions
997?996the colors: 1 dark or 2 light follows
999?998the view: 1 potentially visible or 2 not visible follows

A terminal that receives one of these answers has not been asked anything, and does not answer it.

These are the answers in xterm’s CASE_DSR, from a default build, which is a VT420 (DFT_DECID). Each is gated on a terminal level: the printer, keyboard and user-defined key reports need a VT220 or later, the locator reports a VT330, and DECMSR, DECCKSR, data integrity and multiple sessions a VT420. The locator answers depend on how xterm was built: with --enable-dec-locator, which is off by default, it answers CSI ? 50 n (ready) and CSI ? 57 ; 1 n (a mouse) instead. xterm also answers CSI ? 5 n with CSI ? 0 n, the operating status in the private form.

DECXCPR is the cursor position report with the page number added. DEC STD 070 makes it a level 3 and 4 function, and counts the line and column from the margins in origin mode, as CPR does. Its answer starts CSI ?; the VT510 manual’s DECXCPR page leaves the ? out, but xterm sends it, and esctest2’s test_DECDSR_DECXCPR expects it. xterm, with one page, always reports page 1.

DECMSR reports the bytes free for macros, divided by 16 (DEC STD 070 §5.12.3, p. 5-185). xterm has no macros and reports none; it writes the number as four hexadecimal digits, 0000, where DEC STD 070 defines a plain number.

DECCKSR reports a checksum as four hexadecimal digits in a control string labelled with the Pid the request gave (DEC STD 070 §5.12.2, p. 5-181). The same report answers DECRQCRA’s checksum of a rectangle. With no macros, xterm reports 0000.

The VT510 manual describes the others on their own pages: printer port, user-defined keys, keyboard, macro space, memory checksum and data integrity.

Not in libghostty-vt

libghostty-vt answers only DECXCPR, ?6, of DEC’s requests, always with page 1, as xterm does. Its DSR dispatch in stream.zig looks the request up in a table, entries in device_status.zig, that has only the ANSI requests 5 and 6, DECXCPR, and two private ones of its own, ?996 (the color scheme) and ?998 (visibility); any other request, and any with two parameters such as ?63 ; Pid, is logged as invalid and dropped. Every case below that expects an answer to another request is therefore a known difference: xterm, a VT420 by default, sends it.

Support

TerminalVersionSupportNotes
VT220manual, 2nd ed., 1984Partlyprinter, user-defined keys and keyboard only (§4.17.2 Device Status Report (DSR))
VT510manual, 1st ed., 1993PartlyDSR: no locator (55, 56) or multiple-session (85) reports
xtermpatch 412, xterm-411aYesreports no locator unless built with --enable-dec-locator
libghostty-vt919dca5Partlyanswers only DECXCPR, ?6, of these, and its own ?996 and ?998
kitty0.49.1, run in a VMNofails the 2 cases that show it working
foot1.28.0, run in a VMNofails the 2 cases that show it working
pyte0.8.2, run as a libraryNofails the 2 cases that show it working
xterm.js headless6.0.0, run as a libraryNofails the 2 cases that show it working
alacritty_terminal0.26.0, run as a libraryNofails the 2 cases that show it working
ConEmubuild 230724, its documentationNolists only ESC [ 5 n and ESC [ 6 n: ANSI escape codes
rxvt-unicode9.31, run in a VMNofails the 2 cases that show it working
VTE0.84.1, run as a libraryYespasses the 2 cases that show it working

Validation

DECDSR-1: Extended cursor position

\e[2;3H
\e[?6n
|_____|
|_____|
|_____|
reply \e[?2;3;1R

DECDSR-2: Counted from the margins in origin mode

\e[?69h   # allow left and right margins
\e[2;5s   # margins at columns 2 and 5
\e[2;4r   # region is lines 2 to 4
\e[?6h    # origin mode
\e[2;2H   # line 3, column 3 of the screen
\e[?6n
|_____|
|_____|
|_____|
|_____|
cursor 3,3
reply \e[?2;2;1R

DECDSR-3: Operating status, the private way

\e[?5n
|_____|
reply \e[?0n

DECDSR-4: Printer, user-defined keys and keyboard

\e[?15n   # printer
\e[?25n   # user-defined keys
\e[?26n   # keyboard
|_____|
reply \e[?13n\e[?20n\e[?27;1;0;0n

DECDSR-5: The locator

\e[?55n   # status
\e[?56n   # type
|_____|
reply \e[?53n\e[?57;0n

DECDSR-6: Macro space

\e[?62n
|_____|
reply \e[0000*{

DECDSR-7: Memory checksum

\e[?63;123n
|_____|
reply \eP123!~0000\e\\

DECDSR-8: Data integrity and multiple sessions

\e[?75n   # data integrity
\e[?85n   # multiple sessions
|_____|
reply \e[?70n\e[?83n

DECDSR-9: A request it does not know

\e[?99n
|_____|
reply none
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.