Files
MontaukOS/kernel/src/Terminal/Terminal.hpp
T

192 lines
5.0 KiB
C++

/*
* Terminal.hpp
* Terminal implementation
* Copyright (c) 2025 Daniel Hammer
*/
#pragma once
#include <cstdint>
#include <cstddef>
#include <Libraries/String.hpp>
#include <CppLib/Stream.hpp>
#include <CppLib/Spinlock.hpp>
using namespace kcp;
namespace Kt
{
constexpr const char *newline = "\r\n";
namespace screen
{
constexpr const char *clear = "\033[2J";
constexpr const char *cursor_reset = "\033[H";
namespace colors {
constexpr const char* black = "\u001b[30m";
constexpr const char* red = "\u001b[31m";
constexpr const char* green = "\u001b[32m";
constexpr const char* blue = "\u001b[34m";
constexpr const char* cyan = "\u001b[36m";
constexpr const char* yellow = "\u001b[33m";
constexpr const char* magenta = "\u001b[35m";
constexpr const char* white = "\u001b[37m";
};
};
void Initialize(std::uint32_t *framebuffer, std::size_t width, std::size_t height, std::size_t pitch,
std::uint8_t red_mask_size, std::uint8_t red_mask_shift,
std::uint8_t green_mask_size, std::uint8_t green_mask_shift,
std::uint8_t blue_mask_size, std::uint8_t blue_mask_shift);
void Putchar(char c);
void Print(const char *text);
// Terminal mutex - protects flanterm from concurrent CPU access.
// Uses Mutex (not Spinlock) to keep interrupts enabled while held,
// preventing dropped PS/2 mouse/keyboard bytes during log output.
extern kcp::Mutex g_termLock;
void Rescale(std::size_t font_scale_x, std::size_t font_scale_y);
std::size_t GetFontScaleX();
std::size_t GetFontScaleY();
inline base base_custom(int custom)
{
return (base)custom;
}
class KernelOutStream
{
public:
base streamBaseType = base::dec;
// C++ streaming operator like cout
friend KernelOutStream &operator<<(KernelOutStream &t, const char *string)
{
Print(string);
return t;
}
// C++ streaming operator like cout
friend KernelOutStream &operator<<(KernelOutStream &t, const char chr)
{
Putchar(chr);
return t;
}
friend KernelOutStream &operator<<(KernelOutStream &t, int number)
{
Print(Lib::int2basestr(number, t.streamBaseType));
return t;
}
friend KernelOutStream &operator<<(KernelOutStream &t, std::uint32_t number)
{
Print(Lib::uint2basestr(number, t.streamBaseType));
return t;
}
friend KernelOutStream &operator<<(KernelOutStream &t, std::uint64_t number)
{
Print(Lib::u64_2_basestr(number, t.streamBaseType));
return t;
}
friend KernelOutStream &operator<<(KernelOutStream &t, base newBase)
{
t.streamBaseType = newBase;
return t;
}
};
enum KernelLogLevel {
INFO,
WARNING,
ERROR,
DEBUG,
OK
};
extern uint32_t g_kernelLogDepth;
extern bool g_suppressKernelLog;
void SuppressKernelLog();
int64_t ReadKernelLog(char* buf, uint64_t size);
class KernelLogStream {
KernelOutStream localStream{};
const char* componentName = "";
public:
const char* LogLevelToStringWithColor(KernelLogLevel level) {
switch (level) {
case INFO:
return "\e[0;36mINFO\e[0m"; // Cyan
case WARNING:
return "\e[0;33mWARNING\e[0m"; // Yellow
case ERROR:
return "\e[0;31mERROR\e[0m"; // Red
case DEBUG:
return "\e[0;35mDEBUG\e[0m"; // Magenta
case OK:
return "\e[0;32mOK\e[0m"; // Green
default:
return "UNKNOWN";
}
}
KernelLogStream(KernelLogLevel level, const char* desiredComponentName) {
g_termLock.Acquire();
g_kernelLogDepth++;
componentName = desiredComponentName;
localStream << componentName << ": " << "[" << LogLevelToStringWithColor(level) << "] ";
}
~KernelLogStream() {
localStream << newline;
g_kernelLogDepth--;
g_termLock.Release();
}
template<typename T>
KernelLogStream &operator<<(T item) {
localStream << item;
return *this;
}
};
};
extern Kt::KernelOutStream kout;
namespace Kt
{
class KernelErrorStream
{
public:
template <typename T>
friend KernelErrorStream &operator<<(KernelErrorStream &t, T value)
{
kout << "\e[0;31m" << value << "\e[0m";
return t;
}
};
};
extern Kt::KernelErrorStream kerr;
// Forward-declare flanterm context for syscall access
struct flanterm_context;
namespace Kt {
extern flanterm_context *ctx;
}