保存图标像素数据指针以便退出时释放对应的内存

This commit is contained in:
2025-09-01 15:31:45 +08:00
parent e58a43386d
commit 88d9dfd714
4 changed files with 46 additions and 51 deletions

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <cairo.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>

View File

@@ -166,20 +166,17 @@ typedef struct {
char time[256]; char time[256];
} status_t; } status_t;
typedef struct icon_res_t {
/* 图像像素数据RGBA 顺序) */
uint32_t *pixels;
/* cairo_surface_t * 类型,为避免引入 cairo 头文件使用 void * 类型代替 */
void *surface;
} icon_res_t;
typedef struct icons_t { typedef struct icons_t {
/* 像素数据 */ icon_res_t net_down;
uint32_t *net_down_pixels; icon_res_t net_up;
uint32_t *net_up_pixels; icon_res_t volume;
uint32_t *volume_pixels; icon_res_t memory;
uint32_t *memory_pixels; icon_res_t cpu;
uint32_t *cpu_pixels; icon_res_t clock;
uint32_t *clock_pixels;
/* cairo_t * 类型,为避免引入 cairo 库使用 void * 类型代替 */
void *net_down;
void *net_up;
void *volume;
void *memory;
void *cpu;
void *clock;
} icons_t; } icons_t;

View File

