mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 10:48:38 +00:00
graphics settings
This commit is contained in:
parent
d19075750b
commit
93b59064c7
13 changed files with 431 additions and 8 deletions
BIN
boredos.iso
BIN
boredos.iso
Binary file not shown.
BIN
build/explorer.o
BIN
build/explorer.o
Binary file not shown.
BIN
build/graphics.o
BIN
build/graphics.o
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
|
|
@ -12,6 +12,8 @@ static uint32_t g_bg_color = 0xFF696969;
|
|||
|
||||
extern void serial_write(const char *str);
|
||||
|
||||
static int g_color_mode = 0;
|
||||
|
||||
#define PATTERN_SIZE 128
|
||||
static uint32_t g_bg_pattern[PATTERN_SIZE * PATTERN_SIZE];
|
||||
static bool g_use_pattern = false;
|
||||
|
|
@ -54,6 +56,30 @@ void graphics_init_fonts(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void graphics_update_resolution(int width, int height, int bpp, void* fb_addr, int color_mode) {
|
||||
if (!g_fb) return;
|
||||
|
||||
uint64_t rflags;
|
||||
asm volatile("pushfq; pop %0; cli" : "=r"(rflags));
|
||||
|
||||
g_fb->width = width;
|
||||
g_fb->height = height;
|
||||
g_fb->bpp = bpp;
|
||||
g_fb->pitch = width * (bpp / 8);
|
||||
g_fb->address = fb_addr;
|
||||
g_color_mode = color_mode;
|
||||
|
||||
// Clear back buffer
|
||||
for (int i = 0; i < MAX_FB_WIDTH * MAX_FB_HEIGHT; i++) {
|
||||
g_back_buffer[i] = 0;
|
||||
}
|
||||
|
||||
// Clear dirty rect
|
||||
g_dirty.active = false;
|
||||
|
||||
asm volatile("push %0; popfq" : : "r"(rflags));
|
||||
}
|
||||
|
||||
void graphics_set_font(const char *path) {
|
||||
ttf_font_t *new_font = font_manager_load(path, 15.0f);
|
||||
if (new_font) {
|
||||
|
|
@ -576,9 +602,67 @@ void graphics_flip_buffer(void) {
|
|||
for (int i = 0; i < h; i++) {
|
||||
int curr_y = y + i;
|
||||
uint32_t *src_row = &g_back_buffer[curr_y * g_fb->width + x];
|
||||
uint32_t *dst_row = (uint32_t *)((uint8_t *)g_fb->address + curr_y * g_fb->pitch) + x;
|
||||
for (int j = 0; j < w; j++) {
|
||||
dst_row[j] = src_row[j];
|
||||
|
||||
if (g_fb->bpp == 32) {
|
||||
uint32_t *dst_row = (uint32_t *)((uint8_t *)g_fb->address + curr_y * g_fb->pitch) + x;
|
||||
for (int j = 0; j < w; j++) {
|
||||
dst_row[j] = src_row[j];
|
||||
}
|
||||
} else if (g_fb->bpp == 16) {
|
||||
uint16_t *dst_row = (uint16_t *)((uint8_t *)g_fb->address + curr_y * g_fb->pitch) + x;
|
||||
for (int j = 0; j < w; j++) {
|
||||
uint32_t c = src_row[j];
|
||||
uint16_t r = ((c >> 16) & 0xFF) >> 3;
|
||||
uint16_t g = ((c >> 8) & 0xFF) >> 2;
|
||||
uint16_t b = (c & 0xFF) >> 3;
|
||||
dst_row[j] = (r << 11) | (g << 5) | b;
|
||||
}
|
||||
} else if (g_fb->bpp == 8) {
|
||||
uint8_t *dst_row = (uint8_t *)((uint8_t *)g_fb->address + curr_y * g_fb->pitch) + x;
|
||||
if (g_color_mode == 1) { // Grayscale
|
||||
for (int j = 0; j < w; j++) {
|
||||
uint32_t c = src_row[j];
|
||||
uint8_t r = (c >> 16) & 0xFF;
|
||||
uint8_t g = (c >> 8) & 0xFF;
|
||||
uint8_t b = c & 0xFF;
|
||||
dst_row[j] = (uint8_t)((r * 77 + g * 150 + b * 29) >> 8);
|
||||
}
|
||||
} else if (g_color_mode == 2) { // Monochrome
|
||||
static const uint8_t bayer2[2][2] = {
|
||||
{ 0, 128 },
|
||||
{192, 64 }
|
||||
};
|
||||
for (int j = 0; j < w; j++) {
|
||||
uint32_t c = src_row[j];
|
||||
uint8_t r = (c >> 16) & 0xFF;
|
||||
uint8_t g = (c >> 8) & 0xFF;
|
||||
uint8_t b = c & 0xFF;
|
||||
|
||||
int gray = (r * 77 + g * 150 + b * 29) >> 8;
|
||||
|
||||
// Boost contrast by 2x to separate the dark UI colors:
|
||||
// Background (~30) -> 60
|
||||
// Panel (~40) -> 80
|
||||
// With thresholds {0, 64, 128, 192}:
|
||||
// BG > 0 (1/4 white), Panel > 64 (2/4 white - checkerboard)
|
||||
// Text (~170) -> 255 (solid white)
|
||||
gray = gray * 2;
|
||||
if (gray > 255) gray = 255;
|
||||
|
||||
int sx = x + j;
|
||||
uint8_t threshold = bayer2[curr_y & 1][sx & 1];
|
||||
|
||||
dst_row[j] = (gray > threshold) ? 255 : 0;
|
||||
}
|
||||
} else { // 256 Colors (Standard)
|
||||
for (int j = 0; j < w; j++) {
|
||||
uint32_t c = src_row[j];
|
||||
uint8_t r = ((c >> 16) & 0xFF) >> 5;
|
||||
uint8_t g = ((c >> 8) & 0xFF) >> 5;
|
||||
uint8_t b = (c & 0xFF) >> 6;
|
||||
dst_row[j] = (r << 5) | (g << 2) | b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ void draw_boredos_logo(int x, int y, int scale);
|
|||
// Get screen dimensions
|
||||
int get_screen_width(void);
|
||||
int get_screen_height(void);
|
||||
void graphics_update_resolution(int width, int height, int bpp, void* fb_addr, int color_mode);
|
||||
|
||||
// Dirty rectangle management
|
||||
void graphics_mark_dirty(int x, int y, int w, int h);
|
||||
|
|
|
|||
|
|
@ -1156,6 +1156,30 @@ static uint64_t syscall_handler_inner(registers_t *regs) {
|
|||
extern void mem_memcpy(void *dest, const void *src, size_t len);
|
||||
mem_memcpy(user_buf, model, 49);
|
||||
return 0;
|
||||
} else if (cmd == 47) { // SYSTEM_CMD_SET_RESOLUTION
|
||||
uint16_t req_w = (uint16_t)arg2;
|
||||
uint16_t req_h = (uint16_t)arg3;
|
||||
uint16_t req_bpp = (uint16_t)arg4;
|
||||
int req_color_mode = (int)arg5;
|
||||
|
||||
extern bool vga_set_mode(uint16_t width, uint16_t height, uint16_t bpp, void **out_framebuffer);
|
||||
extern void graphics_update_resolution(int width, int height, int bpp, void* fb_addr, int color_mode);
|
||||
extern void wm_refresh(void);
|
||||
extern void vga_set_palette_grayscale(void);
|
||||
extern void vga_set_palette_standard(void);
|
||||
|
||||
void *new_fb = NULL;
|
||||
if (vga_set_mode(req_w, req_h, req_bpp, &new_fb)) {
|
||||
if (req_color_mode == 1 || req_color_mode == 2) {
|
||||
vga_set_palette_grayscale();
|
||||
} else if (req_bpp <= 8) {
|
||||
vga_set_palette_standard();
|
||||
}
|
||||
graphics_update_resolution(req_w, req_h, req_bpp, new_fb, req_color_mode);
|
||||
wm_refresh();
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ typedef struct registers_t registers_t;
|
|||
#define SYSTEM_CMD_PROCESS_LIST 44
|
||||
#define SYSTEM_CMD_GET_CPU_MODEL 45
|
||||
#define SYSTEM_CMD_SLEEP 46
|
||||
#define SYSTEM_CMD_SET_RESOLUTION 47
|
||||
|
||||
void syscall_init(void);
|
||||
uint64_t syscall_handler_c(registers_t *regs);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ extern uint64_t syscall5(uint64_t sys_num, uint64_t arg1, uint64_t arg2, uint64_
|
|||
|
||||
// sys_gui uses syscall #3
|
||||
#define SYS_GUI 3
|
||||
#define GUI_CMD_GET_SCREEN_SIZE 17
|
||||
|
||||
ui_window_t ui_window_create(const char *title, int x, int y, int w, int h) {
|
||||
uint64_t params[4] = { (uint64_t)x, (uint64_t)y, (uint64_t)w, (uint64_t)h };
|
||||
|
|
@ -58,6 +59,10 @@ uint32_t ui_get_font_height(void) {
|
|||
return (uint32_t)syscall3(SYS_GUI, GUI_CMD_GET_FONT_HEIGHT, 0, 0);
|
||||
}
|
||||
|
||||
void ui_get_screen_size(uint64_t *out_w, uint64_t *out_h) {
|
||||
syscall3(SYS_GUI, GUI_CMD_GET_SCREEN_SIZE, (uint64_t)out_w, (uint64_t)out_h);
|
||||
}
|
||||
|
||||
void ui_draw_string_scaled(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale) {
|
||||
uint64_t coords = ((uint64_t)x & 0xFFFFFFFF) | ((uint64_t)y << 32);
|
||||
// Pack color into lower 32, scale (as uint32_t representation) into upper 32
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ void ui_mark_dirty(ui_window_t win, int x, int y, int w, int h);
|
|||
void ui_draw_image(ui_window_t win, int x, int y, int w, int h, uint32_t *image_data);
|
||||
uint32_t ui_get_string_width(const char *str);
|
||||
uint32_t ui_get_font_height(void);
|
||||
void ui_get_screen_size(uint64_t *out_w, uint64_t *out_h);
|
||||
void ui_draw_string_bitmap(ui_window_t win, int x, int y, const char *str, uint32_t color);
|
||||
|
||||
void ui_draw_string_scaled(ui_window_t win, int x, int y, const char *str, uint32_t color, float scale);
|
||||
|
|
|
|||
|
|
@ -29,14 +29,47 @@
|
|||
#define VIEW_DESKTOP 3
|
||||
#define VIEW_MOUSE 4
|
||||
#define VIEW_FONTS 5
|
||||
#define VIEW_DISPLAY 6
|
||||
|
||||
static int disp_sel_res = 2;
|
||||
static int disp_sel_color = 0;
|
||||
|
||||
static int current_view = VIEW_MAIN;
|
||||
static char rgb_r[4] = "";
|
||||
static char rgb_g[4] = "";
|
||||
static char rgb_b[4] = "";
|
||||
static char custom_res_w[6] = "";
|
||||
static char custom_res_h[6] = "";
|
||||
static int focused_field = -1;
|
||||
static int input_cursor = 0;
|
||||
|
||||
static int dyn_res_w[3];
|
||||
static int dyn_res_h[3];
|
||||
static char dyn_res_str[3][32];
|
||||
|
||||
static void init_dynamic_resolutions(void) {
|
||||
uint64_t phys_w = 1920, phys_h = 1080;
|
||||
ui_get_screen_size(&phys_w, &phys_h);
|
||||
|
||||
dyn_res_w[2] = (int)phys_w; dyn_res_h[2] = (int)phys_h;
|
||||
dyn_res_w[1] = (int)((phys_w * 3) / 4); dyn_res_h[1] = (int)((phys_h * 3) / 4);
|
||||
dyn_res_w[0] = (int)(phys_w / 2); dyn_res_h[0] = (int)(phys_h / 2);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
dyn_res_w[i] &= ~1;
|
||||
dyn_res_h[i] &= ~1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char bw[16], bh[16];
|
||||
itoa(dyn_res_w[i], bw);
|
||||
itoa(dyn_res_h[i], bh);
|
||||
strcpy(dyn_res_str[i], bw);
|
||||
strcat(dyn_res_str[i], "x");
|
||||
strcat(dyn_res_str[i], bh);
|
||||
}
|
||||
}
|
||||
|
||||
static char net_status[64] = "";
|
||||
|
||||
// Pattern buffers (128x128)
|
||||
|
|
@ -248,6 +281,17 @@ static void control_panel_paint_main(ui_window_t win) {
|
|||
ui_draw_string(win, offset_x + 14, offset_y + item_y + 10, "Aa", 0xFF6A9EF5);
|
||||
ui_draw_string(win, offset_x + 60, offset_y + item_y + 15, "Fonts", COLOR_DARK_TEXT);
|
||||
ui_draw_string(win, offset_x + 60, offset_y + item_y + 35, "Choose system font", COLOR_DKGRAY);
|
||||
|
||||
// Display
|
||||
item_y += item_h + item_spacing;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, offset_y + item_y, win_w - 16, item_h, 8, COLOR_DARK_PANEL);
|
||||
// Monitor icon
|
||||
ui_draw_rect(win, offset_x + 14, offset_y + item_y + 12, 32, 22, 0xFF4A90E2);
|
||||
ui_draw_rect(win, offset_x + 16, offset_y + item_y + 14, 28, 18, 0xFF87CEEB);
|
||||
ui_draw_rect(win, offset_x + 26, offset_y + item_y + 34, 8, 4, 0xFFB0B0B0);
|
||||
ui_draw_rect(win, offset_x + 22, offset_y + item_y + 38, 16, 2, 0xFFB0B0B0);
|
||||
ui_draw_string(win, offset_x + 60, offset_y + item_y + 15, "Display", COLOR_DARK_TEXT);
|
||||
ui_draw_string(win, offset_x + 60, offset_y + item_y + 35, "Screen resolution & color", COLOR_DKGRAY);
|
||||
}
|
||||
|
||||
static void control_panel_paint_wallpaper(ui_window_t win) {
|
||||
|
|
@ -507,6 +551,73 @@ static void control_panel_paint_fonts(ui_window_t win) {
|
|||
}
|
||||
}
|
||||
|
||||
static void control_panel_paint_display(ui_window_t win) {
|
||||
int offset_x = 8;
|
||||
int offset_y = 6;
|
||||
int right_x = offset_x + 160;
|
||||
|
||||
ui_draw_rounded_rect_filled(win, offset_x, offset_y + 5, 80, 25, 6, COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 10, offset_y + 13, "< Back", COLOR_DARK_TEXT);
|
||||
ui_draw_string(win, offset_x, offset_y + 40, "Resolution:", COLOR_DARK_TEXT);
|
||||
|
||||
int btn_y = offset_y + 60;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 140, 30, 6, (disp_sel_res == 0) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 30, btn_y + 10, "640x480", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 140, 30, 6, (disp_sel_res == 1) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 30, btn_y + 10, "800x600", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 140, 30, 6, (disp_sel_res == 2) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 30, btn_y + 10, dyn_res_str[0], COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 140, 30, 6, (disp_sel_res == 3) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 30, btn_y + 10, dyn_res_str[1], COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 140, 30, 6, (disp_sel_res == 4) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 30, btn_y + 10, dyn_res_str[2], COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 140, 30, 6, (disp_sel_res == 5) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 30, btn_y + 10, "Custom:", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 60, 25, 4, (focused_field == 3) ? 0xFF4A90E2 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 5, btn_y + 7, custom_res_w[0] ? custom_res_w : "W", (custom_res_w[0] || focused_field == 3) ? 0xFFFFFFFF : 0xFF888888);
|
||||
ui_draw_string(win, offset_x + 65, btn_y + 7, "x", COLOR_DARK_TEXT);
|
||||
ui_draw_rounded_rect_filled(win, offset_x + 80, btn_y, 60, 25, 4, (focused_field == 4) ? 0xFF4A90E2 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, offset_x + 85, btn_y + 7, custom_res_h[0] ? custom_res_h : "H", (custom_res_h[0] || focused_field == 4) ? 0xFFFFFFFF : 0xFF888888);
|
||||
|
||||
btn_y = offset_y + 60;
|
||||
ui_draw_string(win, right_x, offset_y + 40, "Color Depth:", COLOR_DARK_TEXT);
|
||||
|
||||
ui_draw_rounded_rect_filled(win, right_x, btn_y, 140, 30, 6, (disp_sel_color == 0) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, right_x + 40, btn_y + 10, "32-bit", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, right_x, btn_y, 140, 30, 6, (disp_sel_color == 1) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, right_x + 40, btn_y + 10, "16-bit", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, right_x, btn_y, 140, 30, 6, (disp_sel_color == 2) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, right_x + 25, btn_y + 10, "256 Colors", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, right_x, btn_y, 140, 30, 6, (disp_sel_color == 3) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, right_x + 30, btn_y + 10, "Grayscale", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y += 35;
|
||||
ui_draw_rounded_rect_filled(win, right_x, btn_y, 140, 30, 6, (disp_sel_color == 4) ? 0xFF3D5A80 : COLOR_DARK_PANEL);
|
||||
ui_draw_string(win, right_x + 25, btn_y + 10, "Monochrome", COLOR_DARK_TEXT);
|
||||
|
||||
btn_y = offset_y + 320;
|
||||
ui_draw_rounded_rect_filled(win, offset_x, btn_y, 300, 35, 6, 0xFF4A90E2);
|
||||
ui_draw_string(win, offset_x + 125, btn_y + 12, "Apply", 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static void control_panel_paint(ui_window_t win) {
|
||||
// Fill background
|
||||
ui_draw_rect(win, 0, 0, 350, 500, COLOR_DARK_BG);
|
||||
|
|
@ -523,6 +634,8 @@ static void control_panel_paint(ui_window_t win) {
|
|||
control_panel_paint_mouse(win);
|
||||
} else if (current_view == VIEW_FONTS) {
|
||||
control_panel_paint_fonts(win);
|
||||
} else if (current_view == VIEW_DISPLAY) {
|
||||
control_panel_paint_display(win);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -544,6 +657,7 @@ static void fetch_kernel_state(void) {
|
|||
desktop_max_cols = sys_system(7, 4, 0, 0, 0);
|
||||
mouse_speed = sys_system(8 /*GET_MOUSE_SPEED*/, 0, 0, 0, 0);
|
||||
|
||||
init_dynamic_resolutions();
|
||||
load_wallpapers();
|
||||
}
|
||||
|
||||
|
|
@ -579,6 +693,10 @@ static void control_panel_handle_click(int x, int y) {
|
|||
current_view = VIEW_FONTS;
|
||||
if (font_count == 0) load_fonts();
|
||||
}
|
||||
item_y += item_h + item_spacing;
|
||||
if (x >= offset_x && x < win_w - 8 && y >= item_y && y < item_y + item_h) {
|
||||
current_view = VIEW_DISPLAY;
|
||||
}
|
||||
} else if (current_view == VIEW_WALLPAPER) {
|
||||
int offset_x = 8;
|
||||
int offset_y = 6;
|
||||
|
|
@ -762,6 +880,73 @@ static void control_panel_handle_click(int x, int y) {
|
|||
}
|
||||
item_y += 40;
|
||||
}
|
||||
} else if (current_view == VIEW_DISPLAY) {
|
||||
int offset_x = 8;
|
||||
int offset_y = 6;
|
||||
int right_x = offset_x + 160;
|
||||
|
||||
if (x >= offset_x && x < offset_x + 80 && y >= offset_y + 5 && y < offset_y + 30) {
|
||||
current_view = VIEW_MAIN;
|
||||
return;
|
||||
}
|
||||
|
||||
int btn_y = offset_y + 60;
|
||||
if (x >= offset_x && x < offset_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_res = 0;
|
||||
if (x >= right_x && x < right_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_color = 0;
|
||||
|
||||
btn_y += 35;
|
||||
if (x >= offset_x && x < offset_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_res = 1;
|
||||
if (x >= right_x && x < right_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_color = 1;
|
||||
|
||||
btn_y += 35;
|
||||
if (x >= offset_x && x < offset_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_res = 2;
|
||||
if (x >= right_x && x < right_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_color = 2;
|
||||
|
||||
btn_y += 35;
|
||||
if (x >= offset_x && x < offset_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_res = 3;
|
||||
if (x >= right_x && x < right_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_color = 3;
|
||||
|
||||
btn_y += 35;
|
||||
if (x >= offset_x && x < offset_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_res = 4;
|
||||
if (x >= right_x && x < right_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_color = 4;
|
||||
|
||||
btn_y += 35;
|
||||
if (x >= offset_x && x < offset_x + 140 && y >= btn_y && y < btn_y + 30) disp_sel_res = 5;
|
||||
|
||||
// Custom Inputs
|
||||
btn_y += 35;
|
||||
if (x >= offset_x && x < offset_x + 60 && y >= btn_y && y < btn_y + 25) {
|
||||
focused_field = 3; disp_sel_res = 5;
|
||||
int len = 0; while (custom_res_w[len]) len++; input_cursor = len;
|
||||
}
|
||||
if (x >= offset_x + 80 && x < offset_x + 140 && y >= btn_y && y < btn_y + 25) {
|
||||
focused_field = 4; disp_sel_res = 5;
|
||||
int len = 0; while (custom_res_h[len]) len++; input_cursor = len;
|
||||
}
|
||||
|
||||
btn_y = offset_y + 320;
|
||||
if (x >= offset_x && x < offset_x + 300 && y >= btn_y && y < btn_y + 35) {
|
||||
int w = 1024, h = 768;
|
||||
if (disp_sel_res == 0) { w = 640; h = 480; }
|
||||
else if (disp_sel_res == 1) { w = 800; h = 600; }
|
||||
else if (disp_sel_res >= 2 && disp_sel_res <= 4) {
|
||||
w = dyn_res_w[disp_sel_res - 2];
|
||||
h = dyn_res_h[disp_sel_res - 2];
|
||||
} else if (disp_sel_res == 5) {
|
||||
extern int atoi(const char *str);
|
||||
int cw = atoi(custom_res_w);
|
||||
int ch = atoi(custom_res_h);
|
||||
if (cw >= 320 && ch >= 200) { w = cw; h = ch; }
|
||||
}
|
||||
|
||||
int bpp = 32, mode = 0;
|
||||
if (disp_sel_color == 1) { bpp = 16; }
|
||||
if (disp_sel_color == 2) { bpp = 8; mode = 0; }
|
||||
if (disp_sel_color == 3) { bpp = 8; mode = 1; }
|
||||
if (disp_sel_color == 4) { bpp = 8; mode = 2; }
|
||||
|
||||
sys_system(47 /*SET_RESOLUTION*/, w, h, bpp, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -769,13 +954,15 @@ static void control_panel_handle_key(char c, bool pressed) {
|
|||
if (!pressed) return;
|
||||
if (focused_field < 0) return;
|
||||
|
||||
if (current_view == VIEW_WALLPAPER) {
|
||||
if (current_view == VIEW_WALLPAPER || current_view == VIEW_DISPLAY) {
|
||||
char *focused_buffer = NULL;
|
||||
int max_len = 3;
|
||||
|
||||
if (focused_field == 0) focused_buffer = rgb_r;
|
||||
else if (focused_field == 1) focused_buffer = rgb_g;
|
||||
else if (focused_field == 2) focused_buffer = rgb_b;
|
||||
if (focused_field == 0 && current_view == VIEW_WALLPAPER) focused_buffer = rgb_r;
|
||||
else if (focused_field == 1 && current_view == VIEW_WALLPAPER) focused_buffer = rgb_g;
|
||||
else if (focused_field == 2 && current_view == VIEW_WALLPAPER) focused_buffer = rgb_b;
|
||||
else if (focused_field == 3 && current_view == VIEW_DISPLAY) { focused_buffer = custom_res_w; max_len = 5; }
|
||||
else if (focused_field == 4 && current_view == VIEW_DISPLAY) { focused_buffer = custom_res_h; max_len = 5; }
|
||||
else return;
|
||||
|
||||
if (c == '\b') {
|
||||
|
|
|
|||
84
src/kernel/vga.c
Normal file
84
src/kernel/vga.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#include "vga.h"
|
||||
#include "io.h"
|
||||
#include "pci.h"
|
||||
#include "platform.h"
|
||||
|
||||
extern void serial_write(const char *str);
|
||||
extern void serial_write_num(uint32_t n);
|
||||
|
||||
static void vga_write_register(uint16_t index, uint16_t data) {
|
||||
outw(VBE_DISPI_IOPORT_INDEX, index);
|
||||
outw(VBE_DISPI_IOPORT_DATA, data);
|
||||
}
|
||||
|
||||
bool vga_set_mode(uint16_t width, uint16_t height, uint16_t bpp, void **out_framebuffer) {
|
||||
// 1. Locate the BGA PCI device to get the physical framebuffer address
|
||||
pci_device_t bga_dev;
|
||||
// Standard VGA compatible controller is Class 0x03, Subclass 0x00
|
||||
if (!pci_find_device_by_class(0x03, 0x00, &bga_dev)) {
|
||||
serial_write("[VGA] Error: VGA compatible controller not found via PCI!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read BAR0 (offset 0x10)
|
||||
uint32_t bar0 = pci_read_config(bga_dev.bus, bga_dev.device, bga_dev.function, 0x10);
|
||||
// physical address is bar0 with the lower 4 bits masked out
|
||||
uint32_t phys_base = bar0 & 0xFFFFFFF0;
|
||||
|
||||
if (phys_base == 0) {
|
||||
serial_write("[VGA] Error: Invalid BAR0 physical base.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
serial_write("[VGA] Found VGA Controller. LFB Phys Base: ");
|
||||
serial_write_num(phys_base);
|
||||
serial_write("\n");
|
||||
|
||||
// Map physical to virtual using p2v
|
||||
void *vram_ptr = (void *)p2v(phys_base);
|
||||
|
||||
// 2. Disable BGA extensions first
|
||||
vga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
|
||||
|
||||
// 3. Set resolution and BPP
|
||||
vga_write_register(VBE_DISPI_INDEX_XRES, width);
|
||||
vga_write_register(VBE_DISPI_INDEX_YRES, height);
|
||||
vga_write_register(VBE_DISPI_INDEX_BPP, bpp);
|
||||
|
||||
// 4. Re-enable BGA and Linear Framebuffer
|
||||
vga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
|
||||
|
||||
if (out_framebuffer) {
|
||||
*out_framebuffer = vram_ptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void vga_set_palette_grayscale(void) {
|
||||
outb(0x03C8, 0); // Palette index
|
||||
for (int i = 0; i < 256; i++) {
|
||||
// VGA palette uses 6 bits per channel (0-63)
|
||||
uint8_t val = i >> 2;
|
||||
outb(0x03C9, val); // R
|
||||
outb(0x03C9, val); // G
|
||||
outb(0x03C9, val); // B
|
||||
}
|
||||
}
|
||||
|
||||
void vga_set_palette_standard(void) {
|
||||
outb(0x03C8, 0); // Palette index
|
||||
for (int i = 0; i < 256; i++) {
|
||||
// Standard 3:3:2 RGB mapping to 6-bit per channel
|
||||
uint8_t r = (i >> 5) & 0x7;
|
||||
uint8_t g = (i >> 2) & 0x7;
|
||||
uint8_t b = i & 0x3;
|
||||
|
||||
outb(0x03C9, (r * 63) / 7);
|
||||
outb(0x03C9, (g * 63) / 7);
|
||||
outb(0x03C9, (b * 63) / 3);
|
||||
}
|
||||
}
|
||||
36
src/kernel/vga.h
Normal file
36
src/kernel/vga.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2023-2026 Chris (boreddevnl)
|
||||
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
|
||||
// This header needs to maintain in any file it is present in, as per the GPL license terms.
|
||||
#ifndef VGA_H
|
||||
#define VGA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define VBE_DISPI_IOPORT_INDEX 0x01CE
|
||||
#define VBE_DISPI_IOPORT_DATA 0x01CF
|
||||
|
||||
#define VBE_DISPI_INDEX_ID 0
|
||||
#define VBE_DISPI_INDEX_XRES 1
|
||||
#define VBE_DISPI_INDEX_YRES 2
|
||||
#define VBE_DISPI_INDEX_BPP 3
|
||||
#define VBE_DISPI_INDEX_ENABLE 4
|
||||
#define VBE_DISPI_INDEX_BANK 5
|
||||
#define VBE_DISPI_INDEX_VIRT_WIDTH 6
|
||||
#define VBE_DISPI_INDEX_VIRT_HEIGHT 7
|
||||
#define VBE_DISPI_INDEX_X_OFFSET 8
|
||||
#define VBE_DISPI_INDEX_Y_OFFSET 9
|
||||
|
||||
#define VBE_DISPI_DISABLED 0x00
|
||||
#define VBE_DISPI_ENABLED 0x01
|
||||
#define VBE_DISPI_LFB_ENABLED 0x40
|
||||
|
||||
#define COLOR_MODE_NORMAL 0
|
||||
#define COLOR_MODE_GRAYSCALE 1
|
||||
#define COLOR_MODE_MONOCHROME 2
|
||||
|
||||
bool vga_set_mode(uint16_t width, uint16_t height, uint16_t bpp, void **out_framebuffer);
|
||||
void vga_set_palette_grayscale(void);
|
||||
void vga_set_palette_standard(void);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue