Files
MontaukOS/kernel/src/Api/Window.hpp
T

135 lines
5.3 KiB
C++

/*
* Window.hpp
* SYS_WINCREATE, SYS_WINDESTROY, SYS_WINPRESENT, SYS_WINPOLL,
* SYS_WINENUM, SYS_WINMAP, SYS_WINSENDEVENT, SYS_WINRESIZE,
* SYS_WINSETCURSOR, SYS_WINSETFLAGS, SYS_WINSETSCALE, SYS_WINGETSCALE syscalls,
* and window server messaging: SYS_WIN_REQUEST, SYS_WIN_REQUEST_POLL,
* SYS_WIN_DRAG_BEGIN, SYS_WIN_DRAG_FORMATS, SYS_WIN_DRAG_GET_DATA
* Copyright (c) 2026 Daniel Hammer
*/
#pragma once
#include <Sched/Scheduler.hpp>
#include "Syscall.hpp"
#include "WinServer.hpp"
namespace montauk::abi {
static int Sys_WinCreate(const char* title, int w, int h, WinCreateResult* result) {
if (result == nullptr || title == nullptr) return InvalidArgument;
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr) return GenericFailure;
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 ? Success : id;
}
static int Sys_WinDestroy(int windowId) {
return WinServer::Destroy(windowId, Sched::GetCurrentPid());
}
static uint64_t Sys_WinPresent(int windowId) {
return WinServer::Present(windowId, Sched::GetCurrentPid());
}
static int Sys_WinPoll(int windowId, WinEvent* outEvent) {
if (outEvent == nullptr) return InvalidArgument;
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);
}
// Mapping another process's window and injecting input into it are the
// compositor's job alone. Left open, any app could read every window's
// pixels or click on any window -- including a prompt asking the user
// whether to grant that same app authority.
static uint64_t Sys_WinMap(int windowId) {
if (!Sched::HasCapability(CAP_COMPOSITOR)) return 0;
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr) return 0;
return WinServer::Map(windowId, proc->pid, proc->pml4Phys, proc->heapNext);
}
static int Sys_WinUnmap(int windowId) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr) return GenericFailure;
return WinServer::Unmap(windowId, proc->pid, proc->pml4Phys);
}
static int Sys_WinSendEvent(int windowId, const WinEvent* event) {
if (!Sched::HasCapability(CAP_COMPOSITOR)) return CapabilityDenied;
if (event == nullptr) return InvalidArgument;
return WinServer::SendEvent(windowId, event);
}
static uint64_t Sys_WinResize(int windowId, int newW, int newH) {
auto* proc = Sched::GetCurrentProcessPtr();
if (proc == nullptr) return 0;
uint64_t outVa = 0;
int r = WinServer::Resize(windowId, proc->pid, proc->pml4Phys, newW, newH,
proc->heapNext, outVa);
return (r == 0) ? outVa : 0;
}
static int Sys_WinSetCursor(int windowId, int cursor) {
return WinServer::SetCursor(windowId, Sched::GetCurrentPid(), cursor);
}
static int Sys_WinSetFlags(int windowId, uint32_t flags) {
return WinServer::SetFlags(windowId, Sched::GetCurrentPid(), flags);
}
static int Sys_WinSetScale(int scale) {
return WinServer::SetScale(scale);
}
static int Sys_WinGetScale() {
return WinServer::GetScale();
}
// Any app may post requests, but only about its own windows (checked in
// WinServer); only the compositor may read them back.
static int Sys_WinRequest(int windowId, const WinRequest* request) {
if (request == nullptr) return InvalidArgument;
WinRequest copy = *request;
return WinServer::PostRequest(windowId, Sched::GetCurrentPid(), copy);
}
static int Sys_WinRequestPoll(WinRequest* out) {
if (!Sched::HasCapability(CAP_COMPOSITOR)) return CapabilityDenied;
if (out == nullptr) return InvalidArgument;
return WinServer::PollRequest(out);
}
static int Sys_WinDragBegin(int windowId, const WinDragBegin* info,
const TransferItem* items, uint32_t count) {
if (info == nullptr) return InvalidArgument;
WinDragBegin infoCopy = *info;
DataTransfer::Transfer transfer;
int rc = DataTransfer::BuildFromUser(items, count, transfer);
if (rc != Success) return rc;
return WinServer::DragBegin(windowId, Sched::GetCurrentPid(),
Sched::HasCapability(CAP_COMPOSITOR), infoCopy, transfer);
}
static int Sys_WinDragFormats(uint32_t serial, TransferFormatInfo* out, uint32_t max) {
return WinServer::DragFormats(serial, Sched::GetCurrentPid(),
Sched::HasCapability(CAP_COMPOSITOR), out, max);
}
static int Sys_WinDragGetData(uint32_t serial, const char* mime, void* buffer,
uint32_t bufferLen, uint32_t* outLen) {
return WinServer::DragGetData(serial, Sched::GetCurrentPid(),
Sched::HasCapability(CAP_COMPOSITOR), mime,
buffer, bufferLen, outLen);
}
};