初始化配色方案

This commit is contained in:
2025-08-13 23:59:33 +08:00
parent e78c847125
commit 0827208a95
5 changed files with 168 additions and 0 deletions

View File

@@ -58,3 +58,17 @@ const rule_t rules[] = {
{.class = "Emacs", .monitor_amount = 1, .monitor_index = 0, .tags = 1 << 2}, {.class = "Emacs", .monitor_amount = 1, .monitor_index = 0, .tags = 1 << 2},
{.class = "Emacs", .monitor_amount = 2, .monitor_index = 0, .tags = 1 << 1}, {.class = "Emacs", .monitor_amount = 2, .monitor_index = 0, .tags = 1 << 1},
}; };
const char *const bar_bg = "#222222";
const char *const tag_color = "#bbbbbb";
const char *const layout_color = "#bbbbbb";
const char *const client_name_color = "#bbbbbb";
const char *const status_color = "#bbbbbb";
const char *const border_color = "#444444";
const char *const active_bar_bg = "#eeeeee";
const char *const active_tag_color = "#005577";
const char *const active_layout_color = "#005577";
const char *const active_client_name_color = "#005577";
const char *const active_status_color = "#005577";
const char *const active_border_color = "#005577";

View File

@@ -73,3 +73,24 @@ typedef struct rule_t {
bool maximize; bool maximize;
bool floating; bool floating;
} rule_t; } rule_t;
typedef struct color_t {
uint32_t rgba;
uint32_t argb;
double red;
double green;
double blue;
double alpha;
} color_t;
typedef struct color_set_t {
color_t bar_bg;
color_t tag_color;
color_t layout_color;
color_t client_name_color;
color_t status_color;
color_t border_color;
} color_set_t;
typedef struct color_scheme_t {
color_set_t normal;
color_set_t active;
} color_scheme_t;

View File

@@ -2,6 +2,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#define LENGTH(X) (sizeof(X) / sizeof(X)[0]) #define LENGTH(X) (sizeof(X) / sizeof(X)[0])
@@ -12,3 +13,28 @@ void die(const char *format, ...);
void *ecalloc(size_t number_of_member, size_t member_size); void *ecalloc(size_t number_of_member, size_t member_size);
bool file_exist(const char *path); bool file_exist(const char *path);
/**
* @brief 将 16 进制的颜色配置转换成 uint32 格式的 rgba数据
*
* @param hex 16 进制的颜色表示,支持的格式有
* RGB/RGBA/RRGGBB/RRGGBBAA/#RGB/#RGBA/#RRGGBB/#RRGGBBAA
* @param rgba 返回数据的指针,解析结果会放到这个指针指向的内存中
* @return 如果 hex 是一个能正常解析的颜色,返回 true ,否则返回 false
*/
bool hex_color_to_rgba(const char *hex, uint32_t *rgba);
/**
* @brief 将 rgba 通道顺序的颜色转换成 argb 顺序
* @description xcb 库用到的颜色需要是 argb 通道顺序
*/
uint32_t rgba_to_argb(uint32_t rgba);
/**
* @brief 提取颜色中的各个颜色通道数值
* @param rgba uint32 表示的颜色
* @param red red channel, range 0~1
* @param green green channel, range 0~1
* @param blue blue channel, range 0~1
* @param alpha alpha channel, range 0~1
*/
void extract_color_channel(const uint32_t rgba, double *red, double *green,
double *blue, double *alpha);

View File

