When we're handling the initial set of globals, the data-device and
primary-selection-device objects may, or may not be registered before
the seat(s).
We need to handle both cases.
When adding a seat, instantiate the data-device and
primary-selection-device **if available**.
When adding the device objects, instantiate them on **all** currently
available seats.
Remove assertion that row be less than the scrolling region end. The
cursor may in fact be *inside* the margin.
Inside the margin, content never scrolls, but we must make sure we
don't move the cursor outside the grid.
As that breaks e.g. selection marking (SPACER cells didn't get
inverted when rendered).
Instead, skip them in extract_one() only. I.e. when copying text from
the grid.
Ignore *old* cells containing spacers.
Pad new grid with spacers if a multi-column character doesn't fit at
the end of a line.
Insert spacers after a multi-column character.
When printing a multi-column character, write CELL_MULT_COL_SPACER
instead of '0' to both padding cells (when character doesn't fit at
the end of the line), and to the cells following the actual character.
When printing a multi-column character at the end of the line, and it
doesn't fit, we currently insert a forced line-wrap. This means the
last character(s) on the previous line will be empty, followed by a
multi-column character in the first cell on the next line.
Without special code to handle this, the selection text extraction
code will insert a hard newline, since this is normally the correct
thing to do.
Add a TODO, to consider writing a special place holder value to these
padding cells.
While this might seem like it would slow down things, it should in
fact help the compiler optimize: the "normal" code path, that prints
regular ASCII characters, always call term_print() with width == 1.
LF should always clear LCF. Previously, it was done implicitly in
term_cursor_down(). I.e it was cleared as long as the cursor wasn't at
the bottom of the scrolling region
Previously, C0::VT was implemented as a simple 'cursor down'. I.e. it
would behave as LF **until** it reached the bottom of the screen,
where instead of scrolling, it became a no-op.
See https://vt100.net/docs/vt102-ug/chapter5.html