yterm

commit 5550681192244d9db6c3d3ea4b6efecfa67b4508

Author: mesyeti <mesyeti@mesyeti.uk>

add TODOs for more sequences

 source/interpreter/vt100.c | 126 +++++++++++++++++++++++++++++++++++++++
 source/screen.c | 1 
 source/screen.h | 1 
 source/terminal.h | 4 +


diff --git a/source/interpreter/vt100.c b/source/interpreter/vt100.c
index 213cb5b1e08740168832b403b26a309a4318df28..61efd0007b01821f2166967890f5d5d73bba65bd 100644
--- a/source/interpreter/vt100.c
+++ b/source/interpreter/vt100.c
@@ -7,12 +7,23 @@
 enum {
 	MODE_READY = 0,
 	MODE_ESCAPE,
-	MODE_CSI
+	MODE_CSI, // \e[
+	MODE_OSC  // \e]
+};
+
+enum {
+	MOUSE_OFF,
+	MOUSE_PRESS,
+	MOUSE_BOTH
 };
 
 typedef struct {
 	int  mode;
 	char reading[1024];
+
+	// terminal settings
+	bool bracketedPaste;
+	int  mouseMode;
 } Vt100;
 
 static void SendInput(Interpreter* p_this, Terminal* terminal, Event* e) {
@@ -130,6 +141,22 @@ 						terminal->attr.fgMode = BUF_DEFAULT;
 						terminal->attr.bgMode = BUF_DEFAULT;
 						break;
 					}
+					case 1: break; // TODO: bold
+					case 4: break; // TODO: underline
+					case 5: break; // TODO: blink
+					case 7: {
+						terminal->attr.invert = true;
+						break;
+					}
+					case 8: break; // TODO: hidden
+					case 22: break; // TODO: normal
+					case 24: break; // TODO: not underlined
+					case 25: break; // TODO: steady - not blinking
+					case 27: {
+						terminal->attr.invert = false;
+						break;
+					}
+					case 28: break; // TODO: visible - not hidden
 					default: {
 						if (((part >= 30) && (part <= 39)) || ((part >= 90) && (part <= 97))) {
 							terminal->attr.fgMode = BUF_16COL;
@@ -185,6 +212,79 @@ 			}
 
 			break;
 		}
