diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/action.c | 45 | ||||
| -rw-r--r-- | src/action.h | 31 | ||||
| -rw-r--r-- | src/block.c | 13 | ||||
| -rw-r--r-- | src/block.h | 2 | ||||
| -rw-r--r-- | src/config.c | 58 | ||||
| -rw-r--r-- | src/config.h | 4 |
6 files changed, 152 insertions, 1 deletions
diff --git a/src/action.c b/src/action.c new file mode 100644 index 0000000..c8ccee1 --- /dev/null +++ b/src/action.c @@ -0,0 +1,45 @@ +#include <stdlib.h> +#include <string.h> + +#include "action.h" +#include "block.h" + +void action_perform(action_t *action, block_t *block, config_t *config) +{ + for (size_t i = 0; i < action->length; i++) { + const char *key = action->parts[i].key; + const char *value = action->parts[i].value; + + if (strncmp(key, "block.", 6)) + abort(); + + block_t *target = NULL; + for (size_t i = 0; i < config->n_blocks; i++) { + if (!strcmp(key + 6, config->blocks[i]->label)) { + target = config->blocks[i]; + break; + } + } + + if (target == NULL) + abort(); + + block_change(target, key, value); + } +} + +int action_validate(action_t *action, config_t *config) +{ + // TODO + return 0; +} + +void action_free(action_t *action) +{ + for (size_t i = 0; i < action->length; i++) { + free(action->parts[i].key); + free(action->parts[i].value); + } + + free(action->parts); +} diff --git a/src/action.h b/src/action.h new file mode 100644 index 0000000..02ca1b8 --- /dev/null +++ b/src/action.h @@ -0,0 +1,31 @@ +#ifndef COMET_ACTION_H +#define COMET_ACTION_H + +#include "config.h" + +//typedef enum { +// ACTION_SET, +// ACTION_RUN, +//} action_type_t; + +typedef struct { + //action_type_t type; + char *key; + char *value; +} action_part_t; + +struct action { + char *label; + action_part_t *parts; + size_t length; +}; + +typedef struct action action_t; + +void action_perform(action_t *action, block_t *block, config_t *config); + +int action_validate(action_t *action, config_t *config); + +void action_free(action_t *action); + +#endif diff --git a/src/block.c b/src/block.c index e7cb72d..f3283e9 100644 --- a/src/block.c +++ b/src/block.c @@ -50,6 +50,19 @@ void block_update(block_t *block) } } +int block_change(block_t *block, const char *key, const char *value) +{ + if (block->scheme->change_fn == NULL) { + log_value_debug("Ignored block change", + "s:label", block->label, + "s:key", key, + "s:value", value); + return 0; + } + + return block->scheme->change_fn(block, key, value); +} + void block_free(block_t *block) { if (block->scheme->clean_fn != NULL) diff --git a/src/block.h b/src/block.h index 6b3b2c5..896eb8a 100644 --- a/src/block.h +++ b/src/block.h @@ -121,6 +121,8 @@ extern const block_scheme_t *block_schemes[]; void block_update(block_t *block); +int block_change(block_t *block, const char *key, const char *value); + void block_free(block_t *block); #endif diff --git a/src/config.c b/src/config.c index 13addef..d20aebe 100644 --- a/src/config.c +++ b/src/config.c @@ -9,7 +9,7 @@ #include "config.h" #include "util.h" #include "block.h" -#include "block.h" +#include "action.h" #define ANY_INI_IMPLEMENT #include "any_ini.h" @@ -431,6 +431,18 @@ static block_t *config_alloc_block(config_t *config, const block_scheme_t *schem return block; } +static config_status_t config_read_action(action_t *action, const char **type, + const char *section, const char *key, const char *value) +{ + action->parts = realloc(action->parts, ++action->length * sizeof(action_part_t)); + assert(action->parts != NULL); + + action->parts[action->length - 1].key = strcopy(key); + action->parts[action->length - 1].value = strcopy(key); + + return CONFIG_SUCCESS; +} + // TODO: More robust way to define defaults void config_init(config_t *config) { @@ -463,6 +475,8 @@ int config_read(config_t *config, FILE *file) int errors = 0; bool bar_section = false; + action_t *action = NULL; + const block_scheme_t *scheme = NULL; block_t *block = NULL; @@ -519,6 +533,32 @@ int config_read(config_t *config, FILE *file) "i:line", ini.line); goto skip_pair; + } else if (!strncmp(section, "action.", 7)) { + char *label = strcopy(section + 7); + + if (label == NULL || *label == '\0') { + ++errors; + log_value_error("Action section must have a valid label", + "s:section", section, + "i:line", ini.line); + } else { + for (size_t i = 0; i < config->n_actions; i++) { + if (!strcmp(label, config->actions[i].label)) { + ++errors; + log_value_error("Action section must have a unique label", + "s:section", section, + "i:line", ini.line); + } + } + } + + config->actions = realloc(config->actions, ++config->n_actions * sizeof(action_t)); + assert(config->actions != NULL); + + action = &config->actions[config->n_actions - 1]; + memset(action, 0, sizeof(action_t)); + action->label = label; + } else if (!strcmp(section, "bar")) { bar_section = true; } else @@ -552,6 +592,10 @@ int config_read(config_t *config, FILE *file) status = config_read_block(scheme, block, &type, section, key, value); } + if (action != NULL) { + status = config_read_action(action, &type, section, key, value); + } + switch (status) { case CONFIG_SUCCESS: break; @@ -613,6 +657,15 @@ int config_validate(config_t *config) block->validated = tmp == 0; } + // Validate actions + // NOTE: Maybe move this after the config is resolved? + // + for (size_t i = 0; i < config->n_actions; i++) { + action_t *action = &config->actions[i]; + log_debug("Validating 'action.%s'", action->label); + errors += action_validate(action, config); + } + return errors; } @@ -694,6 +747,9 @@ void config_free(config_t *config) for (size_t i = 0; i < config->n_blocks; i++) block_free(config->blocks[i]); + for (size_t i = 0; i < config->n_actions; i++) + action_free(&config->actions[i]); + gradient_free(&config->background); free(config->blocks); diff --git a/src/config.h b/src/config.h index dd1bf1f..e005dff 100644 --- a/src/config.h +++ b/src/config.h @@ -8,6 +8,8 @@ typedef struct block block_t; +typedef struct action action_t; + typedef enum { CONFIG_STRING, CONFIG_INT, @@ -31,6 +33,8 @@ typedef struct { typedef struct { size_t n_blocks; block_t **blocks; + size_t n_actions; + action_t *actions; char *font; char *monitor; bool override_redirect; |
