feat(config file): add a config file

This commit is contained in:
2025-09-23 22:46:19 -04:00
parent b4715770db
commit 80dde85a2e
11 changed files with 229 additions and 22 deletions

9
.gitmodules vendored
View File

@@ -1,3 +1,12 @@
[submodule "lib/log.c"]
path = lib/log.c
url = https://github.com/rxi/log.c
[submodule "lib/tomlc99"]
path = lib/tomlc99
url = https://github.com/cktan/tomlc99
[submodule "lib/tinyexpr"]
path = lib/tinyexpr
url = https://github.com/codeplea/tinyexpr
[submodule "lib/cargs"]
path = lib/cargs
url = https://github.com/likle/cargs

View File

@@ -1,11 +0,0 @@
#include <math.h>
static const char *notification_name = "Event Handler"; /* name to use in notifications */
static const char *battery_dir = "/sys/class/power_supply/BAT1"; /* path to the batteries directory */
static const char *linefile = "/sys/class/power_supply/ACAD/online"; /* path to the file which tells us if we are online (plugged in) */
static const char *ledfile = "/sys/class/leds/input0::capslock/brightness"; /* path to the file which lights up the led */
static const char *acpid_sock = "/run/acpid.socket"; /* acpid socket file */
static const int blink_start = 15; /* percentage to start blinking at */
const double blink_formula(int x) { /* formula used to set the blinking rate, this function takes in one argument: the battery percentage */
return 1.7 + 18.5 * exp(-0.29 * x);
}

16
example_config.toml Normal file
View File

@@ -0,0 +1,16 @@
[battery]
status_path = "/sys/class/power_supply/BAT1"
power_source = "/sys/class/power_supply/ACAD/online"
[led]
brightness_path = "/sys/class/leds/input0::capslock/brightness"
[led.blink]
trigger_level = 15
timing_formula = "1.7 + 18.5 * exp(-0.29 * p)"
[acpi_daemon]
socket_path = "/run/acpid.socket"
[log]
level = "INFO"

27
include/config.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#define LED_BLINK_TRIGGER_DISABLED 101
/**
* @brief parse the config file
*
* @param path the path to the config file
*/
void parse_config_file(char *path);
/**
* @brief setup the led formula
*/
void setup_led_formula(void);
extern char *battery_status_path;
extern char *battery_power_source;
extern char *led_brightness_path;
extern unsigned int led_blink_trigger_level;
extern char *led_blink_timing_formula;
double led_blink_timing_func(int percent);
extern char *acpi_daemon_socket_path;

1
lib/cargs Submodule

Submodule lib/cargs added at 0698c3f903

1
lib/tinyexpr Submodule

Submodule lib/tinyexpr added at 9907207e5d

1
lib/tomlc99 Submodule

Submodule lib/tomlc99 added at 26b9c1ea77

View File

@@ -9,7 +9,9 @@ srcfiles = files(
'src/led.c',
'src/wayland.c',
'src/acpi.c',
'src/utils.c'
'src/utils.c',
'src/battery.c',
'src/config.c'
)
# wayland stuff
@@ -55,10 +57,22 @@ executable('eh', srcfiles,
],
include_directories: [
'lib/log.c/src',
'lib/tinyexpr',
'lib/tomlc99',
'lib/cargs/include',
'include'
],
link_with: [
static_library('log.c', 'lib/log.c/src/log.c',
include_directories: 'lib/log.c/src')
include_directories: 'lib/log.c/src'),
static_library('tinyexpr', 'lib/tinyexpr/tinyexpr.c',
include_directories: 'lib/tinyexpr'),
static_library('tomlc99', 'lib/tomlc99/toml.c',
include_directories: 'lib/tomlc99'),
static_library('cargs', 'lib/cargs/src/cargs.c',
include_directories: 'lib/cargs/include')
]
)

View File

@@ -15,7 +15,7 @@ char
FILE *f;
/* open up the battery capacity for reading */
d = concat(battery_dir, "/capacity");
d = concat(battery_status_path, "/capacity");
f = fopen(d, "r");
free(d);

