# Screen Mode (DECSCNM)

> Show the whole screen in reverse video: dark text on a light background.

- **Sequence:** `CSI ? 5 h/l`
- **DEC STD 070:** [§5.6 Set/Reset Screen Mode, p. 5-94](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n348/mode/1up)
- **VT220:** [§4.6.12 Screen Mode (DECSCNM)](https://vt100.net/docs/vt220-rm/chapter4.html#S4.6.12)
- **VT510:** [DECSCNM—Screen Mode: Light or Dark Screen](https://vt100.net/docs/vt510-rm/DECSCNM.html)

`CSI ? 5 h` sets reverse screen and `CSI ? 5 l` puts it back to normal.
Reverse screen swaps the foreground and background colors of the whole
display, so that a terminal showing light text on a dark background shows
dark text on a light one. DEC STD 070 says the actual colors are the
implementation's to choose, and that every character rendition must still
work in both modes. Normal is the default in the VT510 manual.

It is a way of showing the screen, not a change to it. The VT510 manual says
DECSCNM "does not change the data in page memory": the characters and their
attributes, such as those set with [SGR](https://control-codes.page/csi/sgr/index.html.md), stay as they were.

libghostty-vt records the mode and leaves drawing it to its host, and the
terminals drawn on this site do not show it, so the cases check the mode
with DECRQM, and that the cells are unchanged.

## Support

| Terminal | Version | Support | Notes |
| --- | --- | --- | --- |
| VT220 | [manual](https://vt100.net/docs/vt220-rm/), 2nd ed., 1984 | Yes | [§4.6.12 Screen Mode (DECSCNM)](https://vt100.net/docs/vt220-rm/chapter4.html#S4.6.12) |
| VT510 | [manual](https://vt100.net/docs/vt510-rm/), 1st ed., 1993 | Yes | [DECSCNM](https://vt100.net/docs/vt510-rm/DECSCNM.html) |
| xterm | patch 412, [xterm-411a](https://github.com/ThomasDickey/xterm-snapshots/tree/xterm-411a) | Yes |  |
| libghostty-vt | [0f171f6](https://github.com/ghostty-org/ghostty/tree/0f171f650a1cbbd6df4a2573b6b0c7de57cc6d90) | Yes | records the mode and leaves drawing it to the host |
| kitty | 0.49.1, [run in a VM](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/kitty.json) | Yes | passes the 3 cases that show it working |
| foot | 1.28.0, [run in a VM](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/foot.json) | Yes | passes the 2 cases that show it working |
| pyte | 0.8.2, [run as a library](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/pyte.json) | No | fails the case that shows it working |
| xterm.js headless | 6.0.0, [run as a library](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/xtermjs.json) | No | fails the 3 cases that show it working |
| alacritty_terminal | 0.26.0, [run as a library](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/alacritty.json) | No | fails the 3 cases that show it working |
| ConEmu | build 230724, its [documentation](https://conemu.github.io/en/AnsiEscapeCodes.html) | No | not in ConEmu's list, [ANSI escape codes](https://conemu.github.io/en/AnsiEscapeCodes.html) |
| rxvt-unicode | 9.31, [run in a VM](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/urxvt.json) | Yes | passes the 3 cases that show it working |
| VTE | 0.84.1, [run as a library](https://git.jcollie.dev/jeff/control-codes/src/branch/main/emulators/results/vte.json) | Yes | passes the 2 cases that show it working |

## Validation

### DECSCNM-1: Set, and the cells are unchanged

Input, one step per line:

```text
AB
\e[?5h
\e[?5$p   # DECRQM: is mode 5 set?
```

Expected screen:

```text
|AB___|
attr 1,1 plain
reply \e[?5;1$y
```

### DECSCNM-2: Reset

Input, one step per line:

```text
\e[?5h
\e[?5l
\e[?5$p
```

Expected screen:

```text
|_____|
reply \e[?5;2$y
```

### DECSCNM-3: Normal to begin with

Input, one step per line:

```text
\e[?5$p
```

Expected screen:

```text
|_____|
reply \e[?5;2$y
```

---

This is the Markdown version of <https://control-codes.page/modes/decscnm/>. On that page every validation case runs live in libghostty-vt, the terminal emulation core of Ghostty, compiled to WebAssembly.

The validation cases are written in the notation described in <https://control-codes.page/notation/index.html.md>.
