#include #include #include #include #include #include #include "renderer.h" #include "types.h" #include "utils.h" /** * @brief 生成需要由 xcb 绘制的壁纸数据 * @returns 壁纸数据,使用后记得释放 */ uint32_t *generate_wallpaper(const wallpaper_config_t *wallpaper_config, const monitor_t *monitors, const uint32_t index, const uint32_t screen_width, const uint32_t screen_height) { if (!wallpaper_config || !monitors) return NULL; Imlib_Image final_image = imlib_create_image(screen_width, screen_height); if (!final_image) return NULL; imlib_context_set_image(final_image); imlib_image_set_has_alpha(false); /* 填充背景色 */ imlib_context_set_color(0, 0, 0, 255); imlib_image_fill_rectangle(0, 0, screen_width, screen_height); const monitor_t *monitor = monitors; uint32_t monitor_index = 0; while (monitor) { uint32_t img_index = (index + monitor_index) % wallpaper_config->count; const char *path = wallpaper_config->path_list[img_index]; Imlib_Image wallpaper_img = imlib_load_image(path); if (!wallpaper_img) { monitor = monitor->next; monitor_index++; continue; } uint32_t dst_width = monitor->monitor_width; uint32_t dst_height = monitor->monitor_height; /* 获取图片原始尺寸 */ imlib_context_set_image(wallpaper_img); uint32_t img_width = imlib_image_get_width(); uint32_t img_height = imlib_image_get_height(); /* 计算缩放比例,保持原始宽高比 */ float width_ratio = (float)dst_width / img_width; float height_ratio = (float)dst_height / img_height; float scale = MAX(width_ratio, height_ratio); /* 图片居中显示,计算原图绘制区域 */ int src_width = dst_width / scale; int src_height = dst_height / scale; int src_x = (img_width - src_width) / 2; int src_y = (img_height - src_height) / 2; /* 绘制图片到最终图像上 */ imlib_context_set_image(final_image); imlib_blend_image_onto_image(wallpaper_img, 1, src_x, src_y, src_width, src_height, monitor->monitor_x, monitor->monitor_y, dst_width, dst_height); /* 释放图片资源 */ imlib_context_set_image(wallpaper_img); imlib_free_image(); monitor = monitor->next; monitor_index++; } /* 获取最终图像数据 */ imlib_context_set_image(final_image); uint32_t *data = imlib_image_get_data_for_reading_only(); /* 复制数据到自己分配的内存中(原数据会在图像释放后无效) */ size_t data_size = screen_width * screen_height * sizeof(uint32_t); uint32_t *result = ecalloc(1, data_size); if (result) memcpy(result, data, data_size); /* 释放图像 */ imlib_context_set_image(final_image); imlib_free_image(); return result; }