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);