feat: TrueType (TTF) font rendering, many new desktop applications and DOOM support, among other improvements

This commit is contained in:
2026-02-20 22:46:41 +01:00
parent a0db5899ef
commit 596be25eaf
124 changed files with 9021 additions and 355 deletions
+250 -1
View File
@@ -29,6 +29,12 @@
#include <Hal/GDT.hpp>
#include <Graphics/Cursor.hpp>
#include "../Libraries/flanterm/src/flanterm.h"
#include "WinServer.hpp"
#include <Pci/Pci.hpp>
#include <Drivers/USB/Xhci.hpp>
#include <Drivers/Graphics/IntelGPU.hpp>
#include <Drivers/PS2/PS2Controller.hpp>
#include <Hal/Apic/ApicInit.hpp>
// Assembly entry point
extern "C" void SyscallEntry();
@@ -605,6 +611,228 @@ namespace Zenith {
return 0;
}
// ---- Process listing / kill ----
static int Sys_ProcList(ProcInfo* buf, int maxCount) {
if (buf == nullptr || maxCount <= 0) return 0;
int count = 0;
for (int i = 0; i < Sched::MaxProcesses && count < maxCount; i++) {
auto* proc = Sched::GetProcessSlot(i);
if (!proc || proc->state == Sched::ProcessState::Free) continue;
buf[count].pid = (int32_t)proc->pid;
buf[count].parentPid = (int32_t)proc->parentPid;
buf[count].state = (uint8_t)proc->state;
buf[count]._pad[0] = 0;
buf[count]._pad[1] = 0;
buf[count]._pad[2] = 0;
{
int j = 0;
for (; j < 63 && proc->name[j]; j++)
buf[count].name[j] = proc->name[j];
buf[count].name[j] = '\0';
}
buf[count].heapUsed = (proc->heapNext > Sched::UserHeapBase)
? proc->heapNext - Sched::UserHeapBase : 0;
count++;
}
return count;
}
static int Sys_Kill(int pid) {
// Refuse to kill PID 0 (init)
if (pid == 0) return -1;
// Refuse to kill the caller's own process
if (pid == Sched::GetCurrentPid()) return -1;
auto* proc = Sched::GetProcessByPid(pid);
if (!proc) return -1;
// Clean up any windows owned by this process
WinServer::CleanupProcess(pid);
proc->state = Sched::ProcessState::Terminated;
return 0;
}
// ---- Device list ----
static void dl_strcpy(char* dst, const char* src, int max) {
int i = 0;
for (; i < max - 1 && src[i]; i++) dst[i] = src[i];
dst[i] = '\0';
}
static int dl_append(char* dst, int pos, const char* src, int max) {
for (int i = 0; src[i] && pos < max - 1; i++) dst[pos++] = src[i];
dst[pos] = '\0';
return pos;
}
static int dl_append_hex(char* dst, int pos, unsigned val, int digits, int max) {
const char* hex = "0123456789abcdef";
char tmp[8];
for (int i = digits - 1; i >= 0; i--) { tmp[i] = hex[val & 0xF]; val >>= 4; }
for (int i = 0; i < digits && pos < max - 1; i++) dst[pos++] = tmp[i];
dst[pos] = '\0';
return pos;
}
static int dl_append_dec(char* dst, int pos, int val, int max) {
if (val == 0) { if (pos < max - 1) dst[pos++] = '0'; dst[pos] = '\0'; return pos; }
char tmp[12]; int i = 0;
while (val > 0) { tmp[i++] = '0' + (val % 10); val /= 10; }
while (i > 0 && pos < max - 1) dst[pos++] = tmp[--i];
dst[pos] = '\0';
return pos;
}
static int Sys_DevList(DevInfo* buf, int maxCount) {
if (buf == nullptr || maxCount <= 0) return 0;
int count = 0;
auto add = [&](uint8_t cat, const char* name, const char* detail) {
if (count >= maxCount) return;
buf[count].category = cat;
buf[count]._pad[0] = 0; buf[count]._pad[1] = 0; buf[count]._pad[2] = 0;
dl_strcpy(buf[count].name, name, 48);
dl_strcpy(buf[count].detail, detail, 48);
count++;
};
// CPU cores (category 0)
int cpuCount = Hal::GetDetectedCpuCount();
if (cpuCount > 0) {
char detail[48];
int p = 0;
p = dl_append(detail, p, "x86_64, ", 48);
p = dl_append_dec(detail, p, cpuCount, 48);
p = dl_append(detail, p, " core(s)", 48);
add(0, "Processor", detail);
}
// Interrupt controllers (category 1)
add(1, "Local APIC", "Per-CPU interrupt controller");
add(1, "I/O APIC", "System interrupt router");
// Timer (category 2)
add(2, "LAPIC Timer", "Local APIC periodic timer");
// PS/2 Input (category 3)
add(3, "PS/2 Keyboard", "IRQ 1, scan code set 1");
if (Drivers::PS2::IsDualChannel()) {
add(3, "PS/2 Mouse", "IRQ 12, dual-channel 8042");
}
// USB devices (category 4)
if (Drivers::USB::Xhci::IsInitialized()) {
for (uint8_t slot = 1; slot <= Drivers::USB::Xhci::MAX_SLOTS && count < maxCount; slot++) {
auto* dev = Drivers::USB::Xhci::GetDevice(slot);
if (!dev || !dev->Active) continue;
const char* devName = "USB Device";
if (dev->InterfaceClass == 3) {
if (dev->InterfaceProtocol == 1) devName = "USB HID Keyboard";
else if (dev->InterfaceProtocol == 2) devName = "USB HID Mouse";
else devName = "USB HID Device";
} else if (dev->InterfaceClass == 8) {
devName = "USB Mass Storage";
} else if (dev->InterfaceClass == 9) {
devName = "USB Hub";
}
char detail[48];
int p = 0;
p = dl_append(detail, p, "Port ", 48);
p = dl_append_dec(detail, p, dev->PortId, 48);
p = dl_append(detail, p, ", VID:", 48);
p = dl_append_hex(detail, p, dev->VendorId, 4, 48);
p = dl_append(detail, p, " PID:", 48);
p = dl_append_hex(detail, p, dev->ProductId, 4, 48);
add(4, devName, detail);
}
}
// Network (category 5)
if (Drivers::Net::E1000::IsInitialized()) {
add(5, "Intel E1000", "Gigabit Ethernet (82540EM)");
}
if (Drivers::Net::E1000E::IsInitialized()) {
add(5, "Intel E1000E", "Gigabit Ethernet (82574L)");
}
// Display (category 6)
if (Drivers::Graphics::IntelGPU::IsInitialized()) {
auto* gpu = Drivers::Graphics::IntelGPU::GetGpuInfo();
if (gpu) {
add(6, gpu->name, "Intel Integrated Graphics");
}
}
// PCI devices (category 7)
auto& pciDevs = Pci::GetDevices();
for (int i = 0; i < (int)pciDevs.size() && count < maxCount; i++) {
auto& d = pciDevs[i];
const char* className = Pci::GetClassName(d.ClassCode, d.SubClass);
char detail[48];
int p = 0;
p = dl_append_hex(detail, p, d.Bus, 2, 48);
p = dl_append(detail, p, ":", 48);
p = dl_append_hex(detail, p, d.Device, 2, 48);
p = dl_append(detail, p, ".", 48);
p = dl_append_dec(detail, p, d.Function, 48);
p = dl_append(detail, p, " ", 48);
p = dl_append_hex(detail, p, d.VendorId, 4, 48);
p = dl_append(detail, p, ":", 48);
p = dl_append_hex(detail, p, d.DeviceId, 4, 48);
add(7, className, detail);
}
return count;
}
// ---- Window server syscalls ----
static int Sys_WinCreate(const char* title, int w, int h, WinCreateResult* result) {
if (result == nullptr || title == nullptr) return -1;
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr) return -1;
uint64_t outVa = 0;
int id = WinServer::Create(proc->pid, proc->pml4Phys, title, w, h,
proc->heapNext, outVa);
result->id = id;
result->pixelVa = (id >= 0) ? outVa : 0;
return id >= 0 ? 0 : -1;
}
static int Sys_WinDestroy(int windowId) {
return WinServer::Destroy(windowId, Sched::GetCurrentPid());
}
static int Sys_WinPresent(int windowId) {
return WinServer::Present(windowId, Sched::GetCurrentPid());
}
static int Sys_WinPoll(int windowId, WinEvent* outEvent) {
if (outEvent == nullptr) return -1;
return WinServer::Poll(windowId, Sched::GetCurrentPid(), outEvent);
}
static int Sys_WinEnum(WinInfo* outArray, int maxCount) {
if (outArray == nullptr || maxCount <= 0) return 0;
return WinServer::Enumerate(outArray, maxCount);
}
static uint64_t Sys_WinMap(int windowId) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr) return 0;
return WinServer::Map(windowId, proc->pid, proc->pml4Phys, proc->heapNext);
}
static int Sys_WinSendEvent(int windowId, const WinEvent* event) {
if (event == nullptr) return -1;
return WinServer::SendEvent(windowId, event);
}
// ---- Dispatch ----
extern "C" int64_t SyscallDispatch(SyscallFrame* frame) {
@@ -743,6 +971,27 @@ namespace Zenith {
return (int64_t)Sys_ChildIoWriteKey((int)frame->arg1, (const KeyEvent*)frame->arg2);
case SYS_CHILDIO_SETTERMSZ:
return (int64_t)Sys_ChildIoSetTermsz((int)frame->arg1, (int)frame->arg2, (int)frame->arg3);
case SYS_WINCREATE:
return (int64_t)Sys_WinCreate((const char*)frame->arg1, (int)frame->arg2,
(int)frame->arg3, (WinCreateResult*)frame->arg4);
case SYS_WINDESTROY:
return (int64_t)Sys_WinDestroy((int)frame->arg1);
case SYS_WINPRESENT:
return (int64_t)Sys_WinPresent((int)frame->arg1);
case SYS_WINPOLL:
return (int64_t)Sys_WinPoll((int)frame->arg1, (WinEvent*)frame->arg2);
case SYS_WINENUM:
return (int64_t)Sys_WinEnum((WinInfo*)frame->arg1, (int)frame->arg2);
case SYS_WINMAP:
return (int64_t)Sys_WinMap((int)frame->arg1);
case SYS_WINSENDEVENT:
return (int64_t)Sys_WinSendEvent((int)frame->arg1, (const WinEvent*)frame->arg2);
case SYS_PROCLIST:
return (int64_t)Sys_ProcList((ProcInfo*)frame->arg1, (int)frame->arg2);
case SYS_KILL:
return (int64_t)Sys_Kill((int)frame->arg1);
case SYS_DEVLIST:
return (int64_t)Sys_DevList((DevInfo*)frame->arg1, (int)frame->arg2);
default:
return -1;
}
@@ -769,7 +1018,7 @@ namespace Zenith {
Hal::WriteMSR(Hal::IA32_FMASK, 0x200);
Kt::KernelLogStream(Kt::OK, "Syscall") << "SYSCALL/SYSRET initialized (LSTAR="
<< kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", 53 syscalls)";
<< kcp::hex << (uint64_t)SyscallEntry << kcp::dec << ", 64 syscalls)";
}
}