Kernel/LibC: Rework TIOC{G,S}WINSZ more linux like
Userspace can freely set terminal size, kernel just updates it when for example new font is loaded. Also SIGWINCH is now sent by kernel instead of userspace.
This commit is contained in:
@@ -204,20 +204,4 @@ namespace Kernel
|
||||
return master->m_buffer_size < master->m_buffer->size();
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> PseudoTerminalSlave::ioctl_impl(int request, void* argument)
|
||||
{
|
||||
switch (request)
|
||||
{
|
||||
case TIOCSWINSZ:
|
||||
{
|
||||
const auto* winsize = static_cast<struct winsize*>(argument);
|
||||
m_width = winsize->ws_col;
|
||||
m_height = winsize->ws_row;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return TTY::ioctl_impl(request, argument);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -181,7 +181,9 @@ namespace Kernel
|
||||
}, 0600, 0, 0)
|
||||
, m_name(MUST(BAN::String::formatted("ttyS{}", s_next_tty_number++)))
|
||||
, m_serial(serial)
|
||||
{}
|
||||
{
|
||||
update_winsize(m_serial.width(), m_serial.height());
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::RefPtr<SerialTTY>> SerialTTY::create(Serial serial)
|
||||
{
|
||||
@@ -254,16 +256,6 @@ namespace Kernel
|
||||
handle_input_byte(*ptr++);
|
||||
}
|
||||
|
||||
uint32_t SerialTTY::width() const
|
||||
{
|
||||
return m_serial.width();
|
||||
}
|
||||
|
||||
uint32_t SerialTTY::height() const
|
||||
{
|
||||
return m_serial.height();
|
||||
}
|
||||
|
||||
bool SerialTTY::putchar_impl(uint8_t ch)
|
||||
{
|
||||
m_serial.putchar(ch);
|
||||
|
||||
@@ -184,6 +184,13 @@ namespace Kernel
|
||||
return {};
|
||||
}
|
||||
|
||||
void TTY::update_winsize(unsigned short cols, unsigned short rows)
|
||||
{
|
||||
m_winsize.ws_col = cols;
|
||||
m_winsize.ws_row = rows;
|
||||
(void)Process::kill(-m_foreground_pgrp, SIGWINCH);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> TTY::ioctl_impl(int request, void* argument)
|
||||
{
|
||||
switch (request)
|
||||
@@ -198,8 +205,14 @@ namespace Kernel
|
||||
case TIOCGWINSZ:
|
||||
{
|
||||
auto* winsize = static_cast<struct winsize*>(argument);
|
||||
winsize->ws_col = width();
|
||||
winsize->ws_row = height();
|
||||
*winsize = m_winsize;
|
||||
return 0;
|
||||
}
|
||||
case TIOCSWINSZ:
|
||||
{
|
||||
const auto* winsize = static_cast<const struct winsize*>(argument);
|
||||
m_winsize = *winsize;
|
||||
(void)Process::kill(-m_foreground_pgrp, SIGWINCH);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace Kernel
|
||||
{
|
||||
m_width = m_terminal_driver->width();
|
||||
m_height = m_terminal_driver->height();
|
||||
update_winsize(m_width, m_height);
|
||||
|
||||
m_buffer = new Cell[m_width * m_height];
|
||||
ASSERT(m_buffer);
|
||||
@@ -71,34 +72,38 @@ namespace Kernel
|
||||
if (!m_terminal_driver->has_font())
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
SpinLockGuard _(m_write_lock);
|
||||
|
||||
TRY(m_terminal_driver->set_font(BAN::move(font)));
|
||||
|
||||
uint32_t new_width = m_terminal_driver->width();
|
||||
uint32_t new_height = m_terminal_driver->height();
|
||||
|
||||
if (m_width != new_width || m_height != new_height)
|
||||
{
|
||||
Cell* new_buffer = new Cell[new_width * new_height];
|
||||
ASSERT(new_buffer);
|
||||
SpinLockGuard _(m_write_lock);
|
||||
|
||||
for (uint32_t i = 0; i < new_width * m_height; i++)
|
||||
new_buffer[i] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
||||
TRY(m_terminal_driver->set_font(BAN::move(font)));
|
||||
|
||||
for (uint32_t y = 0; y < BAN::Math::min<uint32_t>(m_height, new_height); y++)
|
||||
for (uint32_t x = 0; x < BAN::Math::min<uint32_t>(m_width, new_width); x++)
|
||||
new_buffer[y * new_width + x] = m_buffer[y * m_width + x];
|
||||
uint32_t new_width = m_terminal_driver->width();
|
||||
uint32_t new_height = m_terminal_driver->height();
|
||||
|
||||
delete[] m_buffer;
|
||||
m_buffer = new_buffer;
|
||||
m_width = new_width;
|
||||
m_height = new_height;
|
||||
if (m_width != new_width || m_height != new_height)
|
||||
{
|
||||
Cell* new_buffer = new Cell[new_width * new_height];
|
||||
ASSERT(new_buffer);
|
||||
|
||||
for (uint32_t i = 0; i < new_width * m_height; i++)
|
||||
new_buffer[i] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
||||
|
||||
for (uint32_t y = 0; y < BAN::Math::min<uint32_t>(m_height, new_height); y++)
|
||||
for (uint32_t x = 0; x < BAN::Math::min<uint32_t>(m_width, new_width); x++)
|
||||
new_buffer[y * new_width + x] = m_buffer[y * m_width + x];
|
||||
|
||||
delete[] m_buffer;
|
||||
m_buffer = new_buffer;
|
||||
m_width = new_width;
|
||||
m_height = new_height;
|
||||
}
|
||||
|
||||
for (uint32_t y = 0; y < m_height; y++)
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
render_from_buffer(x, y);
|
||||
}
|
||||
|
||||
for (uint32_t y = 0; y < m_height; y++)
|
||||
for (uint32_t x = 0; x < m_width; x++)
|
||||
render_from_buffer(x, y);
|
||||
update_winsize(m_width, m_height);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user