@@ -21,6 +21,8 @@ static gboolean update_wallpaper(gpointer user_data);
static void set_wallpaper_by_index(uint32_t index); static void set_wallpaper_by_index(uint32_t index);
static wallpaper_config_t *parse_wallpaper_config(void); static wallpaper_config_t *parse_wallpaper_config(void);
static void free_wallpaper_config(wallpaper_config_t *wallpaper_config); static void free_wallpaper_config(wallpaper_config_t *wallpaper_config);
static void init_color_scheme(void);
static void parse_color(const char *hex, color_t *color);
static void init_xcb_event_loop(void); static void init_xcb_event_loop(void);
static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition, static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition,
gpointer userdata); gpointer userdata);
@@ -28,6 +30,7 @@ static void cleanup(void);
static monitor_t *monitors = NULL; static monitor_t *monitors = NULL;
static wallpaper_config_t *wallpaper_config = NULL; static wallpaper_config_t *wallpaper_config = NULL;
static color_scheme_t *color_scheme = NULL;
static GMainLoop *loop = NULL; static GMainLoop *loop = NULL;
/* 调试函数,开发完成后删除 */ /* 调试函数,开发完成后删除 */
@@ -45,6 +48,27 @@ static void print_monitor_list_info(monitor_t *monitor_list) {
} }
printf("======================= monitor info end =======================\n"); printf("======================= monitor info end =======================\n");
} }
static void print_color(const char *prompt, const color_t *color) {
const char *p = strlen(prompt) ? " " : "";
printf("%s%srgba: #%08x, argb: #%08x\n", prompt, p, color->rgba, color->argb);
}
static void print_color_set(color_set_t *set) {
print_color("== bar bg:", &set->bar_bg);
print_color("== tag color:", &set->tag_color);
print_color("== layout bg:", &set->layout_color);
print_color("== client name color:", &set->client_name_color);
print_color("== status color:", &set->status_color);
print_color("== border color:", &set->border_color);
}
static void print_color_scheme(color_scheme_t *scheme) {
printf("================== normal colors ==================\n");
print_color_set(&scheme->normal);
printf("================ normal colors end ================\n");
printf("================== active colors ==================\n");
print_color_set(&scheme->active);
printf("================ active colors end ================\n");
}
static void print_wallpaper_config(wallpaper_config_t *config) { static void print_wallpaper_config(wallpaper_config_t *config) {
if (!config) { if (!config) {
printf("no wallpaper\n"); printf("no wallpaper\n");
@@ -205,6 +229,34 @@ void free_wallpaper_config(wallpaper_config_t *wallpaper_config) {
free(wallpaper_config); free(wallpaper_config);
} }
void init_color_scheme(void) {
color_scheme = ecalloc(1, sizeof(color_scheme_t));
parse_color(bar_bg, &color_scheme->normal.bar_bg);
parse_color(tag_color, &color_scheme->normal.tag_color);
parse_color(layout_color, &color_scheme->normal.layout_color);
parse_color(client_name_color, &color_scheme->normal.client_name_color);
parse_color(status_color, &color_scheme->normal.status_color);
parse_color(border_color, &color_scheme->normal.border_color);
parse_color(active_bar_bg, &color_scheme->active.bar_bg);
parse_color(active_tag_color, &color_scheme->active.tag_color);
parse_color(active_layout_color, &color_scheme->active.layout_color);
parse_color(active_client_name_color,
&color_scheme->active.client_name_color);
parse_color(active_status_color, &color_scheme->active.status_color);
parse_color(active_border_color, &color_scheme->active.border_color);
}
void parse_color(const char *hex, color_t *color) {
bool success = hex_color_to_rgba(hex, &color->rgba);
if (!success) die("invalid hex color: %s", hex);
color->argb = rgba_to_argb(color->rgba);
extract_color_channel(color->rgba, &color->red, &color->green, &color->blue,
&color->alpha);
}
void init_xcb_event_loop(void) { void init_xcb_event_loop(void) {
GIOChannel *channel = g_io_channel_unix_new(get_xcb_connection_fd()); GIOChannel *channel = g_io_channel_unix_new(get_xcb_connection_fd());
g_io_channel_set_encoding(channel, NULL, NULL); g_io_channel_set_encoding(channel, NULL, NULL);
@@ -230,6 +282,9 @@ void cleanup(void) {
free_wallpaper_config(wallpaper_config); free_wallpaper_config(wallpaper_config);
wallpaper_config = NULL; wallpaper_config = NULL;
free(color_scheme);
color_scheme = NULL;
monitor_t *m = monitors; monitor_t *m = monitors;
client_t *c = m->clients; client_t *c = m->clients;
while (m) { while (m) {
@@ -252,11 +307,13 @@ int main(int argc, char *argv[]) {
} }
init_monitors(); init_monitors();
init_color_scheme();
init_wallpaper(); init_wallpaper();
window_list_t *window_list = scan_window_list(); window_list_t *window_list = scan_window_list();
print_monitor_list_info(monitors); print_monitor_list_info(monitors);
print_color_scheme(color_scheme);
print_wallpaper_config(wallpaper_config); print_wallpaper_config(wallpaper_config);
print_window_list(window_list); print_window_list(window_list);

View File

@@ -37,3 +37,53 @@ bool file_exist(const char *path) {
if (!path || !*path) return false; if (!path || !*path) return false;
return access(path, R_OK) == 0; return access(path, R_OK) == 0;
} }
bool hex_color_to_rgba(const char *hex, uint32_t *rgba) {
if (hex[0] == '#') hex++;
size_t len = strlen(hex);
char extended[9] = {0};
uint32_t color = 0x00000000;
if (len == 3 || len == 4) {
extended[0] = extended[1] = hex[0];
extended[2] = extended[3] = hex[1];
extended[4] = extended[5] = hex[2];
if (len == 3) {
extended[6] = extended[7] = 'F';
} else {
extended[6] = extended[7] = hex[3];
}
} else if (len == 6) {
strncpy(extended, hex, len);
extended[6] = extended[7] = 'F';
} else if (len == 8) {
strncpy(extended, hex, len);
} else {
return false;
}
color = strtoul(extended, NULL, 16) & 0xffffffff;
*rgba = color;
return true;
}
#define EXTRACE_COLOR_BIT(C, R) (((C) >> (R)) & 0xff)
uint32_t rgba_to_argb(uint32_t rgba) {
uint32_t r = EXTRACE_COLOR_BIT(rgba, 24);
uint32_t g = EXTRACE_COLOR_BIT(rgba, 16);
uint32_t b = EXTRACE_COLOR_BIT(rgba, 8);
uint32_t a = EXTRACE_COLOR_BIT(rgba, 0);
uint32_t argb = (a << 24) | (r << 16) | (g << 8) | b;
return argb;
}
#define COLOR_SPLIT(C, R) (EXTRACE_COLOR_BIT((C), (R)) / (double)0xff)
void extract_color_channel(const uint32_t rgba, double *red, double *green,
double *blue, double *alpha) {
*red = COLOR_SPLIT(rgba, 24);
*green = COLOR_SPLIT(rgba, 16);
*blue = COLOR_SPLIT(rgba, 8);
*alpha = COLOR_SPLIT(rgba, 0);
}