Compare commits

...

3 commits

Author SHA1 Message Date
0a88ca1b8c
check that paths exist before using them 2026-01-08 14:50:28 -05:00
1456db633d
remove unused macro 2026-01-07 16:07:07 -05:00
d4c1c34016
a :retab a day keeps the doctor away 2026-01-07 16:06:42 -05:00
4 changed files with 127 additions and 100 deletions

View file

@ -1,7 +1,5 @@
#pragma once
#define LED_BLINK_TRIGGER_DISABLED 101
/**
* @brief parse the config file
*
@ -14,6 +12,11 @@ void parse_config_file(char *path);
*/
void setup_led_formula(void);
/**
* @brief ensure that the config paths are valid
*/
void check_config();
extern char *battery_status_path;
extern char *battery_power_source;

View file

@ -3,33 +3,42 @@
#include <stdlib.h>
#include <log.h>
#include <sys/stat.h>
#include <toml.h>
#include <tinyexpr.h>
#include "config.h"
#define table(tt, v, vn) do { \
v = toml_table_in(tt, vn); \
if (!v) { \
log_warn("missing [%s]", vn); \
} \
} while (0);
#define table(tt, v, vn) do { \
v = toml_table_in(tt, vn); \
if (!v) { \
log_warn("missing [%s]", vn); \
} \
} while (0)
#define set_str_conf(op, tt, v) do { \
toml_datum_t val; \
val = toml_string_in(tt, v); \
if (val.ok) { \
op = val.u.s; \
} \
} while (0);
#define set_str_conf(op, tt, v) do { \
toml_datum_t val; \
val = toml_string_in(tt, v); \
if (val.ok) { \
op = val.u.s; \
} \
} while (0)
#define set_int_conf(op, tt, v) do { \
toml_datum_t val; \
val = toml_int_in(tt, v); \
if (val.ok) { \
op = val.u.i; \
} \
} while (0);
#define set_int_conf(op, tt, v) do { \
toml_datum_t val; \
val = toml_int_in(tt, v); \
if (val.ok) { \
op = val.u.i; \
} \
} while (0)
#define check_path(path) do { \
struct stat sb; \
if (stat(path, &sb) == -1) { \
log_fatal("path does not exist: %s", path); \
exit(1); \
} \
} while (0)
static te_expr *expr;
static double percentage;
@ -47,63 +56,74 @@ char *acpi_daemon_socket_path = "/run/acpid.socket";
double
led_blink_timing_func(int percent)
{
percentage = percent;
return te_eval(expr);
percentage = percent;
return te_eval(expr);
}
static void
free_eval(int sig)
{
te_free(expr);
te_free(expr);
}
void
setup_led_formula(void)
{
int err;
int err;
te_variable vars[] = { { "p", &percentage } };
expr = te_compile(led_blink_timing_formula, vars, 1, &err);
if (!expr) {
log_fatal("%s", led_blink_timing_formula);
log_fatal("%*s^ Error near here", err - 1, "");
te_variable vars[] = { { "p", &percentage } };
expr = te_compile(led_blink_timing_formula, vars, 1, &err);
if (!expr) {
log_fatal("%s", led_blink_timing_formula);
log_fatal("%*s^ Error near here", err - 1, "");
exit(1);
}
signal(SIGINT, free_eval);
exit(1);
}
signal(SIGINT, free_eval);
}
void
parse_config_file(char *path)
{
FILE *f;
toml_table_t *config, *battery, *led, *led_blink, *acpi_daemon;
char errbuf[200];
FILE *f;
toml_table_t *config, *battery, *led, *led_blink, *acpi_daemon;
char errbuf[200];
f = fopen(path, "r");
if (!f) {
log_fatal("Failed to open config file: %s", path);
f = fopen(path, "r");
if (!f) {
log_fatal("Failed to open config file: %s", path);
return;
}
}
config = toml_parse_file(f, errbuf, sizeof(errbuf));
fclose(f);
config = toml_parse_file(f, errbuf, sizeof(errbuf));
fclose(f);
if (!config) {
log_fatal("error: %s", errbuf);
}
if (!config) {
log_fatal("error: %s", errbuf);
}
table(config, battery, "battery");
table(config, led, "led");
table(led, led_blink, "blink");
table(config, acpi_daemon, "acpi_daemon");
table(config, battery, "battery");
table(config, led, "led");
table(led, led_blink, "blink");
table(config, acpi_daemon, "acpi_daemon");
set_str_conf(battery_status_path, battery, "status_path");
set_str_conf(battery_power_source, battery, "power_source");
set_str_conf(led_brightness_path, led, "brightness_path");
set_int_conf(led_blink_trigger_level, led_blink, "power_source");
set_str_conf(led_blink_timing_formula, led_blink, "timing_formula");
set_str_conf(acpi_daemon_socket_path, acpi_daemon, "socket_path");
set_str_conf(battery_status_path, battery, "status_path");
set_str_conf(battery_power_source, battery, "power_source");
set_str_conf(led_brightness_path, led, "brightness_path");
set_int_conf(led_blink_trigger_level, led_blink, "power_source");
set_str_conf(led_blink_timing_formula, led_blink, "timing_formula");
set_str_conf(acpi_daemon_socket_path, acpi_daemon, "socket_path");
check_config();
toml_free(config);
}
void
check_config()
{
check_path(battery_status_path);
check_path(battery_power_source);
check_path(led_brightness_path);
check_path(acpi_daemon_socket_path);
}

