Notepad port to userspace and bug fixes

This commit is contained in:
boreddevnl
2026-02-26 16:21:20 +01:00
parent 23ec181f29
commit c2ead0d6a7
67 changed files with 828 additions and 399 deletions

View File

@@ -4,6 +4,8 @@
#include "gui_ipc.h"
#include "process.h"
#include "wm.h"
#include "fat32.h"
#include "fat32.h"
// Read MSR
static inline uint64_t rdmsr(uint32_t msr) {
@@ -67,6 +69,14 @@ static void user_window_click(Window *win, int x, int y) {
process_push_gui_event(proc, &ev);
}
static void user_window_key(Window *win, char c) {
process_t *proc = (process_t *)win->data;
if (!proc) return;
gui_event_t ev = { .type = GUI_EVENT_KEY, .arg1 = (int)c };
process_push_gui_event(proc, &ev);
}
uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) {
extern void cmd_write(const char *str);
extern void serial_write(const char *str);
@@ -76,37 +86,60 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
// arg2 is the buffer based on our user_test logic
cmd_write((const char*)arg2);
serial_write((const char*)arg2);
} else if (syscall_num == 0) { // SYS_EXIT
process_t *proc = process_get_current();
if (proc && proc->ui_window) {
wm_remove_window((Window *)proc->ui_window);
proc->ui_window = NULL;
}
cmd_process_finished();
// The actual process termination and scheduling will be handled later
// For now this just releases the CMD prompt lock.
// We will eventually need to mark the process_t as DEAD here.
} else if (syscall_num == 0 || syscall_num == 60) { // SYS_EXIT
serial_write("Kernel: SYS_EXIT called\n");
uint64_t next_rsp = process_terminate_current();
extern void context_switch_to(uint64_t rsp);
context_switch_to(next_rsp);
// This point is never reached
while(1);
} else if (syscall_num == 3) { // SYS_GUI
int cmd = (int)arg1;
process_t *proc = process_get_current();
if (cmd == GUI_CMD_WINDOW_CREATE) {
extern void serial_write(const char *str);
serial_write("Kernel: GUI_CMD_WINDOW_CREATE\n");
const char *title = (const char *)arg2;
uint64_t *params = (uint64_t *)arg3;
if (!params) return 0;
uint64_t *u_params = (uint64_t *)arg3;
if (!u_params) {
serial_write("Kernel: Error - params is NULL\n");
return 0;
}
// Copy params from user space to kernel space for safety
uint64_t params[4];
for (int i = 0; i < 4; i++) params[i] = u_params[i];
serial_write("Kernel: Window params copied.\n");
Window *win = kmalloc(sizeof(Window));
if (!win) return 0;
if (!win) {
serial_write("Kernel: Error - kmalloc failed for Window\n");
return 0;
}
serial_write("Kernel: Window allocated.\n");
// Copy title from user space to kernel space so wm.c can access it safely
int title_len = 0;
while (title[title_len] && title_len < 255) title_len++;
if (title) {
while (title[title_len] && title_len < 255) title_len++;
}
char *kernel_title = kmalloc(title_len + 1);
if (kernel_title) {
for (int i = 0; i < title_len; i++) {
kernel_title[i] = title[i];
}
kernel_title[title_len] = '\0';
serial_write("Kernel: Title copied: ");
serial_write(kernel_title);
serial_write("\n");
} else {
serial_write("Kernel: Warning - kernel_title kmalloc failed\n");
}
// Basic initialization
@@ -116,6 +149,8 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
win->w = (int)params[2];
win->h = (int)params[3];
serial_write("Kernel: Init win dims.\n");
// Sanity checks for dimensions
if (win->w <= 0 || win->w > 4096) win->w = 400;
if (win->h <= 0 || win->h > 4096) win->h = 400;
@@ -127,10 +162,15 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
win->buffer[0] = 0;
win->data = proc;
serial_write("Kernel: Dims initialized.\n");
// Safe allocation
size_t pixel_size = (size_t)win->w * win->h * 4;
win->pixels = kmalloc(pixel_size);
win->comp_pixels = kmalloc(pixel_size);
serial_write("Kernel: Buffers allocated.\n");
if (win->pixels) {
extern void mem_memset(void *dest, int val, size_t len);
mem_memset(win->pixels, 0, pixel_size);
@@ -140,10 +180,13 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
mem_memset(win->comp_pixels, 0, pixel_size);
}
serial_write("Kernel: Buffers cleared.\n");
// Set callbacks
win->paint = user_window_paint;
win->handle_click = user_window_click;
win->handle_close = user_window_close;
win->handle_key = NULL;
win->handle_key = user_window_key;
win->handle_right_click = NULL;
proc->ui_window = win;
@@ -152,9 +195,12 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
return (uint64_t)win;
} else if (cmd == GUI_CMD_DRAW_RECT) {
Window *win = (Window *)arg2;
uint64_t *p = (uint64_t *)arg3;
uint64_t *u_params = (uint64_t *)arg3;
uint32_t color = (uint32_t)arg4;
if (win && p) {
if (win && u_params) {
uint64_t params[4];
for (int i = 0; i < 4; i++) params[i] = u_params[i];
extern void draw_rect(int x, int y, int w, int h, uint32_t color);
extern void graphics_set_render_target(uint32_t *buffer, int w, int h);
@@ -163,8 +209,8 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
if (win->pixels) {
// Strict user-to-window relative clamping
int rx = (int)p[0]; int ry = (int)p[1];
int rw = (int)p[2]; int rh = (int)p[3];
int rx = (int)params[0]; int ry = (int)params[1];
int rw = (int)params[2]; int rh = (int)params[3];
if (rx < 0) { rw += rx; rx = 0; }
if (ry < 0) { rh += ry; ry = 0; }
if (rx + rw > win->w) rw = win->w - rx;
@@ -176,16 +222,19 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
graphics_set_render_target(NULL, 0, 0);
}
} else {
draw_rect(win->x + p[0], win->y + p[1], p[2], p[3], color);
draw_rect(win->x + params[0], win->y + params[1], params[2], params[3], color);
}
asm volatile("push %0; popfq" : : "r"(rflags));
}
} else if (cmd == GUI_CMD_DRAW_ROUNDED_RECT_FILLED) {
Window *win = (Window *)arg2;
uint64_t *p = (uint64_t *)arg3;
uint64_t *u_params = (uint64_t *)arg3;
uint32_t color = (uint32_t)arg4;
if (win && p) {
if (win && u_params) {
uint64_t params[5];
for (int i = 0; i < 5; i++) params[i] = u_params[i];
extern void draw_rounded_rect_filled(int x, int y, int w, int h, int radius, uint32_t color);
extern void graphics_set_render_target(uint32_t *buffer, int w, int h);
@@ -193,9 +242,9 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
if (win->pixels) {
int rx = (int)p[0]; int ry = (int)p[1];
int rw = (int)p[2]; int rh = (int)p[3];
int rr = (int)p[4];
int rx = (int)params[0]; int ry = (int)params[1];
int rw = (int)params[2]; int rh = (int)params[3];
int rr = (int)params[4];
if (rx < 0) { rw += rx; rx = 0; }
if (ry < 0) { rh += ry; ry = 0; }
if (rx + rw > win->w) rw = win->w - rx;
@@ -206,8 +255,6 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
draw_rounded_rect_filled(rx, ry, rw, rh, rr, color);
graphics_set_render_target(NULL, 0, 0);
}
} else {
draw_rounded_rect_filled(win->x + p[0], win->y + p[1], p[2], p[3], p[4], color);
}
asm volatile("push %0; popfq" : : "r"(rflags));
@@ -251,14 +298,17 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
}
} else if (cmd == GUI_CMD_MARK_DIRTY) {
Window *win = (Window *)arg2;
uint64_t *p = (uint64_t *)arg3;
if (win && p) {
uint64_t *u_params = (uint64_t *)arg3;
if (win && u_params) {
uint64_t params[4];
for (int i = 0; i < 4; i++) params[i] = u_params[i];
// Dual-buffer commit: copy pixels to comp_pixels
if (win->pixels && win->comp_pixels) {
extern void mem_memcpy(void *dest, const void *src, size_t len);
mem_memcpy(win->comp_pixels, win->pixels, (size_t)win->w * win->h * 4);
}
wm_mark_dirty(win->x + p[0], win->y + p[1], p[2], p[3]);
wm_mark_dirty(win->x + (int)params[0], win->y + (int)params[1], (int)params[2], (int)params[3]);
}
} else if (cmd == GUI_CMD_GET_EVENT) {
Window *win = (Window *)arg2;
@@ -271,6 +321,83 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u
}
return 0;
}
} else if (syscall_num == SYS_FS) {
int cmd = (int)arg1;
process_t *proc = process_get_current();
if (cmd == FS_CMD_OPEN) {
const char *path = (const char *)arg2;
const char *mode = (const char *)arg3;
if (!path || !mode) return -1;
FAT32_FileHandle *fh = fat32_open(path, mode);
if (!fh) return -1;
for (int i = 0; i < MAX_PROCESS_FDS; i++) {
if (proc->fds[i] == NULL) {
proc->fds[i] = fh;
return (uint64_t)i;
}
}
fat32_close(fh);
return -1;
} else if (cmd == FS_CMD_READ) {
int fd = (int)arg2;
void *buf = (void *)arg3;
uint32_t len = (uint32_t)arg4;
if (fd < 0 || fd >= MAX_PROCESS_FDS || !proc->fds[fd]) return -1;
return (uint64_t)fat32_read((FAT32_FileHandle*)proc->fds[fd], buf, (int)len);
} else if (cmd == FS_CMD_WRITE) {
int fd = (int)arg2;
const void *buf = (const void *)arg3;
uint32_t len = (uint32_t)arg4;
if (fd < 0 || fd >= MAX_PROCESS_FDS || !proc->fds[fd]) return -1;
return (uint64_t)fat32_write((FAT32_FileHandle*)proc->fds[fd], buf, (int)len);
} else if (cmd == FS_CMD_CLOSE) {
int fd = (int)arg2;
if (fd < 0 || fd >= MAX_PROCESS_FDS || !proc->fds[fd]) return -1;
fat32_close((FAT32_FileHandle*)proc->fds[fd]);
proc->fds[fd] = NULL;
return 0;
} else if (cmd == FS_CMD_SEEK) {
int fd = (int)arg2;
int offset = (int)arg3;
int whence = (int)arg4; // 0=SET, 1=CUR, 2=END
if (fd < 0 || fd >= MAX_PROCESS_FDS || !proc->fds[fd]) return -1;
return (uint64_t)fat32_seek((FAT32_FileHandle*)proc->fds[fd], offset, whence);
} else if (cmd == FS_CMD_TELL) {
int fd = (int)arg2;
if (fd < 0 || fd >= MAX_PROCESS_FDS || !proc->fds[fd]) return -1;
return (uint64_t)((FAT32_FileHandle*)proc->fds[fd])->position;
} else if (cmd == FS_CMD_SIZE) {
int fd = (int)arg2;
if (fd < 0 || fd >= MAX_PROCESS_FDS || !proc->fds[fd]) return -1;
return (uint64_t)((FAT32_FileHandle*)proc->fds[fd])->size;
}
else if (cmd == FS_CMD_LIST) {
const char *path = (const char *)arg2;
FAT32_FileInfo *entries = (FAT32_FileInfo *)arg3;
int max_entries = (int)arg4;
if (!path || !entries) return -1;
return (uint64_t)fat32_list_directory(path, entries, max_entries);
} else if (cmd == FS_CMD_DELETE) {
const char *path = (const char *)arg2;
if (!path) return -1;
return fat32_delete(path) ? 0 : -1;
} else if (cmd == FS_CMD_MKDIR) {
const char *path = (const char *)arg2;
if (!path) return -1;
return fat32_mkdir(path) ? 0 : -1;
} else if (cmd == FS_CMD_EXISTS) {
const char *path = (const char *)arg2;
if (!path) return 0;
return fat32_exists(path) ? 1 : 0;
}
return 0;
} else if (syscall_num == 8) { // DEBUG_SERIAL_WRITE
extern void serial_write(const char *str);
serial_write((const char *)arg2);
return 0;
}
return 0;