diff --git a/.gitignore b/.gitignore index 6ae2c38..e558c71 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,6 @@ limine 2/Makefile limine 2/limine limine 2/limine.dSYM/Contents/Resources/DWARF/limine limine 2/limine.exe -build/* boredos.dump -qemu-debug.log \ No newline at end of file +qemu-debug.log +build/ diff --git a/boredos.iso b/boredos.iso index 7a5dc8d..08b68cc 100644 Binary files a/boredos.iso and b/boredos.iso differ diff --git a/build/about.o b/build/about.o index 7185caa..c900339 100644 Binary files a/build/about.o and b/build/about.o differ diff --git a/build/boredos.elf b/build/boredos.elf index 55ca819..81f159f 100755 Binary files a/build/boredos.elf and b/build/boredos.elf differ diff --git a/build/cli_apps/cli_utils.o b/build/cli_apps/cli_utils.o index e4ac893..1c8317b 100644 Binary files a/build/cli_apps/cli_utils.o and b/build/cli_apps/cli_utils.o differ diff --git a/build/cmd.o b/build/cmd.o index 8bc3876..12f848e 100644 Binary files a/build/cmd.o and b/build/cmd.o differ diff --git a/build/explorer.o b/build/explorer.o index 4086d32..4b55bdc 100644 Binary files a/build/explorer.o and b/build/explorer.o differ diff --git a/build/fat32.o b/build/fat32.o index 748db05..8652b72 100644 Binary files a/build/fat32.o and b/build/fat32.o differ diff --git a/build/icmp.o b/build/icmp.o index 8886576..a58dbf3 100644 Binary files a/build/icmp.o and b/build/icmp.o differ diff --git a/build/main.o b/build/main.o index 52299fc..06b795a 100644 Binary files a/build/main.o and b/build/main.o differ diff --git a/build/ps2.o b/build/ps2.o index f1ca8f1..d717b35 100644 Binary files a/build/ps2.o and b/build/ps2.o differ diff --git a/build/vm.o b/build/vm.o index c78b21d..d90482e 100644 Binary files a/build/vm.o and b/build/vm.o differ diff --git a/build/wallpaper.o b/build/wallpaper.o index 1b0abc7..132dc0c 100644 Binary files a/build/wallpaper.o and b/build/wallpaper.o differ diff --git a/build/wm.o b/build/wm.o index dd6efe7..7c4f595 100644 Binary files a/build/wm.o and b/build/wm.o differ diff --git a/disk.img b/disk.img index 3fec5bb..60d5217 100644 Binary files a/disk.img and b/disk.img differ diff --git a/iso_root/bin/calculator.elf b/iso_root/bin/calculator.elf index 1339fbe..69b143c 100755 Binary files a/iso_root/bin/calculator.elf and b/iso_root/bin/calculator.elf differ diff --git a/iso_root/bin/crash.elf b/iso_root/bin/crash.elf index 9a31208..b4c2d1c 100755 Binary files a/iso_root/bin/crash.elf and b/iso_root/bin/crash.elf differ diff --git a/iso_root/bin/hello.elf b/iso_root/bin/hello.elf index 928a245..3a28dda 100755 Binary files a/iso_root/bin/hello.elf and b/iso_root/bin/hello.elf differ diff --git a/iso_root/bin/markdown.elf b/iso_root/bin/markdown.elf index 1c1a7ff..541c80b 100755 Binary files a/iso_root/bin/markdown.elf and b/iso_root/bin/markdown.elf differ diff --git a/iso_root/bin/minesweeper.elf b/iso_root/bin/minesweeper.elf index 8532ecf..ca1d740 100755 Binary files a/iso_root/bin/minesweeper.elf and b/iso_root/bin/minesweeper.elf differ diff --git a/iso_root/bin/notepad.elf b/iso_root/bin/notepad.elf index 60ddd31..0452686 100755 Binary files a/iso_root/bin/notepad.elf and b/iso_root/bin/notepad.elf differ diff --git a/iso_root/bin/paint.elf b/iso_root/bin/paint.elf index bf66151..df2ef8e 100755 Binary files a/iso_root/bin/paint.elf and b/iso_root/bin/paint.elf differ diff --git a/iso_root/bin/settings.elf b/iso_root/bin/settings.elf index 4858796..d970c4d 100755 Binary files a/iso_root/bin/settings.elf and b/iso_root/bin/settings.elf differ diff --git a/iso_root/bin/txtedit.elf b/iso_root/bin/txtedit.elf index f4ca530..101de91 100755 Binary files a/iso_root/bin/txtedit.elf and b/iso_root/bin/txtedit.elf differ diff --git a/iso_root/bin/viewer.elf b/iso_root/bin/viewer.elf index 437573c..8589e4d 100755 Binary files a/iso_root/bin/viewer.elf and b/iso_root/bin/viewer.elf differ diff --git a/iso_root/boredos.elf b/iso_root/boredos.elf index 55ca819..81f159f 100755 Binary files a/iso_root/boredos.elf and b/iso_root/boredos.elf differ diff --git a/src/kernel/explorer.c b/src/kernel/explorer.c index 799b823..19b0679 100644 --- a/src/kernel/explorer.c +++ b/src/kernel/explorer.c @@ -915,7 +915,7 @@ static void explorer_draw_file_icon(int x, int y, bool is_dir, uint32_t color, c static void explorer_paint(Window *win) { ExplorerState *state = (ExplorerState*)win->data; int offset_x = win->x + 4; - int offset_y = win->y + 24; + int offset_y = win->y + 20; DirtyRect dirty = graphics_get_dirty_rect(); // Fill background with dark mode @@ -1367,7 +1367,7 @@ static void explorer_handle_click(Window *win, int x, int y) { // Handle Drive Menu Selection if (state->drive_menu_visible) { int menu_x = 4; // Window relative - int menu_y = 50; // 24+26 + int menu_y = 26; // 24+26 int menu_w = 80; int count = disk_get_count(); int menu_h = count * 25; @@ -1396,7 +1396,7 @@ static void explorer_handle_click(Window *win, int x, int y) { // Handle dropdown menu clicks if (state->dropdown_menu_visible) { int dropdown_btn_x = win->w - 90; // Window-relative - int menu_y = 50; // Window-relative (offset_y + 26, where offset_y = 24) + int menu_y = 26; // Window-relative (offset_y + 26, where offset_y = 24) // New File if (x >= dropdown_btn_x && x < dropdown_btn_x + DROPDOWN_MENU_WIDTH && @@ -1434,7 +1434,7 @@ static void explorer_handle_click(Window *win, int x, int y) { // x, y are already relative to window (0,0 is top-left of window content area) // Check Drive Button - int button_y = 27; + int button_y = 3; if (x >= 4 && x < 64 && y >= button_y && y < button_y + 22) { state->drive_menu_visible = !state->drive_menu_visible; state->dropdown_menu_visible = false; // Close other menu @@ -1476,7 +1476,7 @@ static void explorer_handle_click(Window *win, int x, int y) { } // File items start at y=64 relative to window - int content_start_y = 54; + int content_start_y = 30; int offset_x = 4; for (int i = 0; i < state->item_count; i++) { @@ -1647,7 +1647,7 @@ static void explorer_handle_key(Window *win, char c) { static void explorer_handle_right_click(Window *win, int x, int y) { ExplorerState *state = (ExplorerState*)win->data; // File items start at y=64 relative to window - int content_start_y = 54; + int content_start_y = 30; int offset_x = 4; for (int i = 0; i < state->item_count; i++) { diff --git a/src/kernel/fat32.c b/src/kernel/fat32.c index 19677f1..230a022 100644 --- a/src/kernel/fat32.c +++ b/src/kernel/fat32.c @@ -46,6 +46,8 @@ typedef struct { uint32_t total_sectors; uint32_t partition_offset; // LBA offset of partition start bool mounted; + uint32_t cached_fat_sector; + uint8_t cached_fat_buf[512]; } FAT32_Volume; static FAT32_Volume volumes[26]; // A-Z @@ -413,6 +415,7 @@ static bool realfs_mount(char drive) { volumes[idx].fat_size = bpb->sectors_per_fat_32; volumes[idx].total_sectors = bpb->total_sectors_32; volumes[idx].mounted = true; + volumes[idx].cached_fat_sector = 0xFFFFFFFF; fs_serial_str("[FAT32] mounted drive "); fs_serial_char(drive); @@ -456,18 +459,16 @@ static uint32_t realfs_next_cluster(FAT32_Volume *vol, uint32_t cluster) { uint32_t fat_sector = vol->fat_begin_lba + (cluster * 4) / 512; uint32_t fat_offset = (cluster * 4) % 512; - uint8_t *buf = (uint8_t*)kmalloc(512); - if (!buf) return 0xFFFFFFFF; - - if (vol->disk->read_sector(vol->disk, fat_sector, buf) != 0) { - kfree(buf); - return 0xFFFFFFFF; + if (vol->cached_fat_sector != fat_sector) { + if (vol->disk->read_sector(vol->disk, fat_sector, vol->cached_fat_buf) != 0) { + return 0xFFFFFFFF; + } + vol->cached_fat_sector = fat_sector; } - uint32_t next = *(uint32_t*)&buf[fat_offset]; + uint32_t next = *(uint32_t*)&vol->cached_fat_buf[fat_offset]; next &= 0x0FFFFFFF; // Mask top 4 bits - kfree(buf); return next; } @@ -791,6 +792,9 @@ static uint32_t realfs_allocate_cluster(FAT32_Volume *vol) { if ((val & 0x0FFFFFFF) == 0) { *(uint32_t*)&fat_buf[offset] = 0x0FFFFFFF; // EOC vol->disk->write_sector(vol->disk, sector, fat_buf); + if (vol->cached_fat_sector == sector) { + vol->cached_fat_sector = 0xFFFFFFFF; + } kfree(fat_buf); return current; } diff --git a/src/kernel/gui_ipc.h b/src/kernel/gui_ipc.h index 10e530a..62b0157 100644 --- a/src/kernel/gui_ipc.h +++ b/src/kernel/gui_ipc.h @@ -7,6 +7,7 @@ #define GUI_CMD_MARK_DIRTY 4 #define GUI_CMD_GET_EVENT 5 #define GUI_CMD_DRAW_ROUNDED_RECT_FILLED 6 +#define GUI_CMD_DRAW_IMAGE 7 #define GUI_EVENT_NONE 0 #define GUI_EVENT_PAINT 1 diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 6577565..ca093dc 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -209,10 +209,18 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u serial_write("Kernel: Dims initialized.\n"); + size_t pixel_size = 0; // Safe allocation - size_t pixel_size = (size_t)win->w * win->h * 4; - win->pixels = kmalloc(pixel_size); - win->comp_pixels = kmalloc(pixel_size); + size_t client_h = win->h - 20; + if (win->w <= 0 || win->h <= 20) { + // Invalid dimensions, but prevent underflow/bad alloc + win->pixels = NULL; + win->comp_pixels = NULL; + } else { + pixel_size = (size_t)win->w * client_h * 4; + win->pixels = kmalloc(pixel_size); + win->comp_pixels = kmalloc(pixel_size); + } serial_write("Kernel: Buffers allocated.\n"); @@ -259,10 +267,10 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u if (rx < 0) { rw += rx; rx = 0; } if (ry < 0) { rh += ry; ry = 0; } if (rx + rw > win->w) rw = win->w - rx; - if (ry + rh > win->h) rh = win->h - ry; + if (ry + rh > (win->h - 20)) rh = (win->h - 20) - ry; if (rw > 0 && rh > 0) { - graphics_set_render_target(win->pixels, win->w, win->h); + graphics_set_render_target(win->pixels, win->w, win->h - 20); draw_rect(rx, ry, rw, rh, color); graphics_set_render_target(NULL, 0, 0); } @@ -293,10 +301,10 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u if (rx < 0) { rw += rx; rx = 0; } if (ry < 0) { rh += ry; ry = 0; } if (rx + rw > win->w) rw = win->w - rx; - if (ry + rh > win->h) rh = win->h - ry; + if (ry + rh > (win->h - 20)) rh = (win->h - 20) - ry; if (rw > 0 && rh > 0) { - graphics_set_render_target(win->pixels, win->w, win->h); + graphics_set_render_target(win->pixels, win->w, win->h - 20); draw_rounded_rect_filled(rx, ry, rw, rh, rr, color); graphics_set_render_target(NULL, 0, 0); } @@ -330,8 +338,8 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u if (win->pixels) { // String clipping is handled by draw_char -> put_pixel, // but we ensure coordinate sanity here - if (ux >= -100 && ux < win->w && uy >= -100 && uy < win->h) { - graphics_set_render_target(win->pixels, win->w, win->h); + if (ux >= -100 && ux < win->w && uy >= -100 && uy < (win->h - 20)) { + graphics_set_render_target(win->pixels, win->w, win->h - 20); draw_string(ux, uy, kernel_str, color); graphics_set_render_target(NULL, 0, 0); } @@ -339,6 +347,41 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u draw_string(win->x + ux, win->y + uy, kernel_str, color); } + asm volatile("push %0; popfq" : : "r"(rflags)); + } + } else if (cmd == GUI_CMD_DRAW_IMAGE) { + Window *win = (Window *)arg2; + uint64_t *u_params = (uint64_t *)arg3; + uint32_t *image_data = (uint32_t *)arg4; + if (win && u_params && image_data) { + uint64_t params[4]; + for (int i = 0; i < 4; i++) params[i] = u_params[i]; + + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + + if (win->pixels) { + int rx = (int)params[0]; int ry = (int)params[1]; + int rw = (int)params[2]; int rh = (int)params[3]; + + int src_x_offset = 0; + int src_y_offset = 0; + if (rx < 0) { src_x_offset = -rx; rw += rx; rx = 0; } + if (ry < 0) { src_y_offset = -ry; rh += ry; ry = 0; } + if (rx + rw > win->w) rw = win->w - rx; + if (ry + rh > (win->h - 20)) rh = (win->h - 20) - ry; + + if (rw > 0 && rh > 0) { + for (int y = 0; y < rh; y++) { + uint32_t *dest = &win->pixels[(ry + y) * win->w + rx]; + uint32_t *src = &image_data[(src_y_offset + y) * (int)params[2] + src_x_offset]; + for (int x = 0; x < rw; x++) { + dest[x] = src[x]; + } + } + } + } + asm volatile("push %0; popfq" : : "r"(rflags)); } } else if (cmd == GUI_CMD_MARK_DIRTY) { @@ -351,7 +394,7 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u // 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); + mem_memcpy(win->comp_pixels, win->pixels, (size_t)win->w * (win->h - 20) * 4); } wm_mark_dirty(win->x + (int)params[0], win->y + (int)params[1], (int)params[2], (int)params[3]); } @@ -458,14 +501,19 @@ uint64_t syscall_handler_c(uint64_t syscall_num, uint64_t arg1, uint64_t arg2, u uint64_t start_page = (old_end + 0xFFF) & ~0xFFF; uint64_t end_page = (new_end + 0xFFF) & ~0xFFF; - for (uint64_t page = start_page; page < end_page; page += 4096) { - void *phys = kmalloc_aligned(4096, 4096); - if (!phys) return (uint64_t)-1; // Out of memory + if (end_page > start_page) { + uint64_t total_size = end_page - start_page; + void *phys_block = kmalloc_aligned(total_size, 4096); + if (!phys_block) return (uint64_t)-1; // Out of memory extern void mem_memset(void *dest, int val, size_t len); - mem_memset(phys, 0, 4096); + mem_memset(phys_block, 0, total_size); - paging_map_page(proc->pml4_phys, page, v2p((uint64_t)phys), 0x07); // PT_PRESENT | PT_RW | PT_USER + uint64_t phys_addr = (uint64_t)phys_block; + for (uint64_t page = start_page; page < end_page; page += 4096) { + paging_map_page(proc->pml4_phys, page, v2p(phys_addr), 0x07); // PT_PRESENT | PT_RW | PT_USER + phys_addr += 4096; + } } } diff --git a/src/kernel/userland/calculator.c b/src/kernel/userland/calculator.c index 250c051..661eb79 100644 --- a/src/kernel/userland/calculator.c +++ b/src/kernel/userland/calculator.c @@ -86,12 +86,12 @@ static void update_display(void) { static void calculator_paint(void) { int w = 180; int h = 230; - ui_draw_rect(win_calculator, 4, 30, w - 8, h - 34, COLOR_DARK_BG); - ui_draw_rounded_rect_filled(win_calculator, 10, 36, w - 20, 25, 6, COLOR_DARK_PANEL); + ui_draw_rect(win_calculator, 4, 4, w - 8, h - 34, COLOR_DARK_BG); + ui_draw_rounded_rect_filled(win_calculator, 10, 10, w - 20, 25, 6, COLOR_DARK_PANEL); int text_w = display_buf_len * 8; int text_x = w - 15 - text_w; - ui_draw_string(win_calculator, text_x, 44, display_buffer, COLOR_DARK_TEXT); + ui_draw_string(win_calculator, text_x, 18, display_buffer, COLOR_DARK_TEXT); const char *labels[] = { "C", "sqr", "rt", "/", @@ -105,7 +105,7 @@ static void calculator_paint(void) { int bh = 25; int gap = 5; int start_x = 10; - int start_y = 70; + int start_y = 40; for (int i = 0; i < 20; i++) { int r = i / 4; @@ -136,7 +136,7 @@ static void calculator_click(int x, int y) { int bh = 25; int gap = 5; int start_x = 10; - int start_y = 65; // Matches the hitboxes + int start_y = 35; // Matches the hitboxes for (int i = 0; i < 20; i++) { int r = i / 4; diff --git a/src/kernel/userland/calculator.elf b/src/kernel/userland/calculator.elf index 1339fbe..69b143c 100755 Binary files a/src/kernel/userland/calculator.elf and b/src/kernel/userland/calculator.elf differ diff --git a/src/kernel/userland/crash.c b/src/kernel/userland/crash.c index f07f99a..d1c231e 100644 --- a/src/kernel/userland/crash.c +++ b/src/kernel/userland/crash.c @@ -4,7 +4,6 @@ int main() { const char* msg = "Attempting to crash via null dereference...\n"; sys_write(1, msg, 45); - // Null pointer dereference (should not crash the system and instead get this process killed) volatile int* p = (int*)0; *p = 123; diff --git a/src/kernel/userland/crash.elf b/src/kernel/userland/crash.elf index 9a31208..b4c2d1c 100755 Binary files a/src/kernel/userland/crash.elf and b/src/kernel/userland/crash.elf differ diff --git a/src/kernel/userland/hello.elf b/src/kernel/userland/hello.elf index 928a245..3a28dda 100755 Binary files a/src/kernel/userland/hello.elf and b/src/kernel/userland/hello.elf differ diff --git a/src/kernel/userland/libc/libui.c b/src/kernel/userland/libc/libui.c index 014682b..403430d 100644 --- a/src/kernel/userland/libc/libui.c +++ b/src/kernel/userland/libc/libui.c @@ -39,3 +39,8 @@ void ui_mark_dirty(ui_window_t win, int x, int y, int w, int h) { uint64_t params[4] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h }; syscall3(SYS_GUI, GUI_CMD_MARK_DIRTY, (uint64_t)win, (uint64_t)params); } + +void ui_draw_image(ui_window_t win, int x, int y, int w, int h, uint32_t *image_data) { + uint64_t params[4] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h }; + syscall4(SYS_GUI, GUI_CMD_DRAW_IMAGE, (uint64_t)win, (uint64_t)params, (uint64_t)image_data); +} diff --git a/src/kernel/userland/libc/libui.h b/src/kernel/userland/libc/libui.h index 6716b29..0fd0966 100644 --- a/src/kernel/userland/libc/libui.h +++ b/src/kernel/userland/libc/libui.h @@ -11,6 +11,7 @@ #define GUI_CMD_MARK_DIRTY 4 #define GUI_CMD_GET_EVENT 5 #define GUI_CMD_DRAW_ROUNDED_RECT_FILLED 6 +#define GUI_CMD_DRAW_IMAGE 7 // Event Types #define GUI_EVENT_NONE 0 @@ -42,5 +43,6 @@ void ui_draw_rect(ui_window_t win, int x, int y, int w, int h, uint32_t color); void ui_draw_rounded_rect_filled(ui_window_t win, int x, int y, int w, int h, int radius, uint32_t color); void ui_draw_string(ui_window_t win, int x, int y, const char *str, uint32_t color); void ui_mark_dirty(ui_window_t win, int x, int y, int w, int h); +void ui_draw_image(ui_window_t win, int x, int y, int w, int h, uint32_t *image_data); #endif diff --git a/src/kernel/userland/libc/libui.o b/src/kernel/userland/libc/libui.o index c11475a..22ab036 100644 Binary files a/src/kernel/userland/libc/libui.o and b/src/kernel/userland/libc/libui.o differ diff --git a/src/kernel/userland/libc/stdlib.c b/src/kernel/userland/libc/stdlib.c index bcbc48f..82c381a 100644 --- a/src/kernel/userland/libc/stdlib.c +++ b/src/kernel/userland/libc/stdlib.c @@ -24,9 +24,6 @@ static BlockMeta *find_free_block(BlockMeta **last, size_t size) { static BlockMeta *request_space(BlockMeta* last, size_t size) { BlockMeta *block; block = (BlockMeta *)sys_sbrk(0); - // Ask for space, ensuring everything stays 8-byte aligned if sizes are odd. - // For simplicity, we just request exactly what is needed, - // but typically `size` should be aligned. size_t align = 8; if (size % align != 0) { size += align - (size % align); @@ -70,7 +67,6 @@ void *malloc(size_t size) { if (!block) return NULL; } else { // Found free block block->free = 0; - // We could split the block here if block->size is much larger than size... } } diff --git a/src/kernel/userland/libc/syscall.c b/src/kernel/userland/libc/syscall.c index 538903d..236e4f5 100644 --- a/src/kernel/userland/libc/syscall.c +++ b/src/kernel/userland/libc/syscall.c @@ -59,11 +59,10 @@ uint64_t syscall5(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_t arg3, return ret; } -// C-Friendly Wrappers void sys_exit(int status) { syscall1(SYS_EXIT, (uint64_t)status); - while (1); // Halt + while (1); } int sys_write(int fd, const char *buf, int len) { diff --git a/src/kernel/userland/markdown.c b/src/kernel/userland/markdown.c index 44da2fc..fce4c36 100644 --- a/src/kernel/userland/markdown.c +++ b/src/kernel/userland/markdown.c @@ -235,7 +235,7 @@ static void md_draw_text_bold(ui_window_t win, int x, int y, const char *text, u static void md_paint(ui_window_t win) { int offset_x = 4; - int offset_y = 24; + int offset_y = 0; int content_width = win_w - 8; int content_height = win_h - 28; @@ -392,7 +392,7 @@ static void md_handle_key(char c) { static void md_handle_click(int x, int y) { int content_width = win_w - 8; int btn_x_up = 4 + content_width - 50; - int btn_y = 24 + 2; + int btn_y = 2; if (x >= btn_x_up && x < btn_x_up + 20 && y >= btn_y && y < btn_y + 16) { scroll_top -= 3; if (scroll_top < 0) scroll_top = 0; @@ -423,15 +423,15 @@ int main(int argc, char **argv) { if (ui_get_event(win, &ev)) { if (ev.type == GUI_EVENT_PAINT) { md_paint(win); - ui_mark_dirty(win, 0, 0, win_w, win_h); + ui_mark_dirty(win, 0, 0, win_w, win_h - 20); } else if (ev.type == GUI_EVENT_CLICK) { md_handle_click(ev.arg1, ev.arg2); md_paint(win); - ui_mark_dirty(win, 0, 0, win_w, win_h); + ui_mark_dirty(win, 0, 0, win_w, win_h - 20); } else if (ev.type == GUI_EVENT_KEY) { md_handle_key((char)ev.arg1); md_paint(win); - ui_mark_dirty(win, 0, 0, win_w, win_h); + ui_mark_dirty(win, 0, 0, win_w, win_h - 20); } else if (ev.type == GUI_EVENT_CLOSE) { sys_exit(0); } diff --git a/src/kernel/userland/markdown.elf b/src/kernel/userland/markdown.elf index 1c1a7ff..541c80b 100755 Binary files a/src/kernel/userland/markdown.elf and b/src/kernel/userland/markdown.elf differ diff --git a/src/kernel/userland/minesweeper.c b/src/kernel/userland/minesweeper.c index eec647a..cc85e90 100644 --- a/src/kernel/userland/minesweeper.c +++ b/src/kernel/userland/minesweeper.c @@ -26,14 +26,13 @@ static void debug_print(const char *msg) { #define CELL_SIZE 20 // Game state -static int grid[GRID_HEIGHT][GRID_WIDTH]; // -1 = mine, 0-8 = adjacent mine count +static int grid[GRID_HEIGHT][GRID_WIDTH]; static bool revealed[GRID_HEIGHT][GRID_WIDTH]; static bool flagged[GRID_HEIGHT][GRID_WIDTH]; static bool game_over = false; static bool game_won = false; static int revealed_count = 0; -// Helper: Random number generator (simple LCG) static uint32_t random_seed = 12345; static uint32_t random_next(void) { random_seed = random_seed * 1103515245 + 12345; @@ -120,10 +119,8 @@ static void reveal_cell(int x, int y) { } } } else if (grid[y][x] == 0) { - // Empty cell - flood fill flood_fill(x, y); } else { - // Numbered cell revealed[y][x] = true; revealed_count++; } @@ -144,21 +141,19 @@ static void flag_cell(int x, int y) { static void minesweeper_paint(ui_window_t win) { int win_w = 240, win_h = 340; - // Background - dark mode - ui_draw_rect(win, 4, 30, win_w - 8, win_h - 34, COLOR_DARK_BG); + ui_draw_rect(win, 4, 0, win_w - 8, win_h - 34, COLOR_DARK_BG); - // Game status if (game_over) { - ui_draw_string(win, 10, 36, "Game Over!", COLOR_TRAFFIC_RED); + ui_draw_string(win, 10, 6, "Game Over!", COLOR_TRAFFIC_RED); } else if (game_won) { - ui_draw_string(win, 10, 36, "You Won!", 0xFF00FF00); // Bright green + ui_draw_string(win, 10, 6, "You Won!", 0xFF00FF00); // Bright green } else { - ui_draw_string(win, 10, 36, "", COLOR_DARK_TEXT); + ui_draw_string(win, 10, 6, "", COLOR_DARK_TEXT); } // Draw grid int grid_start_x = 10; - int grid_start_y = 56; + int grid_start_y = 26; for (int y = 0; y < GRID_HEIGHT; y++) { for (int x = 0; x < GRID_WIDTH; x++) { @@ -196,7 +191,7 @@ static void minesweeper_paint(ui_window_t win) { static void minesweeper_handle_click(ui_window_t win, int x, int y, int button) { int grid_start_x = 10; - int grid_start_y = 56; + int grid_start_y = 26; int btn_y = grid_start_y + GRID_HEIGHT * CELL_SIZE + 10; // Check "New Game" button @@ -231,7 +226,6 @@ int main(int argc, char **argv) { ui_window_t win = ui_window_create("Minesweeper", 250, 100, 240, 340); if (!win) return 1; - // Use current time or something for seed? No syscall for time right now. random_seed = 987654321; init_game(); @@ -240,17 +234,17 @@ int main(int argc, char **argv) { if (ui_get_event(win, &ev)) { if (ev.type == GUI_EVENT_PAINT) { minesweeper_paint(win); - ui_mark_dirty(win, 0, 0, 240, 340); + ui_mark_dirty(win, 0, 0, 240, 320); } else if (ev.type == GUI_EVENT_CLICK) { debug_print("[MINESWEEPER] LEFT CLICK"); minesweeper_handle_click(win, ev.arg1, ev.arg2, ev.type); minesweeper_paint(win); - ui_mark_dirty(win, 0, 0, 240, 340); + ui_mark_dirty(win, 0, 0, 240, 320); } else if (ev.type == GUI_EVENT_RIGHT_CLICK) { debug_print("[MINESWEEPER] RIGHT CLICK DETECTED"); minesweeper_handle_click(win, ev.arg1, ev.arg2, ev.type); minesweeper_paint(win); - ui_mark_dirty(win, 0, 0, 240, 340); + ui_mark_dirty(win, 0, 0, 240, 320); } else if (ev.type == GUI_EVENT_CLOSE) { sys_exit(0); } diff --git a/src/kernel/userland/minesweeper.elf b/src/kernel/userland/minesweeper.elf index 8532ecf..ca1d740 100755 Binary files a/src/kernel/userland/minesweeper.elf and b/src/kernel/userland/minesweeper.elf differ diff --git a/src/kernel/userland/notepad.c b/src/kernel/userland/notepad.c index 69d5a18..e63e294 100644 --- a/src/kernel/userland/notepad.c +++ b/src/kernel/userland/notepad.c @@ -241,8 +241,7 @@ int main(int argc, char **argv) { sys_exit(0); } } else { - // Optional: sys_yield() or similar to avoid high CPU - // For now, just keep looping but it's better than nothing + for(volatile int i=0; i<10000; i++); } } diff --git a/src/kernel/userland/notepad.elf b/src/kernel/userland/notepad.elf index 60ddd31..0452686 100755 Binary files a/src/kernel/userland/notepad.elf and b/src/kernel/userland/notepad.elf differ diff --git a/src/kernel/userland/paint.c b/src/kernel/userland/paint.c index 4676cb8..e0248a9 100644 --- a/src/kernel/userland/paint.c +++ b/src/kernel/userland/paint.c @@ -50,24 +50,17 @@ static void paint_reset(void) { static void paint_paint(ui_window_t win) { int canvas_x = 60; - int canvas_y = 30; + int canvas_y = 0; - // Canvas Area with dark background and rounded corners (draw first so it's behind everything) ui_draw_rounded_rect_filled(win, canvas_x - 2, canvas_y - 2, CANVAS_W + 4, CANVAS_H + 4, 4, COLOR_DARK_BG); - - // Toolbar area - dark mode - ui_draw_rounded_rect_filled(win, 10, 30, 40, 260 - 40, 6, COLOR_DARK_PANEL); + ui_draw_rounded_rect_filled(win, 10, 0, 40, 230, 6, COLOR_DARK_PANEL); - // Color Palette with rounded corners uint32_t colors[] = {COLOR_BLACK, COLOR_RED, COLOR_APPLE_GREEN, COLOR_APPLE_BLUE, COLOR_APPLE_YELLOW, COLOR_WHITE}; for (int i = 0; i < 6; i++) { - int cy = 40 + (i * 25); + int cy = 10 + (i * 25); ui_draw_rounded_rect_filled(win, 15, cy, 30, 20, 3, colors[i]); - // Highlight selected color with border if (current_color == colors[i]) { - // Note: libui might not have draw_rounded_rect (hollow), so we just draw four lines simulating it - // or we use ui_draw_rect for hollow border ui_draw_rect(win, 13, cy - 2, 34, 1, COLOR_DARK_TEXT); ui_draw_rect(win, 13, cy - 2 + 24, 34, 1, COLOR_DARK_TEXT); ui_draw_rect(win, 13, cy - 2, 1, 24, COLOR_DARK_TEXT); @@ -75,12 +68,11 @@ static void paint_paint(ui_window_t win) { } } - // Toolbar Buttons - dark mode with rounded corners - ui_draw_rounded_rect_filled(win, 12, 260 - 65, 36, 20, 4, COLOR_DARK_BORDER); - ui_draw_string(win, 18, 260 - 58, "CLR", COLOR_DARK_TEXT); + ui_draw_rounded_rect_filled(win, 12, 230 - 65, 36, 20, 4, COLOR_DARK_BORDER); + ui_draw_string(win, 18, 230 - 58, "CLR", COLOR_DARK_TEXT); - ui_draw_rounded_rect_filled(win, 12, 260 - 40, 36, 20, 4, COLOR_DARK_BORDER); - ui_draw_string(win, 18, 260 - 33, "SAV", COLOR_DARK_TEXT); + ui_draw_rounded_rect_filled(win, 12, 230 - 40, 36, 20, 4, COLOR_DARK_BORDER); + ui_draw_string(win, 18, 230 - 33, "SAV", COLOR_DARK_TEXT); // Draw canvas content if (canvas_buffer) { @@ -93,7 +85,7 @@ static void paint_paint(ui_window_t win) { } } -static void paint_put_brush(ui_window_t win, int cx, int cy) { +static void paint_put_brush(ui_window_t win, int cx, int cy, int *min_x, int *min_y, int *max_x, int *max_y) { if (!canvas_buffer) return; for (int dy = 0; dy < 2; dy++) { for (int dx = 0; dx < 2; dx++) { @@ -101,26 +93,32 @@ static void paint_put_brush(ui_window_t win, int cx, int cy) { int py = cy + dy; if (px >= 0 && px < CANVAS_W && py >= 0 && py < CANVAS_H) { canvas_buffer[py * CANVAS_W + px] = current_color; - ui_draw_rect(win, 60 + px, 30 + py, 1, 1, current_color); + ui_draw_rect(win, 60 + px, 0 + py, 1, 1, current_color); + + if (px < *min_x) *min_x = px; + if (py < *min_y) *min_y = py; + if (px > *max_x) *max_x = px; + if (py > *max_y) *max_y = py; } } } - ui_mark_dirty(win, 60 + cx, 30 + cy, 2, 2); } void paint_handle_mouse(ui_window_t win, int x, int y) { int cx = x - 60; - int cy = y - 30; + int cy = y; if (cx < 0 || cx >= CANVAS_W || cy < 0 || cy >= CANVAS_H) { last_mx = -1; return; } + int min_x = CANVAS_W, min_y = CANVAS_H; + int max_x = -1, max_y = -1; + if (last_mx == -1) { - paint_put_brush(win, cx, cy); + paint_put_brush(win, cx, cy, &min_x, &min_y, &max_x, &max_y); } else { - // Bresenham's line algorithm to fill gaps between points int x0 = last_mx, y0 = last_my; int x1 = cx, y1 = cy; int dx = (x1 - x0 > 0) ? (x1 - x0) : (x0 - x1); @@ -130,13 +128,18 @@ void paint_handle_mouse(ui_window_t win, int x, int y) { int err = dx - dy; while (1) { - paint_put_brush(win, x0, y0); + paint_put_brush(win, x0, y0, &min_x, &min_y, &max_x, &max_y); if (x0 == x1 && y0 == y1) break; int e2 = 2 * err; if (e2 > -dy) { err -= dy; x0 += sx; } if (e2 < dx) { err += dx; y0 += sy; } } } + + if (min_x <= max_x && min_y <= max_y) { + ui_mark_dirty(win, 60 + min_x, 0 + min_y, (max_x - min_x) + 1, (max_y - min_y) + 1); + } + last_mx = cx; last_my = cy; } @@ -146,11 +149,9 @@ void paint_reset_last_pos(void) { last_my = -1; } -// Simple window message dialog wrapper using syscall + static void wm_show_message(const char *title, const char *msg) { - // Wait, userland doesn't have wm_show_message syscall available yet, or maybe it does? - // We didn't add it or GUI_EVENT doesn't support it directly. - // For now we do nothing, or just open a small window. + } static void paint_save(const char *path) { @@ -181,13 +182,13 @@ void paint_load(const char *path) { static void paint_click(ui_window_t win, int x, int y) { // Check Buttons if (x >= 12 && x < 48) { - if (y >= 260 - 65 && y < 260 - 45) { + if (y >= 230 - 65 && y < 230 - 45) { paint_reset(); paint_paint(win); - ui_mark_dirty(win, 0, 0, 380, 260); + ui_mark_dirty(win, 0, 0, 380, 230); return; } - if (y >= 260 - 40 && y < 260 - 20) { + if (y >= 230 - 40 && y < 230 - 20) { paint_save(current_file_path); return; } @@ -196,12 +197,12 @@ static void paint_click(ui_window_t win, int x, int y) { // Check Palette if (x >= 15 && x < 45) { for (int i = 0; i < 6; i++) { - int cy = 40 + (i * 25); + int cy = 10 + (i * 25); if (y >= cy && y < cy + 20) { uint32_t colors[] = {COLOR_BLACK, COLOR_RED, COLOR_APPLE_GREEN, COLOR_APPLE_BLUE, COLOR_APPLE_YELLOW, COLOR_WHITE}; current_color = colors[i]; paint_paint(win); - ui_mark_dirty(win, 0, 0, 380, 260); + ui_mark_dirty(win, 0, 0, 380, 230); return; } } @@ -227,11 +228,9 @@ int main(int argc, char **argv) { if (ui_get_event(win, &ev)) { if (ev.type == GUI_EVENT_PAINT) { paint_paint(win); - ui_mark_dirty(win, 0, 0, 380, 260); + ui_mark_dirty(win, 0, 0, 380, 240); } else if (ev.type == GUI_EVENT_CLICK) { paint_click(win, ev.arg1, ev.arg2); - paint_paint(win); - ui_mark_dirty(win, 0, 0, 380, 260); } else if (ev.type == GUI_EVENT_MOUSE_DOWN) { paint_handle_mouse(win, ev.arg1, ev.arg2); } else if (ev.type == GUI_EVENT_MOUSE_UP) { diff --git a/src/kernel/userland/paint.elf b/src/kernel/userland/paint.elf index bf66151..df2ef8e 100755 Binary files a/src/kernel/userland/paint.elf and b/src/kernel/userland/paint.elf differ diff --git a/src/kernel/userland/settings.c b/src/kernel/userland/settings.c index 3e581ef..bd3d566 100644 --- a/src/kernel/userland/settings.c +++ b/src/kernel/userland/settings.c @@ -689,3 +689,4 @@ int main(int argc, char **argv) { } return 0; } + diff --git a/src/kernel/userland/settings.elf b/src/kernel/userland/settings.elf index 4858796..d970c4d 100755 Binary files a/src/kernel/userland/settings.elf and b/src/kernel/userland/settings.elf differ diff --git a/src/kernel/userland/txtedit.c b/src/kernel/userland/txtedit.c index db1b811..270977b 100644 --- a/src/kernel/userland/txtedit.c +++ b/src/kernel/userland/txtedit.c @@ -197,7 +197,7 @@ static void editor_insert_char(char ch) { static void editor_paint(ui_window_t win) { int offset_x = 4; - int offset_y = 24; + int offset_y = 0; int content_width = win_w - 8; int content_height = win_h - 28; @@ -390,7 +390,7 @@ static void editor_handle_key(char c) { static void editor_handle_click(int x, int y) { int content_width = win_w - 8; int button_x = 4 + content_width - 80; - int button_y = 24 + 3; + int button_y = 3; if (x >= button_x && x < button_x + 70 && y >= button_y && y < button_y + 20) { editor_save_file(); @@ -413,15 +413,15 @@ int main(int argc, char **argv) { if (ui_get_event(win, &ev)) { if (ev.type == GUI_EVENT_PAINT) { editor_paint(win); - ui_mark_dirty(win, 0, 0, win_w, win_h); + ui_mark_dirty(win, 0, 0, win_w, win_h - 20); } else if (ev.type == GUI_EVENT_CLICK) { editor_handle_click(ev.arg1, ev.arg2); editor_paint(win); - ui_mark_dirty(win, 0, 0, win_w, win_h); + ui_mark_dirty(win, 0, 0, win_w, win_h - 20); } else if (ev.type == GUI_EVENT_KEY) { editor_handle_key((char)ev.arg1); editor_paint(win); - ui_mark_dirty(win, 0, 0, win_w, win_h); + ui_mark_dirty(win, 0, 0, win_w, win_h - 20); } else if (ev.type == GUI_EVENT_CLOSE) { sys_exit(0); } diff --git a/src/kernel/userland/txtedit.elf b/src/kernel/userland/txtedit.elf index f4ca530..101de91 100755 Binary files a/src/kernel/userland/txtedit.elf and b/src/kernel/userland/txtedit.elf differ diff --git a/src/kernel/userland/viewer.c b/src/kernel/userland/viewer.c index a64d1cf..6ea8fb3 100644 --- a/src/kernel/userland/viewer.c +++ b/src/kernel/userland/viewer.c @@ -49,7 +49,7 @@ static void viewer_scale_rgb_to_argb(const unsigned char *rgb, int src_w, int sr static void viewer_paint(ui_window_t win) { int cx = 4; - int cy = 24; + int cy = 0; int cw = win_w - 8; int ch = win_h - 28; @@ -75,21 +75,25 @@ static void viewer_paint(ui_window_t win) { int ox = cx + (cw - disp_w) / 2; int oy = cy + (ch - disp_h - 30) / 2; - for (int y = 0; y < disp_h; y++) { - int src_y = y * viewer_img_h / disp_h; - if (src_y >= viewer_img_h) src_y = viewer_img_h - 1; - for (int x = 0; x < disp_w; x++) { - int src_x = x * viewer_img_w / disp_w; - if (src_x >= viewer_img_w) src_x = viewer_img_w - 1; - uint32_t pixel = viewer_pixels[src_y * viewer_img_w + src_x]; - ui_draw_rect(win, ox + x, oy + y, 1, 1, pixel); + uint32_t *temp_buf = malloc(disp_w * disp_h * sizeof(uint32_t)); + if (temp_buf) { + for (int y = 0; y < disp_h; y++) { + int src_y = y * viewer_img_h / disp_h; + if (src_y >= viewer_img_h) src_y = viewer_img_h - 1; + for (int x = 0; x < disp_w; x++) { + int src_x = x * viewer_img_w / disp_w; + if (src_x >= viewer_img_w) src_x = viewer_img_w - 1; + temp_buf[y * disp_w + x] = viewer_pixels[src_y * viewer_img_w + src_x]; + } } + ui_draw_image(win, ox, oy, disp_w, disp_h, temp_buf); + free(temp_buf); } int btn_w = 160; int btn_h = 22; int btn_x = cx + (cw - btn_w) / 2; - int btn_y = win_h - 30; + int btn_y = (win_h - 20) - 30; ui_draw_rounded_rect_filled(win, btn_x, btn_y, btn_w, btn_h, 6, 0xFF2D2D2D); ui_draw_string(win, btn_x + 10, btn_y + 6, "Set as Wallpaper", 0xFFF0F0F0); } @@ -101,7 +105,7 @@ static void viewer_handle_click(ui_window_t win, int x, int y) { int cw = win_w - 8; int btn_w = 160; int btn_x = cx + (cw - btn_w) / 2; - int btn_y = win_h - 30; + int btn_y = (win_h - 20) - 30; if (x >= btn_x && x < btn_x + btn_w && y >= btn_y && y < btn_y + 22) { // SYSTEM_CMD_SET_WALLPAPER is 3 based on syscall.c code @@ -214,7 +218,7 @@ int main(int argc, char **argv) { if (ui_get_event(win, &ev)) { if (ev.type == GUI_EVENT_PAINT) { viewer_paint(win); - ui_mark_dirty(win, 0, 0, win_w, win_h); + ui_mark_dirty(win, 0, 0, win_w, win_h - 20); } else if (ev.type == GUI_EVENT_CLICK) { viewer_handle_click(win, ev.arg1, ev.arg2); } else if (ev.type == GUI_EVENT_CLOSE) { diff --git a/src/kernel/userland/viewer.elf b/src/kernel/userland/viewer.elf index 437573c..8589e4d 100755 Binary files a/src/kernel/userland/viewer.elf and b/src/kernel/userland/viewer.elf differ diff --git a/src/kernel/userland/viewer.o b/src/kernel/userland/viewer.o index 18e69a1..d6a263e 100644 Binary files a/src/kernel/userland/viewer.o and b/src/kernel/userland/viewer.o differ diff --git a/src/kernel/wm.c b/src/kernel/wm.c index 2663d8d..ba92134 100644 --- a/src/kernel/wm.c +++ b/src/kernel/wm.c @@ -1003,9 +1003,9 @@ void draw_window(Window *win) { draw_rect(win->x, win->y + 20, win->w, 8, COLOR_DARK_BG); if (win->comp_pixels) { - graphics_blit_buffer(win->comp_pixels, win->x, win->y, win->w, win->h); + graphics_blit_buffer(win->comp_pixels, win->x, win->y + 20, win->w, win->h - 20); } else if (win->pixels) { - graphics_blit_buffer(win->pixels, win->x, win->y, win->w, win->h); + graphics_blit_buffer(win->pixels, win->x, win->y + 20, win->w, win->h - 20); } if (win->paint) { @@ -1051,12 +1051,9 @@ static void erase_cursor(int x, int y) { int w = x2 - x1; int h = y2 - y1; - // Check what's underneath the cursor and redraw it if (y1 < sh - 28) { - // Desktop or window area - draw teal background draw_rect(x1, y1, w, h, COLOR_TEAL); } else { - // Taskbar draw_rect(x1, y1, w, h, COLOR_GRAY); } } @@ -1068,7 +1065,6 @@ static uint8_t rtc_read(uint8_t reg) { } static void draw_clock(int x, int y) { - // Wait for update in progress while (rtc_read(0x0A) & 0x80); uint8_t s = rtc_read(0x00); @@ -1168,7 +1164,6 @@ void wm_paint(void) { } } - // Draw windows in z-order (lowest first) for (int i = 0; i < window_count; i++) { Window *win = sorted_windows[i]; if (!win->visible) continue; @@ -1182,16 +1177,10 @@ void wm_paint(void) { draw_window(win); } - // 4. Top Menu Bar draw_rect(0, 0, sw, 30, COLOR_TOPBAR_BG); - - // Logo dropdown (top-left) draw_boredos_logo(8, 8, 1); - - // Clock (top-right) draw_clock(sw - 80, 12); - // Top menu dropdown (if logo clicked) if (start_menu_open) { int menu_h = 85; draw_rounded_rect_filled(8, 40, 160, menu_h, 8, COLOR_DARK_PANEL); @@ -1201,17 +1190,15 @@ void wm_paint(void) { draw_string(20, 108, "Restart", COLOR_DARK_TEXT); } - // 5. Dock (bottom - macOS style, floating with rounded corners) int dock_h = 60; - int dock_y = sh - dock_h - 6; // Float above bottom + int dock_y = sh - dock_h - 6; int dock_item_size = 48; int dock_spacing = 10; int total_dock_width = 7 * (dock_item_size + dock_spacing); - int dock_bg_x = (sw - total_dock_width) / 2 - 12; // Rounded background extends beyond icons + int dock_bg_x = (sw - total_dock_width) / 2 - 12; int dock_bg_w = total_dock_width + 24; draw_rounded_rect_filled(dock_bg_x, dock_y, dock_bg_w, dock_h, 18, COLOR_DOCK_BG); - // Draw dock apps (centered) int dock_x = (sw - total_dock_width) / 2; int dock_item_y = dock_y + 6; @@ -1321,6 +1308,8 @@ bool rect_contains(int x, int y, int w, int h, int px, int py) { } void wm_bring_to_front(Window *win) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); // Clear focus from all windows for (int i = 0; i < window_count; i++) { all_windows[i]->focused = false; @@ -1336,22 +1325,30 @@ void wm_bring_to_front(Window *win) { win->focused = true; win->z_index = max_z + 1; force_redraw = true; + asm volatile("push %0; popfq" : : "r"(rflags)); } void wm_add_window(Window *win) { + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); if (window_count < 32) { all_windows[window_count++] = win; wm_bring_to_front(win); // Ensure newly added windows are on top } + asm volatile("push %0; popfq" : : "r"(rflags)); } Window* wm_find_window_by_title(const char *title) { if (!title) return NULL; + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); for (int i = 0; i < window_count; i++) { if (all_windows[i] && all_windows[i]->title && str_eq(all_windows[i]->title, title)) { + asm volatile("push %0; popfq" : : "r"(rflags)); return all_windows[i]; } } + asm volatile("push %0; popfq" : : "r"(rflags)); return NULL; } @@ -1363,6 +1360,9 @@ void wm_remove_window(Window *win) { else serial_write("unknown"); serial_write("'\n"); + uint64_t rflags; + asm volatile("pushfq; pop %0; cli" : "=r"(rflags)); + int index = -1; for (int i = 0; i < window_count; i++) { if (all_windows[i] == win) { @@ -1378,22 +1378,22 @@ void wm_remove_window(Window *win) { } window_count--; - // Free resources - if (win->pixels) kfree(win->pixels); - if (win->comp_pixels) kfree(win->comp_pixels); - // If the title was allocated in syscall.c, we should free it, - // but currently we don't know for sure if it was kmalloc'd or a literal. - // In syscall.c it is kmalloc'd. Let's assume we should free it if it's not a known literal. - // Safer to just free it since userland windows always have kmalloc'd titles. - if (win->title && win->handle_close) { // Heuristic: user windows have handle_close set in syscall.c - kfree(win->title); - } - - kfree(win); + // Mark for redraw while protected force_redraw = true; } else { + asm volatile("push %0; popfq" : : "r"(rflags)); serial_write("WM: Window not found in all_windows list!\n"); + return; } + + if (win->pixels) kfree(win->pixels); + if (win->comp_pixels) kfree(win->comp_pixels); + if (win->title && win->handle_close) { + kfree(win->title); + } + kfree(win); + + asm volatile("push %0; popfq" : : "r"(rflags)); } void wm_handle_click(int x, int y) { @@ -1614,7 +1614,7 @@ void wm_handle_click(int x, int y) { } else { // Content click if (topmost->handle_click) { - topmost->handle_click(topmost, x - topmost->x, y - topmost->y); + topmost->handle_click(topmost, x - topmost->x, y - topmost->y - 20); } } pending_desktop_icon_click = -1; @@ -1665,10 +1665,10 @@ void wm_handle_right_click(int x, int y) { // If a window was clicked if (topmost != NULL) { // Don't process close button or title bar for right click - if (y >= topmost->y + 24) { + if (y >= topmost->y + 20) { // Content right click if (topmost->handle_right_click) { - topmost->handle_right_click(topmost, x - topmost->x, y - topmost->y); + topmost->handle_right_click(topmost, x - topmost->x, y - topmost->y - 20); } } } else { @@ -1718,12 +1718,10 @@ void wm_handle_right_click(int x, int y) { bool right = buttons & 0x02; if (left && !prev_left) { - // Mouse Down drag_start_x = mx; drag_start_y = my; - // Check Dock for app clicks (bottom of screen, floating) int dock_h = 60; - int dock_y = sh - dock_h - 6; // Float above bottom + int dock_y = sh - dock_h - 6; int dock_item_size = 48; int dock_spacing = 10; int total_dock_width = 7 * (dock_item_size + dock_spacing); @@ -1778,8 +1776,6 @@ void wm_handle_right_click(int x, int y) { start_menu_pending_app = NULL; } - // Mouse moving with left button, check for file drag start - // 1. Check Desktop Icons if (pending_desktop_icon_click != -1) { int i = pending_desktop_icon_click; DesktopIcon *icon = &desktop_icons[i]; @@ -1953,7 +1949,6 @@ void wm_handle_right_click(int x, int y) { if (is_dragging_file) { // Drop logic - // Check drop target - iterate through all windows to find if dropped on an Explorer Window *drop_win = NULL; int topmost_z = -1; for (int w = 0; w < window_count; w++) { @@ -1983,11 +1978,8 @@ void wm_handle_right_click(int x, int y) { } else { // Dropped on Desktop (or elsewhere) if (drag_file_path[0] == ':' && drag_file_path[1] == ':' && drag_file_path[2] == 'A') { - // Dropped Start Menu App -> Create Shortcut - create_desktop_shortcut(drag_file_path + 7); // Skip ::APP:: + create_desktop_shortcut(drag_file_path + 7); } else { - // If source was NOT desktop, move to desktop - // Check if path starts with /Desktop/ bool from_desktop = (drag_file_path[0]=='/' && drag_file_path[1]=='D' && drag_file_path[2]=='e'); bool dropped_on_target = false; for (int i = 0; i < desktop_icon_count; i++) { @@ -2076,8 +2068,6 @@ void wm_handle_right_click(int x, int y) { } } } else if (!dropped_on_target) { - // Moved within desktop - // Find which icon was dragged int dragged_idx = -1; for(int i=0; idata) { - syscall_send_mouse_down_event(topmost, mx - topmost->x, my - topmost->y); + if (my >= topmost->y + 20) + syscall_send_mouse_down_event(topmost, mx - topmost->x, my - topmost->y - 20); } } @@ -2192,7 +2180,8 @@ void wm_handle_right_click(int x, int y) { } } if (topmost && topmost->data) { - syscall_send_mouse_up_event(topmost, mx - topmost->x, my - topmost->y); + if (my >= topmost->y + 20) + syscall_send_mouse_up_event(topmost, mx - topmost->x, my - topmost->y - 20); } } @@ -2210,7 +2199,8 @@ void wm_handle_right_click(int x, int y) { } } if (topmost && topmost->data) { - syscall_send_mouse_move_event(topmost, mx - topmost->x, my - topmost->y, buttons); + if (my >= topmost->y + 20) + syscall_send_mouse_move_event(topmost, mx - topmost->x, my - topmost->y - 20, buttons); } } @@ -2346,12 +2336,10 @@ void wm_init(void) { all_windows[2] = &win_about; window_count = 3; - // Only show Explorer on desktop (initially hidden) win_explorer.visible = false; win_explorer.focused = false; win_explorer.z_index = 10; - // Rest are hidden initially win_cmd.visible = false; win_about.visible = false; @@ -2366,8 +2354,6 @@ uint32_t wm_get_ticks(void) { void wm_timer_tick(void) { timer_ticks++; - // Auto-refresh desktop every 5 seconds to save CPU in QEMU - // But NOT if the user is dragging a window or file. if (!is_dragging && !is_dragging_file) { desktop_refresh_timer++; if (desktop_refresh_timer >= 300) { @@ -2378,8 +2364,7 @@ void wm_timer_tick(void) { } } - // Only redraw if there are dirty areas (clock updates at most every second, cursor rarely moves in timer only) - // Most of the time, nothing changes between ticks + static uint8_t last_second = 0xFF; @@ -2389,17 +2374,14 @@ void wm_timer_tick(void) { if (current_sec != last_second) { last_second = current_sec; int sw = get_screen_width(); - // Mark clock area in the top menu bar (around draw_clock at sw - 80, y=12) wm_mark_dirty(sw - 110, 6, 110, 24); } - // If force_redraw is set, do a full redraw if (force_redraw) { graphics_mark_screen_dirty(); force_redraw = false; } - // Perform redraw if there are dirty areas DirtyRect dirty = graphics_get_dirty_rect(); if (dirty.active) { wm_paint(); diff --git a/src/kernel/wm.h b/src/kernel/wm.h index 9fc5631..80fe7c4 100644 --- a/src/kernel/wm.h +++ b/src/kernel/wm.h @@ -23,7 +23,6 @@ #define COLOR_APPLE_INDIGO 0xFF4B0082 #define COLOR_APPLE_VIOLET 0xFF9400D3 -// --- Dark Mode Colors --- #define COLOR_NOTEPAD_BG 0xFFF5F5DC #define COLOR_DARK_BG 0xFF1E1E1E // Main dark background #define COLOR_DARK_PANEL 0xFF2D2D2D // Slightly lighter panel background @@ -36,7 +35,7 @@ #define COLOR_TRAFFIC_YELLOW 0xFFFCC02E // Minimize button (not used for now) #define COLOR_TRAFFIC_GREEN 0xFF5FC038 // Zoom button (not used for now) -#define DESKTOP_TOP_DEADSPACE_HEIGHT 80 // Height of the dead space at the top of the desktop grid +#define DESKTOP_TOP_DEADSPACE_HEIGHT 80 // stops files from being rendered under menu bar typedef struct Window Window; struct Window { char *title; @@ -46,10 +45,10 @@ struct Window { int buf_len; int cursor_pos; bool focused; - int z_index; // Layering depth (higher = on top) - void *data; // Per-window private data - uint32_t *pixels; // Pointer to backing buffer for UI events (Back Buffer) - uint32_t *comp_pixels; // Pointer to composition buffer (Front Buffer) + int z_index; + void *data; + uint32_t *pixels; + uint32_t *comp_pixels; // Callbacks void (*paint)(Window *win); @@ -88,7 +87,7 @@ void draw_bevel_rect(int x, int y, int w, int h, bool sunken); void draw_button(int x, int y, int w, int h, const char *text, bool pressed); void draw_rounded_rect(int x, int y, int w, int h, int radius, uint32_t color); void draw_rounded_rect_filled(int x, int y, int w, int h, int radius, uint32_t color); -void draw_traffic_light(int x, int y); // Red close button only +void draw_traffic_light(int x, int y); void draw_icon(int x, int y, const char *label); void draw_folder_icon(int x, int y, const char *label); void draw_document_icon(int x, int y, const char *label);