View file

@ -86,7 +86,7 @@ int
main(int argc, char *argv[])
{
cag_option_context context;
bool plugged = plugged_in(battery_power_source);
bool plugged;
char buffer[MAX_BUFLEN], *out[4], *config_path, *percent;
int sock_fd;
bool debug = false;
@ -113,6 +113,10 @@ main(int argc, char *argv[])
break;
}
}
check_config();
/* get current plugged in state */
plugged = plugged_in(battery_power_source);
/* configure the led blinking formula */
setup_led_formula();

View file

@ -18,12 +18,12 @@
struct Data {
int idle_lock;
struct wl_compositor *compositor;
struct wl_display *display;
struct wl_registry *registry;
struct wl_surface *surface;
struct zwp_idle_inhibitor_v1 *inhibitor;
struct zwp_idle_inhibit_manager_v1 *inhibitmanager;
struct wl_compositor *compositor;
struct wl_display *display;
struct wl_registry *registry;
struct wl_surface *surface;
struct zwp_idle_inhibitor_v1 *inhibitor;
struct zwp_idle_inhibit_manager_v1 *inhibitmanager;
};
/* global data accessed by all threads */
@ -38,12 +38,12 @@ static void
reghandler(void *data, struct wl_registry *registry, uint32_t id,
const char *interface, uint32_t version)
{
struct Data *d = (struct Data *)data;
struct Data *d = (struct Data *)data;
if (strcmp(interface, wl_compositor_interface.name) == 0) {
d->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
} else if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) {
d->inhibitmanager = wl_registry_bind(registry, id, &zwp_idle_inhibit_manager_v1_interface, 1);
}
d->inhibitmanager = wl_registry_bind(registry, id, &zwp_idle_inhibit_manager_v1_interface, 1);
}
}
static const struct wl_registry_listener reglistener = {
@ -59,13 +59,13 @@ static const struct wl_registry_listener reglistener = {
static inline void
idle_lock_set(int lock, struct Data *d)
{
if (lock) {
d->inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor(d->inhibitmanager, d->surface);
} else if (d->inhibitor) {
zwp_idle_inhibitor_v1_destroy(d->inhibitor);
d->inhibitor = NULL;
}
wl_display_roundtrip(d->display);
if (lock) {
d->inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor(d->inhibitmanager, d->surface);
} else if (d->inhibitor) {
zwp_idle_inhibitor_v1_destroy(d->inhibitor);
d->inhibitor = NULL;
}
wl_display_roundtrip(d->display);
}
/**
@ -86,8 +86,8 @@ static void
log_fatal("pthread_cond_wait: %s", strerror(err));
pthread_exit(0);
} else {
break;
}
break;
}
}
/* exit if we're told to */
@ -99,7 +99,7 @@ static void
idle_lock_set(d->idle_lock, d);
}
pthread_exit(0);
pthread_exit(0);
}
/**
@ -111,7 +111,7 @@ static void
static void
pre_exit(int signal)
{
idle_lock_set(false, data);
idle_lock_set(false, data);
wayland_set_idle_lock(-1);
pthread_cond_destroy(&cv);
pthread_mutex_destroy(&mp);
@ -120,7 +120,7 @@ pre_exit(int signal)
wl_registry_destroy(data->registry);
// wl_display_destroy(data->display);
wl_compositor_destroy(data->compositor);
wl_surface_destroy(data->surface);
wl_surface_destroy(data->surface);
/* make sure to cleanup the allocated data */
free(data);
@ -142,39 +142,39 @@ wayland_create_thread(void)
/* setup data */
data = calloc(1, sizeof(struct Data));
/* connect to wayland */
data->display = wl_display_connect(NULL);
if (!data->display) {
log_fatal("failed to connect to wayland display");
return -1;
}
/* connect to wayland */
data->display = wl_display_connect(NULL);
if (!data->display) {
log_fatal("failed to connect to wayland display");
return -1;
}
data->registry = wl_display_get_registry(data->display);
if (wl_registry_add_listener(data->registry, &reglistener, data) < 0) {
log_fatal("failed to connect to the wayland registry");
return -1;
}
log_fatal("failed to connect to the wayland registry");
return -1;
}
/* roundtrip so that the registry listener collects all the data */
/* roundtrip so that the registry listener collects all the data */
wl_display_roundtrip(data->display);
if (!data->compositor) {
log_fatal("wayland needs a compositor to run");
return -1;
}
return -1;
}
if (!data->inhibitmanager) {
log_fatal("compositor doesn't support the idle inhibit protocol");
return -1;
}
return -1;
}
data->surface = wl_compositor_create_surface(data->compositor);
if (!data->surface) {
log_fatal("wayland couldn't create a surface");
return -1;
}
data->surface = wl_compositor_create_surface(data->compositor);
if (!data->surface) {
log_fatal("wayland couldn't create a surface");
return -1;
}
data->idle_lock = false;
data->inhibitor = NULL;
data->idle_lock = false;
data->inhibitor = NULL;
/* zero the array, and setup sig handler and exit handler */
memset(&act, 0, sizeof(act));
@ -222,7 +222,7 @@ wayland_set_idle_lock(int lock)
/* set the idle lock */
data->idle_lock = lock;
log_debug("%s wayland idle lock", lock ? "enabled" : "disabled");
log_debug("%s wayland idle lock", lock ? "enabled" : "disabled");
pthread_cond_signal(&cv);
if (!locked) {