yterm

commit b6a3bb388d3e24f8637c2ece5d860198aa21f3f6

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;