Since we now initialize the worker threads from term_init(), which
returns before the threads terminate, we can no longer use
stack-allocated worker contexts.
We _could_ put them in the terminal struct. But a simpler solution is
to allocate them in term_init(), and let the threads free them when
they don't need them anymore.
We do however need access to it, so provide a pointer. The difference
is that now we can have a *single* wayland instance, but multiple
terminal instances.
With this assumption, we can replace 'a % b' with 'a & (b - 1)'. In
terms of instructions, this means a fast 'and' instead of a slow
'div'.
Further optimize scrolling by:
* not double-initializing empty rows. Previously, grid_row_alloc()
called calloc(), which was then followed by a memset() when
scrolling. This is of course unnecessary.
* Don't loop the entire set of visible rows (this was done to ensure
all visible rows had been allocated, and to prefetch the cell
contents).
This isn't necessary; only newly pulled in rows can be NULL. For
now, don't prefetch at all.
That is, remove the 'regular' and 'bright' color arrays. This is
possible since the 256-color array is defined such that the first 16
colors map to the regular and bright colors.
If we scroll enough, we'll eventually end up wrapping around the
entire scrollback buffer. At this point, a selection is no longer
valid, so cancel it.
Note: this was very obvious when scrolling in the alt screen, since
its scrollback buffer is what you see on the screen (i.e. it has no
scrollback).
The 'attributes' struct is now 8 bytes and naturally packed (used to
be 9 bytes, artificially packed).
'cell' struct is now 12 bytes, naturally packed (used to be 13 bytes,
artificially packed).
Furthermore, the glyph is stored as a wchar instead of a char*. This
makes it easier (faster) to do glyph lookup when rendering.
This patch takes a bit from the foreground color value in a
cell (todo: split up foreground/background into bitfields with a
separate field for 'foreground/background' has been set), and only
re-renders cells that aren't marked as clean.
Note: we use a 'clean' bit rather than a 'dirty' bit to make it easy
to erase cells - we can (keep doing) do that by simply memsetting a
cell range to 0.
Since newly scrolled in lines will be erased, we want them in the
cache.
So, allocate and prefetch new lines, then repair non-scrolling
regions (to give the prefetch time to actually fetch the
data). Finally, erase the newly scrolled in lines.
This also fixes a bug where the fixup for the non-scrolling regions
could crash on an unallocated row (we were accessing rows that would
be, but hadn't yet been, scrolled in).
The row array may now contain NULL pointers. This means the
corresponding row hasn't yet been allocated and initialized.
On a resize, we explicitly allocate the visible rows.
Uninitialized rows are then allocated the first time they are
referenced.
linefeed moves cursor down one row (columns stays the same), or, if
the cursor is at the last row, scrolls up one row.
reverse_index does the opposite; it moves the cursor *up* one row, or,
if the cursor is at the top row, scrolls *down* one row.
Can scroll up and down, and stops when the beginning/end of history is
reached.
However, it probably breaks when the entire scrollback buffer has been
filled - we need to detect when the view has wrapped around to the
current terminal offset.
The detection of when we've reached the bottom of the history is also
flawed, and only works when we overshoot the bottom with at least a
page.
Resizing the windows while in a view most likely doesn't work.
The view will not detect a wrapped around scrollback buffer. I.e. if
the user has scrolled back, and is stationary at a view, but there is
still output being produced. Then eventually the scrollback buffer
will wrap around. In this case, the correct thing to do is make the
view start following the beginning of the history. Right now it
doesn't, meaning once the scrollback buffer wraps around, you'll start
seeing command output...
The grid is now represented with an array of row *pointers*. Each row
contains an array of cells (the row's columns).
The main point of having row pointers is we can now move rows around
almost for free.
This is useful when scrolling with scroll margins for example, where
we previously had to copy the lines in the margins. Now it's just a
matter of swapping two pointers.