From 7754ef36616122eb7766a827dccf814581a98908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 13 Jan 2019 17:43:25 +0100 Subject: [PATCH] decorations: are now plugins --- CMakeLists.txt | 10 +++--- config-verify.c | 67 ++++++-------------------------------- config.c | 54 ++++-------------------------- config.h | 3 +- decoration.h | 3 ++ decorations/CMakeLists.txt | 24 ++++++++++++++ decorations/background.c | 25 ++++++++++++-- decorations/stack.c | 45 +++++++++++++++++++++++-- decorations/underline.c | 27 +++++++++++++-- plugin.c | 17 +++++++--- plugin.h | 9 ++++- 11 files changed, 160 insertions(+), 124 deletions(-) create mode 100644 decorations/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index e18de16..4c39e6a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,10 +35,6 @@ add_executable(f00bar xcb.c xcb.h yml.c yml.h - decorations/background.c decorations/background.h - decorations/stack.c decorations/stack.h - decorations/underline.c decorations/underline.h - particles/dynlist.c particles/dynlist.h ) @@ -70,9 +66,11 @@ target_link_libraries(f00bar ) set_property(TARGET f00bar PROPERTY INSTALL_RPATH \$ORIGIN/../lib/f00bar) -set_property(TARGET f00bar PROPERTY BUILD_RPATH "\$ORIGIN/modules;\$ORIGIN/particles") +set_property(TARGET f00bar PROPERTY + BUILD_RPATH "\$ORIGIN/modules;\$ORIGIN/particles;\$ORIGIN/decorations") install(TARGETS f00bar DESTINATION bin) -add_subdirectory(particles) add_subdirectory(modules) +add_subdirectory(particles) +add_subdirectory(decorations) diff --git a/config-verify.c b/config-verify.c index 3ab76f9..f5bb00d 100644 --- a/config-verify.c +++ b/config-verify.c @@ -164,25 +164,6 @@ conf_verify_font(keychain_t *chain, const struct yml_node *node) return conf_verify_dict(chain, node, attrs); } -static bool -verify_decoration_stack(keychain_t *chain, const struct yml_node *node) -{ - if (!yml_is_list(node)) { - LOG_ERR("%s: must be a list of decorations", conf_err_prefix(chain, node)); - return false; - } - - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it)) - { - if (!conf_verify_decoration(chain, it.node)) - return false; - } - - return true; -} - bool conf_verify_decoration(keychain_t *chain, const struct yml_node *node) { @@ -204,47 +185,19 @@ conf_verify_decoration(keychain_t *chain, const struct yml_node *node) return false; } - if (strcmp(deco_name, "stack") == 0) { - bool ret = verify_decoration_stack(chain_push(chain, deco_name), values); - chain_pop(chain); - return ret; + const struct deco_iface *iface = plugin_load_deco(deco_name); + if (iface == NULL) { + LOG_ERR("%s: invalid decoration name: %s", + conf_err_prefix(chain, deco), deco_name); + return false; } - static const struct attr_info background[] = { - {"color", true, &conf_verify_color}, - {NULL, false, NULL}, - }; + chain_push(chain, deco_name); + if (!iface->verify_conf(chain, values)) + return false; - static const struct attr_info underline[] = { - {"size", true, &conf_verify_int}, - {"color", true, &conf_verify_color}, - {NULL, false, NULL}, - }; - - static const struct { - const char *name; - const struct attr_info *attrs; - size_t count; - } decos[] = { - {"background", background, sizeof(background) / sizeof(background[0])}, - {"underline", underline, sizeof(underline) / sizeof(underline[0])}, - }; - - for (size_t i = 0; i < sizeof(decos) / sizeof(decos[0]); i++) { - if (strcmp(decos[i].name, deco_name) != 0) - continue; - - chain_push(chain, deco_name); - if (!conf_verify_dict(chain, values, decos[i].attrs)) - return false; - - chain_pop(chain); - return true; - } - - LOG_ERR( - "%s: invalid decoration name: %s", conf_err_prefix(chain, deco), deco_name); - return false; + chain_pop(chain); + return true; } bool diff --git a/config.c b/config.c index 505cb45..487cb90 100644 --- a/config.c +++ b/config.c @@ -77,60 +77,18 @@ conf_to_font(const struct yml_node *node) return font_new(family != NULL ? yml_value_as_string(family) : "monospace"); } -static struct deco * -deco_background_from_config(const struct yml_node *node) -{ - const struct yml_node *color = yml_get_value(node, "color"); - return deco_background(conf_to_color(color)); -} - -static struct deco * -deco_underline_from_config(const struct yml_node *node) -{ - const struct yml_node *size = yml_get_value(node, "size"); - const struct yml_node *color = yml_get_value(node, "color"); - return deco_underline(yml_value_as_int(size), conf_to_color(color)); -} - -static struct deco *deco_from_config(const struct yml_node *node); - -static struct deco * -deco_stack_from_config(const struct yml_node *node) -{ - size_t count = yml_list_length(node); - - struct deco *decos[count]; - size_t idx = 0; - - for (struct yml_list_iter it = yml_list_iter(node); - it.node != NULL; - yml_list_next(&it), idx++) - { - decos[idx] = deco_from_config(it.node); - } - - return deco_stack(decos, count); -} - -static struct deco * -deco_from_config(const struct yml_node *node) +struct deco * +conf_to_deco(const struct yml_node *node) { struct yml_dict_iter it = yml_dict_iter(node); const struct yml_node *deco_type = it.key; const struct yml_node *deco_data = it.value; const char *type = yml_value_as_string(deco_type); + const struct deco_iface *iface = plugin_load_deco(type); - if (strcmp(type, "background") == 0) - return deco_background_from_config(deco_data); - else if (strcmp(type, "underline") == 0) - return deco_underline_from_config(deco_data); - else if (strcmp(type, "stack") == 0) - return deco_stack_from_config(deco_data); - else - assert(false); - - return NULL; + assert(iface != NULL); + return iface->from_conf(deco_data); } static struct particle * @@ -191,7 +149,7 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited) const char *on_click_template = on_click != NULL ? yml_value_as_string(on_click) : NULL; - struct deco *deco = deco_node != NULL ? deco_from_config(deco_node) : NULL; + struct deco *deco = deco_node != NULL ? conf_to_deco(deco_node) : NULL; /* * Font and foreground are inheritable attributes. Each particle diff --git a/config.h b/config.h index 3579877..ee3f281 100644 --- a/config.h +++ b/config.h @@ -21,5 +21,6 @@ struct conf_inherit { struct rgba foreground; }; -struct particle * conf_to_particle( +struct particle *conf_to_particle( const struct yml_node *node, struct conf_inherit inherited); +struct deco *conf_to_deco(const struct yml_node *node); diff --git a/decoration.h b/decoration.h index b40602c..78f2f05 100644 --- a/decoration.h +++ b/decoration.h @@ -8,3 +8,6 @@ struct deco { int x, int y, int width, int height); void (*destroy)(struct deco *deco); }; + +#define DECORATION_COMMON_ATTRS \ + {NULL, false, NULL} diff --git a/decorations/CMakeLists.txt b/decorations/CMakeLists.txt new file mode 100644 index 0000000..3d5a52b --- /dev/null +++ b/decorations/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.13) + +add_library(decoration-sdk INTERFACE) +target_compile_options(decoration-sdk INTERFACE ${CAIRO_CFLAGS_OTHER}) +target_include_directories(decoration-sdk INTERFACE ${CAIRO_INCLUDE_DIRS}) + +set(CMAKE_SHARED_MODULE_PREFIX decoration_) + +add_library(background MODULE background.c background.h) +target_link_libraries(background decoration-sdk) + +add_library(stack MODULE stack.c stack.h) +target_link_libraries(stack decoration-sdk) + +add_library(underline MODULE underline.c underline.h) +target_link_libraries(underline decoration-sdk) + +install( + TARGETS + background + stack + underline + + DESTINATION lib/f00bar) diff --git a/decorations/background.c b/decorations/background.c index b0a15a6..ce9d5ec 100644 --- a/decorations/background.c +++ b/decorations/background.c @@ -2,6 +2,9 @@ #include +#include "../config.h" +#include "../config-verify.h" + struct private { struct rgba color; }; @@ -24,8 +27,8 @@ expose(const struct deco *deco, cairo_t *cr, int x, int y, int width, int height cairo_fill(cr); } -struct deco * -deco_background(struct rgba color) +static struct deco * +background_new(struct rgba color) { struct private *priv = malloc(sizeof(*priv)); priv->color = color; @@ -37,3 +40,21 @@ deco_background(struct rgba color) return deco; } + +struct deco * +from_conf(const struct yml_node *node) +{ + const struct yml_node *color = yml_get_value(node, "color"); + return background_new(conf_to_color(color)); +} + +bool +verify_conf(keychain_t *chain, const struct yml_node *node) +{ + static const struct attr_info attrs[] = { + {"color", true, &conf_verify_color}, + DECORATION_COMMON_ATTRS, + }; + + return conf_verify_dict(chain, node, attrs); +} diff --git a/decorations/stack.c b/decorations/stack.c index d7410e4..cc97b13 100644 --- a/decorations/stack.c +++ b/decorations/stack.c @@ -2,6 +2,11 @@ #include +#define LOG_MODULE "stack" +#include "../log.h" +#include "../config.h" +#include "../config-verify.h" + struct private { struct deco **decos; size_t count; @@ -26,8 +31,8 @@ expose(const struct deco *deco, cairo_t *cr, int x, int y, int width, int height d->decos[i]->expose(d->decos[i], cr, x, y, width, height); } -struct deco * -deco_stack(struct deco *decos[], size_t count) +static struct deco * +stack_new(struct deco *decos[], size_t count) { struct private *priv = malloc(sizeof(*priv)); priv->decos = malloc(count * sizeof(priv->decos[0])); @@ -43,3 +48,39 @@ deco_stack(struct deco *decos[], size_t count) return deco; } +struct deco * +from_conf(const struct yml_node *node) +{ + size_t count = yml_list_length(node); + + struct deco *decos[count]; + size_t idx = 0; + + for (struct yml_list_iter it = yml_list_iter(node); + it.node != NULL; + yml_list_next(&it), idx++) + { + decos[idx] = conf_to_deco(it.node); + } + + return stack_new(decos, count); +} + +bool +verify_conf(keychain_t *chain, const struct yml_node *node) +{ + if (!yml_is_list(node)) { + LOG_ERR("%s: must be a list of decorations", conf_err_prefix(chain, node)); + return false; + } + + for (struct yml_list_iter it = yml_list_iter(node); + it.node != NULL; + yml_list_next(&it)) + { + if (!conf_verify_decoration(chain, it.node)) + return false; + } + + return true; +} diff --git a/decorations/underline.c b/decorations/underline.c index 0b7ce27..c0e7afa 100644 --- a/decorations/underline.c +++ b/decorations/underline.c @@ -2,6 +2,9 @@ #include +#include "../config.h" +#include "../config-verify.h" + struct private { int size; struct rgba color; @@ -25,8 +28,8 @@ expose(const struct deco *deco, cairo_t *cr, int x, int y, int width, int height cairo_fill(cr); } -struct deco * -deco_underline(int size, struct rgba color) +static struct deco * +underline_new(int size, struct rgba color) { struct private *priv = malloc(sizeof(*priv)); priv->size = size; @@ -39,3 +42,23 @@ deco_underline(int size, struct rgba color) return deco; } + +struct deco * +from_conf(const struct yml_node *node) +{ + const struct yml_node *size = yml_get_value(node, "size"); + const struct yml_node *color = yml_get_value(node, "color"); + return underline_new(yml_value_as_int(size), conf_to_color(color)); +} + +bool +verify_conf(keychain_t *chain, const struct yml_node *node) +{ + static const struct attr_info attrs[] = { + {"size", true, &conf_verify_int}, + {"color", true, &conf_verify_color}, + DECORATION_COMMON_ATTRS, + }; + + return conf_verify_dict(chain, node, attrs); +} diff --git a/plugin.c b/plugin.c index 0786a56..b43a12f 100644 --- a/plugin.c +++ b/plugin.c @@ -15,8 +15,9 @@ static const char * type2str(enum plugin_type type) { switch (type) { - case PLUGIN_MODULE: return "module"; - case PLUGIN_PARTICLE: return "particle"; + case PLUGIN_MODULE: return "module"; + case PLUGIN_PARTICLE: return "particle"; + case PLUGIN_DECORATION: return "decoration"; } return NULL; @@ -53,10 +54,9 @@ plugin_load(const char *name, enum plugin_type type) } } + char path[128]; - snprintf( - path, sizeof(path), "%s_%s.so", - type == PLUGIN_MODULE ? "module" : "particle", name); + snprintf(path, sizeof(path), "%s_%s.so", type2str(type), name); /* Not loaded - do it now */ void *lib = dlopen(path, RTLD_LOCAL | RTLD_NOW); @@ -102,3 +102,10 @@ plugin_load_particle(const char *name) const struct plugin *plug = plugin_load(name, PLUGIN_PARTICLE); return plug != NULL ? &plug->particle : NULL; } + +const struct deco_iface * +plugin_load_deco(const char *name) +{ + const struct plugin *plug = plugin_load(name, PLUGIN_DECORATION); + return plug != NULL ? &plug->decoration : NULL; +} diff --git a/plugin.h b/plugin.h index aa910c7..d315b6f 100644 --- a/plugin.h +++ b/plugin.h @@ -16,10 +16,16 @@ struct particle_iface { const struct yml_node *node, struct particle *common); }; +struct deco_iface { + bool (*verify_conf)(keychain_t *chain, const struct yml_node *node); + struct deco *(*from_conf)(const struct yml_node *node); +}; + const struct module_iface *plugin_load_module(const char *name); const struct particle_iface *plugin_load_particle(const char *name); +const struct deco_iface *plugin_load_deco(const char *name); -enum plugin_type { PLUGIN_MODULE, PLUGIN_PARTICLE }; +enum plugin_type { PLUGIN_MODULE, PLUGIN_PARTICLE, PLUGIN_DECORATION }; struct plugin { char *name; @@ -34,6 +40,7 @@ struct plugin { struct module_iface module; struct particle_iface particle; + struct deco_iface decoration; }; };