Compare commits
3 Commits
7c6966a9c4
...
703c1a485c
Author | SHA1 | Date |
---|---|---|
|
703c1a485c | |
|
9258c73484 | |
|
6858546ce9 |
|
@ -41,7 +41,6 @@ namespace Kernel
|
||||||
|
|
||||||
virtual uint32_t height() const = 0;
|
virtual uint32_t height() const = 0;
|
||||||
virtual uint32_t width() const = 0;
|
virtual uint32_t width() const = 0;
|
||||||
void putchar(uint8_t ch);
|
|
||||||
|
|
||||||
virtual dev_t rdev() const final override { return m_rdev; }
|
virtual dev_t rdev() const final override { return m_rdev; }
|
||||||
|
|
||||||
|
@ -60,10 +59,13 @@ namespace Kernel
|
||||||
TTY(mode_t mode, uid_t uid, gid_t gid);
|
TTY(mode_t mode, uid_t uid, gid_t gid);
|
||||||
|
|
||||||
virtual void putchar_impl(uint8_t ch) = 0;
|
virtual void putchar_impl(uint8_t ch) = 0;
|
||||||
|
virtual void update_cursor() {}
|
||||||
|
|
||||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
||||||
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void putchar(uint8_t ch);
|
||||||
void do_backspace();
|
void do_backspace();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Kernel
|
||||||
protected:
|
protected:
|
||||||
virtual BAN::StringView name() const override { return m_name; }
|
virtual BAN::StringView name() const override { return m_name; }
|
||||||
virtual void putchar_impl(uint8_t ch) override;
|
virtual void putchar_impl(uint8_t ch) override;
|
||||||
|
void update_cursor() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VirtualTTY(BAN::RefPtr<TerminalDriver>);
|
VirtualTTY(BAN::RefPtr<TerminalDriver>);
|
||||||
|
@ -78,6 +79,7 @@ namespace Kernel
|
||||||
uint32_t m_saved_row { 0 };
|
uint32_t m_saved_row { 0 };
|
||||||
uint32_t m_saved_column { 0 };
|
uint32_t m_saved_column { 0 };
|
||||||
|
|
||||||
|
bool m_cursor_shown { true };
|
||||||
uint32_t m_row { 0 };
|
uint32_t m_row { 0 };
|
||||||
uint32_t m_column { 0 };
|
uint32_t m_column { 0 };
|
||||||
Cell* m_buffer { nullptr };
|
Cell* m_buffer { nullptr };
|
||||||
|
|
|
@ -64,7 +64,9 @@ namespace Kernel
|
||||||
|
|
||||||
const uint32_t indices_per_block = blksize() / sizeof(uint32_t);
|
const uint32_t indices_per_block = blksize() / sizeof(uint32_t);
|
||||||
|
|
||||||
const uint32_t divisor = (depth > 1) ? indices_per_block * (depth - 1) : 1;
|
uint32_t divisor = 1;
|
||||||
|
for (uint32_t i = 1; i < depth; i++)
|
||||||
|
divisor *= indices_per_block;
|
||||||
|
|
||||||
const uint32_t next_block = block_buffer.span().as_span<uint32_t>()[(index / divisor) % indices_per_block];
|
const uint32_t next_block = block_buffer.span().as_span<uint32_t>()[(index / divisor) % indices_per_block];
|
||||||
if (next_block == 0)
|
if (next_block == 0)
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
const uint8_t* glyph = m_font.has_glyph(ch) ? m_font.glyph(ch) : m_font.glyph('?');
|
const uint8_t* glyph = m_font.has_glyph(ch) ? m_font.glyph(ch) : m_font.glyph('?');
|
||||||
|
|
||||||
|
const bool update_cursor = m_cursor_shown && x == m_cursor_x && y == m_cursor_y;
|
||||||
|
|
||||||
x *= m_font.width();
|
x *= m_font.width();
|
||||||
y *= m_font.height();
|
y *= m_font.height();
|
||||||
|
|
||||||
|
@ -34,17 +36,18 @@ namespace Kernel
|
||||||
|
|
||||||
m_framebuffer_device->sync_pixels_rectangle(x, y, m_font.width(), m_font.height());
|
m_framebuffer_device->sync_pixels_rectangle(x, y, m_font.width(), m_font.height());
|
||||||
|
|
||||||
if (x == m_cursor_x && y == m_cursor_y)
|
if (update_cursor)
|
||||||
{
|
|
||||||
read_cursor();
|
|
||||||
show_cursor(false);
|
show_cursor(false);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool FramebufferTerminalDriver::scroll(Color color)
|
bool FramebufferTerminalDriver::scroll(Color color)
|
||||||
{
|
{
|
||||||
|
if (m_cursor_shown)
|
||||||
|
show_cursor(true);
|
||||||
m_framebuffer_device->scroll(m_font.height(), color.rgb);
|
m_framebuffer_device->scroll(m_font.height(), color.rgb);
|
||||||
m_framebuffer_device->sync_pixels_full();
|
m_framebuffer_device->sync_pixels_full();
|
||||||
|
if (m_cursor_shown)
|
||||||
|
show_cursor(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,25 +65,21 @@ namespace Kernel
|
||||||
void FramebufferTerminalDriver::read_cursor()
|
void FramebufferTerminalDriver::read_cursor()
|
||||||
{
|
{
|
||||||
const uint32_t cursor_h = m_font.height() / 8;
|
const uint32_t cursor_h = m_font.height() / 8;
|
||||||
|
const uint32_t cursor_w = m_font.width();
|
||||||
const uint32_t cursor_top = m_font.height() * 13 / 16;
|
const uint32_t cursor_top = m_font.height() * 13 / 16;
|
||||||
|
|
||||||
const uint32_t x = m_cursor_x * m_font.width();
|
const uint32_t x = m_cursor_x * m_font.width();
|
||||||
const uint32_t y = m_cursor_y * m_font.height();
|
const uint32_t y = m_cursor_y * m_font.height();
|
||||||
|
|
||||||
for (uint32_t dy = 0; dy < cursor_h; dy++)
|
for (uint32_t dy = 0; dy < cursor_h; dy++)
|
||||||
for (uint32_t dx = 0; dx < m_font.width(); dx++)
|
for (uint32_t dx = 0; dx < cursor_w; dx++)
|
||||||
m_cursor_data[dy * m_font.width() + dx] = m_framebuffer_device->get_pixel(x + dx, y + cursor_top + dy);
|
m_cursor_data[dy * cursor_w + dx] = m_framebuffer_device->get_pixel(x + dx, y + cursor_top + dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferTerminalDriver::show_cursor(bool use_data)
|
void FramebufferTerminalDriver::show_cursor(bool use_data)
|
||||||
{
|
|
||||||
const auto get_color =
|
|
||||||
[this, use_data](uint32_t x, uint32_t y) -> uint32_t
|
|
||||||
{
|
{
|
||||||
if (!use_data)
|
if (!use_data)
|
||||||
return m_cursor_color.rgb;
|
read_cursor();
|
||||||
return m_cursor_data[y * m_font.width() + x];
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint32_t cursor_h = m_font.height() / 8;
|
const uint32_t cursor_h = m_font.height() / 8;
|
||||||
const uint32_t cursor_w = m_font.width();
|
const uint32_t cursor_w = m_font.width();
|
||||||
|
@ -89,6 +88,14 @@ namespace Kernel
|
||||||
const uint32_t x = m_cursor_x * m_font.width();
|
const uint32_t x = m_cursor_x * m_font.width();
|
||||||
const uint32_t y = m_cursor_y * m_font.height();
|
const uint32_t y = m_cursor_y * m_font.height();
|
||||||
|
|
||||||
|
const auto get_color =
|
||||||
|
[&](uint32_t x, uint32_t y) -> uint32_t
|
||||||
|
{
|
||||||
|
if (!use_data)
|
||||||
|
return m_cursor_color.rgb;
|
||||||
|
return m_cursor_data[y * cursor_w + x];
|
||||||
|
};
|
||||||
|
|
||||||
for (uint32_t dy = 0; dy < cursor_h; dy++)
|
for (uint32_t dy = 0; dy < cursor_h; dy++)
|
||||||
for (uint32_t dx = 0; dx < cursor_w; dx++)
|
for (uint32_t dx = 0; dx < cursor_w; dx++)
|
||||||
m_framebuffer_device->set_pixel(x + dx, y + cursor_top + dy, get_color(dx, dy));
|
m_framebuffer_device->set_pixel(x + dx, y + cursor_top + dy, get_color(dx, dy));
|
||||||
|
@ -100,20 +107,14 @@ namespace Kernel
|
||||||
if (m_cursor_shown == shown)
|
if (m_cursor_shown == shown)
|
||||||
return;
|
return;
|
||||||
m_cursor_shown = shown;
|
m_cursor_shown = shown;
|
||||||
|
show_cursor(!m_cursor_shown);
|
||||||
if (m_cursor_shown)
|
|
||||||
{
|
|
||||||
read_cursor();
|
|
||||||
show_cursor(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
show_cursor(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferTerminalDriver::set_cursor_position(uint32_t x, uint32_t y)
|
void FramebufferTerminalDriver::set_cursor_position(uint32_t x, uint32_t y)
|
||||||
{
|
{
|
||||||
|
if (x == m_cursor_x && y == m_cursor_y)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!m_cursor_shown)
|
if (!m_cursor_shown)
|
||||||
{
|
{
|
||||||
m_cursor_x = x;
|
m_cursor_x = x;
|
||||||
|
@ -124,7 +125,6 @@ namespace Kernel
|
||||||
show_cursor(true);
|
show_cursor(true);
|
||||||
m_cursor_x = x;
|
m_cursor_x = x;
|
||||||
m_cursor_y = y;
|
m_cursor_y = y;
|
||||||
read_cursor();
|
|
||||||
show_cursor(false);
|
show_cursor(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,7 @@ namespace Kernel
|
||||||
auto* ptr = reinterpret_cast<const uint8_t*>(ansi_c_str);
|
auto* ptr = reinterpret_cast<const uint8_t*>(ansi_c_str);
|
||||||
while (*ptr)
|
while (*ptr)
|
||||||
handle_input_byte(*ptr++);
|
handle_input_byte(*ptr++);
|
||||||
|
update_cursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,6 +359,7 @@ namespace Kernel
|
||||||
SpinLockGuard _(m_write_lock);
|
SpinLockGuard _(m_write_lock);
|
||||||
for (size_t i = 0; i < buffer.size(); i++)
|
for (size_t i = 0; i < buffer.size(); i++)
|
||||||
putchar(buffer[i]);
|
putchar(buffer[i]);
|
||||||
|
update_cursor();
|
||||||
return buffer.size();
|
return buffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,6 +368,7 @@ namespace Kernel
|
||||||
ASSERT(s_tty);
|
ASSERT(s_tty);
|
||||||
SpinLockGuard _(s_tty->m_write_lock);
|
SpinLockGuard _(s_tty->m_write_lock);
|
||||||
s_tty->putchar(ch);
|
s_tty->putchar(ch);
|
||||||
|
s_tty->update_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TTY::is_initialized()
|
bool TTY::is_initialized()
|
||||||
|
|
|
@ -357,7 +357,7 @@ namespace Kernel
|
||||||
case 'l':
|
case 'l':
|
||||||
if (m_ansi_state.question && m_ansi_state.nums[0] == 25)
|
if (m_ansi_state.question && m_ansi_state.nums[0] == 25)
|
||||||
{
|
{
|
||||||
m_terminal_driver->set_cursor_shown(ch == 'h');
|
m_cursor_shown = (ch == 'h');
|
||||||
return reset_ansi();
|
return reset_ansi();
|
||||||
}
|
}
|
||||||
reset_ansi();
|
reset_ansi();
|
||||||
|
@ -518,8 +518,21 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
putcodepoint(codepoint);
|
putcodepoint(codepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VirtualTTY::update_cursor()
|
||||||
|
{
|
||||||
|
static bool last_shown = !m_cursor_shown;
|
||||||
|
if (m_cursor_shown != last_shown)
|
||||||
|
m_terminal_driver->set_cursor_shown(m_cursor_shown);
|
||||||
|
last_shown = m_cursor_shown;
|
||||||
|
|
||||||
|
static uint32_t last_column = -1;
|
||||||
|
static uint32_t last_row = -1;
|
||||||
|
if (last_column != m_column || last_row != m_row)
|
||||||
m_terminal_driver->set_cursor_position(m_column, m_row);
|
m_terminal_driver->set_cursor_position(m_column, m_row);
|
||||||
|
last_column = m_column;
|
||||||
|
last_row = m_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue