decorations: are now plugins

This commit is contained in:
Daniel Eklöf 2019-01-13 17:43:25 +01:00
parent 4eee71eaf4
commit 7754ef3661
11 changed files with 160 additions and 124 deletions

View file

@ -35,10 +35,6 @@ add_executable(f00bar
xcb.c xcb.h xcb.c xcb.h
yml.c yml.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 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 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) install(TARGETS f00bar DESTINATION bin)
add_subdirectory(particles)
add_subdirectory(modules) add_subdirectory(modules)
add_subdirectory(particles)
add_subdirectory(decorations)

View file

@ -164,25 +164,6 @@ conf_verify_font(keychain_t *chain, const struct yml_node *node)
return conf_verify_dict(chain, node, attrs); 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 bool
conf_verify_decoration(keychain_t *chain, const struct yml_node *node) conf_verify_decoration(keychain_t *chain, const struct yml_node *node)
{ {
@ -204,49 +185,21 @@ conf_verify_decoration(keychain_t *chain, const struct yml_node *node)
return false; return false;
} }
if (strcmp(deco_name, "stack") == 0) { const struct deco_iface *iface = plugin_load_deco(deco_name);
bool ret = verify_decoration_stack(chain_push(chain, deco_name), values); if (iface == NULL) {
chain_pop(chain); LOG_ERR("%s: invalid decoration name: %s",
return ret; conf_err_prefix(chain, deco), deco_name);
return false;
} }
static const struct attr_info background[] = {
{"color", true, &conf_verify_color},
{NULL, false, NULL},
};
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); chain_push(chain, deco_name);
if (!conf_verify_dict(chain, values, decos[i].attrs)) if (!iface->verify_conf(chain, values))
return false; return false;
chain_pop(chain); chain_pop(chain);
return true; return true;
} }
LOG_ERR(
"%s: invalid decoration name: %s", conf_err_prefix(chain, deco), deco_name);
return false;
}
bool bool
conf_verify_particle_list_items(keychain_t *chain, const struct yml_node *node) conf_verify_particle_list_items(keychain_t *chain, const struct yml_node *node)
{ {

View file

@ -77,60 +77,18 @@ conf_to_font(const struct yml_node *node)
return font_new(family != NULL ? yml_value_as_string(family) : "monospace"); return font_new(family != NULL ? yml_value_as_string(family) : "monospace");
} }
static struct deco * struct deco *
deco_background_from_config(const struct yml_node *node) conf_to_deco(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 yml_dict_iter it = yml_dict_iter(node); struct yml_dict_iter it = yml_dict_iter(node);
const struct yml_node *deco_type = it.key; const struct yml_node *deco_type = it.key;
const struct yml_node *deco_data = it.value; const struct yml_node *deco_data = it.value;
const char *type = yml_value_as_string(deco_type); const char *type = yml_value_as_string(deco_type);
const struct deco_iface *iface = plugin_load_deco(type);
if (strcmp(type, "background") == 0) assert(iface != NULL);
return deco_background_from_config(deco_data); return iface->from_conf(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;
} }
static struct particle * static struct particle *
@ -191,7 +149,7 @@ conf_to_particle(const struct yml_node *node, struct conf_inherit inherited)
const char *on_click_template const char *on_click_template
= on_click != NULL ? yml_value_as_string(on_click) : NULL; = 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 * Font and foreground are inheritable attributes. Each particle

View file

@ -23,3 +23,4 @@ struct conf_inherit {
struct particle *conf_to_particle( struct particle *conf_to_particle(
const struct yml_node *node, struct conf_inherit inherited); const struct yml_node *node, struct conf_inherit inherited);
struct deco *conf_to_deco(const struct yml_node *node);

View file

@ -8,3 +8,6 @@ struct deco {
int x, int y, int width, int height); int x, int y, int width, int height);
void (*destroy)(struct deco *deco); void (*destroy)(struct deco *deco);
}; };
#define DECORATION_COMMON_ATTRS \
{NULL, false, NULL}

View file

@ -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)

View file

@ -2,6 +2,9 @@
#include <stdlib.h> #include <stdlib.h>
#include "../config.h"
#include "../config-verify.h"
struct private { struct private {
struct rgba color; 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); cairo_fill(cr);
} }
struct deco * static struct deco *
deco_background(struct rgba color) background_new(struct rgba color)
{ {
struct private *priv = malloc(sizeof(*priv)); struct private *priv = malloc(sizeof(*priv));
priv->color = color; priv->color = color;
@ -37,3 +40,21 @@ deco_background(struct rgba color)
return deco; 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);
}

View file

@ -2,6 +2,11 @@
#include <stdlib.h> #include <stdlib.h>
#define LOG_MODULE "stack"
#include "../log.h"
#include "../config.h"
#include "../config-verify.h"
struct private { struct private {
struct deco **decos; struct deco **decos;
size_t count; 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); d->decos[i]->expose(d->decos[i], cr, x, y, width, height);
} }
struct deco * static struct deco *
deco_stack(struct deco *decos[], size_t count) stack_new(struct deco *decos[], size_t count)
{ {
struct private *priv = malloc(sizeof(*priv)); struct private *priv = malloc(sizeof(*priv));
priv->decos = malloc(count * sizeof(priv->decos[0])); priv->decos = malloc(count * sizeof(priv->decos[0]));
@ -43,3 +48,39 @@ deco_stack(struct deco *decos[], size_t count)
return deco; 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;
}

View file

@ -2,6 +2,9 @@
#include <stdlib.h> #include <stdlib.h>
#include "../config.h"
#include "../config-verify.h"
struct private { struct private {
int size; int size;
struct rgba color; 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); cairo_fill(cr);
} }
struct deco * static struct deco *
deco_underline(int size, struct rgba color) underline_new(int size, struct rgba color)
{ {
struct private *priv = malloc(sizeof(*priv)); struct private *priv = malloc(sizeof(*priv));
priv->size = size; priv->size = size;
@ -39,3 +42,23 @@ deco_underline(int size, struct rgba color)
return deco; 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);
}

View file

@ -17,6 +17,7 @@ type2str(enum plugin_type type)
switch (type) { switch (type) {
case PLUGIN_MODULE: return "module"; case PLUGIN_MODULE: return "module";
case PLUGIN_PARTICLE: return "particle"; case PLUGIN_PARTICLE: return "particle";
case PLUGIN_DECORATION: return "decoration";
} }
return NULL; return NULL;
@ -53,10 +54,9 @@ plugin_load(const char *name, enum plugin_type type)
} }
} }
char path[128]; char path[128];
snprintf( snprintf(path, sizeof(path), "%s_%s.so", type2str(type), name);
path, sizeof(path), "%s_%s.so",
type == PLUGIN_MODULE ? "module" : "particle", name);
/* Not loaded - do it now */ /* Not loaded - do it now */
void *lib = dlopen(path, RTLD_LOCAL | RTLD_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); const struct plugin *plug = plugin_load(name, PLUGIN_PARTICLE);
return plug != NULL ? &plug->particle : NULL; 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;
}

View file

@ -16,10 +16,16 @@ struct particle_iface {
const struct yml_node *node, struct particle *common); 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 module_iface *plugin_load_module(const char *name);
const struct particle_iface *plugin_load_particle(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 { struct plugin {
char *name; char *name;
@ -34,6 +40,7 @@ struct plugin {
struct module_iface module; struct module_iface module;
struct particle_iface particle; struct particle_iface particle;
struct deco_iface decoration;
}; };
}; };