Merge branch 'feat/gui-desktop' into main

Bring the SUB-OS Graphical Desktop Environment (SUB-WM compositor, SUB-WT
widget toolkit, icon set, modal dialogs, terminal emulator and the desktop
apps) onto main alongside main's userland /sbin/init and framebuffer console.

Conflicts resolved:
- kernel/main.c: boot into gui_start_desktop() by default (unless nogui/text/
  emergency/single), then fall back through fbcon + /sbin/init + shell when the
  GUI session closes or a text console is requested. Splash raised by default
  unless a text console is asked for. Kept main's fbcon include and the
  weave_preempt_selftest path.
- Makefile: kept main's userland init compilation rules and kernel/elf.c,
  kernel/exec.c in CORE_SRCS; retained the feature branch's gui/ sources.
- README.md: kept main's Weave Scheduler section and adopted the feature
  branch's Boot Logo / Console Font / Framebuffer Console / GUI Desktop docs.

Verified: full x86_64 build links cleanly (kernel.elf + SUB-OS.img).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
This commit is contained in:
subhobhai943andClaude Opus 4.8 committed 2026-08-25 16:52:52 +05:30
commit 25c0519c25
28 files changed
+5345 -34

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
#ifndef _GUI_H
#define _GUI_H
#include <gui/gui_theme.h>
#include <gui/gui_gfx.h>
#include <gui/gui_cursor.h>
#include <gui/gui_wm.h>
#include <gui/gui_desktop.h>
#include <gui/gui_apps.h>
#include <gui/gui_terminal.h>
#include <gui/gui_apps_ext.h>
#include <gui/gui_widgets.h>
#include <gui/gui_icons.h>
#include <gui/gui_dialog.h>
void gui_init(void);
int gui_start_desktop(void);
#endif // _GUI_H
+13
View File
@@ -0,0 +1,13 @@
#ifndef _GUI_APPS_H
#define _GUI_APPS_H
#include <gui/gui_wm.h>
#include <gui/gui_terminal.h>
void gui_app_sysmon_launch(int x, int y, int w, int h);
void gui_app_fileman_launch(int x, int y, int w, int h);
void gui_app_calc_launch(int x, int y, int w, int h);
void gui_app_paint_launch(int x, int y, int w, int h);
void gui_app_about_launch(int x, int y, int w, int h);
#endif // _GUI_APPS_H
+16
View File
@@ -0,0 +1,16 @@
#ifndef _GUI_APPS_EXT_H
#define _GUI_APPS_EXT_H
#include <gui/gui_wm.h>
// Second-generation desktop applications, built on the SUB-WT widget toolkit
// rather than raw framebuffer calls.
void gui_app_settings_launch(int x, int y, int w, int h);
void gui_app_taskmgr_launch(int x, int y, int w, int h);
void gui_app_logviewer_launch(int x, int y, int w, int h);
void gui_app_ktest_launch(int x, int y, int w, int h);
void gui_app_clock_launch(int x, int y, int w, int h);
void gui_app_editor_launch(int x, int y, int w, int h);
#endif // _GUI_APPS_EXT_H
+13
View File
@@ -0,0 +1,13 @@
#ifndef _GUI_CURSOR_H
#define _GUI_CURSOR_H
#include <stdint.h>
#include <stdbool.h>
void gui_cursor_init(void);
void gui_cursor_set_pos(int x, int y);
int gui_cursor_get_x(void);
int gui_cursor_get_y(void);
void gui_cursor_draw(void);
#endif // _GUI_CURSOR_H
+38
View File
@@ -0,0 +1,38 @@
#ifndef _GUI_DESKTOP_H
#define _GUI_DESKTOP_H
#include <stdint.h>
#include <stdbool.h>
#define GUI_TASKBAR_HEIGHT 32
#define GUI_DESKTOP_ICON_W 72
#define GUI_DESKTOP_ICON_H 64
void gui_desktop_init(void);
void gui_desktop_render_background(void);
// Drop the cached wallpaper so the next background render repaints it. Needed
// when the resolution changes or the framebuffer is handed to another owner.
void gui_desktop_invalidate_background(void);
void gui_desktop_render_icons(void);
void gui_desktop_render_taskbar(void);
void gui_desktop_render_start_menu(void);
void gui_desktop_render_context_menu(void);
void gui_desktop_toggle_start_menu(void);
bool gui_desktop_is_start_menu_open(void);
void gui_desktop_open_context_menu(int mx, int my);
void gui_desktop_close_menus(void);
// Returns true if the click was consumed by desktop chrome (taskbar, menus,
// icons) rather than falling through to the window manager.
bool gui_desktop_handle_click(int mx, int my);
// Height of the area windows may occupy (screen minus taskbar).
int gui_desktop_workarea_height(void);
void gui_desktop_request_exit(void);
int gui_desktop_run(void);
#endif // _GUI_DESKTOP_H
+42
View File
@@ -0,0 +1,42 @@
#ifndef _GUI_DIALOG_H
#define _GUI_DIALOG_H
#include <stdint.h>
#include <stdbool.h>
#include <gui/gui_icons.h>
// Modal dialogs. Only one is on screen at a time; while it is up the desktop
// dims behind it and the compositor routes every click to the dialog, so no
// window underneath can be interacted with.
typedef enum {
GUI_DIALOG_INFO,
GUI_DIALOG_WARNING,
GUI_DIALOG_CONFIRM,
GUI_DIALOG_ERROR
} gui_dialog_kind_t;
typedef enum {
GUI_DIALOG_RESULT_NONE = 0,
GUI_DIALOG_RESULT_OK,
GUI_DIALOG_RESULT_CANCEL
} gui_dialog_result_t;
typedef void (*gui_dialog_cb_t)(gui_dialog_result_t result, void* ctx);
void gui_dialog_init(void);
void gui_dialog_show(gui_dialog_kind_t kind, const char* title, const char* message);
void gui_dialog_confirm(const char* title, const char* message,
gui_dialog_cb_t on_result, void* ctx);
void gui_dialog_dismiss(void);
bool gui_dialog_is_open(void);
// Returns true when the dialog consumed the input.
bool gui_dialog_handle_mouse(int mx, int my, bool clicked);
bool gui_dialog_handle_key(uint16_t key);
void gui_dialog_render(void);
#endif // _GUI_DIALOG_H
+59
View File
@@ -0,0 +1,59 @@
#ifndef _GUI_GFX_H
#define _GUI_GFX_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <gui/gui_theme.h>
#define GUI_DEFAULT_WIDTH 800
#define GUI_DEFAULT_HEIGHT 600
typedef struct {
int x;
int y;
int width;
int height;
} gui_rect_t;
void gui_gfx_init(uint32_t* fb, int width, int height);
int gui_gfx_get_width(void);
int gui_gfx_get_height(void);
uint32_t* gui_gfx_get_backbuffer(void);
void gui_gfx_clear(uint32_t color);
void gui_gfx_draw_pixel(int x, int y, uint32_t color);
void gui_gfx_draw_pixel_blend(int x, int y, uint32_t color, uint8_t alpha);
void gui_gfx_draw_line(int x0, int y0, int x1, int y1, uint32_t color);
void gui_gfx_draw_rect(int x, int y, int w, int h, uint32_t color);
void gui_gfx_fill_rect(int x, int y, int w, int h, uint32_t color);
void gui_gfx_fill_rect_blend(int x, int y, int w, int h, uint32_t color, uint8_t alpha);
void gui_gfx_draw_rounded_rect(int x, int y, int w, int h, int r, uint32_t color, bool filled);
void gui_gfx_draw_gradient_v(int x, int y, int w, int h, uint32_t top_col, uint32_t bot_col);
void gui_gfx_draw_gradient_h(int x, int y, int w, int h, uint32_t left_col, uint32_t right_col);
// Sharp Typography & Font Rendering
void gui_gfx_draw_char(int x, int y, char c, uint32_t fg, uint32_t bg, bool transparent_bg);
void gui_gfx_draw_char_16(int x, int y, char c, uint32_t fg, uint32_t bg, bool transparent_bg);
void gui_gfx_draw_string(int x, int y, const char* str, uint32_t fg);
void gui_gfx_draw_string_16(int x, int y, const char* str, uint32_t fg);
void gui_gfx_draw_string_bg(int x, int y, const char* str, uint32_t fg, uint32_t bg);
void gui_gfx_draw_string_shadow(int x, int y, const char* str, uint32_t fg, uint32_t shadow);
void gui_gfx_draw_string_16_shadow(int x, int y, const char* str, uint32_t fg, uint32_t shadow);
void gui_gfx_draw_shadow(int x, int y, int w, int h, int blur);
void gui_gfx_blit(int dx, int dy, int w, int h, const uint32_t* src_buf);
// Push the composited frame to the display. Only the pixels that differ from
// the previous frame are written, so an idle desktop costs almost no
// framebuffer traffic.
void gui_gfx_present(void);
// Force the next present to push the whole screen. Needed whenever something
// outside the compositor has drawn over the framebuffer, such as the kernel
// console before the desktop takes the display back.
void gui_gfx_invalidate(void);
// Pixels written to the framebuffer by the last present. Diagnostic only.
uint64_t gui_gfx_last_present_pixels(void);
#endif // _GUI_GFX_H
+40
View File
@@ -0,0 +1,40 @@
#ifndef _GUI_ICONS_H
#define _GUI_ICONS_H
#include <stdint.h>
#include <stdbool.h>
// 16x16 palette-indexed icon set. Each glyph stores one nibble per pixel
// indexing a 16-entry ARGB palette, so the whole set costs 128 bytes an icon
// and can be recoloured per theme without touching the bitmaps.
#define GUI_ICON_SIZE 16
typedef enum {
GUI_ICON_TERMINAL = 0,
GUI_ICON_MONITOR,
GUI_ICON_FOLDER,
GUI_ICON_CALC,
GUI_ICON_PAINT,
GUI_ICON_INFO,
GUI_ICON_SETTINGS,
GUI_ICON_TASKS,
GUI_ICON_LOG,
GUI_ICON_FLASK,
GUI_ICON_CLOCK,
GUI_ICON_FILE,
GUI_ICON_POWER,
GUI_ICON_WARNING,
GUI_ICON_COUNT
} gui_icon_id_t;
void gui_icons_init(void);
// Draw at native 16x16, or scaled by an integer factor (2 = 32x32).
void gui_icon_draw(gui_icon_id_t id, int x, int y);
void gui_icon_draw_scaled(gui_icon_id_t id, int x, int y, int scale);
void gui_icon_draw_tinted(gui_icon_id_t id, int x, int y, int scale, uint32_t tint);
const char* gui_icon_name(gui_icon_id_t id);
#endif // _GUI_ICONS_H
+12
View File
@@ -0,0 +1,12 @@
#ifndef _GUI_TERMINAL_H
#define _GUI_TERMINAL_H
#include <gui/gui_wm.h>
// Desktop terminal emulator. Commands are dispatched to the real LazyBox
// applet table, and the applet's printk output is captured and rendered in
// the window, so the GUI terminal runs the same tools the kernel TTY does.
void gui_app_terminal_launch(int x, int y, int w, int h);
#endif // _GUI_TERMINAL_H
+51
View File
@@ -0,0 +1,51 @@
#ifndef _GUI_THEME_H
#define _GUI_THEME_H
#include <stdint.h>
// 32-bit ARGB Color definitions (0xAARRGGBB)
#define GUI_COLOR_TRANSPARENT 0x00000000
#define GUI_COLOR_BLACK 0xFF000000
#define GUI_COLOR_WHITE 0xFFFFFFFF
// Cyberpunk / Nord Dark Theme
#define GUI_THEME_BG_DARK 0xFF0F172A // Slate 900
#define GUI_THEME_BG_SURFACE 0xFF1E293B // Slate 800
#define GUI_THEME_BG_ELEVATED 0xFF334155 // Slate 700
#define GUI_THEME_BORDER 0xFF475569 // Slate 600
#define GUI_THEME_PRIMARY 0xFF38BDF8 // Sky 400
#define GUI_THEME_PRIMARY_DARK 0xFF0284C7 // Sky 600
#define GUI_THEME_ACCENT 0xFF818CF8 // Indigo 400
#define GUI_THEME_SUCCESS 0xFF34D399 // Emerald 400
#define GUI_THEME_WARNING 0xFFFBBF24 // Amber 400
#define GUI_THEME_DANGER 0xFFF87171 // Red 400
#define GUI_THEME_TEXT_MAIN 0xFFF8FAFC // Slate 50
#define GUI_THEME_TEXT_MUTED 0xFF94A3B8 // Slate 400
#define GUI_THEME_TEXT_DIM 0xFF64748B // Slate 500
#define GUI_THEME_TITLEBAR_ACT 0xFF1E293B
#define GUI_THEME_TITLEBAR_INACT 0xFF0F172A
#define GUI_THEME_TASKBAR_BG 0xFF0B0F19
#define GUI_THEME_BTN_CLOSE 0xFFEF4444
#define GUI_THEME_BTN_MINIMIZE 0xFFF59E0B
#define GUI_THEME_BTN_MAXIMIZE 0xFF10B981
static inline uint32_t gui_color_alpha_blend(uint32_t bg, uint32_t fg, uint8_t alpha) {
if (alpha == 0) return bg;
if (alpha == 255) return fg;
uint32_t rb_bg = bg & 0x00FF00FF;
uint32_t g_bg = bg & 0x0000FF00;
uint32_t rb_fg = fg & 0x00FF00FF;
uint32_t g_fg = fg & 0x0000FF00;
uint32_t rb = rb_bg + (((rb_fg - rb_bg) * alpha) >> 8);
uint32_t g = g_bg + (((g_fg - g_bg) * alpha) >> 8);
return 0xFF000000 | (rb & 0x00FF00FF) | (g & 0x0000FF00);
}
#endif // _GUI_THEME_H
+86
View File
@@ -0,0 +1,86 @@
#ifndef _GUI_WIDGETS_H
#define _GUI_WIDGETS_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <gui/gui_wm.h>
#include <gui/gui_gfx.h>
#include <gui/gui_theme.h>
// SUB-WT: immediate-mode widget toolkit for SUB-OS desktop applications.
//
// An app feeds the toolkit whatever event the window manager delivered
// (gui_widget_feed_event) and then simply calls widget functions from inside
// its paint routine. Each call both draws the control and reports what the
// user did with it, so no retained widget tree has to be kept in sync with
// the window's state.
//
// static void my_paint(gui_window_t* win) {
// gui_widget_begin(win);
// if (gui_button(1, 10, 10, 90, 24, "Refresh")) do_refresh();
// gui_checkbox(2, 10, 44, "Verbose", &verbose);
// gui_widget_end();
// }
#define GUI_FONT_W 8
#define GUI_FONT_H 8
#define GUI_FONT16_H 16
#define GUI_WIDGET_ROW_H 22
typedef enum {
GUI_ALIGN_LEFT,
GUI_ALIGN_CENTER,
GUI_ALIGN_RIGHT
} gui_align_t;
// Per-frame input snapshot the widgets consult.
typedef struct {
int mouse_x; // Window-relative, client area origin
int mouse_y;
bool mouse_down; // Button currently held
bool mouse_clicked; // Press edge, consumed by the first widget hit
bool mouse_released;
uint16_t key; // Pending keystroke, consumed by the focused field
int hot_id; // Widget under the cursor this frame
int active_id; // Widget holding the press
int focus_id; // Widget receiving keystrokes
} gui_widget_input_t;
// Called from an app's handle_event to record what the WM delivered.
void gui_widget_feed_event(gui_window_t* win, const gui_event_t* ev);
// Frame scope. Everything between these two is drawn in client-area
// coordinates: (0,0) is the top-left pixel below the title bar.
void gui_widget_begin(gui_window_t* win);
void gui_widget_end(void);
const gui_widget_input_t* gui_widget_get_input(void);
void gui_widget_set_focus(int id);
int gui_widget_client_width(void);
int gui_widget_client_height(void);
// --- Static content ---------------------------------------------------------
void gui_label(int x, int y, const char* text, uint32_t color);
void gui_label_bold(int x, int y, const char* text, uint32_t color);
void gui_label_aligned(int x, int y, int w, const char* text, uint32_t color, gui_align_t align);
void gui_panel(int x, int y, int w, int h, const char* title);
void gui_separator(int x, int y, int w);
void gui_progress_bar(int x, int y, int w, int h, int percent, uint32_t fill);
void gui_sparkline(int x, int y, int w, int h, const uint8_t* samples, int count, uint32_t color);
void gui_badge(int x, int y, const char* text, uint32_t bg, uint32_t fg);
// --- Interactive controls ---------------------------------------------------
// Every control takes a caller-assigned id that must be unique and stable
// within one window.
bool gui_button(int id, int x, int y, int w, int h, const char* label);
bool gui_button_colored(int id, int x, int y, int w, int h, const char* label, uint32_t accent);
bool gui_checkbox(int id, int x, int y, const char* label, bool* value);
bool gui_radio(int id, int x, int y, const char* label, int* selected, int this_value);
bool gui_slider(int id, int x, int y, int w, int* value, int min_val, int max_val);
bool gui_listbox(int id, int x, int y, int w, int h, const char* const* items, int count, int* selected);
bool gui_textfield(int id, int x, int y, int w, char* buffer, size_t capacity);
int gui_tabbar(int id, int x, int y, int w, const char* const* labels, int count, int* active);
bool gui_scrollbar(int id, int x, int y, int h, int* offset, int total, int visible);
#endif // _GUI_WIDGETS_H
+111
View File
@@ -0,0 +1,111 @@
#ifndef _GUI_WM_H
#define _GUI_WM_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <gui/gui_gfx.h>
#include <gui/gui_theme.h>
#define GUI_MAX_WINDOWS 16
#define GUI_TITLEBAR_HEIGHT 24
#define GUI_RESIZE_GRIP 12
#define GUI_MIN_WINDOW_W 160
#define GUI_MIN_WINDOW_H 100
typedef enum {
GUI_EVENT_MOUSE_MOVE,
GUI_EVENT_MOUSE_DOWN,
GUI_EVENT_MOUSE_UP,
GUI_EVENT_KEY_DOWN,
GUI_EVENT_FOCUS,
GUI_EVENT_RESIZE,
GUI_EVENT_CLOSE
} gui_event_type_t;
typedef struct {
gui_event_type_t type;
int mouse_x;
int mouse_y;
int rel_x;
int rel_y;
bool btn_left;
bool btn_right;
uint16_t key;
} gui_event_t;
// Where a window sits relative to the screen edges.
typedef enum {
GUI_SNAP_NONE = 0,
GUI_SNAP_LEFT,
GUI_SNAP_RIGHT,
GUI_SNAP_MAXIMIZED
} gui_snap_t;
typedef struct gui_window {
int id;
char title[64];
int x;
int y;
int width;
int height;
bool active;
bool minimized;
bool visible;
bool resizable;
// Drag / resize interaction state
bool is_dragging;
bool is_resizing;
int drag_off_x;
int drag_off_y;
// Geometry remembered across maximize / snap so restore is exact
gui_snap_t snap;
int saved_x;
int saved_y;
int saved_width;
int saved_height;
void* user_data;
void (*paint)(struct gui_window* win);
void (*handle_event)(struct gui_window* win, const gui_event_t* ev);
} gui_window_t;
void gui_wm_init(void);
// The work area excludes the taskbar; windows maximize and snap inside it.
void gui_wm_set_workarea(int width, int height);
gui_window_t* gui_wm_create_window(const char* title, int x, int y, int w, int h);
void gui_wm_destroy_window(int win_id);
void gui_wm_focus_window(int win_id);
gui_window_t* gui_wm_get_window(int win_id);
gui_window_t* gui_wm_get_active_window(void);
int gui_wm_get_window_count(void);
// Enumerate in z-order, bottom-most first. Returns NULL past the end.
gui_window_t* gui_wm_get_window_at_index(int index);
void gui_wm_minimize_window(int win_id);
void gui_wm_restore_window(int win_id);
void gui_wm_toggle_maximize(int win_id);
void gui_wm_snap_window(int win_id, gui_snap_t snap);
void gui_wm_close_active(void);
void gui_wm_cycle_focus(void);
void gui_wm_cascade_windows(void);
void gui_wm_tile_windows(void);
// Keep the WM's press-edge detector in step when another layer (a menu, a
// modal dialog) consumed the click instead. Without this the WM still holds
// the pre-press state and reads the still-held button as a fresh press on the
// following frame, stealing focus from whatever the click just opened.
void gui_wm_sync_button_state(bool btn_left);
void gui_wm_handle_mouse(int x, int y, bool btn_left, bool btn_right);
void gui_wm_handle_key(uint16_t key);
void gui_wm_render(void);
#endif // _GUI_WM_H