AmendHub

Download:

jcs

/

subtext

/

amendments

/

37

console: More ANSI support like line insert and delete


jcs made amendment 37 over 2 years ago
--- console.c Wed Dec 15 15:21:23 2021 +++ console.c Thu Dec 23 20:47:51 2021 @@ -31,24 +31,24 @@ #define CONSOLE_PADDING 6 +void console_setup(struct session *session); +void console_redraw(struct console *console, short force); +short console_bound(struct console *console); +void console_parse_csi(struct console *console); + struct node_funcs console_node_funcs = { - NULL, + console_setup, console_input, console_output, console_close }; -void console_redraw(struct console *console, short force); -short console_bound(struct console *console); -void console_parse_csi(struct console *console); - struct console * console_init(struct console **cur_console) { - char title[64] = { 0 }; + char title[64]; struct console *console; - Rect bounds = { 0 }; - Rect data_bounds = { 0, 0, 0, 1 }; /* tlbr */ + Rect bounds; short width, height; console = xmalloczero(sizeof(struct console)); @@ -64,12 +64,12 @@ console_init(struct console **cur_console) bounds.left = (screenBits.bounds.right - width) / 2; bounds.right = bounds.left + width; - bounds.top = ((screenBits.bounds.bottom - height) / 2) + - (GetMBarHeight()); + bounds.top = (GetMBarHeight()) + + ((screenBits.bounds.bottom - height) / 2); bounds.bottom = bounds.top + height; - if (sprintf(title, "%s: console", PROGRAM_NAME) > sizeof(title)) - panic("sprintf overflow!"); + snprintf(title, sizeof(title), "%s: %s: console", PROGRAM_NAME, + db->config.hostname); CtoPstr(title); console->win = NewWindow(0L, &bounds, title, false, noGrowDocProc, @@ -83,7 +83,7 @@ console_init(struct console **cur_console) console->session = session_create("console", "console", &console_node_funcs); console->session->cookie = (void *)console; - console->session->ansi = 1; + console->session->vt100 = 1; console->session->cp437 = 1; console->session->tspeed = 19200; strlcpy(console->session->autologin_username, "sysop", @@ -98,6 +98,14 @@ console_init(struct console **cur_console) } void +console_setup(struct session *session) +{ + struct console *console = (struct console *)session->cookie; + session->terminal_cols = console->ncolumns; + session->terminal_rows = console->nlines; +} + +void console_close(struct session *session) { struct console *console = (struct console *)session->cookie; @@ -259,7 +267,7 @@ console_bound(struct console *console) short n; #endif - while (console->cursor_column >= console->ncolumns) { + while (console->cursor_column > console->ncolumns) { console->cursor_line++; console->cursor_column -= console->ncolumns; } @@ -344,20 +352,22 @@ console_redraw(struct console *console, short force) cursor.right = cursor.left + FONT_WIDTH; cursor.bottom = cursor.top + FONT_HEIGHT; FillRect(&cursor, white); - - MoveTo(cursor.left, cursor.top + FONT_HEIGHT - 2); - if (cbold != (console->attrs[cell] & ATTR_BOLD)) { - if (console->attrs[cell] & ATTR_BOLD) - TextFace(thePort->txFace | bold); - else - TextFace(thePort->txFace & ~bold); - - cbold = console->attrs[cell] & ATTR_BOLD; + if (console->chars[cell] != ' ') { + MoveTo(cursor.left, cursor.top + FONT_HEIGHT - 2); + + if (cbold != (console->attrs[cell] & ATTR_BOLD)) { + if (console->attrs[cell] & ATTR_BOLD) + TextFace(thePort->txFace | bold); + else + TextFace(thePort->txFace & ~bold); + + cbold = console->attrs[cell] & ATTR_BOLD; + } + + DrawChar(console->chars[cell]); } - DrawChar(console->chars[cell]); - if (console->attrs[cell] & ATTR_REVERSE) InvertRect(&cursor); if (console->attrs[cell] & ATTR_CURSOR) @@ -379,6 +389,7 @@ console_parse_csi(struct console *console) short serviced = 0; short param1 = -1, param2 = -1; short parambuflen; + short start, count; char parambuf[4]; unsigned char c; @@ -398,8 +409,11 @@ console_parse_csi(struct console *console) case 'E': case 'F': case 'G': + case 'I': case 'J': case 'K': + case 'L': + case 'M': case 'S': case 'T': case 'd': @@ -468,38 +482,30 @@ console_parse_csi(struct console *console) switch (c) { case 'A': /* CUU - cursor up, stop at top of screen */ - for (x = 0; x < param1 && console->cursor_line > 0; x++) - console->cursor_line--; + console->cursor_line = MAX(0, console->cursor_line - param1); break; case 'B': /* CUD - cursor down, stop at bottom of screen */ - for (x = 0; x < param1 && - console->cursor_line < console->nlines - 1; x++) - console->cursor_line++; + console->cursor_line = MIN(console->nlines - 1, + console->cursor_line + param1); break; case 'C': /* CUF - cursor forward, stop at screen edge */ - for (x = 0; x < param1 && - console->cursor_column < console->ncolumns - 1; x++) - console->cursor_column++; + console->cursor_column = MIN(console->ncolumns - 1, + console->cursor_column + param1); break; case 'D': /* CUB - cursor back, stop at left edge of screen */ - for (x = 0; x < param1 && console->cursor_column > 0; x++) - console->cursor_column--; + console->cursor_column = MAX(0, console->cursor_column - param1); break; case 'E': /* CNL - cursor next line */ console->cursor_column = 0; - for (x = 0; x < param1 && - console->cursor_line < console->nlines - 1; x++) - console->cursor_line++; + console->cursor_line = MAX(console->nlines - 1, + console->cursor_line + param1); break; case 'F': /* CPL - cursor previous line */ console->cursor_column = 0; - for (x = 0; x < param1 && console->cursor_line > 0; x++) - console->cursor_line--; + console->cursor_line = MAX(0, console->cursor_line - param1); break; case 'G': /* CHA - cursor horizontal absolute */ - if (param1 > console->ncolumns) - param1 = console->ncolumns; - console->cursor_column = param1; + console->cursor_column = BOUND(param1, 0, console->ncolumns - 1); break; case 'H': /* CUP - cursor absolute position */ case 'f': /* HVP - horizontal vertical position */ @@ -520,47 +526,30 @@ console_parse_csi(struct console *console) case 'J': /* ED - erase in display */ switch (param1) { case 0: - /* clear from cursor to end of screen */ - for (y = console->cursor_line; y < console->nlines; y++) { - for (x = 0; x < console->ncolumns; x++) { - if (y == console->cursor_line && - x < console->cursor_column) - continue; - - cursor = (y * console->ncolumns) + x; - console->chars[cursor] = ' '; - console->attrs[cursor] = console->cur_attr | ATTR_DIRTY; - } - } + /* clear from cursor (inclusive) to end of screen */ + start = (console->cursor_line * console->ncolumns) + + console->cursor_column; + count = (console->ncolumns * console->nlines) - start; + memset(console->chars + start, ' ', count); + memset(console->attrs + start, console->cur_attr | ATTR_DIRTY, + count); break; case 1: /* clear from cursor to beginning of the screen */ - for (y = console->cursor_line; y >= 0; y--) { - for (x = console->ncolumns; x >= 0; x--) { - if (y == console->cursor_line && - x > console->cursor_column) - continue; - - cursor = (y * console->ncolumns) + x; - console->chars[cursor] = ' '; - console->attrs[cursor] = console->cur_attr | ATTR_DIRTY; - } - } + count = (console->cursor_line * console->ncolumns) + + console->cursor_column; + memset(console->chars, ' ', count); + memset(console->attrs, console->cur_attr | ATTR_DIRTY, count); break; case 2: /* clear entire screen, mark everything clean */ - cursor = 0; - for (y = 0; y < console->nlines; y++) { - for (x = 0; x < console->ncolumns; x++) { - console->chars[cursor] = ' '; - console->attrs[cursor] = console->cur_attr; - cursor++; - } - } - + count = console->ncolumns * console->nlines; + memset(console->chars, ' ', count); + memset(console->attrs, console->cur_attr | ATTR_DIRTY, count); + /* and then quickly clear the screen */ - console_bound(console); - console_redraw(console, CONSOLE_CLEAR_SCREEN); + //console_bound(console); + //console_redraw(console, CONSOLE_CLEAR_SCREEN); break; } break; @@ -568,34 +557,84 @@ console_parse_csi(struct console *console) switch (param1) { case 0: /* clear from cursor to end of line */ - if (console->cursor_column >= console->ncolumns) - break; - for (x = console->cursor_column; x < console->ncolumns; x++) { - cursor = (console->cursor_line * console->ncolumns) + x; - console->chars[cursor] = ' '; - console->attrs[cursor] = console->cur_attr | ATTR_DIRTY; - } + start = (console->cursor_line * console->ncolumns) + + console->cursor_column; + count = console->ncolumns - console->cursor_column; + memset(console->chars + start, ' ', count); + memset(console->attrs + start, console->cur_attr | ATTR_DIRTY, + count); break; case 1: /* clear from cursor to beginning of line */ - if (console->cursor_column == 0) - break; - for (x = console->cursor_column; x >= 0; x--) { - cursor = (console->cursor_line * console->ncolumns) + x; - console->chars[cursor] = ' '; - console->attrs[cursor] = console->cur_attr | ATTR_DIRTY; - } + start = (console->cursor_line * console->ncolumns); + count = console->ncolumns - console->cursor_column; + memset(console->chars + start, ' ', count); + memset(console->attrs + start, console->cur_attr | ATTR_DIRTY, + count); break; case 2: /* clear entire line */ - for (x = 0; x < console->ncolumns - 1; x++) { - cursor = (console->cursor_line * console->ncolumns) + x; - console->chars[cursor] = ' '; - console->attrs[cursor] = console->cur_attr | ATTR_DIRTY; - } + start = (console->cursor_line * console->ncolumns); + count = console->ncolumns; + memset(console->chars + start, ' ', count); + memset(console->attrs + start, console->cur_attr | ATTR_DIRTY, + count); break; } break; + case 'L': /* IL - insert line */ + param1 = BOUND(param1, 0, console->nlines - console->cursor_line); + if (param1 == 0) + break; + if (console->cursor_line != console->nlines - 1) { + /* move remaining lines down */ + count = console->ncolumns * + (console->nlines - console->cursor_line - param1); + memmove(console->chars + + ((console->cursor_line + param1) * console->ncolumns), + console->chars + + (console->cursor_line * console->ncolumns), + count); + memmove(console->attrs + + ((console->cursor_line + param1) * console->ncolumns), + console->attrs + + (console->cursor_line * console->ncolumns), + count); + } + /* clear new lines at cursor line */ + start = console->ncolumns * console->cursor_line; + count = console->ncolumns * param1; + memset(console->chars + start, ' ', count); + memset(console->attrs + start, console->cur_attr, count); + /* mark all of that dirty */ + count = start + (console->ncolumns * + (console->nlines - console->cursor_line)); + for (x = start; x < count; x++) + console->attrs[x] |= ATTR_DIRTY; + break; + case 'M': /* DL - delete line */ + param1 = BOUND(param1, 0, console->nlines - console->cursor_line); + if (param1 == 0) + break; + start = console->cursor_line * console->ncolumns; + count = console->ncolumns * + (console->nlines - console->cursor_line - param1); + memmove(console->chars + start, console->chars + start + + console->ncolumns, count); + memmove(console->attrs + start, console->attrs + start + + console->ncolumns, count); + /* fill in new blank lines at the end */ + start += count; + count = param1 * console->ncolumns; + memset(console->chars + start, ' ', count); + memset(console->attrs + start, console->cur_attr, count); + /* mark all of that dirty */ + start = console->cursor_line * console->ncolumns; + count = start + (console->ncolumns * + (console->nlines - console->cursor_line)); + for (x = start; x < count; x++) + console->attrs[x] |= ATTR_DIRTY; + break; case 'S': /* SU - scroll up */ /* TODO */ break; @@ -702,13 +741,11 @@ console_parse_csi(struct console *console) break; } break; - case '7': /* DECSC - save cursor */ - case 's': /* from ANSI.SYS */ + case 's': /* SCO - save cursor position */ console->saved_cursor_column = console->cursor_column; console->saved_cursor_line = console->cursor_line; break; - case '8': /* DECRC - restore cursor */ - case 'u': /* from ANSI.SYS */ + case 'u': /* SCO - restore saved cursor position */ console->cursor_column = console->saved_cursor_column; console->cursor_line = console->saved_cursor_line; break;