aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/action.c45
-rw-r--r--src/action.h31
-rw-r--r--src/block.c13
-rw-r--r--src/block.h2
-rw-r--r--src/config.c58
-rw-r--r--src/config.h4
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;