Note
Windows local sessions use the bundled Microsoft ConPTY runtime, including
OpenConsole.exe, rather than the OS copy that filters Sixel on some Windows
builds. Sixel producers such as Get-XKCD -Show can therefore render inline
images. Other transports must likewise preserve graphics payloads.
Devolutions.Terminal.Core parses advanced string protocols without depending on Avalonia,
Skia, Win32, or an image codec. It exposes decoded Sixel pixels and bounded
encoded OSC 1337/ConEmu images as renderer-neutral overlay metadata.
| Sequence | Core behavior |
|---|---|
DCS ... q data ST / CSI ? 80 h/l |
Decodes Sixel with macro aspect ratio, repeat, color registers (HLS and RGB), raster attributes, graphics CR/LF, opaque or transparent backgrounds, DECSDM display/scroll behavior, and retained cell geometry. |
DCS $ q request ST |
Implements DECRQSS for SGR, DECSTBM, DECSLRM, DECSCUSR (default style), DECSCA (unprotected), and DECSACE (stream extent). Unknown settings return DCS 0 $ r ST. |
DCS + q names ST |
Implements practical XTGETTCAP reports for TN, Co, RGB, and Tc, with one response per hex-encoded capability name. |
DCS ... { Dscs data ST |
Implements bounded DECDLD soft-font download (one 94/96-character DRCS buffer, 16×32 maximum glyphs), SCS designation, SI/SO, LS2/LS3, LS1R/LS2R/LS3R, and SS2/SS3 invocation. Cells use U+EF20–U+EF7F; DrcsGlyphs exposes renderer-neutral alpha masks. |
DCS Pmid;Pdel;Penc ! z data ST / CSI Pmid * z |
Defines, deletes, and invokes DECDMAC macros in text or hex-pair encoding, including bounded hex repeats. |
CSI ? 2 l / VT52 ESC commands |
Implements VT52 cursor movement, home, reverse index, erase-to-end, direct cursor address, identify (ESC / Z), keypad mode, DEC graphics, and ESC < return to ANSI mode. CSI, OSC, and DCS entry are disabled while in VT52 mode. |
CSI ... $ r/t/v/x/z/{ / CSI ... * y |
Implements DECCARA, DECRARA, DECCRA, DECFRA, DECERA, DECSERA, DECSACE stream/rectangle extent, and DECRQCRA checksums. |
CSI ? Ps J/K / CSI Ps " q |
Implements protected cells and DECSED/DECSEL selective erase. |
CSI 2;Pu $ u / DCS 2 $ p ... ST |
Reports and restores the 256-entry terminal color table in HLS or RGB percentage form. |
CSI Ps $ w / DCS Ps $ t ... ST |
Reports and restores cursor presentation state (Ps=1) and tab stops (Ps=2). |
OSC 1337 ; File=... : base64 ST |
Parses inline iTerm2 image name, declared size, width, height, aspect-ratio preference, and bounded encoded bytes. Non-inline file transfers are explicitly rejected without I/O. |
OSC 9 ; 4 ; st=0 ; sz=N ; base64 ST |
Parses bounded, single-part ConEmu encoded images. Multipart, malformed, size-mismatched, and oversized transfers are rejected. |
APC G control ; base64 ST |
Implements the kitty graphics protocol: direct transmission (t=d) of raw RGBA/RGB (f=32/f=24) and PNG-encoded (f=100) images, optional zlib compression (o=z), multi-chunk assembly (m=), transmit/transmit-and-display/put (a=t/T/p), query probe (a=q), and deletes by all/id/placement (a=d with d=a/A/i/I/p). Placements honor cell sizing (c/r, aspect-preserving when one axis is given), in-cell pixel offsets (x/y), source crop (X/Y/w/h), and z-index (z<0 below text, z>=0 above). a=T moves the cursor below the image unless C=1; a=p never moves it. Responds APC G i=id ; OK/error ST honoring the q quiet flags. |
The DCS state machine handles 7-bit and C1 entry/termination, parameter and
intermediate collection, passthrough, CAN/SUB cancellation, and an ESC
terminator split across input chunks. BEL does not terminate DCS. An ESC
followed by anything other than \ aborts the DCS and starts the new escape
sequence.
DECSDM defaults to reset (scrolling mode): Sixel images anchor at the cursor
unless the application explicitly selects display mode with CSI ? 80 h.
Limits are public constants on TerminalImageLimits and VtResourceLimits.
| Resource | Limit |
|---|---|
| Collected DCS payload | 4 MiB |
| Decoded OSC 1337 image | 768 KiB |
| Collected OSC payload | 1 MiB + 16 KiB (base64 of a 768-KiB image plus bounded metadata) |
| Collected APC payload per chunk | 1 MiB |
| Assembled kitty image (decompressed) | 32 MiB |
| Kitty pixel dimension / count | shared pixel limits below |
| Sixel width or height | 4096 pixels |
| Sixel pixel count | 16,777,216 |
| Sixel pixel writes per sequence | 67,108,864 |
| Retained overlays | 64 |
| Retained Core image data | 64 MiB |
| DRCS buffers | 1 |
| DRCS characters | 96 |
| DRCS glyph dimensions | 16×32 pixels |
| DECDMAC identifiers | 64 |
| Shared macro storage | 256 KiB |
| Macro invocation depth | 16 |
| Bytes expanded by one top-level macro invocation | 256 KiB |
Sequences that exceed a parser or decoder limit are discarded. Invalid DRCS dimensions and malformed macro hex/repeat payloads do not publish partial state. Macro definitions are rejected during macro invocation, and recursion plus total expansion are independently bounded. A failed Sixel decode does not modify persistent color registers. When the retained overlay budget is reached, Core evicts the oldest overlay before publishing the new one, including when different image protocols share that capacity.
Kitty direct-media regressions pin the exact pixel-count boundary separately
from the first value over it, and rejected file/shared-memory media report
ENOTSUP without publishing an overlay or performing I/O.
An inline OSC 1337 or single-part ConEmu transfer of exactly 768 KiB decoded
bytes is accepted; one byte beyond that limit is rejected. OSC collection
reserves enough room for the base64 expansion and its header, so an
otherwise valid maximum-size image is not silently discarded before decoding.
Split OSC/DCS/APC terminators publish no partial image, and malformed
continuations of kitty chunks discard pending data (a mismatched nonzero
image ID is rejected). Oversized individual APC fragments are discarded;
subsequent valid transmissions still work. Sixel raster/repeat dimensions
accept the 4096-pixel edge, reject the next pixel, and do not commit palette
changes from a rejected image.
Renderers can consume TerminalEngine.Images, the detached
TerminalSnapshot.Images, or subscribe to TerminalEngine.ImageAdded.
TerminalImageOverlay provides:
- a monotonic ID and protocol;
- the primary/alternate buffer identity;
- the cursor cell where the image was received;
- a
SixelImage, anInlineImage, or aKittyImageplacement.
SixelImage.PixelIndices contains 16-bit palette indexes. Index 256 is
transparent; indexes 0 through 255 address SixelImage.Palette, whose entries
are packed 0xAARRGGBB. ToRgba32() provides a detached packed RGBA/ARGB
surface for renderers that do not use indexed textures.
For OSC 1337, Core intentionally retains encoded PNG/JPEG/GIF bytes rather than
loading a codec. The renderer validates the encoded format, decodes it with its
own image stack, applies Width, Height, and PreserveAspectRatio, and clips
the result to its terminal viewport.
Overlay anchors retain a logical-line identity and logical cell offset. Snapshots resolve that anchor against the current scrollback/reflow layout, and the overlay is removed deterministically when its owning line segment is evicted. Main and alternate buffers retain independent identities. Regression tests exercise reflow, owning-line eviction, and reset independently for all four image protocols; reset clears both buffers' images, while kitty lowercase placement/all/id deletes remove overlays without freeing transmitted pixels (a later put can place the image again). Uppercase deletes free the corresponding image data. Kitty deletes leave unrelated Sixel overlays untouched. The Skia renderer uses only the available source pixels when a kitty crop extends beyond the right or bottom edge; the cropped region fills its requested cell rectangle. Invalid encoded inline data cannot paint an image, and a renderer reused after delete or reset does not paint stale cached pixels.
- DECTSR terminal-state format 1 (
CSI 1 $ u/DCS 1 $ p) remains unsupported, matching upstreamAdaptDispatch; color-table format 2 is supported. - DRCS font numbers are accepted for compatibility but share one soft-font buffer, matching upstream. Multi-byte DRCS designators are accepted for the common intermediate-plus-final form.
- VT52 printer commands and host keyboard encoding are outside
Devolutions.Terminal.Core; Core tracks cursor-key and keypad modes for input layers to consume. - non-inline OSC 1337 file transfer and remote file access (explicitly rejected)
- multipart ConEmu image payloads (explicitly rejected)
- kitty graphics file/temp-file/shared-memory media (
t=f/t/s) — rejected without I/O, matching the non-inline OSC 1337 policy - kitty animation frame control (
a=f) and Unicode placeholder placements (answeredENOTSUP) - kitty cell/z-index/number-targeted deletes (
d=c/x/y/z/n) — silent no-op; the cursor forf=100images withoutrstays put because Core retains codec bytes without decoding dimensions
These gaps avoid remote I/O and renderer/input dependencies while keeping every implemented parser and downloadable resource path bounded.