diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-12-07 01:19:02 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-12-07 01:19:02 +0100 |
commit | 4f6438ec666843b9ea97d32b2e3458fbe0afb44d (patch) | |
tree | 9c67f5050623c0f206a16f0ae9ce0a693488797b | |
parent | a8c7b6ce868671b3a70ac640ae866744690712ca (diff) | |
download | serenity-4f6438ec666843b9ea97d32b2e3458fbe0afb44d.zip |
VirtualConsole: Support the 'A' and 'D' CSI sequences.
This makes backspace work correctly when line editing with bash-2.05b.
-rw-r--r-- | Kernel/TTY.cpp | 34 | ||||
-rw-r--r-- | Kernel/TTY.h | 2 | ||||
-rw-r--r-- | Kernel/VirtualConsole.cpp | 13 | ||||
-rw-r--r-- | Kernel/VirtualConsole.h | 1 | ||||
-rw-r--r-- | LibC/termcap.cpp | 4 |
5 files changed, 47 insertions, 7 deletions
diff --git a/Kernel/TTY.cpp b/Kernel/TTY.cpp index 11f78a1a50..41a90269b4 100644 --- a/Kernel/TTY.cpp +++ b/Kernel/TTY.cpp @@ -9,16 +9,21 @@ TTY::TTY(unsigned major, unsigned minor) : CharacterDevice(major, minor) { - memset(&m_termios, 0, sizeof(m_termios)); - m_termios.c_lflag |= ISIG | ECHO; - static const char default_cc[32] = "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"; - memcpy(m_termios.c_cc, default_cc, sizeof(default_cc)); + set_default_termios(); } TTY::~TTY() { } +void TTY::set_default_termios() +{ + memset(&m_termios, 0, sizeof(m_termios)); + m_termios.c_lflag |= ISIG | ECHO; + static const char default_cc[32] = "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"; + memcpy(m_termios.c_cc, default_cc, sizeof(default_cc)); +} + ssize_t TTY::read(byte* buffer, size_t size) { return m_buffer.read(buffer, size); @@ -27,7 +32,11 @@ ssize_t TTY::read(byte* buffer, size_t size) ssize_t TTY::write(const byte* buffer, size_t size) { #ifdef TTY_DEBUG - dbgprintf("TTY::write %b {%u}\n", buffer[0], size); + dbgprintf("TTY::write {%u} ", size); + for (size_t i = 0; i < size; ++i) { + dbgprintf("%b ", buffer[i]); + } + dbgprintf("\n"); #endif on_tty_write(buffer, size); return 0; @@ -71,12 +80,25 @@ void TTY::generate_signal(int signal) void TTY::set_termios(const Unix::termios& t) { m_termios = t; - dbgprintf("%s set_termios: IECHO? %u, ISIG? %u, ICANON? %u\n", + dbgprintf("%s set_termios: ECHO=%u, ISIG=%u, ICANON=%u\n", tty_name().characters(), should_echo_input(), should_generate_signals(), in_canonical_mode() ); + dbgprintf("%s set_termios: ECHOE=%u, ECHOK=%u, ECHONL=%u\n", + tty_name().characters(), + (m_termios.c_lflag & ECHOE) != 0, + (m_termios.c_lflag & ECHOK) != 0, + (m_termios.c_lflag & ECHONL) != 0 + ); + dbgprintf("%s set_termios: ISTRIP=%u, ICRNL=%u, INLCR=%u, IGNCR=%u\n", + tty_name().characters(), + (m_termios.c_iflag & ISTRIP) != 0, + (m_termios.c_iflag & ICRNL) != 0, + (m_termios.c_iflag & INLCR) != 0, + (m_termios.c_iflag & IGNCR) != 0 + ); } int TTY::ioctl(Process& process, unsigned request, unsigned arg) diff --git a/Kernel/TTY.h b/Kernel/TTY.h index eb1f18d74f..699dc1ea6d 100644 --- a/Kernel/TTY.h +++ b/Kernel/TTY.h @@ -29,6 +29,8 @@ public: bool should_echo_input() const { return m_termios.c_lflag & ECHO; } bool in_canonical_mode() const { return m_termios.c_lflag & ICANON; } + void set_default_termios(); + protected: virtual void on_tty_write(const byte*, size_t) = 0; void set_size(unsigned short columns, unsigned short rows); diff --git a/Kernel/VirtualConsole.cpp b/Kernel/VirtualConsole.cpp index 7b0fe262a1..86adc96d70 100644 --- a/Kernel/VirtualConsole.cpp +++ b/Kernel/VirtualConsole.cpp @@ -281,6 +281,17 @@ void VirtualConsole::escape$A(const Vector<unsigned>& params) set_cursor(new_row, m_cursor_column); } +void VirtualConsole::escape$D(const Vector<unsigned>& params) +{ + int num = 1; + if (params.size() >= 1) + num = params[0]; + int new_column = (int)m_cursor_column - num; + if (new_column < 0) + new_column = 0; + set_cursor(m_cursor_row, new_column); +} + void VirtualConsole::escape$J(const Vector<unsigned>& params) { int mode = 0; @@ -319,6 +330,8 @@ void VirtualConsole::execute_escape_sequence(byte final) params.append(value); } switch (final) { + case 'A': escape$A(params); break; + case 'D': escape$D(params); break; case 'H': escape$H(params); break; case 'J': escape$J(params); break; case 'm': escape$m(params); break; diff --git a/Kernel/VirtualConsole.h b/Kernel/VirtualConsole.h index 76be9b45bf..2888ced10d 100644 --- a/Kernel/VirtualConsole.h +++ b/Kernel/VirtualConsole.h @@ -41,6 +41,7 @@ private: void put_character_at(unsigned row, unsigned column, byte ch); void escape$A(const Vector<unsigned>&); + void escape$D(const Vector<unsigned>&); void escape$H(const Vector<unsigned>&); void escape$J(const Vector<unsigned>&); void escape$m(const Vector<unsigned>&); diff --git a/LibC/termcap.cpp b/LibC/termcap.cpp index 8bffe27d3f..8db14ee40c 100644 --- a/LibC/termcap.cpp +++ b/LibC/termcap.cpp @@ -114,7 +114,9 @@ char* tgoto(const char* cap, int col, int row) int tputs(const char* str, int affcnt, int (*putc)(int)) { - printf("%s", str); + size_t len = strlen(str); + for (size_t i = 0; i < len; ++i) + putc(str[i]); return 0; } |