csi: implement XTPUSHCOLORS+XTPOPCOLORS+XTREPORTCOLORS

The documentation of these sequences are vague and lacking, as is
often the case with XTerm invented control sequences.

I've tried to replicate what XTerm does (as of xterm-392).

The stack represents *stashed/stored* palettes. The currently active
palette is *not* stored on the stack.

The stack is dynamically allocated, and starts out with zero elements.

Now, XTerm has a somewhat weird definition of "pushing" and "popping"
in this context, and the documentation is somewhat misleading.

What a push does is this: it stores the current palette to the stack
at the specified slot. If the specified slot number (Pm) is 0, the
slot used is the current slot index incremented by 1.

The "current" slot index is then set to the specified slot (which is
current slot + 1 if Pm == 0).

Thus, "push" (i.e. when Pm == 0 is used) means store to the "next"
slot. This is true even if the current slot index points into the
middle of stack.

Pop works in a similar way. The palette is restored from the specified
slot index. If the specified slot number is 0, we use the current slot
index.

The "current" slot index is then set to the specified slot -
1 (current slot - 1 if Pm == 0).

XTREPORTCOLORS return the current slot index, and the number of
palettes stored on the stack, on the format

    CSI ? <slot index> ; <palette count> # Q

When XTPUSHCOLORS grows the stack with more than one element (i.e. via
a 'CSI N # P' sequence), make sure *all* new slots are initialized (to
the current color palette). This avoids uninitialized slots, that
could then be popped with XTPOPCOLORS.

Closes #856
This commit is contained in:
Daniel Eklöf 2024-07-01 17:40:45 +02:00
parent 5d4a002413
commit dd6fc99ae1
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 105 additions and 10 deletions

View file

@ -1227,6 +1227,11 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
.selection_bg = conf->colors.selection_bg,
.use_custom_selection = conf->colors.use_custom.selection,
},
.color_stack = {
.stack = NULL,
.size = 0,
.idx = 0,
},
.origin = ORIGIN_ABSOLUTE,
.cursor_style = conf->cursor.style,
.cursor_blink = {
@ -1823,6 +1828,7 @@ term_destroy(struct terminal *term)
free(term->foot_exe);
free(term->cwd);
free(term->mouse_user_cursor);
free(term->color_stack.stack);
int ret = EXIT_SUCCESS;
@ -2040,6 +2046,10 @@ term_reset(struct terminal *term, bool hard)
term->colors.use_custom_selection = term->conf->colors.use_custom.selection;
memcpy(term->colors.table, term->conf->colors.table,
sizeof(term->colors.table));
free(term->color_stack.stack);
term->color_stack.stack = NULL;
term->color_stack.size = 0;
term->color_stack.idx = 0;
term->origin = ORIGIN_ABSOLUTE;
term->normal.cursor.lcf = false;
term->alt.cursor.lcf = false;