mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 14:47:44 +00:00
VirtualConsole: Support the 'A' and 'D' CSI sequences.
This makes backspace work correctly when line editing with bash-2.05b.
This commit is contained in:
parent
a8c7b6ce86
commit
4f6438ec66
5 changed files with 47 additions and 7 deletions
|
@ -9,16 +9,21 @@
|
||||||
TTY::TTY(unsigned major, unsigned minor)
|
TTY::TTY(unsigned major, unsigned minor)
|
||||||
: CharacterDevice(major, minor)
|
: CharacterDevice(major, minor)
|
||||||
{
|
{
|
||||||
memset(&m_termios, 0, sizeof(m_termios));
|
set_default_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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TTY::~TTY()
|
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)
|
ssize_t TTY::read(byte* buffer, size_t size)
|
||||||
{
|
{
|
||||||
return m_buffer.read(buffer, 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)
|
ssize_t TTY::write(const byte* buffer, size_t size)
|
||||||
{
|
{
|
||||||
#ifdef TTY_DEBUG
|
#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
|
#endif
|
||||||
on_tty_write(buffer, size);
|
on_tty_write(buffer, size);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -71,12 +80,25 @@ void TTY::generate_signal(int signal)
|
||||||
void TTY::set_termios(const Unix::termios& t)
|
void TTY::set_termios(const Unix::termios& t)
|
||||||
{
|
{
|
||||||
m_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(),
|
tty_name().characters(),
|
||||||
should_echo_input(),
|
should_echo_input(),
|
||||||
should_generate_signals(),
|
should_generate_signals(),
|
||||||
in_canonical_mode()
|
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)
|
int TTY::ioctl(Process& process, unsigned request, unsigned arg)
|
||||||
|
|
|
@ -29,6 +29,8 @@ public:
|
||||||
bool should_echo_input() const { return m_termios.c_lflag & ECHO; }
|
bool should_echo_input() const { return m_termios.c_lflag & ECHO; }
|
||||||
bool in_canonical_mode() const { return m_termios.c_lflag & ICANON; }
|
bool in_canonical_mode() const { return m_termios.c_lflag & ICANON; }
|
||||||
|
|
||||||
|
void set_default_termios();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void on_tty_write(const byte*, size_t) = 0;
|
virtual void on_tty_write(const byte*, size_t) = 0;
|
||||||
void set_size(unsigned short columns, unsigned short rows);
|
void set_size(unsigned short columns, unsigned short rows);
|
||||||
|
|
|
@ -281,6 +281,17 @@ void VirtualConsole::escape$A(const Vector<unsigned>& params)
|
||||||
set_cursor(new_row, m_cursor_column);
|
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)
|
void VirtualConsole::escape$J(const Vector<unsigned>& params)
|
||||||
{
|
{
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
|
@ -319,6 +330,8 @@ void VirtualConsole::execute_escape_sequence(byte final)
|
||||||
params.append(value);
|
params.append(value);
|
||||||
}
|
}
|
||||||
switch (final) {
|
switch (final) {
|
||||||
|
case 'A': escape$A(params); break;
|
||||||
|
case 'D': escape$D(params); break;
|
||||||
case 'H': escape$H(params); break;
|
case 'H': escape$H(params); break;
|
||||||
case 'J': escape$J(params); break;
|
case 'J': escape$J(params); break;
|
||||||
case 'm': escape$m(params); break;
|
case 'm': escape$m(params); break;
|
||||||
|
|
|
@ -41,6 +41,7 @@ private:
|
||||||
void put_character_at(unsigned row, unsigned column, byte ch);
|
void put_character_at(unsigned row, unsigned column, byte ch);
|
||||||
|
|
||||||
void escape$A(const Vector<unsigned>&);
|
void escape$A(const Vector<unsigned>&);
|
||||||
|
void escape$D(const Vector<unsigned>&);
|
||||||
void escape$H(const Vector<unsigned>&);
|
void escape$H(const Vector<unsigned>&);
|
||||||
void escape$J(const Vector<unsigned>&);
|
void escape$J(const Vector<unsigned>&);
|
||||||
void escape$m(const Vector<unsigned>&);
|
void escape$m(const Vector<unsigned>&);
|
||||||
|
|
|
@ -114,7 +114,9 @@ char* tgoto(const char* cap, int col, int row)
|
||||||
|
|
||||||
int tputs(const char* str, int affcnt, int (*putc)(int))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue