diff --git a/kernel/textterminal.cpp b/kernel/textterminal.cpp index 39cc7cad..cfd4078b 100644 --- a/kernel/textterminal.cpp +++ b/kernel/textterminal.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016 Jonas 'Sortie' Termansen. + * Copyright (c) 2023 Juhani 'nortti' Krekelä. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -659,8 +660,45 @@ void TextTerminal::RunAnsiCommand(TextBuffer* textbuf, char c) uint32_t fillbg = attr & ATTR_INVERSE ? fgcolor : bgcolor; textbuf->Fill(from, to, TextChar(' ', vgacolor, 0, fillfg, fillbg)); } break; - // TODO: CSI Ps M Delete Ps Line(s) (default = 1) (DL). - // (delete those lines and move the rest of the lines upwards). + case 'L': // Append lines before current line. + { + column = 0; + unsigned count = 0 < ansiusedparams ? ansiparams[0] : 1; + if ( height - line < count ) + count = height - line; + TextPos from(0, line); + TextPos move_to(0, line + count); + unsigned move_lines = height - (line + count); + textbuf->Move(move_to, from, move_lines * width); + if ( 0 < count ) + { + TextPos fill_to(width - 1, line + count - 1); + uint32_t fill_fg = attr & ATTR_INVERSE ? bgcolor : fgcolor; + uint32_t fill_bg = attr & ATTR_INVERSE ? fgcolor : bgcolor; + TextChar fill_char(' ', vgacolor, 0, fill_fg, fill_bg); + textbuf->Fill(from, fill_to, fill_char); + } + } break; + case 'M': // Delete lines starting from beginning of current line. + { + column = 0; + unsigned count = 0 < ansiusedparams ? ansiparams[0] : 1; + if ( height - line < count ) + count = height - line; + TextPos move_from(0, line + count); + TextPos move_to(0, line); + unsigned move_lines = height - (line + count); + textbuf->Move(move_to, move_from, move_lines * width); + if ( 0 < count ) + { + TextPos fill_from(0, height - count); + TextPos fill_to(width - 1, height - 1); + uint32_t fill_fg = attr & ATTR_INVERSE ? bgcolor : fgcolor; + uint32_t fill_bg = attr & ATTR_INVERSE ? fgcolor : bgcolor; + TextChar fill_char(' ', vgacolor, 0, fill_fg, fill_bg); + textbuf->Fill(fill_from, fill_to, fill_char); + } + } break; // TODO: CSI Ps P Delete Ps Character(s) (default = 1) (DCH). // (delete those characters and move the rest of the line leftward). case 'S': // Scroll a line up and place a new line at the buttom. diff --git a/ports/libcurses/libcurses.patch b/ports/libcurses/libcurses.patch index 537ad41e..01661d3e 100644 --- a/ports/libcurses/libcurses.patch +++ b/ports/libcurses/libcurses.patch @@ -293,7 +293,7 @@ diff -Paur --no-dereference -- libcurses.upstream/netbsd_sys/cdefs.h libcurses/n diff -Paur --no-dereference -- libcurses.upstream/terminfo/sortix.terminfo libcurses/terminfo/sortix.terminfo --- libcurses.upstream/terminfo/sortix.terminfo +++ libcurses/terminfo/sortix.terminfo -@@ -0,0 +1,230 @@ +@@ -0,0 +1,231 @@ +# TODO: Decode setab and setaf and see if they are what I want. +# TODO: Implement BEL \a and add bel=^G, +# TODO: Add blink support and add blink=\E[5m, @@ -302,12 +302,9 @@ diff -Paur --no-dereference -- libcurses.upstream/terminfo/sortix.terminfo libcu +# TODO: Support dch=\E[%p1%dP, +# TODO: dch1=\E[P, +# TODO: Add faint support and add dim=\E[2m, -+# TODO: dl1=\E[M, +# TODO: ech=\E[%p1%dX, +# TODO: hts=\EH, +# TODO: ich=\E[%p1%d@, -+# TODO: il=\E[%p1%dL, -+# TODO: il1=\E[L, +# TODO: invis=\E[8m, +# TODO: Some modifiers for the function keys are missing, like control + alt + +# shift + f12, kfxx should probably go up to 96. On the other hand, @@ -346,12 +343,16 @@ diff -Paur --no-dereference -- libcurses.upstream/terminfo/sortix.terminfo libcu + cup=\E[%i%p1%d;%p2%dH, + cuu1=\E[A, + cuu=\E[%p1%dA, ++ dl1=\E[M, ++ dl=\E[%p1%dM, + ed=\E[J, + el1=\E[1K, + el=\E[K, + home=\E[H, + hpa=\E[%i%p1%dG, + ht=^I, ++ il1=\E[L, ++ il=\E[%p1%dL, + ind=^J, + indn=\E[%p1%dS, + nel=^J, diff --git a/terminal/terminal.c b/terminal/terminal.c index 47f515c1..c0b01c56 100644 --- a/terminal/terminal.c +++ b/terminal/terminal.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, 2022 Jonas 'Sortie' Termansen. + * Copyright (c) 2023 Juhani 'nortti' Krekelä. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -211,6 +212,21 @@ static void fill(size_t from_x, size_t from_y, size_t to_x, size_t to_y, scrollback[i] = with; } +static void move(size_t to_x, size_t to_y, size_t from_x, size_t from_y, + size_t num_chars) +{ + // TODO: Assert within bounds? + size_t from = from_y * columns + from_x; + size_t to = to_y * columns + to_x; + if ( to < from ) + for ( size_t i = 0; i < num_chars; i++ ) + scrollback[to + i] = scrollback[from + i]; + else if ( from < to ) + for ( size_t i = 0; i < num_chars; i++ ) + scrollback[to + num_chars - 1 - i] = + scrollback[from + num_chars - 1 - i]; +} + static void scroll(ssize_t offsigned, struct entry with) { if ( 0 < offsigned ) @@ -396,8 +412,38 @@ static void run_ansi_command(char c) with.wc = 0; fill(from_x, from_y, to_x, to_y, with); } break; - // TODO: CSI Ps M Delete Ps Line(s) (default = 1) (DL). - // (delete those lines and move the rest of the lines upwards). + case 'L': // Append lines before current line. + { + column = 0; + unsigned count = 0 < ansiusedparams ? ansiparams[0] : 1; + if ( rows - row < count ) + count = rows - row; + unsigned move_lines = rows - (row + count); + move(0, row + count, 0, row, move_lines * columns); + struct entry with; + with.attr = 0; + with.fgcolor = attr & ATTR_INVERSE ? current_bgcolor : current_fgcolor; + with.bgcolor = attr & ATTR_INVERSE ? current_fgcolor : current_bgcolor; + with.wc = 0; + if ( 0 < count ) + fill(0, row, columns - 1, row + count - 1, with); + } break; + case 'M': // Delete lines starting from beginning of current line. + { + column = 0; + unsigned count = 0 < ansiusedparams ? ansiparams[0] : 1; + if ( rows - row < count ) + count = rows - row; + unsigned move_lines = rows - (row + count); + move(0, row, 0, row + count, move_lines * columns); + struct entry with; + with.attr = 0; + with.fgcolor = attr & ATTR_INVERSE ? current_bgcolor : current_fgcolor; + with.bgcolor = attr & ATTR_INVERSE ? current_fgcolor : current_bgcolor; + with.wc = 0; + if ( 0 < count ) + fill(0, rows - count, columns - 1, rows - 1, with); + } break; // TODO: CSI Ps P Delete Ps Character(s) (default = 1) (DCH). // (delete those characters and move the rest of the line leftward). case 'S': // Scroll a line up and place a new line at the buttom.