# Request Checksum of Rectangular Area (DECRQCRA)

> Ask for a checksum of part of the screen, to check it has not changed.

- **Sequence:** `CSI Pi ; Pp ; Pt ; Pl ; Pb ; Pr * y`
- **Defaults:** Pt = 1, Pl = 1, Pb and Pr = the last line and column
- **DECCKSR**, Memory Checksum Report: `DCS Pi ! ~ D…D ST`
- **XTCHECKSUM**, Select Checksum Extension: `CSI Ps # y`
- **DEC STD 070:** [§5.12.2 Request Checksum of Rectangular Area, p. 5-179](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n433/mode/1up)
- **VT510:** [DECRQCRA—Request Checksum of Rectangular Area](https://vt100.net/docs/vt510-rm/DECRQCRA.html)

Ask the terminal for a checksum of a rectangle of the screen, so that an
application can check nothing there has changed behind its back. `Pi` is a
label of the application's choosing, `Pp` the page, and `Pt`, `Pl`, `Pb` and
`Pr` the rectangle's top, left, bottom and right, as for the other
[rectangle operations](https://control-codes.page/csi/decera/index.html.md). The terminal answers with DECCKSR,
`DCS Pi ! ~ D…D ST`, where `D…D` is the checksum as four hexadecimal digits
([DEC STD 070 p. 5-181](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n435/mode/1up),
[DECCKSR](https://vt100.net/docs/vt510-rm/DECCKSR.html)). DEC STD 070
makes it part of level 4's data integrity features, for transaction
processing.

xterm, a VT420 by default, implements it
([`CASE_DECRQCRA`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L5626-L5646)),
summing the characters in the rectangle with a value added for each video
attribute, skipping blanks at the ends of lines, and negating the total
([`xtermCheckRect`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/screen.c#L3162-L3290);
its `checksumExtension` resource turns parts of that off). But it answers
only when the `GetChecksum` window operation is allowed, and by default it
is not: `GetChecksum` is in xterm's default list of disallowed window
operations
([`main.h`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/main.h#L150-L175)).
So a default xterm sends nothing.

libghostty-vt implements DECRQCRA, and XTCHECKSUM (`CSI Ps # y`), which
chooses the calculation as xterm's `checksumExtension` does, following
xterm's `xtermCheckRect`
([`xt_checksum.zig`](https://github.com/ghostty-org/ghostty/blob/0f171f650a1cbbd6df4a2573b6b0c7de57cc6d90/src/terminal/xt_checksum.zig)). But like xterm it
leaves them off, and for the same reason: a program could checksum the
screen one cell at a time and so read back everything on it. A host turns
them on with `GHOSTTY_TERMINAL_OPT_XT_CHECKSUM_REPORT`, and sets the
calculation with `GHOSTTY_TERMINAL_OPT_XT_CHECKSUM_EXTENSION`
([`terminal.h`](https://github.com/ghostty-org/ghostty/blob/0f171f650a1cbbd6df4a2573b6b0c7de57cc6d90/include/ghostty/vt/terminal.h#L2149-L2184));
until then both are ignored
([`stream_terminal.zig`](https://github.com/ghostty-org/ghostty/blob/0f171f650a1cbbd6df4a2573b6b0c7de57cc6d90/src/terminal/stream_terminal.zig#L1708)). The
first two cases run it as it comes, so it sends nothing, which is what a
default xterm does.

The rest run with checksum reports allowed, as the
[notation](https://control-codes.page/notation/index.html.md) page's `checksum-report` attribute asks, in xterm and
libghostty-vt alike. Both sum the area by default as a DEC terminal does:
each character's code, plus a value for each video attribute in its cell,
`0x80` for bold among them, with cells never written to left out, and the
total negated to 16 bits. XTCHECKSUM's bits change that: `1` leaves the
total as it is, `2` leaves the attributes out, `4` stops blanks being left
out, `8` counts cells never written to as spaces, and `16` uses whole code
points rather than DEC's 8-bit values.

The two differ when the request has only `Pi` and `Pp`. DEC STD 070 has the
bounds left out default to the whole page, and libghostty-vt sums the whole
screen. xterm skips past `Pi` and `Pp` only when there are more than two
parameters
([`xtermCheckRect`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/screen.c#L3182-L3186)), so with two it reads them
as the top and left: `CSI 7 ; 1 * y` asks for a rectangle starting at line
7, which on a screen of two lines is no rectangle at all, and xterm answers
`0000`. DECRQCRA-7 follows xterm and is a known difference. With the bounds
present but empty, `CSI 7 ; 1 ; ; ; ; * y`, xterm uses their defaults too.

## Support

| Terminal | Version | Support | Notes |
| --- | --- | --- | --- |
| VT220 | [manual](https://vt100.net/docs/vt220-rm/), 2nd ed., 1984 | No | not in the manual |
| VT510 | [manual](https://vt100.net/docs/vt510-rm/), 1st ed., 1993 | Yes | [DECRQCRA](https://vt100.net/docs/vt510-rm/DECRQCRA.html) |
| xterm | patch 412, [xterm-411a](https://github.com/ThomasDickey/xterm-snapshots/tree/xterm-411a) | Partly | off by default: `GetChecksum` is in the default `disallowedWindowOps` |
| libghostty-vt | [0f171f6](https://github.com/ghostty-org/ghostty/tree/0f171f650a1cbbd6df4a2573b6b0c7de57cc6d90) | Partly | off by default: the host turns it on with `GHOSTTY_TERMINAL_OPT_XT_CHECKSUM_REPORT`; XTCHECKSUM too; with only `Pi` and `Pp` it sums the whole screen where xterm reads them as the top and left (DECRQCRA-7) |
| ConEmu | build 230724, its [documentation](https://conemu.github.io/en/AnsiEscapeCodes.html) | No | not in its list: [ANSI escape codes](https://conemu.github.io/en/AnsiEscapeCodes.html) |

## Validation

### DECRQCRA-1: No answer by default

Input, one step per line:

```text
ABC
\e[1;1;1;1;1;3*y
```

Expected screen:

```text
|ABC_______|
reply none
```

### DECRQCRA-2: Nor for the whole screen

Input, one step per line:

```text
ABC
\e[7;1*y
```

Expected screen:

```text
|ABC_______|
|__________|
reply none
```

### DECRQCRA-3: Allowed, the sum of the area, negated

*Run with checksum reports allowed, as xterm is once GetChecksum is allowed.*

Input, one step per line:

```text
ABC
\e[1;1;1;1;1;3*y
```

Expected screen:

```text
|ABC_______|
reply \eP1!~FF3A\e\\
```

### DECRQCRA-4: A video attribute adds to its cell

*Run with checksum reports allowed, as xterm is once GetChecksum is allowed.*

Input, one step per line:

```text
\e[1mA\e[0mBC   # A in bold
\e[1;1;1;1;1;3*y
```

Expected screen:

```text
|ABC_______|
reply \eP1!~FEBA\e\\
```

### DECRQCRA-5: Cells never written to are left out

*Run with checksum reports allowed, as xterm is once GetChecksum is allowed.*

Input, one step per line:

```text
AB
\e[1;1;1;1;1;10*y
```

Expected screen:

```text
|AB________|
reply \eP1!~FF7D\e\\
```

### DECRQCRA-6: XTCHECKSUM 1 leaves the sum as it is

*Run with checksum reports allowed, as xterm is once GetChecksum is allowed.*

Input, one step per line:

```text
\e[1#y      # don't negate
ABC
\e[1;1;1;1;1;3*y
```

Expected screen:

```text
|ABC_______|
reply \eP1!~00C6\e\\
```

### DECRQCRA-7: With only two parameters, they are the top and left

*A known difference: libghostty-vt does not pass this case.*

*Run with checksum reports allowed, as xterm is once GetChecksum is allowed.*

Input, one step per line:

```text
ABC
\e[7;1*y      # Pt = 7 is off the screen
```

Expected screen:

```text
|ABC_______|
|__________|
reply \eP7!~0000\e\\
```

### DECRQCRA-8: Empty bounds are the whole screen

*Run with checksum reports allowed, as xterm is once GetChecksum is allowed.*

Input, one step per line:

```text
ABC
\e[7;1;;;;*y
```

Expected screen:

```text
|ABC_______|
|__________|
reply \eP7!~FF3A\e\\
```

---

This is the Markdown version of <https://control-codes.page/csi/decrqcra/>. 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>.
