DSR Device Status Report
Ask the terminal for its status or for the cursor position, and get a report back.
CSI Ps n
CPR Active Position Report
CSI Pl ; Pc R
- Defaults
- Ps = 0
- ECMA-48
- §8.3.35 DSR – Device Status Report, p. 40
- DEC STD 070
- §4, ch. 5 Device Status Report, p. 35
- VT220
- §4.17.2 Device Status Report (DSR)
- VT510
- DSR—Device Status Reports
A host sends DSR to ask the terminal something, and the terminal answers by sending a sequence back. Ps says what is asked:
Ps | Asks for | The terminal answers |
|---|---|---|
5 | its operating status | CSI 0 n, ready, or CSI 3 n, not working |
6 | the cursor position | CSI Pl ; Pc R, a cursor position report |
The answers 0 and 3 are themselves DSRs, sent the other way. A terminal that receives one has not been asked anything, and does not answer.
The cursor position report is CPR, defined in ECMA-48 §8.3.14 as Active Position Report, p. 35, in DEC STD 070 §5.4.4, p. 5-53, and in the VT510 manual as DSR—Cursor Position Report. Pl is the line and Pc the column, counting from 1. With origin mode on, DEC STD 070 counts them from the top and left margins instead, the same way CUP counts the position it is given, so a host can send a report straight back as a CUP.
DEC STD 070 sends its reports with the 8-bit CSI, 9B. libghostty-vt sends ESC [, as a terminal sending only 7-bit controls does.
DEC terminals answer many more Ps values, for the printer, the keyboard, and with a ? before the parameter (CSI ? 6 n is DECXCPR, the cursor position with the page number). libghostty-vt answers 5 and 6 only.
Support
| Terminal | Version | Support | Notes |
|---|---|---|---|
| VT220 | manual, 2nd ed., 1984 | Yes | §4.17.2 Device Status Report (DSR) |
| VT510 | manual, 1st ed., 1993 | Yes | DSR and DSR—Cursor Position Report |
| xterm | patch 412, xterm-411a | Yes | |
| libghostty-vt | 0f171f6 | Yes | answers 5 and 6 only, with ESC [ |
| kitty | 0.49.1, run in a VM | Partly | fails DSR-3, DSR-4 of the 4 cases that show it working |
| foot | 1.28.0, run in a VM | Partly | fails DSR-3 of the 4 cases that show it working |
| pyte | 0.8.2, run as a library | Partly | fails DSR-3, DSR-4 of the 4 cases that show it working |
| xterm.js headless | 6.0.0, run as a library | Partly | fails DSR-3, DSR-4 of the 4 cases that show it working |
| alacritty_terminal | 0.26.0, run as a library | Partly | fails DSR-3 of the 4 cases that show it working |
| ConEmu | build 230724, its documentation | Yes | 5 and 6; ANSI escape codes |
| rxvt-unicode | 9.31, run in a VM | Partly | fails DSR-3 of the 4 cases that show it working |
| VTE | 0.84.1, run as a library | Yes | passes the 4 cases that show it working |
Validation
DSR-1: Operating status
\e[5n
|_____|
reply \e[0n
DSR-2: Cursor position
\e[2;3H
\e[6n
|_____|
|_____|
|_____|
reply \e[2;3R
DSR-3: 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;2R
DSR-4: With a wrap pending
ABCDE # fills the line; a wrap is pending
\e[6n
|ABCDE|
|_____|
reply \e[1;5R
DSR-5: A report is not a question
\e[0n # "ready", as a terminal would answer
\e[3n # "not working"
|_____|
reply none