feat(gui): Implement complete Graphical Desktop Environment, SUB-WM, and apps

- Create separate feature branch 'feat/gui-desktop'
- Implement double-buffered 2D graphics engine with alpha blending, gradients, rounded rects, and font rasterization in gui/gui_gfx.c and include/gui/gui_gfx.h
- Implement alpha-blended mouse pointer overlay in gui/gui_cursor.c and include/gui/gui_cursor.h
- Implement SUB-WM Window Manager with draggable titlebars, close/minimize buttons, drop shadows, and event routing in gui/gui_wm.c and include/gui/gui_wm.h
- Implement Cyberpunk/Nord desktop environment with wallpaper, taskbar, start menu popup, and system tray in gui/gui_desktop.c and include/gui/gui_desktop.h
- Implement built-in GUI apps: System Performance Monitor, GUI Terminal Emulator, File Explorer, Calculator, Paint Studio, and About dialog in gui/gui_apps.c and include/gui/gui_apps.h
- Add 'startx', 'gui', and 'desktop' applets in LazyBox suite
- Verified multi-architecture compilation across x86_64, AArch64, and ARMv8i
This commit is contained in:
subhobhai943 committed 2026-08-21 02:50:55 +05:30
1 parent 492045b24d
commit 109472816c
16 files changed
+1545 -2

No files matched your search