+		case 'h': {
+			if (!q || (num < 1)) break;
+
+			int param = atoi(parts[0]);
+
+			switch (param) {
+				case 9:    this->mouseMode = MOUSE_PRESS; break;
+				case 12:   terminal->blinkCursor = true; break;
+				case 25:   terminal->showCursor  = true; break;
+				case 1047:
+				case 47:   break; // TODO: show alternate screen buffer
+				case 1000: this->mouseMode = MOUSE_BOTH; break;
+				case 1001: break; // TODO: use hilite motion mouse tracking
+				case 1002: break; // TODO: use cell motion mouse tracking
+				case 1003: break; // TODO: use all motion mouse tracking
+				case 1048: break; // TODO: save cursor
+				case 1049: break; // TODO: save cursor & use alternate screen buffer
+				default: printf("Unsupported: %sh\n", param);
+			}
+			break;
+		}
+		case 'l': {
+			if (!q || (num < 1)) break;
+
+			int param = atoi(parts[0]);
+
+			switch (param) {
+				case 9:    this->mouseMode = MOUSE_OFF; break;
+				case 12:   terminal->blinkCursor = false; break;
+				case 25:   terminal->showCursor  = false; break;
+				case 1047:
+				case 47:   break; // TODO: use normal screen buffer
+				case 1000: this->mouseMode = OFF; break;
+				case 1001: break; // TODO: do not use hilite motion mouse tracking
+				case 1002: break; // TODO: do not use cell motion mouse tracking
+				case 1003: break; // TODO: do not use all motion mouse tracking
+				case 1048: break; // TODO: restore cursor
+				case 1049: break; // TODO: restore cursor & use normal screen buffer
+				default: printf("Unsupported: %sh\n", param);
+			}
+			break;
+		}
+		default: {
+			printf("Unsupported: %s %c\n", this->reading, (char) ch);
+			break; // Unsupported
+		}
+	}
+
+	FreeStrArray(parts);
+}
+
+static void HandleOSC(Vt100* this, Terminal* terminal) {
+	// parse sequences
+	const char* str = this->reading;
+	bool        q   = false;
+
+	if (*str == '?') {
+		q = true;
+		++ str;
+	}
+
+	size_t num;
+	char** parts = Split(str, &num, ';');
+
+	int func = atoi(parts[0]);
+
+	switch (func) {
+		case 0:
+		case 2: {
+			// TODO: implement
+			Log("Terminal title = %s", parts[1]);
+			break;
+		}
 		default: {
 			printf("Unsupported: %s\n", this->reading);
 			break; // Unsupported
@@ -227,6 +327,7 @@ 		}
 		case MODE_ESCAPE: {
 			switch (ch) {
 				case '[': this->mode = MODE_CSI; break;
+				case ']': this->mode = MODE_OSC; break;
 				default:  this->mode = MODE_READY; // invalid
 			}
 			break;
@@ -250,6 +351,25 @@ 				strncat(this->reading, &ch2, 1);
 			}
 			break;
 		}
+		case MODE_OSC: {
+			if (strlen(this->reading) > 1022) {
+				this->mode       = MODE_READY;
+				this->reading[0] = 0; // TODO: use a String for this
+				break;
+			}
+
+			if ((ch == 7) || (ch == 0x9C)) {
+				this->mode = MODE_READY;
+				HandleOSC(this, terminal);
+
+				this->reading[0] = 0;
+			}
+			else {
+				char ch2 = (char) ch;
+				strncat(this->reading, &ch2, 1);
+			}
+			break;
+		}
 	}
 }
 
@@ -258,6 +378,10 @@ 	Vt100* data = SafeMalloc(sizeof(Vt100));
 
 	data->reading[0] = 0;
 	data->mode       = MODE_READY;
+
+	// terminal settings
+	data->bracketedPaste = false;
+	data->mouseMode      = MOUSE_OFF;
 
 	return (Interpreter) {
 		.data      = (void*) data,




diff --git a/source/screen.c b/source/screen.c
index 300c79c7cf5a6af81bbebea6a91ce5bab92fd708..14d103107708a433917451be47d1ad8a99b3fea5 100644
--- a/source/screen.c
+++ b/source/screen.c
@@ -24,6 +24,7 @@ 	int cw;
 	int ch;
 	Font_CharSize(&screen.font, &cw, &ch);
 
+	screen.old    = Buffer_New(video.windows[0].width / cw, video.windows[0].height / ch);
 	screen.buffer = Buffer_New(video.windows[0].width / cw, video.windows[0].height / ch);
 	screen.buffer.isScreenBuf = true;
 




diff --git a/source/screen.h b/source/screen.h
index f7e08e93fc8d019cc90989be6556d2e6f58b0652..1a374cc7276b63743f654f4fcde10f14f5d4c500 100644
--- a/source/screen.h
+++ b/source/screen.h
@@ -5,6 +5,7 @@ #include "font.h"
 #include "buffer.h"
 
 typedef struct {
+	Buffer old;
 	Buffer buffer;
 	Font   font;
 } Screen;




diff --git a/source/terminal.h b/source/terminal.h
index 9a7e05fde2de187904766b4c42106269fdc1a0af..14399f7a07dfdb138b56ce5d118903ca49ba0403 100644
--- a/source/terminal.h
+++ b/source/terminal.h
@@ -12,6 +12,10 @@ 	BufAttr attr;
 	Buffer  buffer;
 	SysTerm term;
 	void*   interpreter; // Interpreter*
+
+	// terminal options
+	bool blinkCursor;
+	bool showCursor;
 } Terminal;
 
 Terminal Terminal_New(int w, int h, bool* success);