Kernel: Shell now renders a mouse

PS/2 mouse doesn't seem to work with PIC.
This commit is contained in:
Bananymous 2022-12-30 20:48:15 +02:00
parent 9d9a6b2fec
commit fcec793873
2 changed files with 61 additions and 29 deletions

View File

@ -23,10 +23,18 @@ namespace Kernel
void PrintPrompt(); void PrintPrompt();
void ProcessCommand(const BAN::Vector<BAN::StringView>&); void ProcessCommand(const BAN::Vector<BAN::StringView>&);
void KeyEventCallback(Input::KeyEvent); void KeyEventCallback(Input::KeyEvent);
void MouseMoveEventCallback(Input::MouseMoveEvent);
private: private:
TTY* m_tty; TTY* m_tty;
BAN::String m_buffer; BAN::String m_buffer;
struct
{
bool exists = false;
int32_t x = 0;
int32_t y = 0;
} m_mouse_pos;
}; };
} }

View File

@ -1,6 +1,8 @@
#include <BAN/Math.h>
#include <BAN/StringView.h> #include <BAN/StringView.h>
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <kernel/CPUID.h> #include <kernel/CPUID.h>
#include <kernel/font.h>
#include <kernel/Input.h> #include <kernel/Input.h>
#include <kernel/IO.h> #include <kernel/IO.h>
#include <kernel/PIT.h> #include <kernel/PIT.h>
@ -9,14 +11,34 @@
#include <kernel/Shell.h> #include <kernel/Shell.h>
#include <kernel/TTY.h> #include <kernel/TTY.h>
#define TTY_PRINT(...) BAN::Formatter::print([this](char c) { m_tty->PutChar(c); }, __VA_ARGS__) #define TTY_PRINT(...) Formatter::print([this](char c) { m_tty->PutChar(c); }, __VA_ARGS__)
#define TTY_PRINTLN(...) BAN::Formatter::println([this](char c) { m_tty->PutChar(c); }, __VA_ARGS__) #define TTY_PRINTLN(...) Formatter::println([this](char c) { m_tty->PutChar(c); }, __VA_ARGS__)
namespace Kernel namespace Kernel
{ {
using namespace BAN;
static Shell* s_instance = nullptr; static Shell* s_instance = nullptr;
static uint8_t s_pointer[] {
________,
________,
________,
________,
________,
X_______,
XX______,
XXX_____,
XXXX____,
XXXXX___,
XXXXXX__,
XXXXXXX_,
XXXXXXXX,
XXX_____,
XX______,
X_______,
};
Shell& Shell::Get() Shell& Shell::Get()
{ {
if (!s_instance) if (!s_instance)
@ -27,6 +49,7 @@ namespace Kernel
Shell::Shell() Shell::Shell()
{ {
Input::register_key_event_callback([](Input::KeyEvent event) { Shell::Get().KeyEventCallback(event); }); Input::register_key_event_callback([](Input::KeyEvent event) { Shell::Get().KeyEventCallback(event); });
Input::register_mouse_move_event_callback([](Input::MouseMoveEvent event) { Shell::Get().MouseMoveEventCallback(event); });
m_buffer.Reserve(128); m_buffer.Reserve(128);
} }
@ -50,12 +73,13 @@ namespace Kernel
} }
} }
void Shell::ProcessCommand(const BAN::Vector<BAN::StringView>& arguments) void Shell::ProcessCommand(const Vector<StringView>& arguments)
{ {
if (arguments.Empty()) if (arguments.Empty())
return; {
if (arguments.Front() == "date") }
else if (arguments.Front() == "date")
{ {
if (arguments.Size() != 1) if (arguments.Size() != 1)
{ {
@ -64,10 +88,8 @@ namespace Kernel
} }
auto time = RTC::GetCurrentTime(); auto time = RTC::GetCurrentTime();
TTY_PRINTLN("{}", time); TTY_PRINTLN("{}", time);
return;
} }
else if (arguments.Front() == "echo")
if (arguments.Front() == "echo")
{ {
if (arguments.Size() > 1) if (arguments.Size() > 1)
{ {
@ -76,10 +98,8 @@ namespace Kernel
TTY_PRINT(" {}", arguments[i]); TTY_PRINT(" {}", arguments[i]);
} }
TTY_PRINTLN(""); TTY_PRINTLN("");
return;
} }
else if (arguments.Front() == "clear")
if (arguments.Front() == "clear")
{ {
if (arguments.Size() != 1) if (arguments.Size() != 1)
{ {
@ -88,10 +108,8 @@ namespace Kernel
} }
m_tty->Clear(); m_tty->Clear();
m_tty->SetCursorPosition(0, 0); m_tty->SetCursorPosition(0, 0);
return;
} }
else if (arguments.Front() == "time")
if (arguments.Front() == "time")
{ {
auto new_args = arguments; auto new_args = arguments;
new_args.Remove(0); new_args.Remove(0);
@ -99,10 +117,8 @@ namespace Kernel
ProcessCommand(new_args); ProcessCommand(new_args);
auto duration = PIT::ms_since_boot() - start; auto duration = PIT::ms_since_boot() - start;
TTY_PRINTLN("took {} ms", duration); TTY_PRINTLN("took {} ms", duration);
return;
} }
else if (arguments.Front() == "cpuinfo")
if (arguments.Front() == "cpuinfo")
{ {
if (arguments.Size() != 1) if (arguments.Size() != 1)
{ {
@ -130,11 +146,8 @@ namespace Kernel
TTY_PRINT("{}{}", first ? (first = false, "") : ", ", CPUID::FeatStringEDX((uint32_t)1 << i)); TTY_PRINT("{}{}", first ? (first = false, "") : ", ", CPUID::FeatStringEDX((uint32_t)1 << i));
if (!first) if (!first)
TTY_PRINTLN(""); TTY_PRINTLN("");
return;
} }
else if (arguments.Front() == "random")
if (arguments.Front() == "random")
{ {
if (arguments.Size() != 1) if (arguments.Size() != 1)
{ {
@ -160,11 +173,8 @@ namespace Kernel
asm volatile("rdrand %0" : "=r"(random)); asm volatile("rdrand %0" : "=r"(random));
TTY_PRINTLN(" 0x{8H}", random); TTY_PRINTLN(" 0x{8H}", random);
} }
return;
} }
else if (arguments.Front() == "reboot")
if (arguments.Front() == "reboot")
{ {
if (arguments.Size() != 1) if (arguments.Size() != 1)
{ {
@ -176,13 +186,15 @@ namespace Kernel
good = IO::inb(0x64); good = IO::inb(0x64);
IO::outb(0x64, 0xFE); IO::outb(0x64, 0xFE);
asm volatile("cli; hlt"); asm volatile("cli; hlt");
return; }
else
{
TTY_PRINTLN("unrecognized command '{}'", arguments.Front());
} }
TTY_PRINTLN("unrecognized command '{}'", arguments.Front());
} }
static bool IsSingleUnicode(BAN::StringView sv) static bool IsSingleUnicode(StringView sv)
{ {
if (sv.Size() == 2 && ((uint8_t)sv[0] >> 5) != 0b110) if (sv.Size() == 2 && ((uint8_t)sv[0] >> 5) != 0b110)
return false; return false;
@ -196,7 +208,7 @@ namespace Kernel
return true; return true;
} }
static uint32_t GetLastLength(BAN::StringView sv) static uint32_t GetLastLength(StringView sv)
{ {
if (sv.Size() < 2) if (sv.Size() < 2)
return sv.Size(); return sv.Size();
@ -261,6 +273,18 @@ namespace Kernel
break; break;
} }
} }
if (m_mouse_pos.exists)
VESA::PutBitmapAt(s_pointer, m_mouse_pos.x, m_mouse_pos.y, VESA::Color::BRIGHT_WHITE);
}
void Shell::MouseMoveEventCallback(Input::MouseMoveEvent event)
{
m_mouse_pos.exists = true;
m_tty->RenderFromBuffer(m_mouse_pos.x, m_mouse_pos.y);
m_mouse_pos.x = clamp<int32_t>(m_mouse_pos.x + event.dx, 0, m_tty->Width() - 1);
m_mouse_pos.y = clamp<int32_t>(m_mouse_pos.y - event.dy, 0, m_tty->Height() - 1);
VESA::PutBitmapAt(s_pointer, m_mouse_pos.x, m_mouse_pos.y, VESA::Color::BRIGHT_WHITE);
} }
} }