aboutsummaryrefslogtreecommitdiff
path: root/sys/libterm/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/libterm/window.c')
-rw-r--r--sys/libterm/window.c408
1 files changed, 0 insertions, 408 deletions
diff --git a/sys/libterm/window.c b/sys/libterm/window.c
deleted file mode 100644
index 5d36c8b..0000000
--- a/sys/libterm/window.c
+++ /dev/null
@@ -1,408 +0,0 @@
-#include "term.h"
-
-// -----------------------------------------------------------------------
-// buffers
-
-static
-void
-zero(Row *row, int start, int len)
-{
- int i;
- Cell cell = {
- .txt = L' ',
- .pen = {
- .state = PenNormal,
- .col.fg = -1,
- .col.bg = -1,
- },
- };
-
- for (i = start; i < len + start; i++)
- row->cells[i] = cell;
- row->dirty = 1;
-}
-
-static
-void
-roll(Row *start, Row *end, int count)
-{
- int n = end - start;
-
- /* enforce circularity */
- count %= n;
- if (count < 0)
- count += n;
-
- if (count) {
- char buf[count * sizeof(Row)]; /* XXX: remove VLA */
- memcpy(buf, start, count * sizeof(Row));
- memmove(start, start + count, (n - count) * sizeof(Row));
- memcpy(end - count, buf, count * sizeof(Row));
-
- for (Row *row = start; row < end; row++)
- row->dirty = 1;
- }
-}
-
-/* buffer operations */
-static
-void
-bclear(Buffer *b)
-{
- int i;
- Cell cell = {
- .txt = L' ',
- .pen = {
- .state = PenNormal,
- .col.fg = -1,
- .col.bg = -1,
- },
- };
-
- for (i = 0; i < b->h; i++) {
- Row *row = b->row + i;
- for (int j = 0; j < b->w; j++) {
- row->cells[j] = cell;
- row->dirty = 1;
- }
- }
-}
-
-static
-void
-bfini(Buffer *b)
-{
- int i;
-
- for (i = 0; i < b->h; i++)
- free(b->row[i].cells);
-
- free(b->row);
-
- if (b->scroll.size) {
- for (i = 0; i < b->scroll.size; i++)
- free(b->scroll.buf[i].cells);
-
- free(b->scroll.buf);
- }
-}
-
-static
-void
-bscroll(Buffer *b, int s)
-{
- Row tmp;
- int i, ssz = b->scroll.bot - b->scroll.top;
-
- /* work in quanta of screen size */
- if (s > ssz) {
- bscroll(b, ssz);
- bscroll(b, s - ssz);
- return;
- }
- if (s < -ssz) {
- bscroll(b, -ssz);
- bscroll(b, s + ssz);
- return;
- }
-
- b->scroll.above += s;
- b->scroll.above = CLAMP(b->scroll.above, 0, b->scroll.size);
-
- if (s > 0) {
- if (b->scroll.size) {
- for (i = 0; i < s; i++) {
- tmp = b->scroll.top[i];
- b->scroll.top[i] = b->scroll.buf[b->scroll.index];
- b->scroll.buf[b->scroll.index] = tmp;
-
- b->scroll.index++;
- if (b->scroll.index == b->scroll.size)
- b->scroll.index = 0;
- }
- } else
- for (i = 0; i < s; i++)
- zero(b->scroll.top+i, 0, b->maxw);
- }
-
- roll(b->scroll.top, b->scroll.bot, s);
-
- if (s < 0) {
- if (b->scroll.size) {
- for (i = (-s) - 1; i >= 0; i--) {
- b->scroll.index--;
- if (b->scroll.index == -1)
- b->scroll.index = b->scroll.size - 1;
-
- tmp = b->scroll.top[i];
-
- b->scroll.top[i] = b->scroll.buf[b->scroll.index];
- b->scroll.buf[b->scroll.index] = tmp;
- b->scroll.top[i].dirty = 1;
- }
- } else
- for (i = (-s) - 1; i >= 0; i--)
- zero(b->scroll.top+i, 0, b->maxw);
- }
-}
-
-static
-void
-bresize(Buffer *b, int nrow, int ncol)
-{
- int r, d;
- Row *row = b->row;
- Row *cur = row + b->cur.row;
-
- if (b->h != nrow) {
- /* scroll if we can */
- if (cur >= row + nrow)
- bscroll(b, b->cur.row - nrow + 1);
- while (b->h > nrow) {
- free(row[b->h - 1].cells);
- b->h--;
- }
-
- row = realloc(row, sizeof(Row) * nrow);
- }
-
- if (b->maxw < ncol) {
- /* expand each row */
- for (r = 0; r < b->h; r++) {
- row[r].cells = realloc(row[r].cells, sizeof(Cell) * ncol);
- if (b->h < ncol)
- zero(row + r, b->w, ncol - b->w);
- row[r].dirty = 1;
- }
- /* expand the scroll buffer */
- Row *sbuf = b->scroll.buf;
- for (r = 0; r < b->scroll.size; r++) {
- sbuf[r].cells = realloc(sbuf[r].cells, sizeof(Cell) * ncol);
- if (b->w < ncol)
- zero(sbuf + r, b->w, ncol - b->w);
- }
- b->maxw = b->w = ncol;
- } else if (b->w != ncol) {
- for (r = 0; r < b->h; r++)
- row[r].dirty = 1;
- b->w = ncol;
- }
-
- d = 0;
- if (b->h < nrow) {
- while (b->h < nrow) {
- row[b->h].cells = calloc(b->maxw, sizeof(Cell));
- zero(row + b->h, 0, b->maxw);
- b->h++;
- }
-
- /* prepare for backfill */
- if (cur >= b->scroll.bot - 1) {
- d = b->row + nrow - cur - 1;
- if (d > b->scroll.above)
- d = b->scroll.above;
- }
- }
-
- b->cur.row += row - b->row;
- b->scroll.top = row;
- b->scroll.bot = row + nrow;
- b->row = row;
-
- /* perform backfill */
- if (d > 0) {
- bscroll(b, -d);
- b->cur.row += d;
- }
-}
-
-static
-bool
-binit(Buffer *b, int cols, int rows, int scroll)
-{
- int size;
-
- b->pen.state = PenNormal;
- b->pen.col.fg = b->pen.col.bg = -1;
-
- size = MAX(scroll, 0);
- if (size && !(b->scroll.buf = calloc(size, sizeof(Row))))
- return false;
-
- b->scroll.size = size;
- bresize(b, rows, cols);
-
- b->cur = (Dot){0};
- b->save = b->cur;
-
- return true;
-}
-
-static
-void
-bboundary(Buffer *b, Row **bs, Row **be, Row **as, Row **ae)
-{
- if (bs)
- *bs = nil;
- if (be)
- *be = nil;
- if (as)
- *as = nil;
- if (ae)
- *ae = nil;
- if (!b->scroll.size)
- return;
-
- if (b->scroll.above) {
- if (bs)
- *bs = &b->scroll.buf[(b->scroll.index - b->scroll.above + b->scroll.size) % b->scroll.size];
- if (be)
- *be = &b->scroll.buf[(b->scroll.index-1 + b->scroll.size) % b->scroll.size];
- }
- if (b->scroll.below) {
- if (as)
- *as = &b->scroll.buf[b->scroll.index];
- if (ae)
- *ae = &b->scroll.buf[(b->scroll.index + b->scroll.below-1) % b->scroll.size];
- }
-}
-
-static
-Row *
-browfirst(Buffer *b)
-{
- Row *bstart;
- if (!b->scroll.size || !b->scroll.above)
- return b->row;
- bboundary(b, &bstart, nil, nil, nil);
- return bstart;
-}
-
-static
-Row *
-browlast(Buffer *b)
-{
- Row *aend;
- if (!b->scroll.size || !b->scroll.below)
- return b->row + b->h - 1;
- bboundary(b, nil, nil, nil, &aend);
- return aend;
-}
-
-static
-Row *
-brownext(Buffer *b, Row *row)
-{
- Row *before_start, *before_end, *after_start, *after_end;
- Row *first = b->row, *last = b->row + b->h - 1;
-
- if (!row)
- return nil;
-
- bboundary(b, &before_start, &before_end, &after_start, &after_end);
-
- if (row >= first && row < last)
- return ++row;
- if (row == last)
- return after_start;
- if (row == before_end)
- return first;
- if (row == after_end)
- return nil;
- if (row == &b->scroll.buf[b->scroll.size - 1])
- return b->scroll.buf;
- return ++row;
-}
-
-static
-Row *
-bprevrow(Buffer *b, Row *row)
-{
- Row *before_start, *before_end, *after_start, *after_end;
- Row *first = b->row, *last = b->row + b->h - 1;
-
- if (!row)
- return nil;
-
- bboundary(b, &before_start, &before_end, &after_start, &after_end);
-
- if (row > first && row <= last)
- return --row;
- if (row == first)
- return before_end;
- if (row == before_start)
- return nil;
- if (row == after_start)
- return last;
- if (row == b->scroll.buf)
- return &b->scroll.buf[b->scroll.size - 1];
- return --row;
-}
-
-// -----------------------------------------------------------------------
-// windows
-
-Window *
-wmake(Window *root, int top, int left, int w, int h, int scroll)
-{
- Window *child, *it;
-
- child = calloc(1, sizeof(*child));
- child->top = top;
- child->left = left;
- child->parent = root;
- if (root) {
- if (root->child) {
- for (it = root->child; it->link != nil; it = it->link)
- ;
- it->link = child;
- } else
- root->child = child;
-
- child->curvis = root->curvis;
- child->blink = root->blink;
- }
-
- if (!binit((Buffer*)child, w, h, scroll)) {
- free(child);
- return nil;
- }
-
- return child;
-}
-
-void
-wfree(Window *win)
-{
- free(win);
-}
-
-void
-wresize(Window *win, int w, int h)
-{
- bresize((Buffer*)win, w, h);
-}
-
-/* TODO: more sophisticated damage tracking */
-void
-wputrune(Window *win, rune r)
-{
- Row *row = win->row + win->cur.row;
- Cell *cell = row->cells + win->cur.col;
-
- cell->pen = win->pen;
- cell->txt = r;
-
- if (win->cur.col++ >= win->w) {
- win->cur.col = 0;
- if (win->cur.row++ >= win->h)
- win->cur.row = win->h-1;
- }
- row->dirty = 1;
-}
-
-void
-wscroll(Window *win, int s)
-{
- bscroll((Buffer*)win, s);
-}