DECAUPSS Assign User-Preference Supplemental Set
Choose which supplemental character set is the user's preferred one, or ask which it is.
DCS Ps ! u Pt ST
- DEC STD 070
- §5.8.2 Assign User-Preference Supplemental Set, p. 5-123
- VT510
- DECAUPSS—Assigning User-Preferred Supplemental Sets
A DEC terminal keeps one supplemental character set as the user-preference supplemental set, the UPSS: the set of accented letters and symbols its user chose in Set-Up. DEC STD 070 gives it three jobs. It is the default supplemental set, designated into G2 by a soft reset; it decides which supplemental characters the keyboard can produce; and it lets a program designate “whatever the user prefers” without knowing which set that is.
DCS Ps ! u Pt ST (DECAUPSS) assigns it, and CSI & u (DECRQUPSS) asks which set it is, the terminal answering with a DECAUPSS string of its own. DEC STD 070 allows two values:
Ps | Pt | Set |
|---|---|---|
0 | %5 | DEC Supplemental, 94 characters |
1 | A | ISO Latin-1 supplemental, 96 characters |
Ps says whether the set has 94 or 96 characters, and Pt is the same designator that would select the set with SCS. DECRQUPSS is DEC STD 070 §5.8.2, p. 5-125 and DECRQUPSS in the VT510 manual. DEC STD 070 has both answer and request sent with the 8-bit DCS and ST, 90 and 9C; xterm sends ESC P and ESC \.
The final byte < designates the UPSS itself: DEC STD 070’s example is ESC * <, which “designates the UPSS to G2” (p. 5-117). At the VT320 and VT420 levels, xterm turns < into DEC Supplemental if that is the UPSS and into ISO Latin-1 supplemental otherwise (HandleUPSS).
What xterm does
xterm implements both from the VT320 level up, and it is a VT420 by default (DFT_DECID). What it answers depends on whether it is decoding its input as UTF-8. libghostty-vt always does (see CSI), so the cases here compare it with xterm in UTF-8 mode, in which:
- the UPSS starts out as ASCII, because neither supplemental set can work alongside UTF-8 decoding, as the comment in
resetCharsetsexplains, so DECRQUPSS answers\eP0!uB\e\\(CASE_DECRQUPSS); - DECAUPSS is ignored (
misc.c).
Outside UTF-8 mode the UPSS starts out as ISO Latin-1, because xterm’s preferLatin1 resource is true by default (charproc.c, ptyx.h), and DECAUPSS accepts DEC STD 070’s two values and a few more that real VT520s were found to take (decode_upss).
xterm’s DECRQUPSS also has a bug: unlike the requests around it, it does not return the parser to its ground state afterwards. The parser is left in the table for CSI & sequences (VTPrsTbl.c), in which a printable character just returns to the ground state, so the first character printed after the request is lost.
libghostty-vt implements neither. Its CSI u dispatch in stream.zig has no case for a & intermediate, and its DCS hook in dcs.zig knows only + and $ intermediates, so it does not answer DECRQUPSS and drops a DECAUPSS string unread.
Validation
DECAUPSS-1: Asking for the UPSS
\e[&u # DECRQUPSS
|______|
reply \eP0!uB\e\\
DECAUPSS-2: Assigning it is ignored in UTF-8 mode
\eP1!uA\e\\ # DECAUPSS: ISO Latin-1 supplemental
\e[&u
|______|
reply \eP0!uB\e\\
DECAUPSS-3: The character after the request is lost
\e[&u
AB # xterm drops the A
|B_____|
cursor 1,2
reply \eP0!uB\e\\