open
https://gitlab.synchro.net/main/sbbs/-/work_items/1315
`ANSI_Terminal::handle_SGR_sequence()` (`src/sbbs3/ansi_terminal.cpp`) tracks the terminal's current attribute (`term->curatr`) from every SGR sequence sent. It mishandles the extended color forms, so the tracked attribute drifts from what the terminal is actually showing:
- **256-color and 24-bit color (`38;5;n`, `48;5;n`, `38;2;r;g;b`, `48;2;r;g;b`):** the parameters are walked one at a time with `get_pval()`, so the sub-parameters after 38/48 are treated as standalone SGR codes. For example, in `ESC[38;5;196m` the `5` sets BLINK (or BG_BRIGHT with iCE color). In `ESC[38;2;255;0;44m` the `0` resets the tracked attribute to `ANSI_NORMAL` and the `44` sets a blue background. cterm consumes these sub-parameters (`cterm_parse_extended_colour()`).
- **Bright colors (`90`-`97`, `100`-`107`):** ignored, so the tracked foreground/background keeps its previous value. cterm implements them as the color plus bright (`set_bright_fg()`/`set_bright_bg()`): `9x` sets the foreground color and HIGH; `10x` sets the background color and the bright-background bit when iCE color is enabled.
- **`2` (faint):** handled as "bold off". Less important, since terminals that don't do faint generally ignore it.
### Why it matters
`attrstr()` computes each color change as a diff against the tracked attribute, so drift means later changes can omit codes that are needed (or send unnecessary ones). The most visible case is `pause()`, which saves `term->curatr` before printing its prompt and restores it afterwards (`getkey.cpp`). That is what lets a pause in the middle of ANSI art return to the art's colors after the "[Hit a key]" prompt. Art or message text that uses any of the codes above can come back from a pause in the wrong colors.
### Fix
- Skip the sub-parameters of 38 and 48 the way cterm does: the 2 parameters of `5;n`, the 4 of `2;r;g;b`, or the single parameter when the rest are colon-separated (`38;5:n`, `38;2:r:g:b`; `get_pval()` already truncates at `:`, so `5:196` is currently read as `5`, i.e. blink). With no way to represent the exact extended color, mark the foreground/background unknown (`FG_UNKNOWN`/`BG_UNKNOWN`) so the next explicit color is always sent.
- Track `90`-`97` as the corresponding color with `HIGH`, and `100`-`107` as the background color with `BG_BRIGHT` when the terminal is in iCE color mode, matching cterm.
### Related, lower priority
After a raw `ESC[7m`, the tracker swaps the stored foreground/background (and `set_color()` swaps subsequent ones), but `attrstr()` emits colors unswapped alongside `7`. The two disagree until the next reset. Only reachable through raw ANSI, since only the PETSCII terminal sets `REVERSED` itself.
*Authored by Claude (Claude Code), on behalf of @rswindell*
--- SBBSecho 3.38-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)