109
src/config.c Normal file
View File

@@ -0,0 +1,109 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <log.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 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);
static te_expr *expr;
static double percentage;
char *battery_status_path = "/sys/class/power_supply/BAT1";
char *battery_power_source = "/sys/class/power_supply/ACAD/online";
char *led_brightness_path = "/sys/class/leds/input0::capslock/brightness";
unsigned int led_blink_trigger_level = 15;
char *led_blink_timing_formula = "1.7 + 18.5 * exp(-0.29 * p)";
char *acpi_daemon_socket_path = "/run/acpid.socket";
double
led_blink_timing_func(int percent)
{
percentage = percent;
return te_eval(expr);
// return 1.7 + 18.5 * exp(-0.29 * percent);
}
static void
free_eval(int sig)
{
te_free(expr);
exit(sig);
}
void
setup_led_formula(void)
{
int err;
te_variable vars[] = { { "p", &percentage } };
expr = te_compile(led_blink_timing_formula, vars, 1, &err);
signal(SIGINT, free_eval);
if (!expr) {
log_fatal("%s", led_blink_timing_formula);
log_fatal("%*s^ Error near here", err - 1, "");
exit(1);
}
}
void
parse_config_file(char *path)
{
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);
}
config = toml_parse_file(f, errbuf, sizeof(errbuf));
fclose(f);
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");
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");
}

View File

@@ -11,7 +11,9 @@
#include <unistd.h>
#include <stdbool.h>
#include "log.h"
#include <cargs.h>
#include <log.h>
#include "led.h"
#include "wayland.h"
#include "acpi.h"
@@ -22,6 +24,22 @@
#define MAX_BUFLEN 1024
static struct cag_option options[] = {
{
.identifier = 'c',
.access_letters = "c",
.access_name = "config",
.value_name = "PATH",
.description = "Config file"
},
{
.identifier = 'h',
.access_letters = "h",
.access_name = "help",
.description = "Shows the command help"
}
};
void
on_battery_event(char *percent, bool plugged)
{
@@ -33,8 +51,8 @@ on_battery_event(char *percent, bool plugged)
/* convert battery percentage to an int */
res = strtol(percent, &ep, 10);
if (res <= blink_start) {
rate = blink_formula(res);
if (res <= led_blink_trigger_level) {
rate = led_blink_timing_func(res);
if (rate >= 1) {
led_set_rate(rate);
}
@@ -54,18 +72,40 @@ on_battery_event(char *percent, bool plugged)
int
main(int argc, char *argv[])
{
bool plugged = plugged_in((char *)linefile);
char buffer[MAX_BUFLEN], *out[4];
cag_option_context context;
bool plugged = plugged_in(battery_power_source);
char buffer[MAX_BUFLEN], *out[4], *config_path;
int sock_fd;
cag_option_init(&context, options, CAG_ARRAY_SIZE(options), argc, argv);
while (cag_option_fetch(&context)) {
switch (cag_option_get_identifier(&context)) {
case 'c':
config_path = (char *)cag_option_get_value(&context);
parse_config_file(config_path);
break;
case 'h':
printf("Usage: eh [OPTION]...\n");
printf("Demonstrates the cargs library.\n\n");
cag_option_print(options, CAG_ARRAY_SIZE(options), stdout);
return EXIT_SUCCESS;
case '?':
cag_option_print_error(&context, stdout);
break;
}
}
/* configure the led blinking formula */
setup_led_formula();
/* set the logging level */
log_set_level(LOG_DEBUG);
/* open up socket address */
sock_fd = acpi_create_socket((char *)acpid_sock);
sock_fd = acpi_create_socket(acpi_daemon_socket_path);
/* create the led thread */
led_create_thread((char *)ledfile);
led_create_thread(led_brightness_path);
/* create the wayland thread */
wayland_create_thread();
@@ -96,7 +136,7 @@ main(int argc, char *argv[])
char *s = get_substring(out[1], 0, 2);
if (strcmp(s, "AC") == 0) {
plugged = plugged_in((char *)linefile);
plugged = plugged_in(battery_power_source);
}
free(s);