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
The commit log says that was needed to get tiling in GNOME
working. However, I don't know *which* extension that was.
Force resizing in a configure event means we'll trash a perfectly
valid buffer on e.g. 'activated' state changes.
So, let's revert this for now, and if this breaks GNOME, let's try to
find another solution. If worse comes to worse, we can detect if we're
running under GNOME and do a force-resize then, but not on sane
compositors.
When applying scroll damage, we may have to re-render the
margins.
This is because when we SHM-scroll, we actually move the entire
surface, and thus we end up overwriting the top margin area with old
window content, and scroll in uninitialized memory in the bottom
margin.
But, we don't have to tell the compositor about this - the last frame
always contains correct margins; i.e. there's no change between the
last frame and current frame being rendered.
TODO: we _could_ micro-optimize and only damage the margins after a
surface resize. We do it slightly more often now, when dealing with
state changes in screen flash or scrollback searching. But I don't
think it's worth the effort.
Instead of locking the queue for each dirty row we append, and
signaling a condition variable, just keep the lock while going through
the visible rows.
Release the lock once done.
Since we take the lock *before* posting the 'start' semaphore, all
workers will be waiting for the lock to be released.
Then, one at a time they'll get the lock and pick a row to
render. The queue will never get empty - when all rows have been
rendered, each worker will pick a 'frame done' "job" from the queue,
and break the rendering loop.