Author: mesyeti <mesyeti@mesyeti.uk>
some fixes
source/app.c | 6 source/app.h | 1 source/backend.c | 8 source/backend.h | 4 source/backends/soft.c | 5 source/interpreter/vt100.c | 262 ++++++++++++++++++++++++++-------------
diff --git a/source/app.c b/source/app.c index 380ae20bebd39230d6490ae5bb82e027a61355e6..0ea86677576d5b754e8003e7d23ea1de8f5dbfb7 100644 --- a/source/app.c +++ b/source/app.c @@ -32,6 +32,7 @@ app.bindNewTab = Input_AddKeyBind(KEY_LCTRL, KEY_LSHIFT, 0, KEY_T); app.bindPrevTab = Input_AddKeyBind(KEY_LCTRL, 0, 0, KEY_PAGE_UP); app.bindNextTab = Input_AddKeyBind(KEY_LCTRL, 0, 0, KEY_PAGE_DOWN); app.bindReport = Input_AddKeyBind(KEY_LCTRL, KEY_LSHIFT, 0, KEY_R); + app.bindRedraw = Input_AddKeyBind(KEY_LCTRL, KEY_LSHIFT, 0, KEY_D); } static Pane* GetSelectedPane(Pane* pane) { @@ -77,6 +78,11 @@ Log("REPORT"); Log("======"); Log("Cursor: %d, %d\n", term->cursor.x, term->cursor.y); + return true; + } + if (Input_MatchBind(app.bindRedraw, e)) { + Backend_SetRedraw(); + Log("Redrawing..."); return true; } diff --git a/source/app.h b/source/app.h index 27dffed7b82e9fd32897c7d387e268ef7e26dcde..097ab29a262c993935df22a9965e0b5bd324aacf 100644 --- a/source/app.h +++ b/source/app.h @@ -21,6 +21,7 @@ Input_BindID bindNewTab; Input_BindID bindPrevTab; Input_BindID bindNextTab; Input_BindID bindReport; + Input_BindID bindRedraw; } App; extern App app; diff --git a/source/backend.c b/source/backend.c index 1de9556c194b15ab4194f8493a671ec3c53cfe7b..50335cb4814335a4244893dbcee5f2f0a8d95abf 100644 --- a/source/backend.c +++ b/source/backend.c @@ -30,12 +30,8 @@ void Backend_OnWindowResize(void) { backend.onWindowResize(); } -void Backend_OnScreenUpdate(void) { - backend.onScreenUpdate(); -} - -void Backend_OnCellChange(int x, int y) { - backend.onCellChange(x, y); +void Backend_SetRedraw(void) { + backend.setRedraw(); } void Backend_Render(void) { diff --git a/source/backend.h b/source/backend.h index 4dadee10dceace2eaaa7d001f520a7fc7cb60b33..9cf8b2bfb5008e40263674283e076d93e84cc6fd 100644 --- a/source/backend.h +++ b/source/backend.h @@ -26,8 +26,7 @@ Texture* (*loadTexture)(uint8_t* data, int w, int h, int aW, int aH, int ch); void (*freeTexture)(Texture* texture); Vec2 (*getTextureSize)(Texture* texture); void (*onWindowResize)(void); - void (*onScreenUpdate)(void); - void (*onCellChange)(int x, int y); + void (*setRedraw)(void); void (*render)(void); } Backend; @@ -38,6 +37,7 @@ Texture* Backend_LoadTexture(uint8_t* data, int w, int h, int aW, int aH, int ch); void Backend_FreeTexture(Texture* texture); Vec2 Backend_GetTextureSize(Texture* texture); void Backend_OnWindowResize(void); +void Backend_SetRedraw(void); void Backend_Render(void); #endif diff --git a/source/backends/soft.c b/source/backends/soft.c index 33bc739521d929772494125104b5e4e5ef5254d8..d1adf6856c4944f1d1bbee20d5308610d2b997b8 100644 --- a/source/backends/soft.c +++ b/source/backends/soft.c @@ -230,6 +230,10 @@ SDL_RenderCopy(state.renderer, state.texture, NULL, NULL); SDL_RenderPresent(state.renderer); } +static void SetRedraw(void) { + state.redraw = true; +} + Backend Backend_Soft(void) { return (Backend) { .name = "soft", @@ -239,6 +243,7 @@ .loadTexture = &LoadTexture, .freeTexture = &FreeTexture, .getTextureSize = &GetTextureSize, .onWindowResize = &OnWindowResize, + .setRedraw = &SetRedraw, .render = &Render }; } diff --git a/source/interpreter/vt100.c b/source/interpreter/vt100.c index 62c82943b77502c5325461757f40124275be8f2d..f57285cb711475632abc07c8b53777d15b4b4e79 100644 --- a/source/interpreter/vt100.c +++ b/source/interpreter/vt100.c @@ -9,9 +9,11 @@ enum { MODE_READY = 0, MODE_ESCAPE, - MODE_CSI, // \e[ - MODE_OSC, // \e] - MODE_CHSET // \e( + MODE_CSI, // \e[ + MODE_OSC, // \e] + MODE_CHSET, // \e( + MODE_CHSET_P, // \e% + MODE_HASHTAG // \e# }; enum { @@ -27,6 +29,7 @@ // terminal settings bool bracketedPaste; int mouseMode; + Vec2 savedCursor; } Vt100; static char* KeyToSequence(Key key) { @@ -168,6 +171,93 @@ terminal->cursor.y -= by; } } +static void PrintCSI(char** parts, size_t num, UChar ch) { + printf("CSI "); + + for (size_t i = 0; i < num; ++ i) { + printf("%s ", parts[i]); + } + + printf("%c\n", (char) ch); +} + +static void ColourSeq(int part, Terminal* terminal) { + switch (part) { + case 0: { + terminal->attr.fgMode = BUF_DEFAULT; + terminal->attr.bgMode = BUF_DEFAULT; + terminal->attr.invert = false; + 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; + + switch (part) { + case 30: terminal->attr.fg.idx = 0x0; break; // black + case 31: terminal->attr.fg.idx = 0x1; break; // red + case 32: terminal->attr.fg.idx = 0x2; break; // green + case 33: terminal->attr.fg.idx = 0x3; break; // yellow + case 34: terminal->attr.fg.idx = 0x4; break; // blue + case 35: terminal->attr.fg.idx = 0x5; break; // magenta + case 36: terminal->attr.fg.idx = 0x6; break; // cyan + case 37: terminal->attr.fg.idx = 0x7; break; // white + case 39: terminal->attr.fgMode = BUF_DEFAULT; break; + case 90: terminal->attr.fg.idx = 0x8; break; // grey/bright black + case 91: terminal->attr.fg.idx = 0x9; break; // bright red + case 92: terminal->attr.fg.idx = 0xA; break; // bright green + case 93: terminal->attr.fg.idx = 0xB; break; // bright yellow + case 94: terminal->attr.fg.idx = 0xC; break; // bright blue + case 95: terminal->attr.fg.idx = 0xD; break; // bright magenta + case 96: terminal->attr.fg.idx = 0xE; break; // bright cyan + case 97: terminal->attr.fg.idx = 0xF; break; // bright white + default: break; + } + } + else if (((part >= 40) && (part <= 49)) || ((part >= 100) && (part <= 107))) { + terminal->attr.bgMode = BUF_16COL; + + switch (part) { + case 40: terminal->attr.bg.idx = 0x0; break; // black + case 41: terminal->attr.bg.idx = 0x1; break; // red + case 42: terminal->attr.bg.idx = 0x2; break; // green + case 43: terminal->attr.bg.idx = 0x3; break; // yellow + case 44: terminal->attr.bg.idx = 0x4; break; // blue + case 45: terminal->attr.bg.idx = 0x5; break; // magenta + case 46: terminal->attr.bg.idx = 0x6; break; // cyan + case 47: terminal->attr.bg.idx = 0x7; break; // white + case 49: terminal->attr.bgMode = BUF_DEFAULT; break; + case 100: terminal->attr.bg.idx = 0x8; break; // grey/bright black + case 101: terminal->attr.bg.idx = 0x9; break; // bright red + case 102: terminal->attr.bg.idx = 0xA; break; // bright green + case 103: terminal->attr.bg.idx = 0xB; break; // bright yellow + case 104: terminal->attr.bg.idx = 0xC; break; // bright blue + case 105: terminal->attr.bg.idx = 0xD; break; // bright magenta + case 106: terminal->attr.bg.idx = 0xE; break; // bright cyan + case 107: terminal->attr.bg.idx = 0xF; break; // bright white + default: break; + } + } + } + } +} + static void HandleCSI(Vt100* this, Terminal* terminal, UChar ch) { // parse sequences const char* str = this->reading; @@ -180,6 +270,8 @@ } size_t num; char** parts = Split(str, &num, ';'); + + PrintCSI(parts, num, ch); switch (ch) { case 'A': { // move cursor up # lines @@ -231,10 +323,15 @@ break; } case 'H': case 'f': { - if (num < 2) return; + int y = 0; + int x = 0; - int y = atoi(parts[0]) - 1; - int x = atoi(parts[1]) - 1; + if (num >= 1) { + y = atoi(parts[0]) - 1; + } + if (num >= 2) { + x = atoi(parts[1]) - 1; + } if (x < 0) x = 0; if (y < 0) y = 0; @@ -327,85 +424,15 @@ } break; } case 'm': { + if (num == 0) { + ColourSeq(0, terminal); + break; + } + for (size_t i = 0; i < num; ++ i) { int part = atoi(parts[i]); - // printf("CSI %d m\n", part); - - switch (part) { - case 0: { - terminal->attr.fgMode = BUF_DEFAULT; - terminal->attr.bgMode = BUF_DEFAULT; - terminal->attr.invert = false; - 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; - - switch (part) { - case 30: terminal->attr.fg.idx = 0x0; break; // black - case 31: terminal->attr.fg.idx = 0x1; break; // red - case 32: terminal->attr.fg.idx = 0x2; break; // green - case 33: terminal->attr.fg.idx = 0x3; break; // yellow - case 34: terminal->attr.fg.idx = 0x4; break; // blue - case 35: terminal->attr.fg.idx = 0x5; break; // magenta - case 36: terminal->attr.fg.idx = 0x6; break; // cyan - case 37: terminal->attr.fg.idx = 0x7; break; // white - case 39: terminal->attr.fgMode = BUF_DEFAULT; break; - case 90: terminal->attr.fg.idx = 0x8; break; // grey/bright black - case 91: terminal->attr.fg.idx = 0x9; break; // bright red - case 92: terminal->attr.fg.idx = 0xA; break; // bright green - case 93: terminal->attr.fg.idx = 0xB; break; // bright yellow - case 94: terminal->attr.fg.idx = 0xC; break; // bright blue - case 95: terminal->attr.fg.idx = 0xD; break; // bright magenta - case 96: terminal->attr.fg.idx = 0xE; break; // bright cyan - case 97: terminal->attr.fg.idx = 0xF; break; // bright white - default: break; - } - } - else if (((part >= 40) && (part <= 49)) || ((part >= 100) && (part <= 107))) { - terminal->attr.bgMode = BUF_16COL; - - switch (part) { - case 40: terminal->attr.bg.idx = 0x0; break; // black - case 41: terminal->attr.bg.idx = 0x1; break; // red - case 42: terminal->attr.bg.idx = 0x2; break; // green - case 43: terminal->attr.bg.idx = 0x3; break; // yellow - case 44: terminal->attr.bg.idx = 0x4; break; // blue - case 45: terminal->attr.bg.idx = 0x5; break; // magenta - case 46: terminal->attr.bg.idx = 0x6; break; // cyan - case 47: terminal->attr.bg.idx = 0x7; break; // white - case 49: terminal->attr.bgMode = BUF_DEFAULT; break; - case 100: terminal->attr.bg.idx = 0x8; break; // grey/bright black - case 101: terminal->attr.bg.idx = 0x9; break; // bright red - case 102: terminal->attr.bg.idx = 0xA; break; // bright green - case 103: terminal->attr.bg.idx = 0xB; break; // bright yellow - case 104: terminal->attr.bg.idx = 0xC; break; // bright blue - case 105: terminal->attr.bg.idx = 0xD; break; // bright magenta - case 106: terminal->attr.bg.idx = 0xE; break; // bright cyan - case 107: terminal->attr.bg.idx = 0xF; break; // bright white - default: break; - } - } - } - } + ColourSeq(part, terminal); } break; @@ -425,8 +452,15 @@ 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 + case 1048: { + this->savedCursor = terminal->cursor; + break; + } + case 1049: { + this->savedCursor = terminal->cursor; + break; + // TODO: switch to alternate screen buffer + } case 2004: break; // TODO: bracketed paste mode default: printf("Unsupported: %dh\n", param); } @@ -447,15 +481,22 @@ case 1000: this->mouseMode = MOUSE_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 + case 1048: { + terminal->cursor = this->savedCursor; + break; + } + case 1049: { + terminal->cursor = this->savedCursor; + break; + // TODO: switch to normal screen buffer + } case 2004: break; // TODO: bracketed paste mode default: printf("Unsupported: %dl\n", param); } break; } default: { - printf("Unsupported: %s %c\n", this->reading, (char) ch); + printf("Unsupported: %s %s %c\n", this->reading, q? "?" : "", (char) ch); break; // Unsupported } } @@ -514,6 +555,16 @@ case '\x1b': { this->mode = MODE_ESCAPE; break; } + case 0x08: { + -- terminal->cursor.x; + if (terminal->cursor.x < 0) { + terminal->cursor.x = 0; + } + break; + } + case 0x07: { // bell + break; + } default: { BufCell cell; cell.ch = (UChar) ch; @@ -527,11 +578,32 @@ break; } case MODE_ESCAPE: { switch (ch) { - case '[': this->mode = MODE_CSI; break; - case ']': this->mode = MODE_OSC; break; - case '(': this->mode = MODE_CHSET; break; + case '[': this->mode = MODE_CSI; break; + case ']': this->mode = MODE_OSC; break; + case '(': this->mode = MODE_CHSET; break; + case '%': this->mode = MODE_CHSET_P; break; + case '#': this->mode = MODE_HASHTAG; break; + case 'E': { // next line + ++ terminal->cursor.y; + terminal->cursor.x = 0; + ShouldScroll(terminal); + break; + } + case 'D': { // index: move down one line + ++ terminal->cursor.y; + ShouldScroll(terminal); + break; + } + case 'M': { // reverse index: move up one line + -- terminal->cursor.y; + if (terminal->cursor.y < TermTop(terminal)) { + terminal->cursor.y = TermTop(terminal); + } + + break; + } default: { - printf("Unimplemented: ESC '%c'\n", ch); + printf("Unimplemented: ESC (%d) '%c'\n", ch, ch); this->mode = MODE_READY; // invalid } } @@ -576,6 +648,14 @@ } break; } case MODE_CHSET: { + this->mode = MODE_READY; + break; + } + case MODE_CHSET_P: { + this->mode = MODE_READY; + break; + } + case MODE_HASHTAG: { this->mode = MODE_READY; break; }