解析壁纸配置

This commit is contained in:
2025-08-08 22:53:33 +08:00
parent d82081ca71
commit 16204bd638
7 changed files with 195 additions and 12 deletions

View File

@@ -15,7 +15,7 @@ project(${APP_NAME}
LANGUAGES C LANGUAGES C
) )
add_executable(${APP_NAME} main.c utils.c) add_executable(${APP_NAME} main.c utils.c config.c)
# use C17 # use C17
set_property(TARGET ${APP_NAME} PROPERTY C_STANDARD 17) set_property(TARGET ${APP_NAME} PROPERTY C_STANDARD 17)
@@ -24,6 +24,7 @@ target_include_directories(${APP_NAME} PRIVATE "${SOURCE_DIR}/include")
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0)
pkg_check_modules(XCB REQUIRED pkg_check_modules(XCB REQUIRED
xcb xcb
xcb-cursor xcb-cursor
@@ -35,10 +36,18 @@ pkg_check_modules(XCB REQUIRED
xcb-xinerama xcb-xinerama
xcb-xrm xcb-xrm
) )
target_include_directories(${APP_NAME} SYSTEM PUBLIC ${XCB_INCLUDE_DIRS})
target_include_directories(${APP_NAME} SYSTEM PUBLIC
${GLIB_INCLUDE_DIRS}
${XCB_INCLUDE_DIRS}
)
add_subdirectory(xcb) add_subdirectory(xcb)
target_link_libraries(${APP_NAME} ${LIB_XCB_NAME})
target_link_libraries(${APP_NAME}
${GLIB_LIBRARIES}
${LIB_XCB_NAME}
)
configure_file( configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/app.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/app.h.in"

6
src/config.c Normal file
View File

@@ -0,0 +1,6 @@
#include "config.h"
#include <stdio.h>
/* 壁纸列表,支持通配符和 shell 环境变量拼接,最后以 NULL 结尾 */
const char *wallpager_list[] = {NULL};

3
src/include/config.h Normal file
View File

@@ -0,0 +1,3 @@
#pragma once
extern const char *wallpager_list[];

61
src/include/types.h Normal file
View File

@@ -0,0 +1,61 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
typedef struct monitor_t monitor_t;
typedef struct client_t client_t;
typedef struct layout_t {
const char *symbol;
void (*arrange)(monitor_t *monitor);
} layout_t;
#define TAG_SYMBOL_LENGTH 32
/* 避免引入 xcb 头文件 */
typedef uint32_t xcb_window_t;
struct monitor_t {
uint32_t index;
int32_t monitor_x, monitor_y, window_x, window_y;
uint32_t monitor_width, monitor_height, window_width, window_height;
uint32_t selected_tag;
uint32_t tag_count;
char (*tags)[TAG_SYMBOL_LENGTH];
/* 为了避免引入 cairo 相关头文件,这里用 void *
* 指针代替实际的指针类型,使用时强转为相应指针类型使用即可 */
void *surface; /* cairo_surface_t */
void *cr; /* cairo_t */
const layout_t *layout;
monitor_t *next;
client_t *clients;
client_t *clients_stack;
client_t *selected_client;
xcb_window_t bar_window;
};
struct client_t {
char name[256];
int32_t x, y;
uint32_t width, height, border_width;
uint32_t tags;
bool fullscreen;
bool floating;
monitor_t *monitor;
client_t *next;
client_t *stack_next;
xcb_window_t window;
};
typedef struct wallpaper_config_t {
uint32_t count;
char **path_list;
} wallpaper_config_t;

View File

@@ -1,8 +1,11 @@
#pragma once #pragma once
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#define LENGTH(X) (sizeof(X) / sizeof(X)[0]) #define LENGTH(X) (sizeof(X) / sizeof(X)[0])
void die(const char *format, ...); 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);

View File

@@ -1,26 +1,120 @@
#include <glib.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <wordexp.h>
#include "config.h"
#include "types.h"
#include "utils.h" #include "utils.h"
#include "xcb.h" #include "xcb.h"
static void init_monitors(void);
static wallpaper_config_t *parse_wallpaper_config(const char **wallpapers);
static void free_wallpaper_config(wallpaper_config_t *wallpaper_config);
static void cleanup(void);
static monitor_t *monitors = NULL;
static wallpaper_config_t *wallpaper_config = NULL;
void init_monitors(void) {
monitor_rect_t *mr = detect_monitor_rect();
uint32_t i = 0;
while (mr) {
monitor_t *m = ecalloc(1, sizeof(monitor_t));
m->monitor_x = mr->x;
m->monitor_y = mr->y;
m->monitor_width = mr->width;
m->monitor_height = mr->height;
m->index = i;
printf("mon[%u]: x: %d, y: %d, w: %u, h: %u\n", i, mr->x, mr->y, mr->width,
mr->height);
if (!i) monitors = m;
i++;
monitor_rect_t *next_mr = mr->next;
free(mr);
mr = next_mr;
}
}
wallpaper_config_t *parse_wallpaper_config(const char **wallpapers) {
if (!wallpapers) return NULL;
wallpaper_config_t *wc = ecalloc(1, sizeof(wallpaper_config_t));
GStrvBuilder *builder = g_strv_builder_new();
for (int i = 0; wallpapers && wallpapers[i]; i++) {
wordexp_t p;
if (wordexp(wallpapers[i], &p, 0)) continue;
for (size_t i = 0; i < p.we_wordc; i++) {
size_t len = strlen(p.we_wordv[i]) + 1;
char *realpath = ecalloc(len, sizeof(char));
strncpy(realpath, p.we_wordv[i], len);
g_strstrip(realpath);
if (file_exist(realpath)) g_strv_builder_add(builder, realpath);
free(realpath);
}
wordfree(&p);
}
wc->path_list = g_strv_builder_unref_to_strv(builder);
wc->count = g_strv_length(wc->path_list);
if (wc->count) return wc;
free_wallpaper_config(wc);
return NULL;
}
void free_wallpaper_config(wallpaper_config_t *wallpaper_config) {
if (!wallpaper_config) return;
g_strfreev(wallpaper_config->path_list);
free(wallpaper_config);
}
void cleanup(void) {
clean_xcb();
free_wallpaper_config(wallpaper_config);
wallpaper_config = NULL;
monitor_t *m = monitors;
client_t *c = m->clients;
while (m) {
while (c) {
client_t *tc = c->next;
free(c);
c = tc;
}
monitor_t *tm = m->next;
free(m);
m = tm;
}
monitors = NULL;
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (has_other_wm_running()) { if (has_other_wm_running()) {
die("another window manager is already running"); die("another window manager is already running");
} }
{ wallpaper_config = parse_wallpaper_config(wallpager_list);
monitor_rect_t *mr = detect_monitor_rect(); if (wallpaper_config) {
uint32_t i = 0; printf("wallpaper count: %u\n", wallpaper_config->count);
while (mr) { for (uint32_t i = 0; i < wallpaper_config->count; i++) {
printf("mon[%u]: x: %d, y: %d, w: %u, h: %u\n", i, mr->x, mr->y, printf("wallpaper[%02u]: %s\n", i, wallpaper_config->path_list[i]);
mr->width, mr->height);
mr = mr->next;
free(mr);
} }
} }
init_monitors();
window_list_t *window_list = scan_window_list(); window_list_t *window_list = scan_window_list();
if (window_list) { if (window_list) {
for (uint32_t i = 0; i < window_list->count; i++) { for (uint32_t i = 0; i < window_list->count; i++) {
@@ -31,7 +125,7 @@ int main(int argc, char *argv[]) {
} }
free_window_list(window_list); free_window_list(window_list);
clean_xcb(); cleanup();
return 0; return 0;
} }

View File

@@ -1,9 +1,11 @@
#include "utils.h" #include "utils.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
void die(const char *fmt, ...) { void die(const char *fmt, ...) {
va_list ap; va_list ap;
@@ -30,3 +32,8 @@ void *ecalloc(size_t number_of_member, size_t member_size) {
return p; return p;
} }
bool file_exist(const char *path) {
if (!path || !*path) return false;
return access(path, R_OK) == 0;
}