sixel: implement private mode 80 - sixel scrolling

When enabled (the default), sixels behave much like normal output; the
start where the cursor is, and the cursor moves with the
sixel. I.e. after emitting a sixel the cursor is left after the image;
either to the right, if private mode 8452 is enabled, or otherwise on
the next line. Terminal content is scrolled up if the sixel is larger
than the screen.

When disabled, sixels *always* start at (0,0), the cursor never moves,
and the terminal content never scrolls.

In other words, the ‘disabled’ mode is a much simpler mode.

All we need to do to support both modes is re-write the sixel-emitting
loop to:

* break early if we’re “out of rows”, i.e. we’ve reached the bottom of
  the screen.
* not linefeed, or move the cursor when scrolling is disabled

This patch also fixes a bug in the (new) implementation of private
mode 8452.

When emitting a sixel, we may break it up into smaller pieces, to
ensure a single sixel (as tracked internally) does not cross the
scrollback wrap-around.

The code that checked if we should do a linefeed or not, would skip
the linefeed on the last row of *each* such sixel piece. The correct
thing to do is to skip it only on the last row of the *last* piece.

I chose not to fix this bug in a separate patch since doing so would
have meant re-writing it again when implementing private mode 80.
This commit is contained in:
Daniel Eklöf 2021-02-26 09:28:03 +01:00
parent 792202bf29
commit 849427bf10
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
5 changed files with 75 additions and 41 deletions

View file

@ -360,6 +360,7 @@ struct terminal {
bool modify_escape_key:1;
bool ime:1;
bool sixel_scrolling:1;
bool sixel_private_palette:1;
bool sixel_cursor_right_of_graphics:1;
} xtsave;
@ -533,14 +534,14 @@ struct terminal {
bool autosize;
} image;
bool use_private_palette:1; /* Private mode 1070 */
bool scrolling:1; /* Private mode 80 */
bool use_private_palette:1; /* Private mode 1070 */
bool cursor_right_of_graphics:1; /* Private mode 8452 */
unsigned params[5]; /* Collected parameters, for RASTER, COLOR_SPEC */
unsigned param; /* Currently collecting parameter, for RASTER, COLOR_SPEC and REPEAT */
unsigned param_idx; /* Parameters seen */
bool cursor_right_of_graphics:1; /* Private mode 8452 */
/* Application configurable */
unsigned palette_size; /* Number of colors in palette */
unsigned max_width; /* Maximum image width, in pixels */