mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
269 lines
11 KiB
C
269 lines
11 KiB
C
#include <drivers/canvas.h>
|
|
#include <drivers/fb.h>
|
|
#include <mm/kmalloc.h>
|
|
#include <lib/string.h>
|
|
#include <kernel/printk.h>
|
|
|
|
static uint32_t* back_buffer = NULL;
|
|
static uint32_t screen_width = 320;
|
|
static uint32_t screen_height = 200;
|
|
|
|
// Basic 8x8 font bitmap for ASCII characters (32..126)
|
|
static const uint8_t font8x8_basic[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,0x3a,0x00}, // G
|
|
{0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00}, // H
|
|
{0x7e,0x18,0x18,0x18,0x18,0x18,0x7e,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,0xfe,0xd6,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,0x7c,0x0e,0x00}, // 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,0x6c,0x38,0x10,0x00}, // V
|
|
{0xc6,0xc6,0xd6,0xfe,0xfe,0xee,0xc6,0x00}, // W
|
|
{0xc6,0x6c,0x38,0x38,0x6c,0xc6,0x00,0x00}, // X
|
|
{0x66,0x66,0x66,0x3c,0x18,0x18,0x3c,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,0xd6,0xd6,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,0xd6,0xfe,0xfe,0x6c,0x00}, // w
|
|
{0x00,0x00,0xc6,0x6c,0x38,0x6c,0xc6,0x00}, // x
|
|
{0x00,0x00,0xc6,0xc6,0xce,0x76,0x06,0x7c}, // y
|
|
{0x00,0x00,0xfe,0x0c,0x38,0x60,0xfe,0x00}, // z
|
|
};
|
|
|
|
void canvas_init(void) {
|
|
const fb_info_t* fb = fb_get_info();
|
|
if (fb && fb->width > 0 && fb->height > 0) {
|
|
screen_width = fb->width;
|
|
screen_height = fb->height;
|
|
}
|
|
back_buffer = (uint32_t*)kzalloc(screen_width * screen_height * sizeof(uint32_t));
|
|
printk(KERN_INFO "CANVAS: 2D Graphics Canvas & Rasterizer online (%ux%u 32bpp)\n",
|
|
screen_width, screen_height);
|
|
}
|
|
|
|
void canvas_clear(uint32_t color) {
|
|
if (!back_buffer) return;
|
|
for (size_t i = 0; i < screen_width * screen_height; i++) {
|
|
back_buffer[i] = color;
|
|
}
|
|
}
|
|
|
|
void canvas_draw_pixel(int x, int y, uint32_t color) {
|
|
if (!back_buffer || x < 0 || x >= (int)screen_width || y < 0 || y >= (int)screen_height) return;
|
|
back_buffer[y * screen_width + x] = color;
|
|
}
|
|
|
|
void canvas_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 ? dx : -dy) / 2;
|
|
|
|
while (1) {
|
|
canvas_draw_pixel(x0, y0, color);
|
|
if (x0 == x1 && y0 == y1) break;
|
|
int e2 = err;
|
|
if (e2 > -dx) { err -= dy; x0 += sx; }
|
|
if (e2 < dy) { err += dx; y0 += sy; }
|
|
}
|
|
}
|
|
|
|
void canvas_draw_rect(int x, int y, int w, int h, uint32_t color, bool filled) {
|
|
if (w <= 0 || h <= 0) return;
|
|
if (filled) {
|
|
for (int j = y; j < y + h; j++) {
|
|
for (int i = x; i < x + w; i++) {
|
|
canvas_draw_pixel(i, j, color);
|
|
}
|
|
}
|
|
} else {
|
|
canvas_draw_line(x, y, x + w - 1, y, color);
|
|
canvas_draw_line(x, y + h - 1, x + w - 1, y + h - 1, color);
|
|
canvas_draw_line(x, y, x, y + h - 1, color);
|
|
canvas_draw_line(x + w - 1, y, x + w - 1, y + h - 1, color);
|
|
}
|
|
}
|
|
|
|
void canvas_draw_circle(int cx, int cy, int r, uint32_t color, bool filled) {
|
|
int x = r;
|
|
int y = 0;
|
|
int err = 0;
|
|
|
|
while (x >= y) {
|
|
if (filled) {
|
|
canvas_draw_line(cx - x, cy + y, cx + x, cy + y, color);
|
|
canvas_draw_line(cx - x, cy - y, cx + x, cy - y, color);
|
|
canvas_draw_line(cx - y, cy + x, cx + y, cy + x, color);
|
|
canvas_draw_line(cx - y, cy - x, cx + y, cy - x, color);
|
|
} else {
|
|
canvas_draw_pixel(cx + x, cy + y, color);
|
|
canvas_draw_pixel(cx + y, cy + x, color);
|
|
canvas_draw_pixel(cx - y, cy + x, color);
|
|
canvas_draw_pixel(cx - x, cy + y, color);
|
|
canvas_draw_pixel(cx - x, cy - y, color);
|
|
canvas_draw_pixel(cx - y, cy - x, color);
|
|
canvas_draw_pixel(cx + y, cy - x, color);
|
|
canvas_draw_pixel(cx + x, cy - y, color);
|
|
}
|
|
if (err <= 0) {
|
|
y += 1;
|
|
err += 2*y + 1;
|
|
}
|
|
if (err > 0) {
|
|
x -= 1;
|
|
err -= 2*x + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void canvas_draw_char(int x, int y, char c, uint32_t color, uint32_t bg_color) {
|
|
if (c < 32 || c > 126) c = ' ';
|
|
const uint8_t* glyph = font8x8_basic[c - 32];
|
|
|
|
for (int row = 0; row < 8; row++) {
|
|
uint8_t line = glyph[row];
|
|
for (int col = 0; col < 8; col++) {
|
|
if (line & (1 << (7 - col))) {
|
|
canvas_draw_pixel(x + col, y + row, color);
|
|
} else if (bg_color != 0) {
|
|
canvas_draw_pixel(x + col, y + row, bg_color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void canvas_draw_string(int x, int y, const char* str, uint32_t color, uint32_t bg_color) {
|
|
if (!str) return;
|
|
int cur_x = x;
|
|
while (*str) {
|
|
canvas_draw_char(cur_x, y, *str, color, bg_color);
|
|
cur_x += 8;
|
|
str++;
|
|
}
|
|
}
|
|
|
|
void canvas_render_desktop_mockup(void) {
|
|
// 1. Wallpaper (Navy Gradient)
|
|
canvas_clear(COLOR_NAVY);
|
|
|
|
// 2. Top Banner / Desktop Header
|
|
canvas_draw_rect(0, 0, screen_width, 16, COLOR_TITLE_BAR, true);
|
|
canvas_draw_string(8, 4, "SUB-OS Graphical Desktop Environment v0.2.0", COLOR_WHITE, 0);
|
|
canvas_draw_string(screen_width - 80, 4, "13:45 UTC", COLOR_YELLOW, 0);
|
|
|
|
// 3. Floating Terminal Window (Simulated Window Manager)
|
|
int win_x = 24, win_y = 30, win_w = 270, win_h = 135;
|
|
canvas_draw_rect(win_x, win_y, win_w, win_h, COLOR_DARK_GRAY, true);
|
|
canvas_draw_rect(win_x, win_y, win_w, win_h, COLOR_LIGHT_GRAY, false);
|
|
|
|
// Window Title Bar
|
|
canvas_draw_rect(win_x, win_y, win_w, 14, COLOR_ACCENT, true);
|
|
canvas_draw_string(win_x + 6, win_y + 3, "Terminal - root@sub-os:~", COLOR_WHITE, 0);
|
|
canvas_draw_circle(win_x + win_w - 8, win_y + 7, 3, COLOR_RED, true);
|
|
canvas_draw_circle(win_x + win_w - 18, win_y + 7, 3, COLOR_YELLOW, true);
|
|
canvas_draw_circle(win_x + win_w - 28, win_y + 7, 3, COLOR_GREEN, true);
|
|
|
|
// Window Content
|
|
canvas_draw_string(win_x + 8, win_y + 22, "Welcome to SUB-OS Kernel 0.2.0", COLOR_GREEN, 0);
|
|
canvas_draw_string(win_x + 8, win_y + 36, "Tasks: 16 running | Memory: 122MB Free", COLOR_WHITE, 0);
|
|
canvas_draw_string(win_x + 8, win_y + 50, "Services: HTTPD, SSHD, NetFilter active", COLOR_YELLOW, 0);
|
|
canvas_draw_string(win_x + 8, win_y + 68, "sub-os:/> neofetch", COLOR_CYAN, 0);
|
|
canvas_draw_string(win_x + 8, win_y + 82, "OS: SUB-OS (x86_64 Long Mode)", COLOR_WHITE, 0);
|
|
canvas_draw_string(win_x + 8, win_y + 96, "Kernel: 0.2.0-lts Modular Monolithic", COLOR_WHITE, 0);
|
|
canvas_draw_string(win_x + 8, win_y + 112, "sub-os:/> _", COLOR_GREEN, 0);
|
|
|
|
// 4. Bottom Taskbar
|
|
canvas_draw_rect(0, screen_height - 18, screen_width, 18, COLOR_TITLE_BAR, true);
|
|
canvas_draw_rect(4, screen_height - 15, 45, 12, COLOR_ACCENT, true);
|
|
canvas_draw_string(8, screen_height - 13, "Start", COLOR_WHITE, 0);
|
|
canvas_draw_string(60, screen_height - 13, "[Terminal]", COLOR_LIGHT_GRAY, 0);
|
|
canvas_draw_string(140, screen_height - 13, "[Nano]", COLOR_LIGHT_GRAY, 0);
|
|
canvas_draw_string(195, screen_height - 13, "[HTTPD: 80]", COLOR_GREEN, 0);
|
|
canvas_draw_string(screen_width - 45, screen_height - 13, "[OK]", COLOR_YELLOW, 0);
|
|
|
|
canvas_present();
|
|
}
|
|
|
|
void canvas_present(void) {
|
|
if (!back_buffer) return;
|
|
const fb_info_t* fb = fb_get_info();
|
|
if (fb && fb->address != 0) {
|
|
uint32_t* hw_fb = (uint32_t*)fb->address;
|
|
memcpy(hw_fb, back_buffer, screen_width * screen_height * sizeof(uint32_t));
|
|
}
|
|
}
|