+305
View File
@@ -0,0 +1,305 @@
// High-Performance 2D Graphics Engine & Software Compositor for SUB-OS
#include <gui/gui_gfx.h>
#include <mm/kmalloc.h>
#include <lib/string.h>
static uint32_t* g_frontbuffer = NULL;
static uint32_t* g_backbuffer = NULL;
static int g_width = 320;
static int g_height = 200;
// Standard 8x8 font bitmap table for printable ASCII characters (32..126)
static const uint8_t font8x8[96][8] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
{0x18,0x3c,0x3c,0x18,0x18,0x00,0x18,0x00}, // !
{0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00}, // "
{0x6c,0x6c,0xfe,0x6c,0xfe,0x6c,0x6c,0x00}, // #
{0x18,0x3e,0x60,0x3c,0x06,0x7c,0x18,0x00}, // $
{0x00,0x63,0x66,0x0c,0x18,0x33,0x63,0x00}, // %
{0x38,0x6c,0x38,0x76,0xdc,0xcc,0x76,0x00}, // &
{0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00}, // '
{0x0c,0x18,0x30,0x30,0x30,0x18,0x0c,0x00}, // (
{0x30,0x18,0x0c,0x0c,0x0c,0x18,0x30,0x00}, // )
{0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00}, // *
{0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00}, // +
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
{0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00}, // -
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
{0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00}, // /
{0x7c,0xc6,0xce,0xd6,0xe6,0xc6,0x7c,0x00}, // 0
{0x18,0x38,0x18,0x18,0x18,0x18,0x7e,0x00}, // 1
{0x7c,0xc6,0x06,0x1c,0x30,0x66,0xfe,0x00}, // 2
{0x7c,0xc6,0x06,0x3c,0x06,0xc6,0x7c,0x00}, // 3
{0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x1e,0x00}, // 4
{0xfe,0xc0,0xfc,0x06,0x06,0xc6,0x7c,0x00}, // 5
{0x7c,0xc6,0xc0,0xfc,0xc6,0xc6,0x7c,0x00}, // 6
{0xfe,0x06,0x0c,0x18,0x30,0x30,0x30,0x00}, // 7
{0x7c,0xc6,0xc6,0x7c,0xc6,0xc6,0x7c,0x00}, // 8
{0x7c,0xc6,0xc6,0x7e,0x06,0xc6,0x7c,0x00}, // 9
{0x00,0x18,0x18,0x00,0x18,0x18,0x00,0x00}, // :
{0x00,0x18,0x18,0x00,0x18,0x18,0x30,0x00}, // ;
{0x06,0x0c,0x18,0x30,0x18,0x0c,0x06,0x00}, // <
{0x00,0x00,0x7e,0x00,0x7e,0x00,0x00,0x00}, // =
{0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00}, // >
{0x7c,0xc6,0x0c,0x18,0x18,0x00,0x18,0x00}, // ?
{0x7c,0xc6,0xde,0xde,0xdc,0xc0,0x7c,0x00}, // @
{0x38,0x6c,0xc6,0xfe,0xc6,0xc6,0xc6,0x00}, // A
{0xfc,0x66,0x66,0x7c,0x66,0x66,0xfc,0x00}, // B
{0x3c,0x66,0xc0,0xc0,0xc0,0x66,0x3c,0x00}, // C
{0xf8,0x6c,0x66,0x66,0x66,0x6c,0xf8,0x00}, // D
{0xfe,0x62,0x68,0x78,0x68,0x62,0xfe,0x00}, // E
{0xfe,0x62,0x68,0x78,0x68,0x60,0xf0,0x00}, // F
{0x3c,0x66,0xc0,0xc0,0xce,0x66,0x3e,0x00}, // G
{0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00}, // H
{0x3c,0x18,0x18,0x18,0x18,0x18,0x3c,0x00}, // I
{0x1e,0x0c,0x0c,0x0c,0xcc,0xcc,0x78,0x00}, // J
{0xe6,0x66,0x6c,0x78,0x6c,0x66,0xe6,0x00}, // K
{0xf0,0x60,0x60,0x60,0x62,0x66,0xfe,0x00}, // L
{0xc6,0xee,0xfe,0xd6,0xc6,0xc6,0xc6,0x00}, // M
{0xc6,0xe6,0xf6,0xde,0xce,0xc6,0xc6,0x00}, // N
{0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00}, // O
{0xfc,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00}, // P
{0x7c,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x06}, // Q
{0xfc,0x66,0x66,0x7c,0x6c,0x66,0xe6,0x00}, // R
{0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00}, // S
{0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x00}, // T
{0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00}, // U
{0xc6,0xc6,0xc6,0xc6,0xc6,0x6c,0x38,0x00}, // V
{0xc6,0xc6,0xc6,0xd6,0xfe,0xee,0xc6,0x00}, // W
{0xc6,0xc6,0x6c,0x38,0x6c,0xc6,0xc6,0x00}, // X
{0x66,0x66,0x66,0x3c,0x18,0x18,0x18,0x00}, // Y
{0xfe,0x06,0x0c,0x18,0x30,0x60,0xfe,0x00}, // Z
{0x3c,0x30,0x30,0x30,0x30,0x30,0x3c,0x00}, // [
{0xc0,0x60,0x30,0x18,0x0c,0x06,0x02,0x00}, // \
{0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00}, // ]
{0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00}, // ^
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, // _
{0x30,0x18,0x0c,0x00,0x00,0x00,0x00,0x00}, // `
{0x00,0x00,0x78,0x0c,0x7c,0xcc,0x76,0x00}, // a
{0xe0,0x60,0x7c,0x66,0x66,0x66,0xdc,0x00}, // b
{0x00,0x00,0x78,0xcc,0xc0,0xcc,0x78,0x00}, // c
{0x1c,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00}, // d
{0x00,0x00,0x78,0xcc,0xfc,0xc0,0x78,0x00}, // e
{0x38,0x6c,0x60,0xf0,0x60,0x60,0xf0,0x00}, // f
{0x00,0x00,0x76,0xcc,0xcc,0x7c,0x0c,0xf8}, // g
{0xe0,0x60,0x6c,0x76,0x66,0x66,0xe6,0x00}, // h
{0x18,0x00,0x38,0x18,0x18,0x18,0x3c,0x00}, // i
{0x0c,0x00,0x1c,0x0c,0x0c,0xcc,0xcc,0x78}, // j
{0xe0,0x60,0x66,0x6c,0x78,0x6c,0xe6,0x00}, // k
{0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00}, // l
{0x00,0x00,0xec,0xfe,0xd6,0xc6,0xc6,0x00}, // m
{0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x00}, // n
{0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0x00}, // o
{0x00,0x00,0xdc,0x66,0x66,0x7c,0x60,0xf0}, // p
{0x00,0x00,0x76,0xcc,0xcc,0x7c,0x0c,0x1e}, // q
{0x00,0x00,0xdc,0x76,0x60,0x60,0xf0,0x00}, // r
{0x00,0x00,0x7c,0xc0,0x78,0x0c,0xf8,0x00}, // s
{0x10,0x30,0x7c,0x30,0x30,0x34,0x18,0x00}, // t
{0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x76,0x00}, // u
{0x00,0x00,0xc6,0xc6,0xc6,0x6c,0x38,0x00}, // v
{0x00,0x00,0xc6,0xc6,0xd6,0xfe,0x6c,0x00}, // w
{0x00,0x00,0xc6,0x6c,0x38,0x6c,0xc6,0x00}, // x
{0x00,0x00,0xcc,0xcc,0xcc,0x7c,0x0c,0xf8}, // y
{0x00,0x00,0xfc,0x18,0x30,0x60,0xfc,0x00}, // z
{0x0e,0x18,0x18,0x70,0x18,0x18,0x0e,0x00}, // {
{0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00}, // |
{0x70,0x18,0x18,0x0e,0x18,0x18,0x70,0x00}, // }
{0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // DEL
};
void gui_gfx_init(uint32_t* fb, int width, int height) {
g_frontbuffer = fb;
g_width = (width > 0) ? width : 320;
g_height = (height > 0) ? height : 200;
if (!g_backbuffer) {
g_backbuffer = (uint32_t*)kzalloc(g_width * g_height * sizeof(uint32_t));
}
}
int gui_gfx_get_width(void) { return g_width; }
int gui_gfx_get_height(void) { return g_height; }
uint32_t* gui_gfx_get_backbuffer(void) { return g_backbuffer; }
void gui_gfx_clear(uint32_t color) {
if (!g_backbuffer) return;
size_t count = g_width * g_height;
for (size_t i = 0; i < count; i++) {
g_backbuffer[i] = color;
}
}
void gui_gfx_draw_pixel(int x, int y, uint32_t color) {
if (!g_backbuffer || x < 0 || y < 0 || x >= g_width || y >= g_height) return;
g_backbuffer[y * g_width + x] = color;
}
void gui_gfx_draw_pixel_blend(int x, int y, uint32_t color, uint8_t alpha) {
if (!g_backbuffer || x < 0 || y < 0 || x >= g_width || y >= g_height) return;
uint32_t bg = g_backbuffer[y * g_width + x];
g_backbuffer[y * g_width + x] = gui_color_alpha_blend(bg, color, alpha);
}
void gui_gfx_draw_line(int x0, int y0, int x1, int y1, uint32_t color) {
int dx = (x1 > x0) ? (x1 - x0) : (x0 - x1);
int dy = (y1 > y0) ? (y1 - y0) : (y0 - y1);
int sx = (x0 < x1) ? 1 : -1;
int sy = (y0 < y1) ? 1 : -1;
int err = dx - dy;
while (1) {
gui_gfx_draw_pixel(x0, y0, color);
if (x0 == x1 && y0 == y1) break;
int e2 = 2 * err;
if (e2 > -dy) { err -= dy; x0 += sx; }
if (e2 < dx) { err += dx; y0 += sy; }
}
}
void gui_gfx_draw_rect(int x, int y, int w, int h, uint32_t color) {
gui_gfx_draw_line(x, y, x + w - 1, y, color);
gui_gfx_draw_line(x, y + h - 1, x + w - 1, y + h - 1, color);
gui_gfx_draw_line(x, y, x, y + h - 1, color);
gui_gfx_draw_line(x + w - 1, y, x + w - 1, y + h - 1, color);
}
void gui_gfx_fill_rect(int x, int y, int w, int h, uint32_t color) {
if (!g_backbuffer) return;
if (x < 0) { w += x; x = 0; }
if (y < 0) { h += y; y = 0; }
if (x + w > g_width) w = g_width - x;
if (y + h > g_height) h = g_height - y;
if (w <= 0 || h <= 0) return;
for (int j = y; j < y + h; j++) {
uint32_t* row = &g_backbuffer[j * g_width + x];
for (int i = 0; i < w; i++) {
row[i] = color;
}
}
}
void gui_gfx_fill_rect_blend(int x, int y, int w, int h, uint32_t color, uint8_t alpha) {
if (!g_backbuffer) return;
if (x < 0) { w += x; x = 0; }
if (y < 0) { h += y; y = 0; }
if (x + w > g_width) w = g_width - x;
if (y + h > g_height) h = g_height - y;
if (w <= 0 || h <= 0) return;
for (int j = y; j < y + h; j++) {
uint32_t* row = &g_backbuffer[j * g_width + x];
for (int i = 0; i < w; i++) {
row[i] = gui_color_alpha_blend(row[i], color, alpha);
}
}
}
void gui_gfx_draw_rounded_rect(int x, int y, int w, int h, int r, uint32_t color, bool filled) {
if (r <= 0) {
if (filled) gui_gfx_fill_rect(x, y, w, h, color);
else gui_gfx_draw_rect(x, y, w, h, color);
return;
}
if (filled) {
gui_gfx_fill_rect(x + r, y, w - 2 * r, h, color);
gui_gfx_fill_rect(x, y + r, r, h - 2 * r, color);
gui_gfx_fill_rect(x + w - r, y + r, r, h - 2 * r, color);
} else {
gui_gfx_draw_line(x + r, y, x + w - r, y, color);
gui_gfx_draw_line(x + r, y + h - 1, x + w - r, y + h - 1, color);
gui_gfx_draw_line(x, y + r, x, y + h - r, color);
gui_gfx_draw_line(x + w - 1, y + r, x + w - 1, y + h - r, color);
}
}
void gui_gfx_draw_gradient_v(int x, int y, int w, int h, uint32_t top_col, uint32_t bot_col) {
if (h <= 0 || w <= 0) return;
for (int j = 0; j < h; j++) {
uint8_t factor = (uint8_t)((j * 255) / h);
uint32_t row_col = gui_color_alpha_blend(top_col, bot_col, factor);
gui_gfx_fill_rect(x, y + j, w, 1, row_col);
}
}
void gui_gfx_draw_gradient_h(int x, int y, int w, int h, uint32_t left_col, uint32_t right_col) {
if (w <= 0 || h <= 0) return;
for (int i = 0; i < w; i++) {
uint8_t factor = (uint8_t)((i * 255) / w);
uint32_t col = gui_color_alpha_blend(left_col, right_col, factor);
gui_gfx_fill_rect(x + i, y, 1, h, col);
}
}
void gui_gfx_draw_char(int x, int y, char c, uint32_t fg, uint32_t bg, bool transparent_bg) {
if (c < 32 || c > 126) c = '?';
const uint8_t* glyph = font8x8[c - 32];
for (int row = 0; row < 8; row++) {
uint8_t bits = glyph[row];
for (int col = 0; col < 8; col++) {
if (bits & (1 << (7 - col))) {
gui_gfx_draw_pixel(x + col, y + row, fg);
} else if (!transparent_bg) {
gui_gfx_draw_pixel(x + col, y + row, bg);
}
}
}
}
void gui_gfx_draw_string(int x, int y, const char* str, uint32_t fg) {
if (!str) return;
int cx = x;
while (*str) {
gui_gfx_draw_char(cx, y, *str, fg, 0, true);
cx += 8;
str++;
}
}
void gui_gfx_draw_string_bg(int x, int y, const char* str, uint32_t fg, uint32_t bg) {
if (!str) return;
int cx = x;
while (*str) {
gui_gfx_draw_char(cx, y, *str, fg, bg, false);
cx += 8;
str++;
}
}
void gui_gfx_draw_string_shadow(int x, int y, const char* str, uint32_t fg, uint32_t shadow) {
gui_gfx_draw_string(x + 1, y + 1, str, shadow);
gui_gfx_draw_string(x, y, str, fg);
}
void gui_gfx_draw_shadow(int x, int y, int w, int h, int blur) {
for (int r = 1; r <= blur; r++) {
uint8_t alpha = (uint8_t)(60 / r);
gui_gfx_fill_rect_blend(x + r, y + h, w, r, GUI_COLOR_BLACK, alpha);
gui_gfx_fill_rect_blend(x + w, y + r, r, h, GUI_COLOR_BLACK, alpha);
}
}
void gui_gfx_blit(int dx, int dy, int w, int h, const uint32_t* src_buf) {
if (!g_backbuffer || !src_buf) return;
for (int j = 0; j < h; j++) {
int py = dy + j;
if (py < 0 || py >= g_height) continue;
for (int i = 0; i < w; i++) {
int px = dx + i;
if (px < 0 || px >= g_width) continue;
uint32_t pixel = src_buf[j * w + i];
if ((pixel >> 24) > 0) {
g_backbuffer[py * g_width + px] = pixel;
}
}
}
}
void gui_gfx_present(void) {
if (g_frontbuffer && g_backbuffer) {
memcpy(g_frontbuffer, g_backbuffer, g_width * g_height * sizeof(uint32_t));
}
}