# Locator (DECELR, DECSLE, DECRQLP, DECEFR, DECLKD)

> Report the position of a mouse or tablet, the locator, to the host.

- **Sequence:** `CSI Ps ; Pu ' z`
- **Defaults:** Ps = 0, reports disabled; Pu = 0, character cells
- **DECEFR**, Enable Filter Rectangle: `CSI Pt ; Pl ; Pb ; Pr ' w`
- **DECSLE**, Select Locator Events: `CSI Pm ' {`
- **DECRQLP**, Request Locator Position: `CSI Ps ' |`
- **DECLKD**, Locator Key Definition: `DCS Pc $ w … ST`
- **DEC STD 070:** [§13, ch. 4 Enable Locator Reports, p. 5](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1019/mode/1up)
- **xterm:** [Functions using CSI](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)

DEC calls a mouse or a tablet a *locator*. With these functions a host can
ask a terminal that has one to report where it is and which buttons are
down:

| Sequence | Function | Does |
| --- | --- | --- |
| `CSI Ps ; Pu ' z` | DECELR, enable locator reports | `Ps`: `0` off, `1` on, `2` one report, then off; `Pu`: character cells or pixels |
| `CSI Pm ' {` | DECSLE, select locator events | which button presses and releases send a report |
| `CSI Ps ' \|` | DECRQLP, request locator position | asks for one report now |
| `CSI Pt ; Pl ; Pb ; Pr ' w` | DECEFR, enable filter rectangle | report once the locator leaves this rectangle |
| `DCS Pc $ w … ST` | DECLKD, locator key definition | what each button sends in ReGIS graphics input |

A report is DECLRP, `CSI Pe ; Pb ; Pr ; Pc ; Pp & w`: the event, the buttons
down, then the row, column and page of the locator.

All of this is DEC STD 070's Text Locator Extension, section 13, an optional
extension (its levels read "1x, 2x, 3x, 4x"). DECELR, DECSLE, DECRQLP and
DECEFR are in its chapter 4, from
[p. 5](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1019/mode/1up),
with DECLRP on
[p. 6](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1020/mode/1up);
DECLKD, for the separate Locator Port Extension, is §5.4 on
[p. 13](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1027/mode/1up).
A terminal that has the extension always answers a request, so an
application never waits for a report that will not come. With locator
reports disabled, DECRQLP is answered with event code `0`, "the locator is
unavailable", and no other parameters, `CSI 0 & w`
([p. 8](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n1022/mode/1up)),
and so is a DECEFR received while reports are disabled.

A default xterm does not have the extension. It is built in only with
`--enable-dec-locator`, which is off unless asked for
([`configure.in`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/configure.in#L1064-L1071)),
and without it xterm's parser maps the final byte of all four CSI sequences
to the handling it gives a malformed one
([`VTPrsTbl.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/VTPrsTbl.c#L63-L72)).
That does not end the sequence: it goes on ignoring until the next byte
from `@` to `~`, and takes that as the end
([`charproc.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/charproc.c#L6424-L6426)),
so the first letter or the like after the sequence is swallowed. That is a
bug, but this site follows a default xterm, bugs included.
DECLKD is not implemented in any build: xterm's DCS handling acts on `$` only
when `t` follows it
([`misc.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/misc.c#L5330-L5348)),
and its graphics code lists "locator key definitions (DECLKD)" as still to
do ([`graphics.c`](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/graphics.c#L58-L70)).
The cases follow a default xterm, as the [sources](https://control-codes.page/sources/index.html.md) page explains,
so they expect these sequences to draw no report, and to swallow the letter
after them. That is what DEC STD 070 asks of a terminal without the
extension, too, since it says a terminal ignores a function it does not
implement
([§3.5.1.3, p. 3-20](https://archive.org/details/bitsavers_decstandar0VideoSystemsReferenceManualDec91_74264381/page/n124/mode/1up));
a terminal with it would answer DECRQLP. libghostty-vt has no handler for
any of them, and ignores them, but ends each at its final byte, so the
letter after it is printed; those cases are known differences.

xterm and libghostty-vt both have a different kind of mouse reporting,
xterm's own, [mouse tracking](https://control-codes.page/modes/mouse/index.html.md), turned on with private modes
such as `CSI ? 1000 h`. The
locator's own status request, `CSI ? 55 n`, is on the
[DEC status reports](https://control-codes.page/csi/decdsr/index.html.md) page.

## 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 | No | not in the manual |
| xterm | patch 412, [xterm-411a](https://github.com/ThomasDickey/xterm-snapshots/tree/xterm-411a) | Partly | only when built with `--enable-dec-locator`, off by default; without it the letter after the sequence is swallowed; DECLKD in no build |
| libghostty-vt | [0f171f6](https://github.com/ghostty-org/ghostty/tree/0f171f650a1cbbd6df4a2573b6b0c7de57cc6d90) | No | ignored, but ends each at its final byte (DECELR-1, DECELR-3) |
| 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

### DECELR-1: The letter after it is swallowed

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

Input, one step per line:

```text
A
\e[1;2'z  # DECELR: reports on, in character cells
B         # taken as the end of the ignored sequence
```

Expected screen:

```text
|A_____|
cursor 1,2
reply none
```

### DECELR-2: No locator, no report

Input, one step per line:

```text
\e[1;2'z  # DECELR
\e['|     # DECRQLP
```

Expected screen:

```text
|______|
reply none
```

### DECELR-3: DECSLE and DECEFR are consumed, and so is the letter after

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

Input, one step per line:

```text
A
\e[1;3'{  # DECSLE: report presses and releases
\e[1;1;2;2'w # DECEFR
B
```

Expected screen:

```text
|A_____|
reply none
```

### DECELR-4: DECLKD's string is consumed

Input, one step per line:

```text
A
\eP0$w1/41/42\e\\ # DECLKD: button 1 sends A down, B up
B
```

Expected screen:

```text
|AB____|
reply none
```

---

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