Author: mesyeti <mesyeti@mesyeti.uk>
scrolling
source/buffer.c | 10 +++++++- source/interpreter/vt100.c | 41 ++++++++++++++++++++++++++------------- source/pane.c | 2 source/terminal.c | 6 +++- source/terminal.h | 2 +
diff --git a/source/buffer.c b/source/buffer.c index 49ceab5694012aff86601647afa5b2fb8798069a..17b718ac73366eb9ccaf435beb7d23ec4ef83d91 100644 --- a/source/buffer.c +++ b/source/buffer.c @@ -156,6 +156,12 @@ buf->height = h; } void Buffer_Scroll(Buffer* buf, int by) { - (void) buf; - (void) by; + size_t rowSize = sizeof(BufCell) * buf->width; + + for (int i = by; i < buf->height; ++ i) { + BufCell* src = Buffer_Get(buf, 0, i); + BufCell* dest = Buffer_Get(buf, 0, i - by); + + memcpy(dest, src, rowSize); + } } diff --git a/source/interpreter/vt100.c b/source/interpreter/vt100.c index 61239350887a97d7217df088668c64a90b6a38a9..be950a61ccf834a65283ff06e74a6bc07fa5c3a2 100644 --- a/source/interpreter/vt100.c +++ b/source/interpreter/vt100.c @@ -9,9 +9,9 @@ enum { MODE_READY = 0, MODE_ESCAPE, - MODE_CSI, // \e[ - MODE_OSC, // \e] - MODE_CHSET + MODE_CSI, // \e[ + MODE_OSC, // \e] + MODE_CHSET // \e( }; enum { @@ -155,6 +155,19 @@ default: break; } } +static int TermTop(Terminal* terminal) { + return terminal->buffer.height - terminal->height; +} + +static void ShouldScroll(Terminal* terminal) { + if (terminal->cursor.y >= terminal->buffer.height) { + int by = (terminal->cursor.y - terminal->buffer.height) + 1; + + Buffer_Scroll(&terminal->buffer, by); + terminal->cursor.y -= by; + } +} + static void HandleCSI(Vt100* this, Terminal* terminal, UChar ch) { // parse sequences const char* str = this->reading; @@ -174,8 +187,8 @@ int amount = 1; if (num >= 1) amount = atoi(parts[0]); terminal->cursor.y -= amount; - if (terminal->cursor.y < 0) { - terminal->cursor.y = 0; + if (terminal->cursor.y < TermTop(terminal)) { + terminal->cursor.y = TermTop(terminal); } break; } @@ -184,9 +197,7 @@ int amount = 1; if (num >= 1) amount = atoi(parts[0]); terminal->cursor.y += amount; - if (terminal->cursor.y >= terminal->buffer.height) { - terminal->cursor.y = terminal->buffer.height - 1; - } + ShouldScroll(terminal); break; } case 'C': { // move cursor right # columns @@ -227,10 +238,10 @@ int x = atoi(parts[1]) - 1; if (x < 0) x = 0; if (y < 0) y = 0; - if (x >= terminal->buffer.width) x = terminal->buffer.width - 1; - if (y >= terminal->buffer.height) y = terminal->buffer.height - 1; + if (x >= terminal->buffer.width) x = terminal->buffer.width - 1; + if (y >= terminal->height) y = terminal->height - 1; - terminal->cursor = (Vec2) {x, y}; + terminal->cursor = (Vec2) {x, y + TermTop(terminal)}; break; } case 'J': { @@ -255,7 +266,7 @@ break; } case 2: { Buffer_Clear(&terminal->buffer); - terminal->cursor = (Vec2) {0, 0}; + terminal->cursor = (Vec2) {0, TermTop(terminal)}; break; } } @@ -307,10 +318,11 @@ break; } case 'd': { // cursor row position if (num < 1) { - terminal->cursor.y = 1; + terminal->cursor.y = TermTop(terminal); } else { - terminal->cursor.y = atoi(parts[0]) - 1; + terminal->cursor.y = (atoi(parts[0]) - 1) + TermTop(terminal); + ShouldScroll(terminal); } break; } @@ -492,6 +504,7 @@ } case '\n': { ++ terminal->cursor.y; terminal->cursor.x = 0; + ShouldScroll(terminal); break; } case '\x1b': { diff --git a/source/pane.c b/source/pane.c index a0e7de216ae848710b3846c08a724e2b110609de..f7034801b4e77daf5400ceb96cc6561224cbdd1c 100644 --- a/source/pane.c +++ b/source/pane.c @@ -71,7 +71,7 @@ case PANE_TERMINAL: { Buffer* buf = &pane->v.terminal.buffer; Rect clip; clip.x = 0; - clip.y = buf->height - within.h; + clip.y = pane->v.terminal.scroll; clip.w = within.w; clip.h = within.h; diff --git a/source/terminal.c b/source/terminal.c index 142e709e0352ba70601727fcb14f6a7f68ccee77..7596b8265349bcee63b26ec6ed1417dd42d56959 100644 --- a/source/terminal.c +++ b/source/terminal.c @@ -5,9 +5,11 @@ #include "interpreter/vt100.h" Terminal Terminal_New(int w, int h, bool* success) { Terminal ret; - ret.cursor = (Vec2) {0, 0}; + ret.cursor = (Vec2) {0, 1000 - h}; + ret.scroll = ret.cursor.y; + ret.height = h; ret.attr = BufAttr_Default(); - ret.buffer = Buffer_New(w, h); + ret.buffer = Buffer_New(w, 1000); bool success2; ret.term = SysTerm_New(&success2, w, h); diff --git a/source/terminal.h b/source/terminal.h index 84f7482cc3567599a4033126be58e1860dcad420..7027ff71bb1f15d8932c179aa0772733aa8c0652 100644 --- a/source/terminal.h +++ b/source/terminal.h @@ -12,6 +12,8 @@ BufAttr attr; Buffer buffer; SysTerm term; void* interpreter; // Interpreter* + int height; + int scroll; // terminal options bool blinkCursor;