@@ -502,37 +502,35 @@ void free_wallpaper_config(wallpaper_config_t *wallpaper_config) {
void init_icons(void) { void init_icons(void) {
typedef struct { typedef struct {
const char *img_path; const char *img_path;
cairo_surface_t **icon; icon_res_t *icon_res;
uint32_t **pixels;
} icon_path_surface_map_t; } icon_path_surface_map_t;
if (icons) return; if (icons) return;
icons = ecalloc(1, sizeof(icons_t)); icons = ecalloc(1, sizeof(icons_t));
icon_path_surface_map_t map[] = { icon_path_surface_map_t map[] = {
{NET_DOWN_ICON, (cairo_surface_t **)&icons->net_down, {NET_DOWN_ICON, &icons->net_down}, {NET_UP_ICON, &icons->net_up},
&icons->net_down_pixels}, {SPEAKER_ICON, &icons->volume}, {MEM_ICON, &icons->memory},
{NET_UP_ICON, (cairo_surface_t **)&icons->net_up, &icons->net_up_pixels}, {CPU_ICON, &icons->cpu}, {CLOCK_ICON, &icons->clock},
{SPEAKER_ICON, (cairo_surface_t **)&icons->volume, &icons->volume_pixels},
{MEM_ICON, (cairo_surface_t **)&icons->memory, &icons->memory_pixels},
{CPU_ICON, (cairo_surface_t **)&icons->cpu, &icons->cpu_pixels},
{CLOCK_ICON, (cairo_surface_t **)&icons->clock, &icons->clock_pixels},
}; };
for (int i = 0; i < LENGTH(map); i++) { for (int i = 0; i < LENGTH(map); i++) {
const char *path = map[i].img_path; const char *path = map[i].img_path;
uint32_t **pixels_addr = map[i].pixels; icon_res_t *res = map[i].icon_res;
cairo_surface_t **surface_addr = map[i].icon;
if (path && strlen(path)) { if (path && strlen(path)) {
*pixels_addr = uint32_t *pixels =
generate_icon_pixels(path, bar_height, bar_height, status_icon_pad); generate_icon_pixels(path, bar_height, bar_height, status_icon_pad);
cairo_format_t format = CAIRO_FORMAT_ARGB32; cairo_format_t format = CAIRO_FORMAT_ARGB32;
int stride = cairo_format_stride_for_width(format, bar_height); int stride = cairo_format_stride_for_width(format, bar_height);
cairo_surface_t *surface = cairo_image_surface_create_for_data( cairo_surface_t *surface = cairo_image_surface_create_for_data(
(uint8_t *)*pixels_addr, format, bar_height, bar_height, stride); (uint8_t *)pixels, format, bar_height, bar_height, stride);
if (cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS) { if (cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS) {
*surface_addr = surface; res->pixels = pixels;
res->surface = surface;
} else { } else {
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
free(pixels);
res->pixels = NULL;
res->surface = NULL;
} }
} }
} }
@@ -541,19 +539,21 @@ void init_icons(void) {
void clean_icons(void) { void clean_icons(void) {
if (!icons) return; if (!icons) return;
if (icons->net_down) cairo_surface_destroy(icons->net_down); icon_res_t icon_res_list[] = {
if (icons->net_up) cairo_surface_destroy(icons->net_up); icons->net_down, icons->net_up, icons->volume,
if (icons->volume) cairo_surface_destroy(icons->volume); icons->memory, icons->cpu, icons->clock,
if (icons->memory) cairo_surface_destroy(icons->memory); };
if (icons->cpu) cairo_surface_destroy(icons->cpu); for (int i = 0; i < LENGTH(icon_res_list); i++) {
if (icons->clock) cairo_surface_destroy(icons->clock); icon_res_t res = icon_res_list[i];
if (res.surface) {
cairo_surface_finish(res.surface);
free(res.pixels);
cairo_surface_destroy(res.surface);
if (icons->net_down_pixels) free(icons->net_down); res.pixels = NULL;
if (icons->net_up_pixels) free(icons->net_up); res.surface = NULL;
if (icons->volume_pixels) free(icons->volume); }
if (icons->memory_pixels) free(icons->memory); }
if (icons->cpu_pixels) free(icons->cpu);
if (icons->clock_pixels) free(icons->clock);
free(icons); free(icons);
icons = NULL; icons = NULL;

View File

@@ -143,7 +143,7 @@ static int32_t draw_status(monitor_t *monitor, status_t *status, icons_t *icons,
typedef struct { typedef struct {
const char *const text; const char *const text;
color_t *color; color_t *color;
cairo_surface_t *surface; icon_res_t *icon_res;
} status_item_t; } status_item_t;
char cpu[16], mem[64], volume[600]; char cpu[16], mem[64], volume[600];
@@ -156,12 +156,12 @@ static int32_t draw_status(monitor_t *monitor, status_t *status, icons_t *icons,
status_item_t items[] = { status_item_t items[] = {
{status->net_speed.down, &color_set->status_net_recv_color, {status->net_speed.down, &color_set->status_net_recv_color,
icons->net_down}, &icons->net_down},
{status->net_speed.up, &color_set->status_net_send_color, icons->net_up}, {status->net_speed.up, &color_set->status_net_send_color, &icons->net_up},
{volume, &color_set->status_volume_color, icons->volume}, {volume, &color_set->status_volume_color, &icons->volume},
{mem, &color_set->status_memory_color, icons->memory}, {mem, &color_set->status_memory_color, &icons->memory},
{cpu, &color_set->status_cpu_color, icons->cpu}, {cpu, &color_set->status_cpu_color, &icons->cpu},
{status->time, &color_set->status_datetime_color, icons->clock}, {status->time, &color_set->status_datetime_color, &icons->clock},
}; };
int32_t x = monitor->monitor_width; int32_t x = monitor->monitor_width;
@@ -177,14 +177,13 @@ static int32_t draw_status(monitor_t *monitor, status_t *status, icons_t *icons,
draw_text(monitor->cr, text, color, x, 0, width, height, false); draw_text(monitor->cr, text, color, x, 0, width, height, false);
cairo_surface_t *surface = items[i].surface; cairo_surface_t *surface = items[i].icon_res->surface;
if (surface) { if (surface) {
if (x - height < end) return x; if (x - height < end) return x;
x -= height; x -= height;
cairo_set_source_surface(monitor->cr, surface, x, 0); cairo_set_source_surface(monitor->cr, surface, x, 0);
cairo_paint(monitor->cr); cairo_paint(monitor->cr);
/* refresh_window(monitor->bar_window); */
} }
x -= x_padding; x -= x_padding;