#include #include #include "block.h" #include "util.h" #include "action.h" #include "any_log.h" extern const block_scheme_t block_text_scheme; extern const block_scheme_t block_group_scheme; extern const block_scheme_t block_ram_scheme; extern const block_scheme_t block_fs_scheme; extern const block_scheme_t block_date_scheme; extern const block_scheme_t block_script_scheme; extern const block_scheme_t block_slider_scheme; const block_scheme_t *block_schemes[] = { &block_text_scheme, &block_group_scheme, &block_ram_scheme, &block_fs_scheme, &block_date_scheme, &block_script_scheme, &block_slider_scheme, NULL, }; void block_update(block_t *block) { if (block->update_fn != NULL) { struct timespec now, diff; timespec_get(&now, TIME_UTC); diff = timespec_diff(now, block->update_last); if (timespec_greater(diff, block->update_interval)) { log_value_trace("Updating block", "s:label", block->label, "g:ts", ANY_LOG_FORMATTER(timespec_print), &now); block->update_fn(block); block->update_last = now; } } // NOTE: Block spec should handle its children by itself... // if (block->type == BLOCK_GROUP) { block_group_t *group = (block_group_t *)block; for (size_t i = 0; i < group->n_children; i++) block_update(group->children[i]); } } bool block_resolve_action(block_t *block, config_t *config, action_t **action) { if (action == NULL || *action == NULL) return true; char *label = (char *)*action; bool result = config_resolve_action(config, label, action); if (!result) { log_error("Action '%s' not found (referenced by block '%s')", label, block->label); } free(label); return result; } bool block_resolve(block_t *block, config_t *config) { if (block->resolved) return true; block->resolved = true; for (size_t i = 0; i < EVENT_MAX; i++) { if (!block_resolve_action(block, config, &block->actions[i])) return false; } return block->scheme->resolve_fn == NULL || block->scheme->resolve_fn(block, config); } bool block_change(block_t *block, config_t *config, const char *key, const char *value) { extern const config_entry_t block_entries[]; // Ignore notify invocations config_status_t status = key == NULL ? CONFIG_UNKNOWN : config_read_entry(block_entries, block, NULL, key, value); if (status == CONFIG_UNKNOWN && block->scheme->change_fn != NULL) status = block->scheme->change_fn(block, config, key, value); return status == CONFIG_SUCCESS || (!config->action_strict_set && status == CONFIG_UNKNOWN); } void block_free(block_t *block) { if (block->scheme->clean_fn != NULL) block->scheme->clean_fn(block); gradient_clean(&block->bg_color); gradient_clean(&block->line_color); free(block->label); free(block); }