添加壁纸功能
This commit is contained in:
14
src/renderer/CMakeLists.txt
Normal file
14
src/renderer/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
set(LIB_RENDERER "zswm-renderer")
|
||||
set(LIB_RENDERER_NAME ${LIB_RENDERER} PARENT_SCOPE)
|
||||
|
||||
add_library(${LIB_RENDERER} STATIC image.c)
|
||||
target_include_directories(${LIB_RENDERER} SYSTEM
|
||||
PRIVATE ${RENDERER_INCLUDE_DIRS}
|
||||
)
|
||||
target_include_directories(${LIB_RENDERER}
|
||||
PRIVATE "${CMAKE_SOURCE_DIR}/include"
|
||||
)
|
||||
|
||||
target_link_libraries(${LIB_RENDERER}
|
||||
PRIVATE ${RENDERER_LIBRARIES}
|
||||
)
|
||||
95
src/renderer/image.c
Normal file
95
src/renderer/image.c
Normal file
@@ -0,0 +1,95 @@
|
||||
#include <Imlib2.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
|
||||
Imlib_Image wallpaper_img =
|
||||
imlib_load_image(wallpaper_config->path_list[img_index]);
|
||||
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);
|
||||
|
||||
uint32_t scaled_width = img_width * scale;
|
||||
uint32_t scaled_height = img_height * scale;
|
||||
|
||||
/* 图片居中显示,计算原图绘制区域 */
|
||||
int src_x = (scaled_width - dst_width) / (2 * scale);
|
||||
int src_y = (scaled_height - dst_height) / (2 * scale);
|
||||
int src_width = dst_width / scale;
|
||||
int src_height = dst_height / scale;
|
||||
|
||||
/* 绘制图片到最终图像上 */
|
||||
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 = malloc(data_size);
|
||||
if (result) memcpy(result, data, data_size);
|
||||
|
||||
/* 释放图像 */
|
||||
imlib_context_set_image(final_image);
|
||||
imlib_free_image();
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user