forked from external/yambar
decorations: are now plugins
This commit is contained in:
parent
4eee71eaf4
commit
7754ef3661
11 changed files with 160 additions and 124 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
54
config.c
54
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");
|
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
|
||||||
|
|
1
config.h
1
config.h
|
@ -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);
|
||||||
|
|
|
@ -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}
|
||||||
|
|
24
decorations/CMakeLists.txt
Normal file
24
decorations/CMakeLists.txt
Normal 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)
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
13
plugin.c
13
plugin.c
|
@ -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;
|
||||||
|
}
|
||||||
|
|
9
plugin.h
9
plugin.h
|
@ -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;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue