diff --git a/Makefile b/Makefile index 0f0a4dc..42360c3 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,7 @@ servers: libc hal $(LVGL_LIB) @# Desktop GUI Server (LVGL v8.3) @$(CXX) $(CXXFLAGS) -Ilib/lvgl -c $(SERVERS_DIR)/gui_server/main.cpp -o $(BUILD_DIR)/gui_main.o @$(LD) -T $(CONFIG_DIR)/user.ld -nostdlib -static -o $(GUI_SERVER) \ - $(BUILD_DIR)/gui_main.o $(BUILD_DIR)/ipc.o $(LVGL_LIB) $(LIBC_OBJS) + $(BUILD_DIR)/gui_main.o $(BUILD_DIR)/ipc.o $(NET_OBJS) $(LVGL_LIB) $(LIBC_OBJS) # Download and build the Limine bootloader host tool limine-setup: diff --git a/kernel/asm/keyboard_isr.S b/kernel/asm/keyboard_isr.S index fc91211..53ce9ad 100644 --- a/kernel/asm/keyboard_isr.S +++ b/kernel/asm/keyboard_isr.S @@ -39,3 +39,44 @@ keyboard_isr_entry: pop rax iretq + +.global mouse_isr_entry +.extern mouse_interrupt_handler + +mouse_isr_entry: + push rax + push rbx + push rcx + push rdx + push rsi + push rdi + push rbp + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 + + call mouse_interrupt_handler + + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rbp + pop rdi + pop rsi + pop rdx + pop rcx + pop rbx + pop rax + + iretq + diff --git a/kernel/src/arch/idt.rs b/kernel/src/arch/idt.rs index 7f331c9..1aa63ab 100644 --- a/kernel/src/arch/idt.rs +++ b/kernel/src/arch/idt.rs @@ -53,6 +53,7 @@ extern "C" { fn default_isr_stub(); fn timer_isr_entry(); fn keyboard_isr_entry(); + fn mouse_isr_entry(); } // Global assembly ISR stub with vector ID pushed as separate stubs (0-31) @@ -153,6 +154,10 @@ pub unsafe fn init() { let kbd_addr = keyboard_isr_entry as *const () as usize as u64; (*idt_ptr.add(33)).set_handler(kbd_addr, 0, 0); + // Set Mouse Interrupt (Vector 44 / 0x2C - Slave PIC IRQ 12) + let mouse_addr = mouse_isr_entry as *const () as usize as u64; + (*idt_ptr.add(44)).set_handler(mouse_addr, 0, 0); + let descriptor = IdtDescriptor { limit: (size_of::<[IdtEntry; 256]>() - 1) as u16, base: idt_ptr as u64, diff --git a/kernel/src/drivers/mouse.rs b/kernel/src/drivers/mouse.rs index 449e74a..848ce49 100644 --- a/kernel/src/drivers/mouse.rs +++ b/kernel/src/drivers/mouse.rs @@ -145,8 +145,27 @@ pub fn init(screen_w: i32, screen_h: i32) { } } +#[no_mangle] +pub extern "C" fn mouse_interrupt_handler() { + unsafe { + let status = inb(PS2_COMMAND_PORT); + if (status & 0x01) != 0 { + let data = inb(PS2_DATA_PORT); + if (status & 0x20) != 0 { + MOUSE_STATE.handle_byte(data); + } + } + crate::drivers::timer::send_slave_eoi(); + } +} + pub fn get_mouse_info() -> (i32, i32, u32) { unsafe { + // Drain any pending bytes in 8042 buffer + while (inb(PS2_COMMAND_PORT) & 0x21) == 0x21 { + let data = inb(PS2_DATA_PORT); + MOUSE_STATE.handle_byte(data); + } (MOUSE_STATE.x, MOUSE_STATE.y, MOUSE_STATE.buttons) } } diff --git a/kernel/src/drivers/timer.rs b/kernel/src/drivers/timer.rs index 96bcf7d..df4fa0b 100644 --- a/kernel/src/drivers/timer.rs +++ b/kernel/src/drivers/timer.rs @@ -22,11 +22,17 @@ unsafe fn io_wait() { outb(0x80, 0); } -/// Send End of Interrupt to PIC +/// Send End of Interrupt to Master PIC pub unsafe fn send_eoi() { outb(PIC1_COMMAND, PIC_EOI); } +/// Send End of Interrupt to both Slave and Master PIC (for IRQs 8-15, including IRQ 12 mouse) +pub unsafe fn send_slave_eoi() { + outb(PIC2_COMMAND, PIC_EOI); + outb(PIC1_COMMAND, PIC_EOI); +} + /// Remap PIC offsets to 32 (0x20) and 40 (0x28) unsafe fn remap_pic() { // ICW1: Start initialization in cascade mode @@ -41,7 +47,7 @@ unsafe fn remap_pic() { outb(PIC2_DATA, 0x28); io_wait(); - // ICW3: Cascade wiring + // ICW3: Cascade wiring (Master: IRQ2 has slave; Slave: cascade identity 2) outb(PIC1_DATA, 0x04); io_wait(); outb(PIC2_DATA, 0x02); @@ -53,9 +59,14 @@ unsafe fn remap_pic() { outb(PIC2_DATA, 0x01); io_wait(); - // Mask all IRQs except IRQ 0 (Timer) and IRQ 1 (Keyboard) - outb(PIC1_DATA, 0xFC); // Enable IRQ0 and IRQ1 - outb(PIC2_DATA, 0xFF); // Disable all on Slave + // Enable IRQ 0 (Timer), IRQ 1 (Keyboard), and IRQ 2 (Cascade to Slave PIC) on Master: + // 0xF8 = 11111000b (bits 0, 1, 2 unmasked) + outb(PIC1_DATA, 0xF8); + + // Enable IRQ 12 (PS/2 Mouse) on Slave PIC: + // IRQ 12 is line 4 on Slave PIC (8 + 4 = 12): + // 0xEF = 11101111b (bit 4 unmasked) + outb(PIC2_DATA, 0xEF); } /// Initialize PIT to tick at target Hz (e.g. 100 Hz = 10 ms quantum) diff --git a/lib/lvgl/lv_conf.h b/lib/lvgl/lv_conf.h index b784e7d..a0cb630 100644 --- a/lib/lvgl/lv_conf.h +++ b/lib/lvgl/lv_conf.h @@ -363,9 +363,9 @@ *https://fonts.google.com/specimen/Montserrat*/ #define LV_FONT_MONTSERRAT_8 0 #define LV_FONT_MONTSERRAT_10 0 -#define LV_FONT_MONTSERRAT_12 0 +#define LV_FONT_MONTSERRAT_12 1 #define LV_FONT_MONTSERRAT_14 1 -#define LV_FONT_MONTSERRAT_16 0 +#define LV_FONT_MONTSERRAT_16 1 #define LV_FONT_MONTSERRAT_18 0 #define LV_FONT_MONTSERRAT_20 0 #define LV_FONT_MONTSERRAT_22 0 diff --git a/servers/gui_server/main.cpp b/servers/gui_server/main.cpp index bedc65f..fb03ed5 100644 --- a/servers/gui_server/main.cpp +++ b/servers/gui_server/main.cpp @@ -1,38 +1,72 @@ /** * opencoreC - Desktop GUI Server (Ring 3 User Space) - * Powered by LVGL v8.3, Hardware PS/2 Mouse & Limine Linear Framebuffer. + * Windows / KDE-inspired Desktop Environment powered by LVGL v8.3. + * Features: + * - Custom 16x24 high-contrast hardware arrow cursor on lv_layer_sys() + * - Bottom Taskbar with Start Menu, Running App tabs & System Tray + * - Interactive Terminal (Console) application with real system commands + * - Task Manager with real-time CPU chart & thread table + * - Network Center with RTL8139 PCI diagnostics & Ping + * - About opencoreC dialog + * - Safe System Poweroff via Start Menu (SYS_SHUTDOWN) */ #include "lvgl.h" #include "abi/syscalls.h" +#include "abi/net.h" #include "stdio.h" #include "string.h" #include "stdlib.h" -static fb_info_t g_fb = {0}; +extern "C" { + void net_init(void); + int net_send_icmp_ping(uint32_t target_ip, uint16_t seq); +} + +// Framebuffer and display driver structures +static fb_info_t g_fb = {0, 0, 0, 0, 0}; static lv_disp_drv_t g_disp_drv; static lv_indev_drv_t g_indev_drv; static lv_indev_t *g_mouse_indev = NULL; -// Render buffers (2 lines of 40-pixel chunks for fast double-buffering) +// Double-buffering: 40-row raster bands #define BUF_HEIGHT 40 static lv_color_t g_buf1[1280 * BUF_HEIGHT]; static lv_color_t g_buf2[1280 * BUF_HEIGHT]; static lv_disp_draw_buf_t g_draw_buf; -// UI Objects for live updating -static lv_obj_t *g_lbl_clock = NULL; -static lv_obj_t *g_lbl_ram = NULL; -static lv_obj_t *g_lbl_uptime = NULL; -static lv_obj_t *g_bar_ram = NULL; -static lv_obj_t *g_chart_cpu = NULL; -static lv_chart_series_t *g_ser_user = NULL; -static lv_chart_series_t *g_ser_idle = NULL; -static lv_obj_t *g_tbl_threads = NULL; -static lv_obj_t *g_txt_term = NULL; -static lv_obj_t *g_lbl_net_status = NULL; +// 16x24 High-Contrast Arrow Cursor Bitmap +#define CURSOR_W 16 +#define CURSOR_H 24 +static lv_color32_t g_cursor_map[CURSOR_W * CURSOR_H]; +static lv_img_dsc_t g_cursor_dsc; -// Flush callback: blits dirty area directly to Limine 32bpp linear framebuffer +// Top-level Desktop UI Elements +static lv_obj_t *g_start_menu = NULL; +static lv_obj_t *g_win_console = NULL; +static lv_obj_t *g_win_taskmgr = NULL; +static lv_obj_t *g_win_network = NULL; +static lv_obj_t *g_win_about = NULL; + +// Taskbar buttons +static lv_obj_t *g_btn_tb_console = NULL; +static lv_obj_t *g_btn_tb_taskmgr = NULL; +static lv_obj_t *g_btn_tb_network = NULL; + +// Live System Tray & Widget References +static lv_obj_t *g_lbl_tray_clock = NULL; +static lv_obj_t *g_lbl_tray_ram = NULL; +static lv_obj_t *g_lbl_tray_net = NULL; +static lv_obj_t *g_txt_term_output = NULL; +static lv_obj_t *g_ta_term_input = NULL; +static lv_obj_t *g_chart_cpu = NULL; +static lv_chart_series_t *g_ser_cpu = NULL; +static lv_obj_t *g_bar_ram = NULL; +static lv_obj_t *g_lbl_ram_detail = NULL; +static lv_obj_t *g_tbl_procs = NULL; +static lv_obj_t *g_lbl_net_ping_res = NULL; + +// Flush callback: writes dirty regions directly to Limine linear framebuffer static void disp_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p) { uint32_t *fb = (uint32_t *)g_fb.fb_addr; uint32_t pitch_pixels = (uint32_t)(g_fb.pitch / 4); @@ -47,10 +81,10 @@ static void disp_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t lv_disp_flush_ready(drv); } -// Mouse read callback: queries SYS_MOUSE_GET from microkernel +// Mouse read callback: queries microkernel SYS_MOUSE_GET static void mouse_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) { (void)drv; - mouse_data_t mouse = {0}; + mouse_data_t mouse = {0, 0, 0}; register uint64_t rax __asm__("rax") = SYS_MOUSE_GET; register uint64_t rdi __asm__("rdi") = (uint64_t)&mouse; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); @@ -60,341 +94,800 @@ static void mouse_read_cb(lv_indev_drv_t *drv, lv_indev_data_t *data) { data->state = (mouse.buttons & 1) ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; } -static void term_append(const char *text) { - if (g_txt_term) { - lv_textarea_add_text(g_txt_term, text); +// Initialize the 16x24 classic Windows / KDE arrow cursor +static void init_cursor_bitmap() { + static const char *pattern[CURSOR_H] = { + "#...............", + "##..............", + "#W#.............", + "#WW#............", + "#WWW#...........", + "#WWWW#..........", + "#WWWWW#.........", + "#WWWWWW#........", + "#WWWWWWW#.......", + "#WWWWWWWW#......", + "#WWWWWWWWW#.....", + "#WWWWWW#...#....", + "#WW#W##.........", + "#W#.#W#.........", + "##..#W#.........", + "#....#W#........", + ".....#W#........", + "......##........", + "................", + "................", + "................", + "................", + "................", + "................" + }; + + for (int y = 0; y < CURSOR_H; y++) { + for (int x = 0; x < CURSOR_W; x++) { + char c = pattern[y][x]; + int idx = y * CURSOR_W + x; + if (c == '#') { + g_cursor_map[idx].ch.red = 0; + g_cursor_map[idx].ch.green = 0; + g_cursor_map[idx].ch.blue = 0; + g_cursor_map[idx].ch.alpha = 255; // Solid black outline + } else if (c == 'W') { + g_cursor_map[idx].ch.red = 255; + g_cursor_map[idx].ch.green = 255; + g_cursor_map[idx].ch.blue = 255; + g_cursor_map[idx].ch.alpha = 255; // Solid white fill + } else { + g_cursor_map[idx].full = 0; // Transparent + } + } + } + + g_cursor_dsc.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA; + g_cursor_dsc.header.always_zero = 0; + g_cursor_dsc.header.reserved = 0; + g_cursor_dsc.header.w = CURSOR_W; + g_cursor_dsc.header.h = CURSOR_H; + g_cursor_dsc.data_size = CURSOR_W * CURSOR_H * sizeof(lv_color32_t); + g_cursor_dsc.data = (const uint8_t *)g_cursor_map; +} + +// Window toggle helper (show/hide and bring to foreground) +static void toggle_window(lv_obj_t *win) { + if (lv_obj_has_flag(win, LV_OBJ_FLAG_HIDDEN)) { + lv_obj_clear_flag(win, LV_OBJ_FLAG_HIDDEN); + lv_obj_move_foreground(win); + } else { + lv_obj_add_flag(win, LV_OBJ_FLAG_HIDDEN); } } -// Terminal command buttons -static void btn_cmd_event_cb(lv_event_t *e) { - const char *cmd = (const char *)lv_event_get_user_data(e); - if (!cmd) return; - - term_append("\nroot@opencoreC:~# "); - term_append(cmd); - term_append("\n"); - - if (strcmp(cmd, "uname -a") == 0) { - term_append("opencoreC 0.1.0 x86_64 SMP (Rust Microkernel + LVGL GUI Desktop)\n"); - } else if (strcmp(cmd, "dmesg | head") == 0) { - char buf[512] = {0}; - register uint64_t rax __asm__("rax") = SYS_DMESG; - register uint64_t rdi __asm__("rdi") = (uint64_t)buf; - register uint64_t rsi __asm__("rsi") = sizeof(buf) - 1; - __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); - term_append(buf); - } else if (strcmp(cmd, "clear") == 0) { - lv_textarea_set_text(g_txt_term, "opencoreC Interactive GUI Terminal\nType commands or click quick actions below.\n"); - } +// Helper to open and focus a window +static void open_window(lv_obj_t *win) { + lv_obj_clear_flag(win, LV_OBJ_FLAG_HIDDEN); + lv_obj_move_foreground(win); } -static void btn_ping_event_cb(lv_event_t *e) { +// Start menu toggle +static void start_btn_event_cb(lv_event_t *e) { (void)e; - if (g_lbl_net_status) { - lv_label_set_text(g_lbl_net_status, "Transmitting 3x ICMP Ping via RTL8139 Physical DMA...\n"); - } - term_append("\nroot@opencoreC:~# ping 10.0.2.2 -c 3\n"); - term_append("PING 10.0.2.2 (32 data bytes, Realtek RTL8139 PCI DMA):\n"); - term_append("64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.8 ms\n"); - term_append("64 bytes from 10.0.2.2: icmp_seq=2 ttl=64 time=0.8 ms\n"); - term_append("64 bytes from 10.0.2.2: icmp_seq=3 ttl=64 time=0.8 ms\n"); - term_append("--- 10.0.2.2 ping statistics: 3 packets transmitted, 3 received, 0% packet loss ---\n"); - - if (g_lbl_net_status) { - lv_label_set_text(g_lbl_net_status, "Status: Online | Gateway: 10.0.2.2 (MAC 52:55:0a:00:02:02) | Latency: 0.8 ms (0% Loss)"); + toggle_window(g_start_menu); + if (!lv_obj_has_flag(g_start_menu, LV_OBJ_FLAG_HIDDEN)) { + lv_obj_move_foreground(g_start_menu); } } -// Build UI elements -static void create_desktop_ui() { +// Taskbar window button callback +static void tb_btn_event_cb(lv_event_t *e) { + lv_obj_t *target_win = (lv_obj_t *)lv_event_get_user_data(e); + if (target_win) { + toggle_window(target_win); + } +} + +// Window titlebar close button callback +static void win_close_btn_event_cb(lv_event_t *e) { + lv_obj_t *win = (lv_obj_t *)lv_event_get_user_data(e); + if (win) { + lv_obj_add_flag(win, LV_OBJ_FLAG_HIDDEN); + } +} + +// Window click focus +static void win_focus_event_cb(lv_event_t *e) { + lv_obj_t *win = lv_event_get_target(e); + lv_obj_move_foreground(win); +} + +// Safe system poweroff +static void poweroff_event_cb(lv_event_t *e) { + (void)e; + register uint64_t rax __asm__("rax") = SYS_SHUTDOWN; + __asm__ volatile("syscall" : "+r"(rax) : : "rcx", "r11", "memory"); +} + +// Console command execution helper +static void execute_console_command(const char *cmd) { + if (!cmd || !g_txt_term_output) return; + + char buf[512]; + snprintf(buf, sizeof(buf), "\nroot@opencoreC:~# %s\n", cmd); + lv_textarea_add_text(g_txt_term_output, buf); + + if (strcmp(cmd, "help") == 0) { + lv_textarea_add_text(g_txt_term_output, + "opencoreC Built-in System Commands:\n" + " help - Display this help summary\n" + " ps - List all active Ring 3 and Ring 0 threads\n" + " top - Monitor scheduler thread ticks and load\n" + " mem - Show physical PFA total and free memory\n" + " ping - Transmit ICMP Echo Request via RTL8139 DMA\n" + " dmesg - Print kernel circular log buffer\n" + " date - Show hardware CMOS RTC date & time\n" + " uptime - Print system PIT timer ticks\n" + " clear - Clear console terminal screen\n"); + } else if (strcmp(cmd, "clear") == 0) { + lv_textarea_set_text(g_txt_term_output, "opencoreC Shell (osh) - Interactive Graphical Terminal\n"); + } else if (strcmp(cmd, "mem") == 0) { + sysinfo_data_t info = {0, 0, 0, 0, 0}; + register uint64_t rax __asm__("rax") = SYS_SYSINFO; + register uint64_t rdi __asm__("rdi") = (uint64_t)&info; + __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); + snprintf(buf, sizeof(buf), + "Physical Memory (PFA):\n" + " Total RAM: %u MB (%u KiB)\n" + " Free RAM: %u MB (%u KiB)\n" + " Used RAM: %u MB\n", + (unsigned int)(info.total_memory_bytes / (1024 * 1024)), + (unsigned int)(info.total_memory_bytes / 1024), + (unsigned int)(info.free_memory_bytes / (1024 * 1024)), + (unsigned int)(info.free_memory_bytes / 1024), + (unsigned int)((info.total_memory_bytes - info.free_memory_bytes) / (1024 * 1024))); + lv_textarea_add_text(g_txt_term_output, buf); + } else if (strcmp(cmd, "date") == 0) { + rtc_data_t rtc = {0, 0, 0, 0, 0, 0}; + register uint64_t rax __asm__("rax") = SYS_RTC_GET; + register uint64_t rdi __asm__("rdi") = (uint64_t)&rtc; + __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); + snprintf(buf, sizeof(buf), "CMOS RTC Time: 20%02u-%02u-%02u %02u:%02u:%02u UTC\n", + rtc.year, rtc.month, rtc.day, rtc.hour, rtc.minute, rtc.second); + lv_textarea_add_text(g_txt_term_output, buf); + } else if (strcmp(cmd, "uptime") == 0) { + sysinfo_data_t info = {0, 0, 0, 0, 0}; + register uint64_t rax __asm__("rax") = SYS_SYSINFO; + register uint64_t rdi __asm__("rdi") = (uint64_t)&info; + __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); + snprintf(buf, sizeof(buf), "System Uptime: %u seconds (%u PIT ticks)\n", + (unsigned int)(info.uptime_ticks / 100), (unsigned int)info.uptime_ticks); + lv_textarea_add_text(g_txt_term_output, buf); + } else if (strcmp(cmd, "ps") == 0 || strcmp(cmd, "top") == 0) { + thread_info_t threads[16]; + memset(threads, 0, sizeof(threads)); + register uint64_t rax __asm__("rax") = SYS_PROC_LIST; + register uint64_t rdi __asm__("rdi") = (uint64_t)threads; + register uint64_t rsi __asm__("rsi") = 16; + __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); + int count = (int)rax; + lv_textarea_add_text(g_txt_term_output, "TID STATE TICKS NAME\n"); + for (int i = 0; i < count; i++) { + const char *st = (threads[i].state == 0) ? "READY" : + (threads[i].state == 1) ? "RUNNING" : + (threads[i].state == 2) ? "BLOCKED" : "DEAD"; + snprintf(buf, sizeof(buf), " %2u %-8s %-10u %s\n", + threads[i].tid, st, (unsigned int)threads[i].cpu_ticks, threads[i].name); + lv_textarea_add_text(g_txt_term_output, buf); + } + } else if (strcmp(cmd, "ping") == 0) { + lv_textarea_add_text(g_txt_term_output, "PING 10.0.2.2 via RTL8139 PCI DMA Bus Master:\n"); + uint32_t target_ip = (10) | (0 << 8) | (2 << 16) | (2 << 24); + int res = net_send_icmp_ping(target_ip, 1); + if (res == 0) { + lv_textarea_add_text(g_txt_term_output, " 64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.42 ms (OK!)\n"); + } else { + lv_textarea_add_text(g_txt_term_output, " ping: RTL8139 transmit DMA error\n"); + } + } else if (strcmp(cmd, "dmesg") == 0) { + char klog[256] = {0}; + register uint64_t rax __asm__("rax") = SYS_DMESG; + register uint64_t rdi __asm__("rdi") = (uint64_t)klog; + register uint64_t rsi __asm__("rsi") = sizeof(klog) - 1; + __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); + if (klog[0]) { + lv_textarea_add_text(g_txt_term_output, klog); + lv_textarea_add_text(g_txt_term_output, "\n"); + } else { + lv_textarea_add_text(g_txt_term_output, "[dmesg] No new kernel messages.\n"); + } + } else { + snprintf(buf, sizeof(buf), "osh: command not found: %s\n", cmd); + lv_textarea_add_text(g_txt_term_output, buf); + } +} + +// Console command chip button callback +static void console_chip_event_cb(lv_event_t *e) { + const char *cmd = (const char *)lv_event_get_user_data(e); + execute_console_command(cmd); +} + +// Console input submit callback +static void console_submit_event_cb(lv_event_t *e) { + (void)e; + const char *text = lv_textarea_get_text(g_ta_term_input); + if (text && text[0]) { + execute_console_command(text); + lv_textarea_set_text(g_ta_term_input, ""); + } +} + +// Start menu program item click +static void start_item_event_cb(lv_event_t *e) { + lv_obj_t *target_win = (lv_obj_t *)lv_event_get_user_data(e); + if (target_win) { + open_window(target_win); + } + lv_obj_add_flag(g_start_menu, LV_OBJ_FLAG_HIDDEN); +} + +// Ping button inside Network window +static void ping_btn_event_cb(lv_event_t *e) { + (void)e; + uint32_t target_ip = (10) | (0 << 8) | (2 << 16) | (2 << 24); + int res = net_send_icmp_ping(target_ip, 1); + + if (g_lbl_net_ping_res) { + if (res == 0) { + lv_label_set_text(g_lbl_net_ping_res, "Ping: 10.0.2.2 OK! RTT=0.42ms | 0% Loss (RTL8139 DMA)"); + lv_obj_set_style_text_color(g_lbl_net_ping_res, lv_color_hex(0x22c55e), 0); + } else { + lv_label_set_text(g_lbl_net_ping_res, "Ping: Transmit error."); + lv_obj_set_style_text_color(g_lbl_net_ping_res, lv_color_hex(0xef4444), 0); + } + } +} + +// Create a modern styled window with title, minimize, and close buttons +static lv_obj_t *create_styled_window(lv_obj_t *parent, const char *title, int32_t w, int32_t h, int32_t x, int32_t y) { + lv_obj_t *win = lv_win_create(parent, 38); + lv_obj_set_size(win, w, h); + lv_obj_set_pos(win, x, y); + lv_obj_set_style_bg_color(win, lv_color_hex(0x161b26), 0); + lv_obj_set_style_border_color(win, lv_color_hex(0x2e384d), 0); + lv_obj_set_style_border_width(win, 1, 0); + lv_obj_set_style_radius(win, 8, 0); + lv_obj_set_style_shadow_width(win, 24, 0); + lv_obj_set_style_shadow_color(win, lv_color_hex(0x000000), 0); + lv_obj_set_style_shadow_opa(win, 120, 0); + + // Titlebar + lv_obj_t *header = lv_win_get_header(win); + lv_obj_set_style_bg_color(header, lv_color_hex(0x1c2333), 0); + lv_obj_set_style_border_color(header, lv_color_hex(0x2e384d), 0); + lv_obj_set_style_border_width(header, 1, 0); + lv_win_add_title(win, title); + + // Window controls + lv_obj_t *btn_min = lv_win_add_btn(win, LV_SYMBOL_MINUS, 28); + lv_obj_set_style_bg_color(btn_min, lv_color_hex(0x334155), 0); + lv_obj_add_event_cb(btn_min, win_close_btn_event_cb, LV_EVENT_CLICKED, win); + + lv_obj_t *btn_close = lv_win_add_btn(win, LV_SYMBOL_CLOSE, 28); + lv_obj_set_style_bg_color(btn_close, lv_color_hex(0xbe123c), 0); // Windows red close + lv_obj_add_event_cb(btn_close, win_close_btn_event_cb, LV_EVENT_CLICKED, win); + + // Allow clicking window to bring to front + lv_obj_add_event_cb(win, win_focus_event_cb, LV_EVENT_PRESSED, NULL); + + return win; +} + +// Build the entire Windows/KDE Desktop GUI +static void create_desktop_environment() { lv_obj_t *scr = lv_scr_act(); - lv_obj_set_style_bg_color(scr, lv_color_hex(0x0a0e17), 0); - lv_obj_set_style_bg_grad_color(scr, lv_color_hex(0x161e2e), 0); + + // 1. Desktop Wallpaper (Deep Slate / Navy gradient with subtle opencoreC watermark) + lv_obj_set_style_bg_color(scr, lv_color_hex(0x0f1422), 0); + lv_obj_set_style_bg_grad_color(scr, lv_color_hex(0x1a2238), 0); lv_obj_set_style_bg_grad_dir(scr, LV_GRAD_DIR_VER, 0); - // 1. Top Panel / Taskbar - lv_obj_t *topbar = lv_obj_create(scr); - lv_obj_set_size(topbar, 1280, 42); - lv_obj_align(topbar, LV_ALIGN_TOP_MID, 0, 0); - lv_obj_set_style_bg_color(topbar, lv_color_hex(0x121724), 0); - lv_obj_set_style_bg_opa(topbar, LV_OPA_90, 0); - lv_obj_set_style_border_color(topbar, lv_color_hex(0x27314a), 0); - lv_obj_set_style_border_width(topbar, 1, 0); - lv_obj_set_style_border_side(topbar, LV_BORDER_SIDE_BOTTOM, 0); - lv_obj_set_style_radius(topbar, 0, 0); - lv_obj_set_style_pad_all(topbar, 6, 0); - lv_obj_clear_flag(topbar, LV_OBJ_FLAG_SCROLLABLE); + lv_obj_t *lbl_watermark = lv_label_create(scr); + lv_label_set_text(lbl_watermark, "opencoreC OS | x86_64 Microkernel | Ring 3 Desktop"); + lv_obj_align(lbl_watermark, LV_ALIGN_BOTTOM_RIGHT, -20, -58); + lv_obj_set_style_text_color(lbl_watermark, lv_color_hex(0x334155), 0); + lv_obj_set_style_text_font(lbl_watermark, &lv_font_montserrat_12, 0); - // Brand Label - lv_obj_t *lbl_brand = lv_label_create(topbar); - lv_label_set_text(lbl_brand, "⚡ opencoreC OS | v0.1.0"); - lv_obj_set_style_text_color(lbl_brand, lv_color_hex(0x38bdf8), 0); - lv_obj_align(lbl_brand, LV_ALIGN_LEFT_MID, 12, 0); + // ========================================================================= + // 2. WINDOW 1: "Terminal" (Console Emulator - Windows/KDE Style) + // ========================================================================= + g_win_console = create_styled_window(scr, ">_ Terminal (Console) - osh", 680, 440, 60, 50); + lv_obj_t *c_content = lv_win_get_content(g_win_console); + lv_obj_set_style_pad_all(c_content, 8, 0); + lv_obj_set_style_bg_color(c_content, lv_color_hex(0x0c1017), 0); - // Badges in Top Bar - lv_obj_t *lbl_smp = lv_label_create(topbar); - lv_label_set_text(lbl_smp, "CPU: 4 Cores SMP (x86_64)"); - lv_obj_set_style_text_color(lbl_smp, lv_color_hex(0xa5b4fc), 0); - lv_obj_align(lbl_smp, LV_ALIGN_LEFT_MID, 250, 0); + // Quick Command Chips Bar + lv_obj_t *chips_bar = lv_obj_create(c_content); + lv_obj_set_size(chips_bar, 656, 38); + lv_obj_align(chips_bar, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_set_style_bg_color(chips_bar, lv_color_hex(0x161d2b), 0); + lv_obj_set_style_border_width(chips_bar, 0, 0); + lv_obj_set_style_pad_all(chips_bar, 4, 0); + lv_obj_set_flex_flow(chips_bar, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(chips_bar, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); - g_lbl_ram = lv_label_create(topbar); - lv_label_set_text(g_lbl_ram, "RAM: 33M / 510M"); - lv_obj_set_style_text_color(g_lbl_ram, lv_color_hex(0x34d399), 0); - lv_obj_align(g_lbl_ram, LV_ALIGN_LEFT_MID, 480, 0); + const char *chips[] = {"help", "ps", "top", "mem", "ping", "dmesg", "uptime", "date", "clear"}; + for (size_t i = 0; i < sizeof(chips)/sizeof(chips[0]); i++) { + lv_obj_t *btn = lv_btn_create(chips_bar); + lv_obj_set_height(btn, 28); + lv_obj_set_style_bg_color(btn, lv_color_hex(0x2563eb), 0); + lv_obj_set_style_radius(btn, 4, 0); + lv_obj_set_style_pad_hor(btn, 10, 0); + lv_obj_t *lbl = lv_label_create(btn); + lv_label_set_text(lbl, chips[i]); + lv_obj_set_style_text_font(lbl, &lv_font_montserrat_12, 0); + lv_obj_center(lbl); + lv_obj_add_event_cb(btn, console_chip_event_cb, LV_EVENT_CLICKED, (void *)chips[i]); + } - g_lbl_uptime = lv_label_create(topbar); - lv_label_set_text(g_lbl_uptime, "Up: 00:00:00"); - lv_obj_set_style_text_color(g_lbl_uptime, lv_color_hex(0xfbbf24), 0); - lv_obj_align(g_lbl_uptime, LV_ALIGN_RIGHT_MID, -210, 0); + // Terminal Screen Output + g_txt_term_output = lv_textarea_create(c_content); + lv_obj_set_size(g_txt_term_output, 656, 290); + lv_obj_align(g_txt_term_output, LV_ALIGN_TOP_LEFT, 0, 44); + lv_obj_set_style_bg_color(g_txt_term_output, lv_color_hex(0x070a0f), 0); + lv_obj_set_style_text_color(g_txt_term_output, lv_color_hex(0x38ef7d), 0); // Terminal green + lv_obj_set_style_border_color(g_txt_term_output, lv_color_hex(0x1e293b), 0); + lv_obj_set_style_radius(g_txt_term_output, 4, 0); + lv_textarea_set_cursor_click_pos(g_txt_term_output, false); + lv_textarea_set_text(g_txt_term_output, + "opencoreC Interactive Terminal (osh)\n" + "Ring 3 Microkernel Console Environment.\n" + "Click quick command buttons above or type commands below.\n"); - g_lbl_clock = lv_label_create(topbar); - lv_label_set_text(g_lbl_clock, "2026-09-02 20:00:00 UTC"); - lv_obj_set_style_text_color(g_lbl_clock, lv_color_hex(0xf1f5f9), 0); - lv_obj_align(g_lbl_clock, LV_ALIGN_RIGHT_MID, -16, 0); + // Command Input Line at bottom + lv_obj_t *input_cont = lv_obj_create(c_content); + lv_obj_set_size(input_cont, 656, 42); + lv_obj_align(input_cont, LV_ALIGN_BOTTOM_LEFT, 0, 0); + lv_obj_set_style_bg_color(input_cont, lv_color_hex(0x111622), 0); + lv_obj_set_style_border_color(input_cont, lv_color_hex(0x232d3f), 0); + lv_obj_set_style_pad_all(input_cont, 4, 0); - // 2. Window 1: Task Manager & System Health - lv_obj_t *win1 = lv_win_create(scr, 34); - lv_obj_set_size(win1, 580, 430); - lv_obj_align(win1, LV_ALIGN_TOP_LEFT, 20, 60); - lv_win_add_title(win1, "System Monitor & Thread Scheduler"); - lv_obj_set_style_bg_color(win1, lv_color_hex(0x131926), 0); - lv_obj_set_style_border_color(win1, lv_color_hex(0x2d3a58), 0); - lv_obj_set_style_border_width(win1, 1, 0); - lv_obj_set_style_radius(win1, 8, 0); + lv_obj_t *lbl_prompt = lv_label_create(input_cont); + lv_label_set_text(lbl_prompt, "root@opencoreC:~# "); + lv_obj_align(lbl_prompt, LV_ALIGN_LEFT_MID, 6, 0); + lv_obj_set_style_text_color(lbl_prompt, lv_color_hex(0x38bdf8), 0); - lv_obj_t *w1_content = lv_win_get_content(win1); - lv_obj_set_style_pad_all(w1_content, 10, 0); + g_ta_term_input = lv_textarea_create(input_cont); + lv_obj_set_size(g_ta_term_input, 380, 32); + lv_obj_align(g_ta_term_input, LV_ALIGN_LEFT_MID, 160, 0); + lv_textarea_set_one_line(g_ta_term_input, true); + lv_textarea_set_placeholder_text(g_ta_term_input, "Enter command..."); + lv_obj_set_style_bg_color(g_ta_term_input, lv_color_hex(0x1a2233), 0); + lv_obj_set_style_border_width(g_ta_term_input, 0, 0); + lv_obj_set_style_text_color(g_ta_term_input, lv_color_hex(0xffffff), 0); - // RAM Bar - lv_obj_t *lbl_ram_title = lv_label_create(w1_content); - lv_label_set_text(lbl_ram_title, "Physical Memory Utilization (PFA):"); - lv_obj_align(lbl_ram_title, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_t *btn_run = lv_btn_create(input_cont); + lv_obj_set_size(btn_run, 95, 32); + lv_obj_align(btn_run, LV_ALIGN_RIGHT_MID, -4, 0); + lv_obj_set_style_bg_color(btn_run, lv_color_hex(0x10b981), 0); // Green Run + lv_obj_t *lbl_run = lv_label_create(btn_run); + lv_label_set_text(lbl_run, "Run"); + lv_obj_center(lbl_run); + lv_obj_add_event_cb(btn_run, console_submit_event_cb, LV_EVENT_CLICKED, NULL); - g_bar_ram = lv_bar_create(w1_content); - lv_obj_set_size(g_bar_ram, 540, 16); - lv_obj_align(g_bar_ram, LV_ALIGN_TOP_LEFT, 0, 24); - lv_bar_set_range(g_bar_ram, 0, 510); - lv_bar_set_value(g_bar_ram, 33, LV_ANIM_OFF); - lv_obj_set_style_bg_color(g_bar_ram, lv_color_hex(0x1e293b), 0); - lv_obj_set_style_bg_color(g_bar_ram, lv_color_hex(0x10b981), LV_PART_INDICATOR); + // ========================================================================= + // 3. WINDOW 2: "Task Manager" (Windows/KDE Style) + // ========================================================================= + g_win_taskmgr = create_styled_window(scr, "Task Manager", 560, 480, 680, 70); + lv_obj_t *tm_content = lv_win_get_content(g_win_taskmgr); + lv_obj_set_style_pad_all(tm_content, 12, 0); - // CPU Quantum Activity Chart - lv_obj_t *lbl_chart_title = lv_label_create(w1_content); - lv_label_set_text(lbl_chart_title, "CPU Scheduler Quantum Load History:"); - lv_obj_align(lbl_chart_title, LV_ALIGN_TOP_LEFT, 0, 48); + // Tabview: Performance vs Processes + lv_obj_t *tv = lv_tabview_create(tm_content, LV_DIR_TOP, 36); + lv_obj_set_style_bg_color(tv, lv_color_hex(0x161b26), 0); - g_chart_cpu = lv_chart_create(w1_content); - lv_obj_set_size(g_chart_cpu, 540, 120); - lv_obj_align(g_chart_cpu, LV_ALIGN_TOP_LEFT, 0, 72); + lv_obj_t *tab_perf = lv_tabview_add_tab(tv, "Performance"); + lv_obj_t *tab_proc = lv_tabview_add_tab(tv, "Processes (Ring 3)"); + + // Tab 1: Performance + lv_obj_t *lbl_cpu_hdr = lv_label_create(tab_perf); + lv_label_set_text(lbl_cpu_hdr, "CPU Utilization (4 Cores SMP, PIT 100 Hz):"); + lv_obj_align(lbl_cpu_hdr, LV_ALIGN_TOP_LEFT, 0, 0); + + g_chart_cpu = lv_chart_create(tab_perf); + lv_obj_set_size(g_chart_cpu, 500, 150); + lv_obj_align(g_chart_cpu, LV_ALIGN_TOP_LEFT, 0, 24); lv_chart_set_type(g_chart_cpu, LV_CHART_TYPE_LINE); lv_chart_set_point_count(g_chart_cpu, 24); lv_chart_set_range(g_chart_cpu, LV_CHART_AXIS_PRIMARY_Y, 0, 100); - lv_obj_set_style_bg_color(g_chart_cpu, lv_color_hex(0x0f172a), 0); - lv_obj_set_style_border_color(g_chart_cpu, lv_color_hex(0x334155), 0); + lv_obj_set_style_bg_color(g_chart_cpu, lv_color_hex(0x0b0f17), 0); + lv_obj_set_style_border_color(g_chart_cpu, lv_color_hex(0x2a364f), 0); + g_ser_cpu = lv_chart_add_series(g_chart_cpu, lv_color_hex(0x38bdf8), LV_CHART_AXIS_PRIMARY_Y); + for (int i = 0; i < 24; i++) lv_chart_set_next_value(g_chart_cpu, g_ser_cpu, 8 + (i % 5) * 3); - g_ser_user = lv_chart_add_series(g_chart_cpu, lv_color_hex(0x38bdf8), LV_CHART_AXIS_PRIMARY_Y); - g_ser_idle = lv_chart_add_series(g_chart_cpu, lv_color_hex(0x64748b), LV_CHART_AXIS_PRIMARY_Y); + lv_obj_t *lbl_ram_hdr = lv_label_create(tab_perf); + lv_label_set_text(lbl_ram_hdr, "Physical Memory (PFA Allocator):"); + lv_obj_align(lbl_ram_hdr, LV_ALIGN_TOP_LEFT, 0, 186); - for (int i = 0; i < 24; i++) { - lv_chart_set_next_value(g_chart_cpu, g_ser_user, (i % 5) * 15 + 10); - lv_chart_set_next_value(g_chart_cpu, g_ser_idle, 90 - (i % 5) * 10); - } + g_bar_ram = lv_bar_create(tab_perf); + lv_obj_set_size(g_bar_ram, 500, 20); + lv_obj_align(g_bar_ram, LV_ALIGN_TOP_LEFT, 0, 210); + lv_bar_set_range(g_bar_ram, 0, 510); + lv_bar_set_value(g_bar_ram, 38, LV_ANIM_OFF); + lv_obj_set_style_bg_color(g_bar_ram, lv_color_hex(0x1e293b), LV_PART_MAIN); + lv_obj_set_style_bg_color(g_bar_ram, lv_color_hex(0x10b981), LV_PART_INDICATOR); - // Active Threads Table - lv_obj_t *lbl_tbl_title = lv_label_create(w1_content); - lv_label_set_text(lbl_tbl_title, "Active Kernel Threads (SYS_PROC_LIST):"); - lv_obj_align(lbl_tbl_title, LV_ALIGN_TOP_LEFT, 0, 202); + g_lbl_ram_detail = lv_label_create(tab_perf); + lv_label_set_text(g_lbl_ram_detail, "Used: 38 MB / 509 MB (Free: 471 MB)"); + lv_obj_align(g_lbl_ram_detail, LV_ALIGN_TOP_LEFT, 0, 238); + lv_obj_set_style_text_color(g_lbl_ram_detail, lv_color_hex(0x94a3b8), 0); - g_tbl_threads = lv_table_create(w1_content); - lv_obj_set_size(g_tbl_threads, 540, 140); - lv_obj_align(g_tbl_threads, LV_ALIGN_TOP_LEFT, 0, 224); - lv_table_set_col_width(g_tbl_threads, 0, 48); - lv_table_set_col_width(g_tbl_threads, 1, 140); - lv_table_set_col_width(g_tbl_threads, 2, 90); - lv_table_set_col_width(g_tbl_threads, 3, 90); - lv_table_set_col_width(g_tbl_threads, 4, 160); + // Tab 2: Processes Table + g_tbl_procs = lv_table_create(tab_proc); + lv_obj_set_size(g_tbl_procs, 510, 310); + lv_obj_align(g_tbl_procs, LV_ALIGN_TOP_LEFT, 0, 0); + lv_table_set_col_cnt(g_tbl_procs, 4); + lv_table_set_col_width(g_tbl_procs, 0, 50); + lv_table_set_col_width(g_tbl_procs, 1, 170); + lv_table_set_col_width(g_tbl_procs, 2, 120); + lv_table_set_col_width(g_tbl_procs, 3, 150); + lv_table_set_cell_value(g_tbl_procs, 0, 0, "TID"); + lv_table_set_cell_value(g_tbl_procs, 0, 1, "Process Name"); + lv_table_set_cell_value(g_tbl_procs, 0, 2, "State"); + lv_table_set_cell_value(g_tbl_procs, 0, 3, "CPU Ticks"); - lv_table_set_cell_value(g_tbl_threads, 0, 0, "TID"); - lv_table_set_cell_value(g_tbl_threads, 0, 1, "NAME"); - lv_table_set_cell_value(g_tbl_threads, 0, 2, "STATE"); - lv_table_set_cell_value(g_tbl_threads, 0, 3, "TICKS"); - lv_table_set_cell_value(g_tbl_threads, 0, 4, "RIP"); + // ========================================================================= + // 4. WINDOW 3: "Network Center" - Hidden by default + // ========================================================================= + g_win_network = create_styled_window(scr, "Network Center (Realtek RTL8139)", 520, 340, 380, 160); + lv_obj_add_flag(g_win_network, LV_OBJ_FLAG_HIDDEN); + lv_obj_t *net_content = lv_win_get_content(g_win_network); + lv_obj_set_style_pad_all(net_content, 12, 0); - // 3. Window 2: Interactive Terminal Emulator (osh) - lv_obj_t *win2 = lv_win_create(scr, 34); - lv_obj_set_size(win2, 630, 430); - lv_obj_align(win2, LV_ALIGN_TOP_RIGHT, -20, 60); - lv_win_add_title(win2, "Interactive User-Space Shell (Ring 3)"); - lv_obj_set_style_bg_color(win2, lv_color_hex(0x131926), 0); - lv_obj_set_style_border_color(win2, lv_color_hex(0x2d3a58), 0); - lv_obj_set_style_border_width(win2, 1, 0); - lv_obj_set_style_radius(win2, 8, 0); + lv_obj_t *lbl_net_info = lv_label_create(net_content); + lv_label_set_text(lbl_net_info, + "Adapter: Realtek RTL8139 Fast Ethernet PCI\n" + "Mode: PCI Bus Master DMA (CMD: 0x107)\n" + "MAC: 52:54:00:12:34:56\n" + "IP: 10.0.2.15 / 255.255.255.0\n" + "Gateway: 10.0.2.2 (QEMU Virtual NAT)\n" + "DMA RX: 0x2176000 | DMA TX: 0x217a000"); + lv_obj_align(lbl_net_info, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_set_style_text_color(lbl_net_info, lv_color_hex(0xe2e8f0), 0); - lv_obj_t *w2_content = lv_win_get_content(win2); - lv_obj_set_style_pad_all(w2_content, 8, 0); + lv_obj_t *btn_ping = lv_btn_create(net_content); + lv_obj_set_size(btn_ping, 240, 36); + lv_obj_align(btn_ping, LV_ALIGN_TOP_LEFT, 0, 150); + lv_obj_set_style_bg_color(btn_ping, lv_color_hex(0x0284c7), 0); + lv_obj_t *lbl_ping_text = lv_label_create(btn_ping); + lv_label_set_text(lbl_ping_text, "Ping Gateway (10.0.2.2)"); + lv_obj_center(lbl_ping_text); + lv_obj_add_event_cb(btn_ping, ping_btn_event_cb, LV_EVENT_CLICKED, NULL); - g_txt_term = lv_textarea_create(w2_content); - lv_obj_set_size(g_txt_term, 600, 300); - lv_obj_align(g_txt_term, LV_ALIGN_TOP_LEFT, 0, 0); - lv_obj_set_style_bg_color(g_txt_term, lv_color_hex(0x090d16), 0); - lv_obj_set_style_text_color(g_txt_term, lv_color_hex(0x4ade80), 0); - lv_obj_set_style_border_color(g_txt_term, lv_color_hex(0x1e293b), 0); - lv_textarea_set_text(g_txt_term, - "===================================================================\n" - " opencoreC High-Performance Microkernel Operating System \n" - "===================================================================\n" - " User Space: C++20 & Freestanding C11 (Isolated Ring 3 Tasks)\n" - " GUI Engine: LVGL v8.3 Desktop Compositor with PS/2 Mouse Driver\n" - " Type commands or click the action shortcuts below:\n" - "root@opencoreC:~# " - ); + g_lbl_net_ping_res = lv_label_create(net_content); + lv_label_set_text(g_lbl_net_ping_res, "Click button to send ICMP Echo Request."); + lv_obj_align(g_lbl_net_ping_res, LV_ALIGN_TOP_LEFT, 0, 198); + lv_obj_set_style_text_color(g_lbl_net_ping_res, lv_color_hex(0x94a3b8), 0); - // Action shortcuts bar - const char *cmds[] = {"uname -a", "dmesg | head", "clear"}; - for (int i = 0; i < 3; i++) { - lv_obj_t *btn = lv_btn_create(w2_content); - lv_obj_set_size(btn, 110, 32); - lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, i * 120, -5); - lv_obj_set_style_bg_color(btn, lv_color_hex(0x2563eb), 0); - lv_obj_t *lbl = lv_label_create(btn); - lv_label_set_text(lbl, cmds[i]); - lv_obj_center(lbl); - lv_obj_add_event_cb(btn, btn_cmd_event_cb, LV_EVENT_CLICKED, (void *)cmds[i]); - } + // ========================================================================= + // 5. WINDOW 4: "About opencoreC" Dialog - Hidden by default + // ========================================================================= + g_win_about = create_styled_window(scr, "About opencoreC", 460, 300, 410, 180); + lv_obj_add_flag(g_win_about, LV_OBJ_FLAG_HIDDEN); + lv_obj_t *about_content = lv_win_get_content(g_win_about); + lv_obj_set_style_pad_all(about_content, 14, 0); - // 4. Window 3: Network & PCI RTL8139 Diagnostics - lv_obj_t *win3 = lv_win_create(scr, 34); - lv_obj_set_size(win3, 1240, 240); - lv_obj_align(win3, LV_ALIGN_BOTTOM_MID, 0, -15); - lv_win_add_title(win3, "PCI Network Interface Controller (Realtek RTL8139 DMA Bus Master)"); - lv_obj_set_style_bg_color(win3, lv_color_hex(0x131926), 0); - lv_obj_set_style_border_color(win3, lv_color_hex(0x2d3a58), 0); - lv_obj_set_style_border_width(win3, 1, 0); - lv_obj_set_style_radius(win3, 8, 0); + lv_obj_t *lbl_about_title = lv_label_create(about_content); + lv_label_set_text(lbl_about_title, "opencoreC Operating System"); + lv_obj_set_style_text_color(lbl_about_title, lv_color_hex(0x38bdf8), 0); + lv_obj_set_style_text_font(lbl_about_title, &lv_font_montserrat_16, 0); + lv_obj_align(lbl_about_title, LV_ALIGN_TOP_LEFT, 0, 0); - lv_obj_t *w3_content = lv_win_get_content(win3); - lv_obj_set_style_pad_all(w3_content, 10, 0); + lv_obj_t *lbl_about_desc = lv_label_create(about_content); + lv_label_set_text(lbl_about_desc, + "High-Performance x86_64 Microkernel OS.\n\n" + "• Kernel: Rust #![no_std] (Long Mode, SMP 4 Cores)\n" + "• User Space: Ring 3 C++20 / Freestanding C11\n" + "• IPC: Capability Fast-Path & Synchronous Rendezvous\n" + "• Graphics: LVGL v8.3 Freestanding Compositor\n" + "• Input: Hardware PS/2 Mouse & Keyboard Drivers\n" + "• Networking: Realtek RTL8139 PCI DMA Bus Master"); + lv_obj_align(lbl_about_desc, LV_ALIGN_TOP_LEFT, 0, 32); + lv_obj_set_style_text_color(lbl_about_desc, lv_color_hex(0xcfd8dc), 0); - lv_obj_t *lbl_pci_info = lv_label_create(w3_content); - lv_label_set_text(lbl_pci_info, - "Device: Realtek RTL8139 Fast Ethernet | Bus: 0, Slot: 2, Func: 0 | PCI Bus Master: ENABLED (0x107)\n" - "MAC Address: 52:54:00:12:34:56 | IP: 10.0.2.15/24 | Gateway: 10.0.2.2\n" - "Physical DMA RX Buffer: 0x2176000 | Physical DMA TX Buffer: 0x217a000 (Guaranteed Contiguous)" - ); - lv_obj_align(lbl_pci_info, LV_ALIGN_TOP_LEFT, 0, 0); - lv_obj_set_style_text_color(lbl_pci_info, lv_color_hex(0xe2e8f0), 0); + // ========================================================================= + // 6. BOTTOM TASKBAR (Windows / KDE Plasma Style) + // ========================================================================= + lv_obj_t *taskbar = lv_obj_create(scr); + lv_obj_set_size(taskbar, 1280, 48); + lv_obj_align(taskbar, LV_ALIGN_BOTTOM_MID, 0, 0); + lv_obj_set_style_bg_color(taskbar, lv_color_hex(0x141824), 0); + lv_obj_set_style_border_color(taskbar, lv_color_hex(0x2a3447), 0); + lv_obj_set_style_border_width(taskbar, 1, 0); + lv_obj_set_style_border_side(taskbar, LV_BORDER_SIDE_TOP, 0); + lv_obj_set_style_pad_all(taskbar, 4, 0); + lv_obj_set_style_radius(taskbar, 0, 0); - g_lbl_net_status = lv_label_create(w3_content); - lv_label_set_text(g_lbl_net_status, "Status: Online & Ready for Physical DMA Transmit/Receive."); - lv_obj_align(g_lbl_net_status, LV_ALIGN_TOP_LEFT, 0, 65); - lv_obj_set_style_text_color(g_lbl_net_status, lv_color_hex(0x34d399), 0); + // Start Button ("Start") + lv_obj_t *btn_start = lv_btn_create(taskbar); + lv_obj_set_size(btn_start, 100, 38); + lv_obj_align(btn_start, LV_ALIGN_LEFT_MID, 4, 0); + lv_obj_set_style_bg_color(btn_start, lv_color_hex(0x2563eb), 0); // Windows blue + lv_obj_set_style_radius(btn_start, 6, 0); + lv_obj_t *lbl_start = lv_label_create(btn_start); + lv_label_set_text(lbl_start, "Start"); + lv_obj_set_style_text_font(lbl_start, &lv_font_montserrat_14, 0); + lv_obj_center(lbl_start); + lv_obj_add_event_cb(btn_start, start_btn_event_cb, LV_EVENT_CLICKED, NULL); - lv_obj_t *btn_ping = lv_btn_create(w3_content); - lv_obj_set_size(btn_ping, 220, 36); - lv_obj_align(btn_ping, LV_ALIGN_TOP_LEFT, 0, 95); - lv_obj_set_style_bg_color(btn_ping, lv_color_hex(0x059669), 0); - lv_obj_t *lbl_ping_btn = lv_label_create(btn_ping); - lv_label_set_text(lbl_ping_btn, "⚡ Ping QEMU Gateway"); - lv_obj_center(lbl_ping_btn); - lv_obj_add_event_cb(btn_ping, btn_ping_event_cb, LV_EVENT_CLICKED, NULL); + // Taskbar App Tabs container + lv_obj_t *tb_tabs = lv_obj_create(taskbar); + lv_obj_set_size(tb_tabs, 600, 40); + lv_obj_align(tb_tabs, LV_ALIGN_LEFT_MID, 114, 0); + lv_obj_set_style_bg_opa(tb_tabs, 0, 0); + lv_obj_set_style_border_width(tb_tabs, 0, 0); + lv_obj_set_style_pad_all(tb_tabs, 0, 0); + lv_obj_set_flex_flow(tb_tabs, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(tb_tabs, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); - // 5. Custom Mouse Cursor Object - lv_obj_t *cursor = lv_label_create(scr); - lv_label_set_text(cursor, "▲"); - lv_obj_set_style_text_color(cursor, lv_color_hex(0xffffff), 0); - lv_obj_set_style_text_font(cursor, &lv_font_montserrat_14, 0); - lv_indev_set_cursor(g_mouse_indev, cursor); + // Tab 1: Terminal + g_btn_tb_console = lv_btn_create(tb_tabs); + lv_obj_set_size(g_btn_tb_console, 140, 36); + lv_obj_set_style_bg_color(g_btn_tb_console, lv_color_hex(0x1e2638), 0); + lv_obj_set_style_border_color(g_btn_tb_console, lv_color_hex(0x3b82f6), 0); + lv_obj_set_style_border_width(g_btn_tb_console, 1, 0); + lv_obj_t *lbl_t1 = lv_label_create(g_btn_tb_console); + lv_label_set_text(lbl_t1, ">_ Terminal"); + lv_obj_center(lbl_t1); + lv_obj_add_event_cb(g_btn_tb_console, tb_btn_event_cb, LV_EVENT_CLICKED, g_win_console); + + // Tab 2: Task Manager + g_btn_tb_taskmgr = lv_btn_create(tb_tabs); + lv_obj_set_size(g_btn_tb_taskmgr, 150, 36); + lv_obj_set_style_bg_color(g_btn_tb_taskmgr, lv_color_hex(0x1e2638), 0); + lv_obj_set_style_border_color(g_btn_tb_taskmgr, lv_color_hex(0x3b82f6), 0); + lv_obj_set_style_border_width(g_btn_tb_taskmgr, 1, 0); + lv_obj_t *lbl_t2 = lv_label_create(g_btn_tb_taskmgr); + lv_label_set_text(lbl_t2, "Task Manager"); + lv_obj_center(lbl_t2); + lv_obj_add_event_cb(g_btn_tb_taskmgr, tb_btn_event_cb, LV_EVENT_CLICKED, g_win_taskmgr); + + // Tab 3: Network Center + g_btn_tb_network = lv_btn_create(tb_tabs); + lv_obj_set_size(g_btn_tb_network, 120, 36); + lv_obj_set_style_bg_color(g_btn_tb_network, lv_color_hex(0x1e2638), 0); + lv_obj_set_style_border_color(g_btn_tb_network, lv_color_hex(0x3b82f6), 0); + lv_obj_set_style_border_width(g_btn_tb_network, 1, 0); + lv_obj_t *lbl_t3 = lv_label_create(g_btn_tb_network); + lv_label_set_text(lbl_t3, "Network"); + lv_obj_center(lbl_t3); + lv_obj_add_event_cb(g_btn_tb_network, tb_btn_event_cb, LV_EVENT_CLICKED, g_win_network); + + // System Tray (Right side of taskbar) + lv_obj_t *tray = lv_obj_create(taskbar); + lv_obj_set_size(tray, 500, 40); + lv_obj_align(tray, LV_ALIGN_RIGHT_MID, -4, 0); + lv_obj_set_style_bg_opa(tray, 0, 0); + lv_obj_set_style_border_width(tray, 0, 0); + lv_obj_set_style_pad_all(tray, 0, 0); + lv_obj_set_flex_flow(tray, LV_FLEX_FLOW_ROW); + lv_obj_set_flex_align(tray, LV_FLEX_ALIGN_END, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); + + g_lbl_tray_net = lv_label_create(tray); + lv_label_set_text(g_lbl_tray_net, "LAN: 10.0.2.15"); + lv_obj_set_style_text_color(g_lbl_tray_net, lv_color_hex(0x38bdf8), 0); + lv_obj_set_style_pad_hor(g_lbl_tray_net, 8, 0); + + g_lbl_tray_ram = lv_label_create(tray); + lv_label_set_text(g_lbl_tray_ram, "RAM: 38/509 MB"); + lv_obj_set_style_text_color(g_lbl_tray_ram, lv_color_hex(0x10b981), 0); + lv_obj_set_style_pad_hor(g_lbl_tray_ram, 8, 0); + + g_lbl_tray_clock = lv_label_create(tray); + lv_label_set_text(g_lbl_tray_clock, "20:00:00 | 02.09.2026"); + lv_obj_set_style_text_color(g_lbl_tray_clock, lv_color_hex(0xf8fafc), 0); + lv_obj_set_style_text_font(g_lbl_tray_clock, &lv_font_montserrat_14, 0); + lv_obj_set_style_pad_hor(g_lbl_tray_clock, 12, 0); + + // ========================================================================= + // 7. START MENU (Windows 10/11 & KDE Plasma Style) + // ========================================================================= + g_start_menu = lv_obj_create(scr); + lv_obj_set_size(g_start_menu, 340, 430); + lv_obj_align(g_start_menu, LV_ALIGN_BOTTOM_LEFT, 6, -52); // Anchored right above Start button + lv_obj_set_style_bg_color(g_start_menu, lv_color_hex(0x181e2b), 0); + lv_obj_set_style_border_color(g_start_menu, lv_color_hex(0x334155), 0); + lv_obj_set_style_border_width(g_start_menu, 1, 0); + lv_obj_set_style_radius(g_start_menu, 10, 0); + lv_obj_set_style_shadow_width(g_start_menu, 32, 0); + lv_obj_set_style_shadow_color(g_start_menu, lv_color_hex(0x000000), 0); + lv_obj_set_style_shadow_opa(g_start_menu, 160, 0); + lv_obj_set_style_pad_all(g_start_menu, 12, 0); + lv_obj_add_flag(g_start_menu, LV_OBJ_FLAG_HIDDEN); // Hidden by default + + // User Profile Header in Start Menu + lv_obj_t *header_box = lv_obj_create(g_start_menu); + lv_obj_set_size(header_box, 314, 52); + lv_obj_align(header_box, LV_ALIGN_TOP_MID, 0, 0); + lv_obj_set_style_bg_color(header_box, lv_color_hex(0x222a3d), 0); + lv_obj_set_style_border_width(header_box, 0, 0); + lv_obj_set_style_radius(header_box, 8, 0); + lv_obj_set_style_pad_all(header_box, 6, 0); + + lv_obj_t *lbl_user_name = lv_label_create(header_box); + lv_label_set_text(lbl_user_name, "Administrator (root)"); + lv_obj_set_style_text_color(lbl_user_name, lv_color_hex(0xffffff), 0); + lv_obj_align(lbl_user_name, LV_ALIGN_TOP_LEFT, 12, 4); + + lv_obj_t *lbl_user_sub = lv_label_create(header_box); + lv_label_set_text(lbl_user_sub, "opencoreC Microkernel"); + lv_obj_set_style_text_color(lbl_user_sub, lv_color_hex(0x94a3b8), 0); + lv_obj_set_style_text_font(lbl_user_sub, &lv_font_montserrat_12, 0); + lv_obj_align(lbl_user_sub, LV_ALIGN_BOTTOM_LEFT, 12, -4); + + // Section: Programs + lv_obj_t *lbl_sec_apps = lv_label_create(g_start_menu); + lv_label_set_text(lbl_sec_apps, "APPLICATIONS"); + lv_obj_set_style_text_color(lbl_sec_apps, lv_color_hex(0x64748b), 0); + lv_obj_set_style_text_font(lbl_sec_apps, &lv_font_montserrat_12, 0); + lv_obj_align(lbl_sec_apps, LV_ALIGN_TOP_LEFT, 4, 62); + + // Helper lambda for Start Menu program tiles + auto make_start_item = [](lv_obj_t *parent, int y, const char *title, const char *desc, lv_obj_t *target_win) { + lv_obj_t *btn = lv_btn_create(parent); + lv_obj_set_size(btn, 314, 46); + lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, y); + lv_obj_set_style_bg_color(btn, lv_color_hex(0x1b2333), 0); + lv_obj_set_style_border_width(btn, 0, 0); + lv_obj_set_style_radius(btn, 6, 0); + + lv_obj_t *lbl_t = lv_label_create(btn); + lv_label_set_text(lbl_t, title); + lv_obj_set_style_text_color(lbl_t, lv_color_hex(0xf8fafc), 0); + lv_obj_align(lbl_t, LV_ALIGN_TOP_LEFT, 14, 4); + + lv_obj_t *lbl_d = lv_label_create(btn); + lv_label_set_text(lbl_d, desc); + lv_obj_set_style_text_color(lbl_d, lv_color_hex(0x94a3b8), 0); + lv_obj_set_style_text_font(lbl_d, &lv_font_montserrat_12, 0); + lv_obj_align(lbl_d, LV_ALIGN_BOTTOM_LEFT, 14, -4); + + lv_obj_add_event_cb(btn, start_item_event_cb, LV_EVENT_CLICKED, target_win); + }; + + make_start_item(g_start_menu, 84, ">_ Terminal", "opencoreC interactive shell (osh)", g_win_console); + make_start_item(g_start_menu, 138, "Task Manager", "CPU scheduler & memory monitor", g_win_taskmgr); + make_start_item(g_start_menu, 192, "Network Center", "RTL8139 PCI Fast Ethernet", g_win_network); + make_start_item(g_start_menu, 246, "About opencoreC", "Microkernel architecture & specs", g_win_about); + + // Bottom Bar of Start Menu: Power Button + lv_obj_t *btn_pwr = lv_btn_create(g_start_menu); + lv_obj_set_size(btn_pwr, 314, 40); + lv_obj_align(btn_pwr, LV_ALIGN_BOTTOM_MID, 0, 0); + lv_obj_set_style_bg_color(btn_pwr, lv_color_hex(0xbe123c), 0); // Crimson red + lv_obj_set_style_radius(btn_pwr, 6, 0); + lv_obj_t *lbl_pwr = lv_label_create(btn_pwr); + lv_label_set_text(lbl_pwr, "Shut Down (Poweroff)"); + lv_obj_center(lbl_pwr); + lv_obj_add_event_cb(btn_pwr, poweroff_event_cb, LV_EVENT_CLICKED, NULL); + + // ========================================================================= + // 8. CRISP HARDWARE MOUSE CURSOR (Rendered on lv_layer_sys() - Topmost!) + // ========================================================================= + init_cursor_bitmap(); + lv_obj_t *cursor_obj = lv_img_create(lv_layer_sys()); + lv_img_set_src(cursor_obj, &g_cursor_dsc); + lv_indev_set_cursor(g_mouse_indev, cursor_obj); } +// Background metrics updater (called every ~500ms) static void update_live_metrics() { - // 1. Query sysinfo - sysinfo_data_t info = {0}; + char buf[128]; + + // 1. Physical RAM Metrics + sysinfo_data_t info = {0, 0, 0, 0, 0}; register uint64_t rax __asm__("rax") = SYS_SYSINFO; register uint64_t rdi __asm__("rdi") = (uint64_t)&info; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); - // 2. Query RTC time - rtc_data_t rtc = {0}; - sys_rtc_get(&rtc); + uint32_t total_mb = (uint32_t)(info.total_memory_bytes / (1024 * 1024)); + uint32_t free_mb = (uint32_t)(info.free_memory_bytes / (1024 * 1024)); + uint32_t used_mb = total_mb > free_mb ? (total_mb - free_mb) : 0; - char buf[64]; - if (g_lbl_clock) { - snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u:%02u UTC", - rtc.year, rtc.month, rtc.day, rtc.hour, rtc.minute, rtc.second); - lv_label_set_text(g_lbl_clock, buf); - } - - uint64_t uptime_sec = info.uptime_ticks / 100; - if (g_lbl_uptime) { - snprintf(buf, sizeof(buf), "Up: %02u:%02u:%02u", - (unsigned)(uptime_sec / 3600), (unsigned)((uptime_sec % 3600) / 60), (unsigned)(uptime_sec % 60)); - lv_label_set_text(g_lbl_uptime, buf); - } - - uint64_t total_mb = info.total_memory_bytes / (1024 * 1024); - uint64_t free_mb = info.free_memory_bytes / (1024 * 1024); - uint64_t used_mb = total_mb > free_mb ? (total_mb - free_mb) : 0; - - if (g_lbl_ram) { - snprintf(buf, sizeof(buf), "RAM: %luM / %luM", used_mb, total_mb); - lv_label_set_text(g_lbl_ram, buf); + if (g_lbl_tray_ram) { + snprintf(buf, sizeof(buf), "RAM: %u/%u MB", used_mb, total_mb); + lv_label_set_text(g_lbl_tray_ram, buf); } if (g_bar_ram) { - lv_bar_set_range(g_bar_ram, 0, (int32_t)total_mb); - lv_bar_set_value(g_bar_ram, (int32_t)used_mb, LV_ANIM_ON); + lv_bar_set_value(g_bar_ram, used_mb, LV_ANIM_OFF); } - // 3. Update thread list - thread_info_t threads[16] = {0}; + if (g_lbl_ram_detail) { + snprintf(buf, sizeof(buf), "Used: %u MB / %u MB (Free: %u MB)", used_mb, total_mb, free_mb); + lv_label_set_text(g_lbl_ram_detail, buf); + } + + // 2. CMOS RTC Time + rtc_data_t rtc = {0, 0, 0, 0, 0, 0}; + rax = SYS_RTC_GET; + rdi = (uint64_t)&rtc; + __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); + + if (g_lbl_tray_clock) { + snprintf(buf, sizeof(buf), "%02u:%02u:%02u | %02u.%02u.20%02u", + rtc.hour, rtc.minute, rtc.second, rtc.day, rtc.month, rtc.year); + lv_label_set_text(g_lbl_tray_clock, buf); + } + + // 3. CPU Load History Chart + static uint32_t s_prev_ticks[16] = {0}; + thread_info_t threads[16]; + memset(threads, 0, sizeof(threads)); rax = SYS_PROC_LIST; rdi = (uint64_t)threads; register uint64_t rsi __asm__("rsi") = 16; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); + int count = (int)rax; - const char *state_names[] = {"UNUSED", "READY", "RUNNING", "BLOCKED", "DEAD"}; - for (int i = 0; i < 5; i++) { - const char *st = (threads[i].state <= 4) ? state_names[threads[i].state] : "?"; - char tid_buf[8], tick_buf[16], rip_buf[20]; - snprintf(tid_buf, sizeof(tid_buf), "%lu", threads[i].tid); - snprintf(tick_buf, sizeof(tick_buf), "%lu", threads[i].cpu_ticks); - snprintf(rip_buf, sizeof(rip_buf), "0x%lx", threads[i].user_rip); - - lv_table_set_cell_value(g_tbl_threads, i + 1, 0, tid_buf); - lv_table_set_cell_value(g_tbl_threads, i + 1, 1, threads[i].name); - lv_table_set_cell_value(g_tbl_threads, i + 1, 2, st); - lv_table_set_cell_value(g_tbl_threads, i + 1, 3, tick_buf); - lv_table_set_cell_value(g_tbl_threads, i + 1, 4, rip_buf); + uint32_t total_delta = 0; + for (int i = 0; i < count; i++) { + uint32_t delta = (threads[i].cpu_ticks >= s_prev_ticks[i]) ? + (threads[i].cpu_ticks - s_prev_ticks[i]) : 0; + s_prev_ticks[i] = threads[i].cpu_ticks; + if (threads[i].tid != 0) { // Exclude idle thread + total_delta += delta; + } } - // 4. Update CPU Chart - if (g_chart_cpu) { - lv_chart_set_next_value(g_chart_cpu, g_ser_user, (int32_t)((info.uptime_ticks % 30) + 10)); - lv_chart_set_next_value(g_chart_cpu, g_ser_idle, (int32_t)(90 - (info.uptime_ticks % 20))); + uint32_t cpu_percent = total_delta * 4; + if (cpu_percent > 100) cpu_percent = 100; + if (cpu_percent < 5) cpu_percent = 5; + + if (g_chart_cpu && g_ser_cpu) { + lv_chart_set_next_value(g_chart_cpu, g_ser_cpu, (lv_coord_t)cpu_percent); + } + + // 4. Update Process Table + if (g_tbl_procs) { + lv_table_set_row_cnt(g_tbl_procs, count + 1); + for (int i = 0; i < count; i++) { + char tid_str[16]; + snprintf(tid_str, sizeof(tid_str), "%u", threads[i].tid); + lv_table_set_cell_value(g_tbl_procs, i + 1, 0, tid_str); + lv_table_set_cell_value(g_tbl_procs, i + 1, 1, threads[i].name); + + const char *st = (threads[i].state == 0) ? "READY" : + (threads[i].state == 1) ? "RUNNING" : + (threads[i].state == 2) ? "BLOCKED" : "DEAD"; + lv_table_set_cell_value(g_tbl_procs, i + 1, 2, st); + + char tick_str[16]; + snprintf(tick_str, sizeof(tick_str), "%u", (unsigned int)threads[i].cpu_ticks); + lv_table_set_cell_value(g_tbl_procs, i + 1, 3, tick_str); + } } } int main() { - printf("[GUI-SERVER] Starting opencoreC LVGL Desktop Compositor (Ring 3)...\n"); + printf("[GUI-SERVER] Starting opencoreC Windows/KDE Desktop Compositor (Ring 3)...\n"); - // 1. Query Framebuffer + // 1. Query Limine Linear Framebuffer register uint64_t rax __asm__("rax") = SYS_FB_INFO; register uint64_t rdi __asm__("rdi") = (uint64_t)&g_fb; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); - if (rax != 0 || g_fb.fb_addr == 0) { + if (g_fb.fb_addr == 0 || g_fb.width == 0 || g_fb.height == 0) { printf("[GUI-SERVER] Error: Framebuffer not available from microkernel.\n"); return 1; } - printf("[GUI-SERVER] Framebuffer OK: %lux%lu @ %lubpp, Pitch=%lu, Addr=0x%lx\n", + printf("[GUI-SERVER] Framebuffer OK: %ux%u @ %ubpp, Pitch=%u, Addr=0x%lx\n", g_fb.width, g_fb.height, g_fb.bpp, g_fb.pitch, g_fb.fb_addr); - // 2. Initialize LVGL + // 2. Initialize LVGL v8.3 Library and Network subsystem lv_init(); + net_init(); - // 3. Register Display Driver + // 3. Register Framebuffer Display Driver lv_disp_draw_buf_init(&g_draw_buf, g_buf1, g_buf2, 1280 * BUF_HEIGHT); lv_disp_drv_init(&g_disp_drv); g_disp_drv.hor_res = (lv_coord_t)g_fb.width; @@ -403,35 +896,35 @@ int main() { g_disp_drv.draw_buf = &g_draw_buf; lv_disp_drv_register(&g_disp_drv); - // 4. Register Mouse Input Driver + // 4. Register Hardware PS/2 Mouse Input Driver lv_indev_drv_init(&g_indev_drv); g_indev_drv.type = LV_INDEV_TYPE_POINTER; g_indev_drv.read_cb = mouse_read_cb; g_mouse_indev = lv_indev_drv_register(&g_indev_drv); - // 5. Create Desktop UI - create_desktop_ui(); + // 5. Build the Windows / KDE Desktop Environment + create_desktop_environment(); + printf("[GUI-SERVER] Windows/KDE Desktop UI Initialized. Entering Compositor Event Loop.\n"); - printf("[GUI-SERVER] Desktop UI Initialized. Entering Compositor Event Loop.\n"); - - uint32_t last_metric_update = 0; + // 6. Compositor Event Loop + uint32_t tick_counter = 0; while (1) { - lv_tick_inc(10); - lv_timer_handler(); + lv_task_handler(); + lv_tick_inc(5); - last_metric_update++; - if (last_metric_update >= 50) { // update every ~500 ms - last_metric_update = 0; + tick_counter++; + if (tick_counter % 100 == 0) { // Every ~500ms update_live_metrics(); } - // Brief delay loop + // Delay ~5ms (cooperative time slice yield) for (volatile int d = 0; d < 30000; d++); } return 0; } +// System V AMD64 ABI compliant _start entry point extern "C" __attribute__((naked)) void _start() { __asm__ volatile ( "andq $-16, %rsp\n"