Kernel: Start work on making tty a file
TTY is now a file that you can read from/write to. I still have to port shell to use this new interface
This commit is contained in:
@@ -81,8 +81,8 @@ namespace Kernel
|
||||
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> read_directory_inode(BAN::StringView) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||
virtual BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(size_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); }
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); }
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); }
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) { if (mode().ifdir()) return BAN::Error::from_errno(EISDIR); ASSERT_NOT_REACHED(); }
|
||||
|
||||
virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t) { if (!mode().ifdir()) return BAN::Error::from_errno(ENOTDIR); ASSERT_NOT_REACHED(); }
|
||||
};
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Kernel
|
||||
BAN::ErrorOr<int> open(BAN::StringView, int);
|
||||
BAN::ErrorOr<void> close(int);
|
||||
BAN::ErrorOr<size_t> read(int, void*, size_t);
|
||||
BAN::ErrorOr<size_t> write(int, const void*, size_t);
|
||||
BAN::ErrorOr<void> creat(BAN::StringView, mode_t);
|
||||
|
||||
BAN::ErrorOr<void> fstat(int, stat*);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <BAN/String.h>
|
||||
#include <BAN/Vector.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/TTY.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
@@ -11,7 +10,7 @@ namespace Kernel
|
||||
class Shell
|
||||
{
|
||||
public:
|
||||
Shell(TTY*);
|
||||
Shell();
|
||||
Shell(const Shell&) = delete;
|
||||
BAN::ErrorOr<void> set_prompt(BAN::StringView);
|
||||
void run();
|
||||
@@ -23,8 +22,7 @@ namespace Kernel
|
||||
void key_event_callback(Input::KeyEvent);
|
||||
BAN::ErrorOr<void> update_prompt();
|
||||
|
||||
private:
|
||||
TTY* m_tty;
|
||||
private:
|
||||
BAN::Vector<BAN::String> m_old_buffer;
|
||||
BAN::Vector<BAN::String> m_buffer;
|
||||
BAN::String m_prompt_string;
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/TerminalDriver.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
|
||||
class TTY
|
||||
{
|
||||
public:
|
||||
TTY(TerminalDriver*);
|
||||
void clear();
|
||||
void putchar(char ch);
|
||||
void write(const char* data, size_t size);
|
||||
void write_string(const char* data);
|
||||
void set_cursor_position(uint32_t x, uint32_t y);
|
||||
void set_font(const Kernel::Font&);
|
||||
|
||||
uint32_t height() const { return m_height; }
|
||||
uint32_t width() const { return m_width; }
|
||||
|
||||
void render_from_buffer(uint32_t x, uint32_t y);
|
||||
|
||||
// for kprint
|
||||
static void putchar_current(char ch);
|
||||
static bool is_initialized();
|
||||
|
||||
private:
|
||||
void reset_ansi_escape();
|
||||
void handle_ansi_sgr();
|
||||
void handle_ansi_escape(uint16_t ch);
|
||||
void putchar_at(uint16_t ch, uint32_t x, uint32_t y);
|
||||
|
||||
private:
|
||||
struct Cell
|
||||
{
|
||||
TerminalDriver::Color foreground = TerminalColor::BRIGHT_WHITE;
|
||||
TerminalDriver::Color background = TerminalColor::BLACK;
|
||||
uint16_t character = ' ';
|
||||
};
|
||||
|
||||
struct AnsiState
|
||||
{
|
||||
uint8_t mode = '\0';
|
||||
int32_t index = 0;
|
||||
int32_t nums[2] = { -1, -1 };
|
||||
};
|
||||
|
||||
uint32_t m_width { 0 };
|
||||
uint32_t m_height { 0 };
|
||||
uint32_t m_row { 0 };
|
||||
uint32_t m_column { 0 };
|
||||
TerminalDriver::Color m_foreground { TerminalColor::BRIGHT_WHITE };
|
||||
TerminalDriver::Color m_background { TerminalColor::BLACK };
|
||||
Cell* m_buffer { nullptr };
|
||||
AnsiState m_ansi_state;
|
||||
TerminalDriver* m_terminal_driver { nullptr };
|
||||
Kernel::SpinLock m_lock;
|
||||
};
|
||||
113
kernel/include/kernel/Terminal/TTY.h
Normal file
113
kernel/include/kernel/Terminal/TTY.h
Normal file
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Array.h>
|
||||
#include <kernel/Device.h>
|
||||
#include <kernel/Input/KeyEvent.h>
|
||||
#include <kernel/SpinLock.h>
|
||||
#include <kernel/Terminal/TerminalDriver.h>
|
||||
#include <kernel/Terminal/termios.h>
|
||||
#include <kernel/Semaphore.h>
|
||||
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class TTY : public CharacterDevice
|
||||
{
|
||||
public:
|
||||
TTY(TerminalDriver*);
|
||||
void clear();
|
||||
void putchar(uint8_t ch);
|
||||
void set_cursor_position(uint32_t x, uint32_t y);
|
||||
void set_font(const Kernel::Font&);
|
||||
|
||||
uint32_t height() const { return m_height; }
|
||||
uint32_t width() const { return m_width; }
|
||||
|
||||
// for kprint
|
||||
static void putchar_current(uint8_t ch);
|
||||
static bool is_initialized();
|
||||
|
||||
virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t) override;
|
||||
virtual BAN::ErrorOr<size_t> write(size_t, const void*, size_t) override;
|
||||
|
||||
private:
|
||||
void reset_ansi();
|
||||
void handle_ansi_csi(uint8_t ch);
|
||||
void handle_ansi_csi_color();
|
||||
void putchar_at(uint32_t codepoint, uint32_t x, uint32_t y);
|
||||
void render_from_buffer(uint32_t x, uint32_t y);
|
||||
|
||||
void on_key(Input::KeyEvent);
|
||||
|
||||
private:
|
||||
enum class State
|
||||
{
|
||||
Normal,
|
||||
WaitingAnsiEscape,
|
||||
WaitingAnsiCSI,
|
||||
WaitingUTF8,
|
||||
};
|
||||
|
||||
struct AnsiState
|
||||
{
|
||||
int32_t nums[2] { -1, -1 };
|
||||
int32_t index { 0 };
|
||||
};
|
||||
|
||||
struct UTF8State
|
||||
{
|
||||
uint32_t codepoint { 0 };
|
||||
uint8_t bytes_missing { 0 };
|
||||
};
|
||||
|
||||
struct Cell
|
||||
{
|
||||
TerminalDriver::Color foreground { TerminalColor::BRIGHT_WHITE };
|
||||
TerminalDriver::Color background { TerminalColor::BLACK };
|
||||
uint32_t codepoint { ' ' };
|
||||
};
|
||||
|
||||
private:
|
||||
Kernel::SpinLock m_lock;
|
||||
|
||||
State m_state { State::Normal };
|
||||
AnsiState m_ansi_state { };
|
||||
UTF8State m_utf8_state { };
|
||||
|
||||
uint32_t m_width { 0 };
|
||||
uint32_t m_height { 0 };
|
||||
|
||||
uint32_t m_row { 0 };
|
||||
uint32_t m_column { 0 };
|
||||
Cell* m_buffer { nullptr };
|
||||
|
||||
TerminalDriver::Color m_foreground { TerminalColor::BRIGHT_WHITE };
|
||||
TerminalDriver::Color m_background { TerminalColor::BLACK };
|
||||
|
||||
termios m_termios;
|
||||
|
||||
struct Buffer
|
||||
{
|
||||
BAN::Array<uint8_t, 1024> buffer;
|
||||
size_t bytes { 0 };
|
||||
bool flush { false };
|
||||
Semaphore semaphore;
|
||||
};
|
||||
Buffer m_output;
|
||||
|
||||
TerminalDriver* m_terminal_driver { nullptr };
|
||||
|
||||
public:
|
||||
virtual Mode mode() const override { return { Mode::IFCHR | Mode::IRUSR }; }
|
||||
virtual uid_t uid() const override { return 0; }
|
||||
virtual gid_t gid() const override { return 0; }
|
||||
virtual dev_t rdev() const override { return m_rdev; }
|
||||
virtual BAN::StringView name() const { return m_name; }
|
||||
|
||||
private:
|
||||
const dev_t m_rdev;
|
||||
const BAN::String m_name;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/TerminalDriver.h>
|
||||
#include <kernel/Terminal/TerminalDriver.h>
|
||||
|
||||
class VesaTerminalDriver final : public TerminalDriver
|
||||
{
|
||||
12
kernel/include/kernel/Terminal/termios.h
Normal file
12
kernel/include/kernel/Terminal/termios.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
struct termios
|
||||
{
|
||||
bool canonical { true };
|
||||
bool echo { true };
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Formatter.h>
|
||||
#include <kernel/TTY.h>
|
||||
#include <kernel/Terminal/TTY.h>
|
||||
|
||||
#define kprint(...) BAN::Formatter::print(TTY::putchar_current, __VA_ARGS__)
|
||||
#define kprintln(...) BAN::Formatter::println(TTY::putchar_current, __VA_ARGS__)
|
||||
#define kprint(...) BAN::Formatter::print(Kernel::TTY::putchar_current, __VA_ARGS__)
|
||||
#define kprintln(...) BAN::Formatter::println(Kernel::TTY::putchar_current, __VA_ARGS__)
|
||||
|
||||
Reference in New Issue
Block a user