Kernel: Add some functionality to disable TTY input/output

Userspace programs can call tty_ctrl() to disable/enable tty from
handling input and displaying output.

This API is probably going to change in the future to ioctl calls
but I'm not sure how ioctl is used and what functionality should it
have. I decided to create whole new function and syscall for now.

Next I will expose framebuffer in /dev/fb0 and then I can start work
on graphical environment! :D
This commit is contained in:
Bananymous
2023-09-27 15:44:05 +03:00
parent 459afef89e
commit cb76f1ea75
13 changed files with 108 additions and 5 deletions

View File

@@ -883,6 +883,19 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_tty_ctrl(int fildes, int command, int flags)
{
LockGuard _(m_lock);
auto inode = TRY(m_open_file_descriptors.inode_of(fildes));
if (!inode->is_tty())
return BAN::Error::from_errno(ENOTTY);
TRY(((TTY*)inode.ptr())->tty_ctrl(command, flags));
return 0;
}
BAN::ErrorOr<long> Process::sys_termid(char* buffer)
{
LockGuard _(m_lock);

View File

@@ -193,6 +193,9 @@ namespace Kernel
case SYS_MUNMAP:
ret = Process::current().sys_munmap((void*)arg1, (size_t)arg2);
break;
case SYS_TTY_CTRL:
ret = Process::current().sys_tty_ctrl((int)arg1, (int)arg2, (int)arg3);
break;
default:
dwarnln("Unknown syscall {}", syscall);
break;

View File

@@ -286,7 +286,7 @@ namespace Kernel
return m_serial.height();
}
void SerialTTY::putchar(uint8_t ch)
void SerialTTY::putchar_impl(uint8_t ch)
{
m_serial.putchar(ch);
}

View File

@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <string.h>
#include <sys/banan-os.h>
#include <sys/sysmacros.h>
namespace Kernel
@@ -42,6 +43,35 @@ namespace Kernel
MUST(((RamSymlinkInode*)inode.ptr())->set_link_target(name()));
}
BAN::ErrorOr<void> TTY::tty_ctrl(int command, int flags)
{
if (flags & ~(TTY_FLAG_ENABLE_INPUT | TTY_FLAG_ENABLE_OUTPUT))
return BAN::Error::from_errno(EINVAL);
switch (command)
{
case TTY_CMD_SET:
if ((flags & TTY_FLAG_ENABLE_INPUT) && !m_tty_ctrl.receive_input)
{
m_tty_ctrl.receive_input = true;
m_tty_ctrl.semaphore.unblock();
}
if (flags & TTY_FLAG_ENABLE_OUTPUT)
m_tty_ctrl.draw_graphics = true;
break;
case TTY_CMD_UNSET:
if ((flags & TTY_FLAG_ENABLE_INPUT) && m_tty_ctrl.receive_input)
m_tty_ctrl.receive_input = false;
if (flags & TTY_FLAG_ENABLE_OUTPUT)
m_tty_ctrl.draw_graphics = false;
break;
default:
return BAN::Error::from_errno(EINVAL);
}
return {};
}
void TTY::initialize_devices()
{
static bool initialized = false;
@@ -53,6 +83,9 @@ namespace Kernel
auto inode = MUST(VirtualFileSystem::get().file_from_absolute_path({ 0, 0, 0, 0 }, "/dev/input0"sv, O_RDONLY)).inode;
while (true)
{
while (!TTY::current()->m_tty_ctrl.receive_input)
TTY::current()->m_tty_ctrl.semaphore.block();
Input::KeyEvent event;
size_t read = MUST(inode->read(0, &event, sizeof(event)));
ASSERT(read == sizeof(event));
@@ -251,6 +284,12 @@ namespace Kernel
}
}
void TTY::putchar(uint8_t ch)
{
if (m_tty_ctrl.draw_graphics)
putchar_impl(ch);
}
BAN::ErrorOr<size_t> TTY::read_impl(off_t, void* buffer, size_t count)
{
LockGuard _(m_lock);

View File

@@ -304,7 +304,7 @@ namespace Kernel
m_terminal_driver->putchar_at(codepoint, x, y, m_foreground, m_background);
}
void VirtualTTY::putchar(uint8_t ch)
void VirtualTTY::putchar_impl(uint8_t ch)
{
ASSERT(m_lock.is_locked());