Commit: b3d56a1f2e474df4933ebe4789a5c82764b63c96
Parent: b6025c0413114757296b9fa9f6cba5abf1e42923
Author: Randy Palamar
Date: Wed, 14 Aug 2024 06:07:27 -0600
alt screen mostly works
Diffstat:
M | debug.c | | | 14 | ++++++++------ |
M | main.c | | | 14 | +++++++++++--- |
M | os_unix.c | | | 15 | ++++----------- |
M | terminal.c | | | 132 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
M | test.c | | | 56 | ++++++++++++++++++++++++++++++++++++-------------------- |
M | util.c | | | 25 | +++++++++++++++++++++++++ |
M | util.h | | | 24 | +++++++++++++++++------- |
M | vtgl.c | | | 20 | ++++++++++++-------- |
8 files changed, 207 insertions(+), 93 deletions(-)
diff --git a/debug.c b/debug.c
@@ -4,7 +4,7 @@ static Cursor
simulate_line(Term *t, Line *line)
{
Cursor saved_cursor = t->cursor;
- s8 l = line_to_s8(line, &t->log);
+ s8 l = line_to_s8(line, &t->views[t->view_idx].log);
t->cursor.state = line->cursor_state;
@@ -60,15 +60,16 @@ dump_last_line_to_file(Term *t)
printf("dumping line to %s\n", fname);
+ TermView *tv = t->views + t->view_idx;
fputs("Line Idx -1:\n", f);
- Line *line = t->log_lines.buf + get_line_idx(&t->log_lines, -1);
- s8 l = line_to_s8(line, &t->log);
+ Line *line = tv->lines.buf + get_line_idx(&tv->lines, -1);
+ s8 l = line_to_s8(line, &tv->log);
fput_line_info(f, t, line);
fwrite(l.data, 1, l.len, f);
fputs("\nLine Idx 0:\n", f);
- line = t->log_lines.buf + get_line_idx(&t->log_lines, 0);
- l = line_to_s8(line, &t->log);
+ line = tv->lines.buf + get_line_idx(&tv->lines, 0);
+ l = line_to_s8(line, &tv->log);
fput_line_info(f, t, line);
fwrite(l.data, 1, l.len, f);
@@ -85,13 +86,14 @@ fput_cell(FILE *f, Cell *c)
static void
dump_fb_to_file(Term *t)
{
+ TermView *tv = t->views + t->view_idx;
char *fname = "fb.bin";
FILE *f = fopen(fname, "w");
if (!f) return;
printf("dumping fb to %s\n", fname);
for (u32 r = 0; r < t->size.h; r++) {
for (u32 c = 0; c < t->size.w; c++)
- fput_cell(f, &t->fb.rows[r][c]);
+ fput_cell(f, &tv->fb.rows[r][c]);
fputc('\n', f);
}
fclose(f);
diff --git a/main.c b/main.c
@@ -278,10 +278,18 @@ main(void)
init_window(&term, memory);
init_fonts(&term, font_paths, ARRAY_COUNT(font_paths), g_default_fontsize, &memory);
- cursor_reset(&term);
+ for (u32 i = 0; i < ARRAY_COUNT(term.saved_cursors); i++) {
+ cursor_reset(&term);
+ cursor_move_to(&term, 0, 0);
+ cursor_alt(&term, 1);
+ }
- os_alloc_ring_buffer(&term.log, BACKLOG_SIZE);
- line_buf_alloc(&term.log_lines, &memory, term.log.buf, term.cursor.state, BACKLOG_LINES);
+ os_alloc_ring_buffer(&term.views[0].log, BACKLOG_SIZE);
+ line_buf_alloc(&term.views[0].lines, &memory, term.views[0].log.buf, term.cursor.state,
+ BACKLOG_LINES);
+ os_alloc_ring_buffer(&term.views[1].log, ALT_BACKLOG_SIZE);
+ line_buf_alloc(&term.views[1].lines, &memory, term.views[1].log.buf, term.cursor.state,
+ ALT_BACKLOG_LINES);
term.child = os_fork_child("/bin/sh");
diff --git a/os_unix.c b/os_unix.c
@@ -262,24 +262,17 @@ static size
os_read_from_child(os_child c, RingBuf *rb, size unprocessed_bytes)
{
size r = 0, total_bytes_read = 0, remaining = rb->cap - unprocessed_bytes;
+
+ ASSERT(rb->widx < rb->cap);
do {
remaining -= r;
total_bytes_read += r;
r = read(c.fd, rb->buf + rb->widx + total_bytes_read, remaining);
} while (r != -1);
+ ASSERT(total_bytes_read <= rb->cap);
- ASSERT(rb->widx < rb->cap);
- ASSERT(r <= rb->cap);
-
- rb->widx += total_bytes_read;
- rb->filled += total_bytes_read;
-
- CLAMP(rb->filled, 0, rb->cap);
- if (rb->widx >= rb->cap)
- rb->widx -= rb->cap;
+ commit_to_rb(rb, total_bytes_read);
- ASSERT(rb->filled >= 0);
- ASSERT(rb->widx >= 0 && rb->widx < rb->cap);
return total_bytes_read;
}
diff --git a/terminal.c b/terminal.c
@@ -102,16 +102,21 @@ line_to_s8(Line *l, RingBuf *rb)
}
static void
+init_line(Line *l, u8 *position, CellStyle cursor_state)
+{
+ l->start = position;
+ l->end = position;
+ l->has_unicode = 0;
+ l->cursor_state = cursor_state;
+}
+
+static void
feed_line(LineBuf *lb, u8 *position, CellStyle cursor_state)
{
lb->buf[lb->widx++].end = position;
lb->widx = lb->widx >= lb->cap ? 0 : lb->widx;
lb->filled += lb->filled <= lb->widx;
-
- lb->buf[lb->widx].start = position;
- lb->buf[lb->widx].end = position;
- lb->buf[lb->widx].has_unicode = 0;
- lb->buf[lb->widx].cursor_state = cursor_state;
+ init_line(lb->buf + lb->widx, position, cursor_state);
}
static void
@@ -133,10 +138,11 @@ fb_clear_region(Term *t, u32 r1, u32 r2, u32 c1, u32 c2)
CLAMP(r1, 0, t->size.h - 1);
CLAMP(r2, 0, t->size.h - 1);
+ TermView *tv = t->views + t->view_idx;
for (u32 r = r1; r <= r2; r++) {
for (u32 c = c1; c <= c2; c++) {
- t->fb.rows[r][c].style = t->cursor.state;
- t->fb.rows[r][c].cp = ' ';
+ tv->fb.rows[r][c].style = t->cursor.state;
+ tv->fb.rows[r][c].cp = ' ';
}
}
}
@@ -144,30 +150,39 @@ fb_clear_region(Term *t, u32 r1, u32 r2, u32 c1, u32 c2)
static void
fb_scroll_down(Term *t, u32 top, u32 n)
{
+ TermView *tv = t->views + t->view_idx;
// TODO: CLAMP?
- u32 bottom = t->size.h - 1;
+ u32 bottom = t->size.h - 1;
fb_clear_region(t, bottom - n + 1, bottom, 0, t->size.w);
for (u32 i = bottom; i >= top + n; i--) {
- Row tmp = t->fb.rows[i];
- t->fb.rows[i] = t->fb.rows[i - n];
- t->fb.rows[i - n] = tmp;
+ Row tmp = tv->fb.rows[i];
+ tv->fb.rows[i] = tv->fb.rows[i - n];
+ tv->fb.rows[i - n] = tmp;
}
}
static void
fb_scroll_up(Term *t, u32 top, u32 n)
{
+ TermView *tv = t->views + t->view_idx;
// TODO: CLAMP?
- u32 bottom = t->size.h - 1;
+ u32 bottom = t->size.h - 1;
fb_clear_region(t, top, top + n - 1, 0, t->size.w);
for (u32 i = top; i <= bottom - n; i++) {
- Row tmp = t->fb.rows[i];
- t->fb.rows[i] = t->fb.rows[i + n];
- t->fb.rows[i + n] = tmp;
+ Row tmp = tv->fb.rows[i];
+ tv->fb.rows[i] = tv->fb.rows[i + n];
+ tv->fb.rows[i + n] = tmp;
}
}
static void
+swap_screen(Term *t)
+{
+ t->mode ^= TM_ALTSCREEN;
+ t->view_idx = !!(t->mode & TM_ALTSCREEN);
+}
+
+static void
cursor_reset(Term *t)
{
//(Colour){.rgba = 0x1e9e33ff};
@@ -184,6 +199,15 @@ cursor_move_to(Term *t, i32 row, i32 col)
}
static void
+cursor_alt(Term *t, b32 save)
+{
+ i32 mode = t->view_idx;
+ if (save) t->saved_cursors[mode] = t->cursor;
+ else t->cursor = t->saved_cursors[mode];
+}
+
+
+static void
cursor_step_column(Term *t, i32 step)
{
t->cursor.col += step;
@@ -200,9 +224,13 @@ cursor_step_column(Term *t, i32 step)
static void
term_reset(Term *t)
{
- cursor_reset(t);
- cursor_move_to(t, 0, 0);
- fb_clear_region(t, 0, t->size.h, 0, t->size.w);
+ for (u32 i = 0; i < ARRAY_COUNT(t->saved_cursors); i++) {
+ cursor_reset(t);
+ cursor_move_to(t, 0, 0);
+ cursor_alt(t, 1);
+ swap_screen(t);
+ fb_clear_region(t, 0, t->size.h, 0, t->size.w);
+ }
}
static void
@@ -280,6 +308,7 @@ erase_in_line(Term *t, CSI *csi)
static void
set_mode(Term *t, CSI *csi, b32 set)
{
+ i32 alt = t->view_idx;
#define PRIV(a) ((1 << 30) | (a))
for (i32 i = 0; i < csi->argc; i++) {
i32 arg = (csi->argv[i]) | ((csi->priv & 1) << 30);
@@ -300,9 +329,16 @@ set_mode(Term *t, CSI *csi, b32 set)
if (set) t->gl.mode |= WIN_MODE_HIDECURSOR;
else t->gl.mode &= ~WIN_MODE_HIDECURSOR;
break;
- case PRIV(1049): /* TODO: save cursor and switch to alt screen */
- if (set) t->mode |= TM_ALTSCREEN;
- else t->mode &= ~TM_ALTSCREEN;
+ case PRIV(1049): /* xterm: swap cursor then swap screen */
+ cursor_alt(t, set);
+ case PRIV(47): /* xterm: swap screen buffer */
+ case PRIV(1047): /* xterm: swap screen buffer */
+ if (alt) fb_clear_region(t, 0, t->size.h, 0, t->size.w);
+ if (set ^ alt) swap_screen(t);
+ if (csi->argv[i] != 1049) break;
+ /* FALLTHROUGH */
+ case PRIV(1048): /* xterm: swap cursor */
+ cursor_alt(t, set);
break;
default:
fputs("set_mode: unhandled mode: ", stderr);
@@ -418,6 +454,8 @@ set_colours(Term *t, CSI *csi)
static void
window_manipulation(Term *t, CSI *csi)
{
+ /* TODO: you cannot reuse the title from GLFW after the fact; it needs to be copied */
+ return;
switch (csi->argv[0]) {
case 22: t->saved_title = glfwGetWindowTitle(t->gl.window); break;
case 23: glfwSetWindowTitle(t->gl.window, t->saved_title); break;
@@ -482,10 +520,11 @@ handle_csi(Term *t, s8 *raw)
case 't': window_manipulation(t, &csi); break;
case '!':
next = get_ascii(raw);
- ASSERT(next == 'p');
- /* NOTE: DECSTR: soft terminal reset (if next == p) */
- /* IGNORED */
- break;
+ if (next == 'p') {
+ /* NOTE: DECSTR: soft terminal reset IGNORED */
+ break;
+ }
+ /* FALLTHROUGH */
default:
fputs("unknown csi: ", stderr);
dump_csi(&csi);
@@ -636,6 +675,7 @@ check_if_csi_moves_cursor(Term *t, s8 *raw)
if (csi.argc == -1)
return EMC_NEEDS_MORE_BYTES;
+ u32 term_mode = t->mode;
switch (csi.mode) {
case 'H': result = EMC_CURSOR_MOVED; break;
case 'h': set_mode(t, &csi, 1); break;
@@ -644,6 +684,9 @@ check_if_csi_moves_cursor(Term *t, s8 *raw)
default: break;
}
+ if (term_mode != t->mode)
+ result = EMC_CURSOR_MOVED;
+
return result;
}
@@ -683,7 +726,7 @@ check_if_escape_moves_cursor(Term *t, s8 *raw)
static size
split_raw_input_to_lines(Term *t, s8 raw)
{
- LineBuf *lb = &t->log_lines;
+ TermView *tv = t->views + t->view_idx;
size parsed_lines = 0;
__m128i nl = _mm_set1_epi8('\n');
__m128i esc = _mm_set1_epi8(0x1B);
@@ -716,7 +759,7 @@ split_raw_input_to_lines(Term *t, s8 raw)
count -= 16;
data += 16;
}
- lb->buf[lb->widx].has_unicode |= _mm_movemask_epi8(hasutf8);
+ tv->lines.buf[tv->lines.widx].has_unicode |= _mm_movemask_epi8(hasutf8);
raw = consume(raw, data - raw.data);
if (raw.len) {
@@ -729,7 +772,18 @@ split_raw_input_to_lines(Term *t, s8 raw)
return parsed_lines;
case EMC_CURSOR_MOVED:
parsed_lines++;
- feed_line(lb, old.data, t->cursor.state);
+ feed_line(&tv->lines, old.data, t->cursor.state);
+ if ((t->views + t->view_idx) == tv)
+ break;
+ /* NOTE: screen swapped */
+ TermView *nv = t->views + t->view_idx;
+ size nstart = nv->log.widx;
+ mem_copy(raw, (s8){nv->log.cap, nv->log.buf + nstart});
+ commit_to_rb(&tv->log, -raw.len);
+ commit_to_rb(&nv->log, raw.len);
+ raw.data = nv->log.buf + nstart;
+ init_line(nv->lines.buf + nv->lines.widx, raw.data, t->cursor.state);
+ tv = nv;
break;
default: break;
}
@@ -738,9 +792,9 @@ split_raw_input_to_lines(Term *t, s8 raw)
if (cp == '\n') {
raw = consume(raw, 1);
parsed_lines++;
- feed_line(lb, raw.data, t->cursor.state);
+ feed_line(&tv->lines, raw.data, t->cursor.state);
} else if (cp & 0x80) {
- lb->buf[lb->widx].has_unicode = 1;
+ tv->lines.buf[tv->lines.widx].has_unicode = 1;
/* TODO: this is probably slow */
size old_len = raw.len;
if (get_utf8(&raw) == (u32)-1) {
@@ -754,11 +808,11 @@ split_raw_input_to_lines(Term *t, s8 raw)
}
}
- lb->buf[lb->widx].end = raw.data;
+ tv->lines.buf[tv->lines.widx].end = raw.data;
- if (line_length(lb->buf + lb->widx) > SPLIT_LONG) {
+ if (line_length(tv->lines.buf + tv->lines.widx) > SPLIT_LONG) {
parsed_lines++;
- feed_line(lb, raw.data, t->cursor.state);
+ feed_line(&tv->lines, raw.data, t->cursor.state);
}
}
t->unprocessed_bytes = 0;
@@ -786,8 +840,8 @@ push_tab(Term *t)
static void
push_line(Term *t, Line *line, Arena a)
{
- s8 l = line_to_s8(line, &t->log);
-
+ TermView *tv = t->views + t->view_idx;
+ s8 l = line_to_s8(line, &tv->log);
t->cursor.state = line->cursor_state;
Cell *c;
@@ -814,7 +868,7 @@ push_line(Term *t, Line *line, Arena a)
/* TODO properly make sure characters are printable */
CLAMP(cp, ' ', '~');
- c = &t->fb.rows[t->cursor.row][t->cursor.col];
+ c = &tv->fb.rows[t->cursor.row][t->cursor.col];
c->cp = cp;
c->style = t->cursor.state;
@@ -847,8 +901,10 @@ blit_lines(Term *t, Arena a, size line_count)
//t->cursor.col = t->mode & TM_ALTSCREEN ? t->cursor.col : 0;
t->cursor.col = 0;
+ TermView *tv = t->views + t->view_idx;
+ CLAMP(line_count, 0, tv->lines.filled);
for (size i = 0; i <= line_count; i++) {
- size line_idx = get_line_idx(&t->log_lines, -line_count + i);
- push_line(t, t->log_lines.buf + line_idx, a);
+ size line_idx = get_line_idx(&tv->lines, -line_count + i);
+ push_line(t, tv->lines.buf + line_idx, a);
}
}
diff --git a/test.c b/test.c
@@ -32,11 +32,15 @@ static Test_Fn *tests[] = {
static void
buffer_reset(Term *t)
{
- t->log.widx = 0;
- t->log.filled = 0;
- t->unprocessed_bytes = 0;
- t->log_lines.widx = 0;
- t->log_lines.filled = 0;
+ t->views[0].log.widx = 0;
+ t->views[0].log.filled = 0;
+ t->views[1].log.widx = 0;
+ t->views[1].log.filled = 0;
+ t->unprocessed_bytes = 0;
+ t->views[0].lines.widx = 0;
+ t->views[0].lines.filled = 0;
+ t->views[1].lines.widx = 0;
+ t->views[1].lines.filled = 0;
}
static size
@@ -71,10 +75,11 @@ check_cells_equal(Cell *a, Cell *b)
static s8
launder_static_string(Term *term, s8 static_str)
{
- term->unprocessed_bytes += copy_into_ringbuf(&term->log, static_str);
+ RingBuf *rb = &term->views[term->view_idx].log;
+ term->unprocessed_bytes += copy_into_ringbuf(rb, static_str);
s8 raw = {
.len = term->unprocessed_bytes,
- .data = term->log.buf + (term->log.widx - term->unprocessed_bytes)
+ .data = rb->buf + (rb->widx - term->unprocessed_bytes)
};
return raw;
}
@@ -116,7 +121,7 @@ static TEST_FN(colour_setting)
.fg = g_colours.data[3],
.attr = (ATTR_INVISIBLE|ATTR_STRUCK),
}};
- result.status = check_cells_equal(&c, term->fb.rows[0]);
+ result.status = check_cells_equal(&c, term->views[term->view_idx].fb.rows[0]);
return result;
}
@@ -156,16 +161,17 @@ static TEST_FN(cursor_at_line_boundary)
s8 raw = launder_static_string(term, long_line);
+ LineBuf *lb = &term->views[term->view_idx].lines;
/* NOTE: check if line actually split and that it was split after red dragon */
size parsed_lines = split_raw_input_to_lines(term, raw);
result.status = parsed_lines == 2;
- result.status &= line_length(term->log_lines.buf) > SPLIT_LONG;
+ result.status &= line_length(lb->buf) > SPLIT_LONG;
/* NOTE: check that cursor state was transferred */
- Cursor line_end = simulate_line(term, term->log_lines.buf);
- result.status &= !memcmp(&line_end.state,
- &term->log_lines.buf[1].cursor_state,
- sizeof(term->log_lines.buf[0].cursor_state));
+ Cursor line_end = simulate_line(term, lb->buf);
+ result.status &= !memcmp(&line_end.state,
+ &lb->buf[1].cursor_state,
+ sizeof(lb->buf[0].cursor_state));
return result;
}
@@ -173,9 +179,10 @@ static TEST_FN(cursor_at_line_boundary)
static TEST_FN(working_ringbuffer)
{
struct test_result result = {.info = __FUNCTION__};
- term->log.buf[0] = 0xFE;
- result.status = (term->log.buf[0] == term->log.buf[term->log.cap]) &&
- (term->log.buf[0] == term->log.buf[-term->log.cap]);
+ RingBuf *rb = &term->views[term->view_idx].log;
+ rb->buf[0] = 0xFE;
+ result.status = (rb->buf[0] == rb->buf[ rb->cap]) &&
+ (rb->buf[0] == rb->buf[-rb->cap]);
return result;
}
@@ -187,14 +194,23 @@ main(void)
Arena memory = os_new_arena(16 * MEGABYTE);
Term term = {0};
- cursor_reset(&term);
+ for (u32 i = 0; i < ARRAY_COUNT(term.saved_cursors); i++) {
+ cursor_reset(&term);
+ cursor_move_to(&term, 0, 0);
+ cursor_alt(&term, 1);
+ }
- os_alloc_ring_buffer(&term.log, BACKLOG_SIZE);
- line_buf_alloc(&term.log_lines, &memory, term.log.buf, term.cursor.state, BACKLOG_LINES);
+ os_alloc_ring_buffer(&term.views[0].log, BACKLOG_SIZE);
+ line_buf_alloc(&term.views[0].lines, &memory, term.views[0].log.buf, term.cursor.state,
+ BACKLOG_LINES);
+ os_alloc_ring_buffer(&term.views[1].log, ALT_BACKLOG_SIZE);
+ line_buf_alloc(&term.views[1].lines, &memory, term.views[1].log.buf, term.cursor.state,
+ ALT_BACKLOG_LINES);
/* TODO: should probably be some odd size */
term.size = (uv2){.w = 80, .h = 24};
- os_alloc_framebuffer(&term.fb, term.size.h, term.size.w);
+ os_alloc_framebuffer(&term.views[0].fb, term.size.h, term.size.w);
+ os_alloc_framebuffer(&term.views[1].fb, term.size.h, term.size.w);
for (u32 i = 0; i < ARRAY_COUNT(tests); i++) {
buffer_reset(&term);
diff --git a/util.c b/util.c
@@ -15,6 +15,15 @@ die(char *fmt, ...)
exit(1);
}
+static void
+mem_copy(s8 src, s8 dest)
+{
+ ASSERT(src.len > 0 && dest.len > 0);
+ ASSERT(dest.len >= src.len);
+ for (size i = 0; i < src.len; i++)
+ dest.data[i] = src.data[i];
+}
+
static void *
mem_clear(u8 *p, u8 c, size len)
{
@@ -39,6 +48,22 @@ alloc_(Arena *a, size len, size align, size count)
}
static void
+commit_to_rb(RingBuf *rb, size len)
+{
+ ASSERT(len <= rb->cap);
+
+ rb->widx += len;
+ rb->filled += len;
+
+ CLAMP(rb->filled, 0, rb->cap);
+ if (rb->widx >= rb->cap)
+ rb->widx -= rb->cap;
+
+ ASSERT(rb->filled >= 0);
+ ASSERT(rb->widx >= 0 && rb->widx < rb->cap);
+}
+
+static void
line_buf_alloc(LineBuf *lb, Arena *a, u8 *start_position, CellStyle state, size capacity)
{
lb->cap = capacity;
diff --git a/util.h b/util.h
@@ -37,6 +37,9 @@
#define BACKLOG_SIZE (16 * MEGABYTE)
#define BACKLOG_LINES (1024UL)
+#define ALT_BACKLOG_SIZE (2 * MEGABYTE)
+#define ALT_BACKLOG_LINES (1024UL)
+
typedef float f32;
typedef double f64;
typedef uint8_t u8;
@@ -143,6 +146,12 @@ typedef struct {
} LineBuf;
typedef struct {
+ RingBuf log;
+ LineBuf lines;
+ Framebuffer fb;
+} TermView;
+
+typedef struct {
/* distance to shift glyph from bounding box origin */
iv2 delta;
/* rendered glyph bitmap data (pixels) */
@@ -255,17 +264,18 @@ typedef struct {
GLCtx gl;
FontAtlas fa;
- RingBuf log;
- LineBuf log_lines;
- size unprocessed_bytes;
+ Cursor cursor;
+ Cursor saved_cursors[2];
+ TermView views[2];
+ i32 view_idx;
- Framebuffer fb;
+ size unprocessed_bytes;
os_child child;
- uv2 size;
- Cursor cursor;
- u32 mode;
+ uv2 size;
+
+ enum terminal_mode mode;
/* NOTE: owned by GLFW; doesn't need to be freed */
const char *saved_title;
diff --git a/vtgl.c b/vtgl.c
@@ -56,7 +56,8 @@ static void
resize(Term *t)
{
v2 ws = t->gl.window_size;
- os_alloc_framebuffer(&t->fb, t->size.h, t->size.w);
+ os_alloc_framebuffer(&t->views[0].fb, t->size.h, t->size.w);
+ os_alloc_framebuffer(&t->views[1].fb, t->size.h, t->size.w);
os_set_term_size(t->child, t->size.h, t->size.w, ws.w, ws.h);
t->gl.flags &= ~NEEDS_RESIZE;
t->gl.flags |= NEEDS_FULL_BLIT;
@@ -257,9 +258,10 @@ render_framebuffer(Term *t, RenderPushBuffer *rpb)
v2 cs = get_cell_size(t);
Rect cr = {.pos = {.y = t->gl.window_size.h - cs.h}, .size = cs};
+ TermView *tv = t->views + t->view_idx;
for (u32 r = 0; r < t->size.h; r++) {
for (u32 c = 0; c < t->size.w; c++) {
- push_cell(rpb, &t->gl, t->fb.rows[r][c], cr, t->fa.deltay);
+ push_cell(rpb, &t->gl, tv->fb.rows[r][c], cr, t->fa.deltay);
cr.pos.x += cs.w;
}
cr.pos.x = 0;
@@ -268,13 +270,14 @@ render_framebuffer(Term *t, RenderPushBuffer *rpb)
/* NOTE: draw cursor */
/* TODO: hide cursor doesn't get reset properly */
- //if (!(t->gl.mode & WIN_MODE_HIDECURSOR)) {
- Cell cursor = t->fb.rows[t->cursor.row][t->cursor.col];
+ //if (!(t->gl.mode & WIN_MODE_HIDECURSOR))
+ {
+ Cell cursor = tv->fb.rows[t->cursor.row][t->cursor.col];
cr.pos.y = t->gl.window_size.h - cs.h * (t->cursor.row + 1);
cr.pos.x = t->cursor.col * cs.w;
cursor.style.attr ^= ATTR_INVERSE;
push_cell(rpb, &t->gl, cursor, cr, t->fa.deltay);
- //}
+ }
}
/* NOTE: called when the window was resized */
@@ -415,19 +418,20 @@ do_terminal(Term *t, Arena a)
if (t->gl.flags & NEEDS_FULL_BLIT) {
t->gl.flags &= ~NEEDS_FULL_BLIT;
term_reset(t);
- blit_lines(t, a, MIN(t->log_lines.filled, t->size.h - 1));
+ blit_lines(t, a, t->size.h - 1);
}
if (os_child_data_available(t->child)) {
+ RingBuf *rb = &t->views[t->view_idx].log;
if (os_child_exited(t->child)) {
/* TODO: is there a reason to not immediately exit? */
glfwSetWindowShouldClose(t->gl.window, GL_TRUE);
return;
}
- t->unprocessed_bytes += os_read_from_child(t->child, &t->log, t->unprocessed_bytes);
+ t->unprocessed_bytes += os_read_from_child(t->child, rb, t->unprocessed_bytes);
s8 raw = {
.len = t->unprocessed_bytes,
- .data = t->log.buf + (t->log.widx - t->unprocessed_bytes)
+ .data = rb->buf + (rb->widx - t->unprocessed_bytes)
};
size parsed_lines = split_raw_input_to_lines(t, raw);
blit_lines(t, a, parsed_lines);