diff options
Diffstat (limited to 'src/config.c')
| -rw-r--r-- | src/config.c | 85 |
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); |
