Merge branch 'decorations-as-plugins'

This commit is contained in:
Daniel Eklöf 2019-01-13 17:51:15 +01:00
commit 5e107414e4
33 changed files with 199 additions and 168 deletions

View file

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

View file

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

View file

@ -7,16 +7,10 @@
#include <dlfcn.h>
#include "color.h"
#include "decoration.h"
#include "decorations/background.h"
#include "decorations/stack.h"
#include "decorations/underline.h"
#include "bar.h"
#include "module.h"
#include "color.h"
#include "config-verify.h"
#include "module.h"
#include "plugin.h"
static uint8_t
@ -77,60 +71,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 +143,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

View file

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

View file

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

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)
target_link_libraries(background decoration-sdk)
add_library(stack MODULE stack.c)
target_link_libraries(stack decoration-sdk)
add_library(underline MODULE underline.c)
target_link_libraries(underline decoration-sdk)
install(
TARGETS
background
stack
underline
DESTINATION lib/f00bar)

View file

@ -1,7 +1,9 @@
#include "background.h"
#include <stdlib.h>
#include "../config.h"
#include "../config-verify.h"
#include "../decoration.h"
struct private {
struct rgba color;
};
@ -24,8 +26,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 +39,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);
}

View file

@ -1,6 +0,0 @@
#pragma once
#include "../color.h"
#include "../decoration.h"
struct deco *deco_background(struct rgba color);

View file

@ -1,7 +1,11 @@
#include "underline.h"
#include <stdlib.h>
#define LOG_MODULE "stack"
#include "../log.h"
#include "../config.h"
#include "../config-verify.h"
#include "../decoration.h"
struct private {
struct deco **decos;
size_t count;
@ -26,8 +30,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 +47,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;
}

View file

@ -1,6 +0,0 @@
#pragma once
#include "../color.h"
#include "../decoration.h"
struct deco *deco_stack(struct deco *decos[], size_t count);

View file

@ -1,7 +1,9 @@
#include "underline.h"
#include <stdlib.h>
#include "../config.h"
#include "../config-verify.h"
#include "../decoration.h"
struct private {
int size;
struct rgba color;
@ -25,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_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 +41,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);
}

View file

@ -1,6 +0,0 @@
#pragma once
#include "../color.h"
#include "../decoration.h"
struct deco *deco_underline(int size, struct rgba color);

View file

@ -8,6 +8,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
#include "../tllist.h"
struct private {

View file

@ -14,6 +14,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
struct private {
struct particle *label;
@ -41,11 +42,15 @@ content(struct module *mod)
const struct private *m = mod->private;
mtx_lock(&mod->lock);
const long current = m->current_brightness;
const long max = m->max_brightness;
const long percent = max > 0 ? 100 * current / max : 0;
struct tag_set tags = {
.tags = (struct tag *[]){
tag_new_int_range(
mod, "brightness", m->current_brightness, 0, m->max_brightness),
tag_new_int_range(mod, "percent", 100 * m->current_brightness / m->max_brightness, 0, 100),
tag_new_int_range(mod, "brightness", current, 0, max),
tag_new_int_range(mod, "percent", percent, 0, 100),
},
.count = 2,
};

View file

@ -15,6 +15,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
enum state { STATE_FULL, STATE_CHARGING, STATE_DISCHARGING };

View file

@ -7,6 +7,7 @@
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
struct private {
struct particle *label;

View file

@ -20,6 +20,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
#include "../particles/dynlist.h"

View file

@ -4,6 +4,7 @@
#include <poll.h>
#include "../config.h"
#include "../config-verify.h"
#include "../module.h"
struct private {

View file

@ -17,6 +17,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
enum state {
STATE_OFFLINE = 1000,

View file

@ -17,6 +17,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
#include "../module.h"
#include "../tllist.h"

View file

@ -17,6 +17,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
#include "../particles/dynlist.h"
#include "../tllist.h"

View file

@ -12,6 +12,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
#include "../xcb.h"
struct layout {

View file

@ -16,6 +16,7 @@
#include "../log.h"
#include "../bar.h"
#include "../config.h"
#include "../config-verify.h"
#include "../xcb.h"
struct private {

View file

@ -2,7 +2,6 @@
#include <cairo.h>
#include "color.h"
#include "config-verify.h"
#include "decoration.h"
#include "font.h"
#include "tag.h"

View file

@ -6,22 +6,22 @@ target_include_directories(particle-sdk INTERFACE ${CAIRO_INCLUDE_DIRS})
set(CMAKE_SHARED_MODULE_PREFIX particle_)
add_library(empty MODULE empty.c empty.h)
add_library(empty MODULE empty.c)
target_link_libraries(empty particle-sdk)
add_library(list MODULE list.c list.h)
add_library(list MODULE list.c)
target_link_libraries(list particle-sdk)
add_library(map MODULE map.c map.h)
add_library(map MODULE map.c)
target_link_libraries(map particle-sdk)
add_library(progress-bar MODULE progress-bar.c progress-bar.h)
add_library(progress-bar MODULE progress-bar.c)
target_link_libraries(progress-bar particle-sdk)
add_library(ramp MODULE ramp.c ramp.h)
add_library(ramp MODULE ramp.c)
target_link_libraries(ramp particle-sdk)
add_library(string MODULE string.c string.h)
add_library(string MODULE string.c)
target_link_libraries(string particle-sdk)
install(

View file

@ -1,6 +1,7 @@
#include <stdlib.h>
#include "../config.h"
#include "../config-verify.h"
#include "../particle.h"
static int

View file

@ -4,6 +4,7 @@
#define LOG_ENABLE_DBG 1
#include "../log.h"
#include "../config.h"
#include "../config-verify.h"
#include "../particle.h"
struct private {

View file

@ -5,6 +5,7 @@
#define LOG_MODULE "map"
#include "../log.h"
#include "../config.h"
#include "../config-verify.h"
#include "../particle.h"
struct particle_map {

View file

@ -6,6 +6,7 @@
#define LOG_ENABLE_DBG 0
#include "../log.h"
#include "../config.h"
#include "../config-verify.h"
#include "../particle.h"
struct private {

View file

@ -5,6 +5,7 @@
#include <stdio.h>
#include "../config.h"
#include "../config-verify.h"
#include "../particle.h"
struct private {

View file

@ -6,6 +6,7 @@
#define LOG_ENABLE_DBG 1
#include "../log.h"
#include "../config.h"
#include "../config-verify.h"
#include "../particle.h"
struct private {

View file

@ -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;
}

View file

@ -4,22 +4,30 @@
#include "module.h"
#include "particle.h"
typedef bool (*verify_func_t)(keychain_t *chain, const struct yml_node *node);
struct module_iface {
bool (*verify_conf)(keychain_t *chain, const struct yml_node *node);
verify_func_t verify_conf;
struct module *(*from_conf)(
const struct yml_node *node, struct conf_inherit inherited);
};
struct particle_iface {
bool (*verify_conf)(keychain_t *chain, const struct yml_node *node);
verify_func_t verify_conf;
struct particle *(*from_conf)(
const struct yml_node *node, struct particle *common);
};
struct deco_iface {
verify_func_t verify_conf;
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 +42,7 @@ struct plugin {
struct module_iface module;
struct particle_iface particle;
struct deco_iface decoration;
};
};