aboutsummaryrefslogtreecommitdiff
path: root/src/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c85
1 files changed, 76 insertions, 9 deletions
diff --git a/src/config.c b/src/config.c
index 32666a8..e13d9b9 100644
--- a/src/config.c
+++ b/src/config.c
@@ -31,15 +31,15 @@ static const config_entry_t bar_entries[] = {
};
static const config_entry_t block_entries[] = {
- { "hidden", CONFIG_BOOL, NULL, offsetof(block_t, hidden) },
- { "color", CONFIG_COLOR, NULL, offsetof(block_t, color) },
- { "line-color", CONFIG_COLOR, NULL, offsetof(block_t, line_color) },
- { "line-width", CONFIG_UINT, NULL, offsetof(block_t, line_width) },
- { "x-padding", CONFIG_UINT, NULL, offsetof(block_t, x_padding) },
- { "y-padding", CONFIG_UINT, NULL, offsetof(block_t, y_padding) },
- { "min-width", CONFIG_UINT, NULL, offsetof(block_t, min_width) },
- { "max-width", CONFIG_UINT, NULL, offsetof(block_t, max_width) },
- { "interval", CONFIG_TIME, NULL, offsetof(block_t, update_interval) },
+ { "hidden", CONFIG_BOOL, NULL, offsetof(block_t, hidden) },
+ { "color", CONFIG_GRADIENT, NULL, offsetof(block_t, bg_color) },
+ { "line-color", CONFIG_GRADIENT, NULL, offsetof(block_t, line_color) },
+ { "line-width", CONFIG_UINT, NULL, offsetof(block_t, line_width) },
+ { "x-padding", CONFIG_UINT, NULL, offsetof(block_t, x_padding) },
+ { "y-padding", CONFIG_UINT, NULL, offsetof(block_t, y_padding) },
+ { "min-width", CONFIG_UINT, NULL, offsetof(block_t, min_width) },
+ { "max-width", CONFIG_UINT, NULL, offsetof(block_t, max_width) },
+ { "interval", CONFIG_TIME, NULL, offsetof(block_t, update_interval) },
{ 0 },
};
@@ -173,6 +173,64 @@ static bool config_read_color(const char *value, color_t *result)
return false;
}
+static bool config_read_gradient(const char *value, gradient_t *result)
+{
+ size_t count = 0;
+ for (size_t i = 0; value[i] != '\0'; ++i)
+ count += value[i] == ',';
+
+ color_t *colors = calloc(count + 1, sizeof(color_t));
+ size_t n = 0;
+
+ char *state, *copy = strcopy(value);
+ for (char *string = copy; ; string = NULL) {
+ char *token = strtok_r(string, ",", &state);
+
+ if (token == NULL)
+ break;
+
+ while (isspace(*token)) token++;
+ char *end = token + strlen(token);
+ while (isspace(*end)) end--;
+ *end = '\0';
+
+ if (!config_read_color(token, &colors[n++])) {
+ free(copy);
+ free(colors);
+ return false;
+ }
+ }
+
+ free(copy);
+ result->colors = colors;
+ result->length = n;
+
+ if (n == 0) {
+ free(colors);
+ log_debug("Expected at least one color");
+ return false;
+ }
+
+ if (n == 1) {
+ result->cached = cairo_pattern_create_rgba(colors->r, colors->g, colors->b, colors->a);
+ return true;
+ }
+
+ result->cached = cairo_pattern_create_linear(0, 0, 1, 0);
+
+ for (size_t i = 0; i < n; i++) {
+ double offset = i * 1.0 / (n - 1);
+ cairo_pattern_add_color_stop_rgba(result->cached,
+ offset,
+ colors[i].r,
+ colors[i].g,
+ colors[i].b,
+ colors[i].a);
+ }
+
+ return true;
+}
+
static bool config_read_enum(const char *value, config_enum_t *data, int *result)
{
for (int i = 0; data[i].label != NULL; i++) {
@@ -306,6 +364,15 @@ static config_status_t config_read_entry(const config_entry_t *entries, void *re
}
break;
+ case CONFIG_GRADIENT:
+ if (config_read_gradient(value, (gradient_t *)result)) {
+ char *gradient = gradient_to_string((gradient_t *)result);
+ log_debug("Set '%s.%s' to '%s'", section, key, gradient);
+ free(gradient);
+ return CONFIG_SUCCESS;
+ }
+ break;
+
case CONFIG_ENUM:
if (config_read_enum(value, (config_enum_t *)entries[i].data, (int *)result)) {
log_debug("Set '%s.%s' to '%d'", section, key, *(int *)result);