DCS escape codes — device control strings
Device Control String. The `ESC P … ESC \` envelope — Sixel graphics, ReGIS, terminfo-query protocol (XTGETTCAP), DECRQSS (request selection or setting). High-bandwidth out-of-band data: anything from an inline image to a query for the terminal's current cursor style.
11 sequences
DCS cookbook — reading the device-control family in five stops
DCS — Device Control String — is the \x1bP … \x1b\\ envelope ECMA-48 reserves for high-bandwidth, opaque payloads aimed at the terminal itself (not at a peer application — that's APC's lane). Five stops cover what the family actually does in 2026: the envelope shape, embedding pixel images (Sixel + Kitty graphics), runtime introspection queries, the legacy VT remap surfaces (user-defined keys, dynamically downloaded glyphs, macros), and the save/replay presentation-state pair.
1. The DCS envelope —
\x1bP … \x1b\\(or\x90 … \x9cin 8-bit)Every DCS sequence is
\x1bP(ESCP), thenPp;Pn;…header params, then a|or final-byte selector, then arbitrary payload, then\x1b\\(ST). The 8-bit C1 form\x90 … \x9cis the same in one byte each but UTF-8-unsafe — avoid outside known Latin-1 channels. The envelope is supposed to round-trip **opaquely** through middleware: tmux'sallow-passthrough on(≥ 3.3) wraps inner DCS in its own outer DCS\x1bPtmux;<doubled-ESC-inner>\x1b\\so the bytes survive a multiplexer hop (seetmux-passthrough-dcspitfall). Payload-length limits vary: xterm'sdecGraphicsTermLevelresource caps the Sixel buffer; kitty has no fixed limit but the parser is stateful (one half-complete DCS in flight per pane); ConPTY historically truncated large DCS bodies at 4KB. **Always emit ST**; a missing terminator hangs the parser until the next stray\x1b\\byte pair, at which point everything past the lost ST is treated as DCS payload and silently swallowed.2. Pictures inside the stream — Sixel and Kitty graphics
Two protocols embed pixel data. **Sixel** is the original —
\x1bPq<sixel-data>\x1b\\(DCS final byteq). Each "sixel" character (?to~) encodes a vertical strip of 6 pixels with a 64-colour palette; predates RGB displays. xterm (with--enable-sixel-graphics), foot, WezTerm, iTerm2, Konsole, mlterm, and Ghostty 1.0+ all render it; macOS Terminal, GNOME Terminal, alacritty, and the Linux console don't. **Kitty graphics** is the modern alternative — despite the slug namedcs-kitty-graphics, the actual byte form is APC (\x1b_G<key>=<val>,…;<base64-pixels>\x1b\\), not DCS, but readers searching for terminal-image protocols land on both pages so the cross-ref makes sense here. Kitty graphics streams PNG / RGBA in chunks (4KB each,m=1continues,m=0ends), supports placement IDs for animation, and works in Kitty, Konsole 22.04+, WezTerm 20240128+, and Ghostty. The colour-banding caveat fromtruecolor-fallback-bandingstill applies inside the pixel envelope on emulators that downsample.3. Asking the terminal questions — DECRQSS, terminfo cap, DECRQTSR, DECRQUPSS, cursor-style
Five queries let a TUI inspect the terminal's current state at runtime.
\x1bP$q<P>\x1b\\(DECRQSS) is the catch-all — substitute<P>form(current SGR),r(top/bottom margin),s(left/right margin),q(cursor style),"q(DECSCA protection),"p(DECSCL compat level). The terminal replies on stdin with a matching DCS containing the actual settings.\x1bP+q<HEX-NAME>;<HEX-NAME>…\x1b\\(XTGETTCAP, slugdcs-termcap-query) asks for terminfo capabilities by their hex-encoded names — the runtime way to detect truecolor (RGB), OSC 52 clipboard (Ms), or styled underline.\x1bP1$u\x1b\\(DECRQTSR / DECRQPSR) requests Terminal State Report — saves the full per-mode bit vector; pair with\x1bP\$t…\x1b\\(DECRSTS) to restore.\x1bP&u\x1b\\(DECRQUPSS) asks which character set is currently loaded into the user-preferred slot.\x1bP$q q\x1b\\(cursor-style sub-query of DECRQSS — slugdecscusr-query) returns the active cursor shape (blink-block, steady-bar, etc.). All replies arrive **asynchronously** on stdin — read with a deadline or aselect(2)rendezvous, not a blocking read.See alsoDECRQSS — Request Selection or Setting (DCS $ q ... ST)XTGETTCAP — Request terminfo capability (DCS + q ... ST)DECRQTSR / DECRSTS — Request / Restore Terminal State ReportDECRQUPSS / DECAUPSS — Request / Assign User-Preferred Supplemental SetDECSCUSR query via DECRQSS — Read the current cursor shape (`\x1bP$q q\x1b\\`)4. VT remap surfaces — DECUDK (user-defined keys) and DECDLD (downloaded glyphs)
Two legacy VT500-line capabilities that xterm + mlterm still honour in 2026 — niche, but they show up in CTF / retrocomputing setups. **DECUDK** (
\x1bPPc;Pl|Ky/St;Ky/St;…\x1b\\) reassigns the DEC user-defined function keys (F6–F20) to arbitrary byte sequences at runtime — a poor-man's macro keymap, useful when you can't edit the user's terminfo.Pccontrols whether to extend or replace the existing UDK table;Plis lock mode; eachKy/Stpair is key number + hex-encoded ST (output string). **DECDLD** (\x1bP<params>{ <pattern>\x1b\\) downloads a Sixel-pattern glyph into a character-set slot — back when terminals had limited glyph ROM you could ship a custom character (a checkmark, a CJK ideograph, a hand-drawn icon) per session. xterm renders it via thedecTerminalID = 220resource path; useful today for retro-styled TUIs that want a custom border-drawing slot beyond Unicode's box-drawing region. Both are safe to emit on terminals that don't implement them — modern emulators discard the body and continue.5. Stateful save / replay — DECDMAC (define macro) and DECRSPS (restore presentation state)
Two save-and-replay primitives from the VT500 line. **DECDMAC** (
\x1bPPid;Pdt;Pen!z<macro-body>\x1b\\) names a sequence of bytes under integerPid(1–63); recall it any time later with\x1b[Pid*z(DECINVM — Invoke Macro).Pdtsays whether to overwrite or append a macro with the same id;Pentoggles between literal body and base-encoded body (compresses repeated bytes). Useful for a TUI that paints the same frame chrome dozens of times — define once, recall with three bytes per repaint. xterm + WezTerm honour it; alacritty, gnome-terminal, macOS Terminal ignore (no-op-safe). **DECRSPS** (\x1bP<Ps>$t<state-data>\x1b\\) is the inverse ofDECRQTSRfrom section 3 — paste the state-report bytes back to restore the full mode vector.Ps=1restores DEC private modes,Ps=2restores cursor info. The round-trip pair (DECRQTSR → save → DECRSPS) lets a TUI checkpoint terminal state before a risky operation and roll back cleanly on failure — the terminal-emulation equivalent of a database transaction.
All sequences in this family
- DCS Sixel — Inline raster graphics (ESC P q … ESC \)
\x1bPq <sixel data> \x1b\\Embed pixel images in the terminal stream using the Sixel device-control payload.
- Kitty graphics protocol — Inline pixel images (ESC _ G … ESC \)
\x1b_Ga=T,f=100,m=1;BASE64_CHUNK\x1b\\Modern alternative to Sixel: stream PNG / RGBA bytes to the terminal via the Kitty APC frame, with sane chunking and a placement protocol.
- DECRQSS — Request Selection or Setting (DCS $ q ... ST)
\x1bP$q<P>\x1b\\Ask the terminal to report the current value of any SGR / mode / margin / cursor-shape setting — the catch-all DCS query.
- XTGETTCAP — Request terminfo capability (DCS + q ... ST)
\x1bP+q<HEX-NAME>;<HEX-NAME>...\x1b\\Ask the terminal to report a terminfo capability value by its name — the runtime way to probe true-colour, RGB, OSC 52, etc.
- DECUDK — Define User-Defined Keys (DCS Pc;Pl|Ky/St;... ST)
\x1bPPc;Pl|Ky/St;Ky/St;...\x1b\\Remap the DEC user-defined function keys (F6–F20) at runtime — legacy DEC VT, still decoded by xterm and its forks.
- DECDLD — Dynamically Redefinable Character Set (DCS ... { ... ST)
\x1bPPfn;Pcn;Pe;Pcms;Pw;Pt{Dscs Sxbp1;Sxbp2;...\x1b\\Download a soft glyph bitmap into a slot the terminal can then display alongside the built-in font — pure DEC VT220+ legacy.
- DECRSPS — Restore Presentation State (DCS $ t ... ST)
\x1bP1$t<saved-state>\x1b\\ (cursor) \x1bP2$t<saved-state>\x1b\\ (tab stops)Inverse of DECRQSS — feed back a previously-saved cursor / SGR / margin snapshot to restore the terminal's exact state.
- DECDMAC / DECINVM — Define & invoke macro (DCS Pn ; Pn ; Pn ! z ... ST / CSI Pn * z)
\x1bP<Pid>;<Pdt>;<Penc>!z<MACRO-BODY>\x1b\\ (define) \x1b[<Pid>*z (invoke)Store a byte sequence under a numeric handle (DECDMAC), then replay it on demand (DECINVM) — DEC VT520's terminal-side macro recorder.
- DECSCUSR query via DECRQSS — Read the current cursor shape (`\x1bP$q q\x1b\\`)
\x1bP$q q\x1b\\Round-trip the cursor-shape parameter — query side of DECSCUSR via DECRQSS, terminal replies with the current `Ps SP q` setting.
- DECRQUPSS / DECAUPSS — Request / Assign User-Preferred Supplemental Set
\x1b[&u request \x1bP<Ps>!u<D…D>\x1b\\ assignQuery (`CSI & u`) and assign (`DCS Ps ! u … ST`) the supplemental character set the terminal maps into the GR slot when no Locking Shift is active. Closes the supplemental-set plumbing left after `single-locking-shift`.
- DECRQTSR / DECRSTS — Request / Restore Terminal State Report
\x1b[Ps$u request \x1bP<Ps>$p<body>\x1b\\ restoreSave (`CSI Ps$u` → DCS reply) and restore (`DCS Ps$p…ST`) the whole DEC terminal state — the terminal-wide complement to `dcs-decrsps`' presentation-state-only scope.