diff --git a/src/userland/gui/settings.c b/src/userland/gui/settings.c index 91da8bf..99a6491 100644 --- a/src/userland/gui/settings.c +++ b/src/userland/gui/settings.c @@ -415,25 +415,52 @@ static void decode_wallpapers_task(void *arg) { wp->name[(nl-4 < 63) ? nl-4 : 63] = 0; // Load and generate thumbnail - int fd = sys_open(wp->path, "r"); - if (fd >= 0) { - int size = sys_seek(fd, 0, 2); // SEEK_END - sys_seek(fd, 0, 0); // SEEK_SET - if (size > 0 && size < 8 * 1024 * 1024) { - unsigned char *buf = (unsigned char *)malloc(size); - if (buf) { - sys_read(fd, buf, size); - int img_w, img_h, channels; - unsigned char *img = stbi_load_from_memory(buf, size, &img_w, &img_h, &channels, 4); - if (img && img_w > 0 && img_h > 0) { - scale_rgba_to_argb(img, img_w, img_h, wp->thumb, WALLPAPER_THUMB_W, WALLPAPER_THUMB_H); - wp->valid = 1; - stbi_image_free(img); + char cache_path[256]; + int cp = 0; + char *cpref = "/Library/Caches/Thumbnails/"; + while (cpref[cp]) { cache_path[cp] = cpref[cp]; cp++; } + int cn = 0; + while (info[i].name[cn]) { cache_path[cp+cn] = info[i].name[cn]; cn++; } + char *csuf = ".bin"; + int cs = 0; + while (csuf[cs]) { cache_path[cp+cn+cs] = csuf[cs]; cs++; } + cache_path[cp+cn+cs] = 0; + + int cfd = sys_open(cache_path, "r"); + if (cfd >= 0) { + sys_read(cfd, wp->thumb, WALLPAPER_THUMB_W * WALLPAPER_THUMB_H * 4); + sys_close(cfd); + wp->valid = 1; + } else { + int fd = sys_open(wp->path, "r"); + if (fd >= 0) { + int size = sys_seek(fd, 0, 2); // SEEK_END + sys_seek(fd, 0, 0); // SEEK_SET + if (size > 0 && size < 8 * 1024 * 1024) { + unsigned char *buf = (unsigned char *)malloc(size); + if (buf) { + sys_read(fd, buf, size); + int img_w, img_h, channels; + unsigned char *img = stbi_load_from_memory(buf, size, &img_w, &img_h, &channels, 4); + if (img && img_w > 0 && img_h > 0) { + scale_rgba_to_argb(img, img_w, img_h, wp->thumb, WALLPAPER_THUMB_W, WALLPAPER_THUMB_H); + wp->valid = 1; + stbi_image_free(img); + + // Save to cache + sys_mkdir("/Library/Caches"); + sys_mkdir("/Library/Caches/Thumbnails"); + int swfd = sys_open(cache_path, "w"); + if (swfd >= 0) { + sys_write_fs(swfd, wp->thumb, WALLPAPER_THUMB_W * WALLPAPER_THUMB_H * 4); + sys_close(swfd); + } + } + free(buf); } - free(buf); // Release memory - } + } + sys_close(fd); } - sys_close(fd); } wallpaper_count++; @@ -624,11 +651,7 @@ static void control_panel_paint_wallpaper(ui_window_t win) { widget_button_draw(&settings_ctx, &btn_wp_thumbs[i]); if (wallpapers[i].valid) { - for (int py = 0; py < WALLPAPER_THUMB_H; py++) { - for (int px = 0; px < WALLPAPER_THUMB_W; px++) { - ui_draw_rect(win, button_x + tx + 4 + px, button_y + ty + 4 + py, 1, 1, wallpapers[i].thumb[py * WALLPAPER_THUMB_W + px]); - } - } + ui_draw_image(win, button_x + tx + 4, button_y + ty + 4, WALLPAPER_THUMB_W, WALLPAPER_THUMB_H, wallpapers[i].thumb); } ui_draw_string(win, button_x + tx + 8, button_y + ty + WALLPAPER_THUMB_H + 8, wallpapers[i].name, 0xFFFFFFFF); } diff --git a/src/wm/wallpaper.c b/src/wm/wallpaper.c index fd752bd..4d412a5 100644 --- a/src/wm/wallpaper.c +++ b/src/wm/wallpaper.c @@ -20,6 +20,53 @@ static volatile const char *pending_wallpaper_path = NULL; static char pending_path_buf[256]; #define WALLPAPER_CONF_PATH "/Library/BWM/Wallpaper/wallpaper" +#define WALLPAPER_CACHE_PATH "/Library/Caches/Wallpaper.bin" + +static void wallpaper_save_cache(void) { + if (!wp_pixels || wp_width <= 0 || wp_height <= 0) return; + fat32_mkdir("/Library/Caches"); + FAT32_FileHandle *fh = fat32_open(WALLPAPER_CACHE_PATH, "w"); + if (fh && fh->valid) { + uint32_t w = (uint32_t)wp_width; + uint32_t h = (uint32_t)wp_height; + fat32_write(fh, &w, 4); + fat32_write(fh, &h, 4); + fat32_write(fh, wp_pixels, w * h * 4); + fat32_close(fh); + } +} + +static int wallpaper_load_cache(void) { + if (!fat32_exists(WALLPAPER_CACHE_PATH)) return 0; + FAT32_FileHandle *fh = fat32_open(WALLPAPER_CACHE_PATH, "r"); + if (!fh || !fh->valid) return 0; + + uint32_t w, h; + fat32_read(fh, &w, 4); + fat32_read(fh, &h, 4); + + if (w != (uint32_t)get_screen_width() || h != (uint32_t)get_screen_height()) { + fat32_close(fh); + return 0; + } + + if (!wp_pixels) { + wp_pixels = (uint32_t*)kmalloc(MAX_WP_WIDTH * MAX_WP_HEIGHT * sizeof(uint32_t)); + if (!wp_pixels) { fat32_close(fh); return 0; } + } + + uint32_t total_size = w * h * 4; + uint32_t bytes_read = fat32_read(fh, wp_pixels, total_size); + fat32_close(fh); + + if (bytes_read == total_size) { + wp_width = (int)w; + wp_height = (int)h; + graphics_set_bg_image(wp_pixels, wp_width, wp_height); + return 1; + } + return 0; +} // Simple nearest-neighbor scale from decoded RGBA to ARGB pixel buffer static void scale_rgba_to_argb(const unsigned char *rgba, int src_w, int src_h, @@ -72,6 +119,7 @@ static int decode_and_set_wallpaper(const unsigned char *jpg_data, unsigned int stbi_image_free(rgba); graphics_set_bg_image(wp_pixels, wp_width, wp_height); + wallpaper_save_cache(); return 1; } @@ -190,13 +238,17 @@ int wallpaper_get_width(void) { return wp_width; } int wallpaper_get_height(void) { return wp_height; } void wallpaper_init(void) { - wallpaper_load_setting(); - - if (pending_wallpaper_path == NULL) { - if (fat32_exists("/Library/images/Wallpapers/bored.jpg")) { - wallpaper_request_set_from_file("/Library/images/Wallpapers/bored.jpg"); - } else if (fat32_exists("/Library/images/Wallpapers/moon.jpg")) { - wallpaper_request_set_from_file("/Library/images/Wallpapers/moon.jpg"); + if (wallpaper_load_cache()) { + serial_str("[WALLPAPER] Loaded from cache\n"); + } else { + wallpaper_load_setting(); + + if (pending_wallpaper_path == NULL) { + if (fat32_exists("/Library/images/Wallpapers/bored.jpg")) { + wallpaper_request_set_from_file("/Library/images/Wallpapers/bored.jpg"); + } else if (fat32_exists("/Library/images/Wallpapers/moon.jpg")) { + wallpaper_request_set_from_file("/Library/images/Wallpapers/moon.jpg"); + } } } }