保存图标像素数据指针以便退出时释放对应的内存
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cairo.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
@@ -166,20 +166,17 @@ typedef struct {
|
||||
char time[256];
|
||||
} 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 {
|
||||
/* 像素数据 */
|
||||
uint32_t *net_down_pixels;
|
||||
uint32_t *net_up_pixels;
|
||||
uint32_t *volume_pixels;
|
||||
uint32_t *memory_pixels;
|
||||
uint32_t *cpu_pixels;
|
||||
uint32_t *clock_pixels;
|
||||
|
||||
/* cairo_t * 类型,为避免引入 cairo 库使用 void * 类型代替 */
|
||||
void *net_down;
|
||||
void *net_up;
|
||||
void *volume;
|
||||
void *memory;
|
||||
void *cpu;
|
||||
void *clock;
|
||||
icon_res_t net_down;
|
||||
icon_res_t net_up;
|
||||
icon_res_t volume;
|
||||
icon_res_t memory;
|
||||
icon_res_t cpu;
|
||||
icon_res_t clock;
|
||||
} icons_t;
|
||||
|
||||
52
src/main.c
52
src/main.c
@@ -502,37 +502,35 @@ void free_wallpaper_config(wallpaper_config_t *wallpaper_config) {
|
||||
void init_icons(void) {
|
||||
typedef struct {
|
||||
const char *img_path;
|
||||
cairo_surface_t **icon;
|
||||
uint32_t **pixels;
|
||||
icon_res_t *icon_res;
|
||||
} icon_path_surface_map_t;
|
||||
|
||||
if (icons) return;
|
||||
|
||||
icons = ecalloc(1, sizeof(icons_t));
|
||||
icon_path_surface_map_t map[] = {
|
||||
{NET_DOWN_ICON, (cairo_surface_t **)&icons->net_down,
|
||||
&icons->net_down_pixels},
|
||||
{NET_UP_ICON, (cairo_surface_t **)&icons->net_up, &icons->net_up_pixels},
|
||||
{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},
|
||||
{NET_DOWN_ICON, &icons->net_down}, {NET_UP_ICON, &icons->net_up},
|
||||
{SPEAKER_ICON, &icons->volume}, {MEM_ICON, &icons->memory},
|
||||
{CPU_ICON, &icons->cpu}, {CLOCK_ICON, &icons->clock},
|
||||
};
|
||||
for (int i = 0; i < LENGTH(map); i++) {
|
||||
const char *path = map[i].img_path;
|
||||
uint32_t **pixels_addr = map[i].pixels;
|
||||
cairo_surface_t **surface_addr = map[i].icon;
|
||||
icon_res_t *res = map[i].icon_res;
|
||||
if (path && strlen(path)) {
|
||||
*pixels_addr =
|
||||
uint32_t *pixels =
|
||||
generate_icon_pixels(path, bar_height, bar_height, status_icon_pad);
|
||||
cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
||||
int stride = cairo_format_stride_for_width(format, bar_height);
|
||||
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) {
|
||||
*surface_addr = surface;
|
||||
res->pixels = pixels;
|
||||
res->surface = surface;
|
||||
} else {
|
||||
cairo_surface_destroy(surface);
|
||||
free(pixels);
|
||||
res->pixels = NULL;
|
||||
res->surface = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,19 +539,21 @@ void init_icons(void) {
|
||||
void clean_icons(void) {
|
||||
if (!icons) return;
|
||||
|
||||
if (icons->net_down) cairo_surface_destroy(icons->net_down);
|
||||
if (icons->net_up) cairo_surface_destroy(icons->net_up);
|
||||
if (icons->volume) cairo_surface_destroy(icons->volume);
|
||||
if (icons->memory) cairo_surface_destroy(icons->memory);
|
||||
if (icons->cpu) cairo_surface_destroy(icons->cpu);
|
||||
if (icons->clock) cairo_surface_destroy(icons->clock);
|
||||
icon_res_t icon_res_list[] = {
|
||||
icons->net_down, icons->net_up, icons->volume,
|
||||
icons->memory, icons->cpu, icons->clock,
|
||||
};
|
||||
for (int i = 0; i < LENGTH(icon_res_list); i++) {
|
||||
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);
|
||||
if (icons->net_up_pixels) free(icons->net_up);
|
||||
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);
|
||||
res.pixels = NULL;
|
||||
res.surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(icons);
|
||||
icons = NULL;
|
||||
|
||||
@@ -143,7 +143,7 @@ static int32_t draw_status(monitor_t *monitor, status_t *status, icons_t *icons,
|
||||
typedef struct {
|
||||
const char *const text;
|
||||
color_t *color;
|
||||
cairo_surface_t *surface;
|
||||
icon_res_t *icon_res;
|
||||
} status_item_t;
|
||||
|
||||
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->net_speed.down, &color_set->status_net_recv_color,
|
||||
icons->net_down},
|
||||
{status->net_speed.up, &color_set->status_net_send_color, icons->net_up},
|
||||
{volume, &color_set->status_volume_color, icons->volume},
|
||||
{mem, &color_set->status_memory_color, icons->memory},
|
||||
{cpu, &color_set->status_cpu_color, icons->cpu},
|
||||
{status->time, &color_set->status_datetime_color, icons->clock},
|
||||
&icons->net_down},
|
||||
{status->net_speed.up, &color_set->status_net_send_color, &icons->net_up},
|
||||
{volume, &color_set->status_volume_color, &icons->volume},
|
||||
{mem, &color_set->status_memory_color, &icons->memory},
|
||||
{cpu, &color_set->status_cpu_color, &icons->cpu},
|
||||
{status->time, &color_set->status_datetime_color, &icons->clock},
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
cairo_surface_t *surface = items[i].surface;
|
||||
cairo_surface_t *surface = items[i].icon_res->surface;
|
||||
if (surface) {
|
||||
if (x - height < end) return x;
|
||||
|
||||
x -= height;
|
||||
cairo_set_source_surface(monitor->cr, surface, x, 0);
|
||||
cairo_paint(monitor->cr);
|
||||
/* refresh_window(monitor->bar_window); */
|
||||
}
|
||||
|
||||
x -= x_padding;
|
||||
|
||||
Reference in New Issue
Block a user