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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user