forked from external/yambar
particles: compile as shared libraries (plugins)
This commit is contained in:
parent
7b98ea2b7c
commit
47018104da
13 changed files with 89 additions and 130 deletions
|
@ -40,12 +40,6 @@ add_executable(f00bar
|
|||
decorations/underline.c decorations/underline.h
|
||||
|
||||
particles/dynlist.c particles/dynlist.h
|
||||
particles/empty.c particles/empty.h
|
||||
particles/list.c particles/list.h
|
||||
particles/map.c particles/map.h
|
||||
particles/progress-bar.c particles/progress-bar.h
|
||||
particles/ramp.c particles/ramp.h
|
||||
particles/string.c particles/string.h
|
||||
)
|
||||
|
||||
# TODO: directory global
|
||||
|
@ -78,15 +72,10 @@ target_link_libraries(f00bar
|
|||
${YAML_LIBRARIES}
|
||||
)
|
||||
|
||||
add_library(module-sdk INTERFACE)
|
||||
target_compile_definitions(module-sdk INTERFACE _GNU_SOURCE)
|
||||
target_compile_options(module-sdk INTERFACE ${CAIRO_CFLAGS_OTHER})
|
||||
target_include_directories(module-sdk INTERFACE ${CAIRO_INCLUDE_DIRS})
|
||||
target_link_libraries(module-sdk INTERFACE ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
set_property(TARGET f00bar PROPERTY INSTALL_RPATH \$ORIGIN/../lib/f00bar)
|
||||
set_property(TARGET f00bar PROPERTY BUILD_RPATH \$ORIGIN/modules)
|
||||
set_property(TARGET f00bar PROPERTY BUILD_RPATH "\$ORIGIN/modules;\$ORIGIN/particles")
|
||||
|
||||
install(TARGETS f00bar DESTINATION bin)
|
||||
|
||||
add_subdirectory(particles)
|
||||
add_subdirectory(modules)
|
||||
|
|
|
@ -9,13 +9,6 @@
|
|||
#include "plugin.h"
|
||||
#include "tllist.h"
|
||||
|
||||
#include "particles/empty.h"
|
||||
#include "particles/list.h"
|
||||
#include "particles/map.h"
|
||||
#include "particles/progress-bar.h"
|
||||
#include "particles/ramp.h"
|
||||
#include "particles/string.h"
|
||||
|
||||
const char *
|
||||
conf_err_prefix(const keychain_t *chain, const struct yml_node *node)
|
||||
{
|
||||
|
@ -285,65 +278,20 @@ conf_verify_particle_dictionary(keychain_t *chain, const struct yml_node *node)
|
|||
return false;
|
||||
}
|
||||
|
||||
#define COMMON_ATTRS \
|
||||
{"margin", false, &conf_verify_int}, \
|
||||
{"left-margin", false, &conf_verify_int}, \
|
||||
{"right-margin", false, &conf_verify_int}, \
|
||||
{"on-click", false, &conf_verify_string},
|
||||
|
||||
#undef COMMON_ATTRS
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
const struct particle_info *info;
|
||||
} particles_v2[] = {
|
||||
{"empty", &particle_empty},
|
||||
{"list", &particle_list},
|
||||
{"map", &particle_map},
|
||||
{"progress-bar", &particle_progress_bar},
|
||||
{"ramp", &particle_ramp},
|
||||
{"string", &particle_string},
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
const struct attr_info *attrs;
|
||||
size_t count;
|
||||
} particles[] = {
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(particles_v2) / sizeof(particles_v2[0]); i++) {
|
||||
if (strcmp(particles_v2[i].name, particle_name) != 0)
|
||||
continue;
|
||||
|
||||
if (!conf_verify_dict(chain_push(chain, particle_name), values,
|
||||
particles_v2[i].info->attrs,
|
||||
particles_v2[i].info->attr_count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
chain_pop(chain);
|
||||
return true;
|
||||
const struct particle_info *info = plugin_load_particle(particle_name);
|
||||
if (info == NULL) {
|
||||
LOG_ERR(
|
||||
"%s: invalid particle name: %s",
|
||||
conf_err_prefix(chain, particle), particle_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(particles) / sizeof(particles[0]); i++) {
|
||||
if (strcmp(particles[i].name, particle_name) != 0)
|
||||
continue;
|
||||
if (!conf_verify_dict(chain_push(chain, particle_name), values,
|
||||
info->attrs, info->attr_count))
|
||||
return false;
|
||||
|
||||
if (!conf_verify_dict(chain_push(chain, particle_name), values,
|
||||
particles[i].attrs, particles[i].count))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
chain_pop(chain);
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_ERR(
|
||||
"%s: invalid particle name: %s", conf_err_prefix(chain, particle), particle_name);
|
||||
return false;
|
||||
chain_pop(chain);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
48
config.c
48
config.c
|
@ -5,6 +5,8 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "color.h"
|
||||
|
||||
#include "decoration.h"
|
||||
|
@ -12,14 +14,6 @@
|
|||
#include "decorations/stack.h"
|
||||
#include "decorations/underline.h"
|
||||
|
||||
#include "particle.h"
|
||||
#include "particles/empty.h"
|
||||
#include "particles/list.h"
|
||||
#include "particles/map.h"
|
||||
#include "particles/progress-bar.h"
|
||||
#include "particles/ramp.h"
|
||||
#include "particles/string.h"
|
||||
|
||||
#include "module.h"
|
||||
#include "config-verify.h"
|
||||
#include "plugin.h"
|
||||
|
@ -153,6 +147,18 @@ particle_simple_list_from_config(const struct yml_node *node,
|
|||
parts[idx] = conf_to_particle(it.node, parent_font);
|
||||
}
|
||||
|
||||
/* Lazy-loaded function pointer to particle_list_new() */
|
||||
static struct particle *(*particle_list_new)(
|
||||
struct particle *particles[], size_t count,
|
||||
int left_spacing, int right_spacing, int left_margin, int right_margin,
|
||||
const char *on_click_template) = NULL;
|
||||
|
||||
if (particle_list_new == NULL) {
|
||||
const struct plugin *plug = plugin_load("list", PLUGIN_PARTICLE);
|
||||
particle_list_new = dlsym(plug->lib, "particle_list_new");
|
||||
assert(particle_list_new != NULL);
|
||||
}
|
||||
|
||||
return particle_list_new(parts, count, 0, 2, 0, 0, NULL);
|
||||
}
|
||||
|
||||
|
@ -178,27 +184,11 @@ conf_to_particle(const struct yml_node *node, const struct font *parent_font)
|
|||
const char *on_click_template
|
||||
= on_click != NULL ? yml_value_as_string(on_click) : NULL;
|
||||
|
||||
struct particle *ret = NULL;
|
||||
if (strcmp(type, "empty") == 0)
|
||||
ret = particle_empty.from_conf(
|
||||
pair.value, parent_font, left, right, on_click_template);
|
||||
else if (strcmp(type, "list") == 0)
|
||||
ret = particle_list.from_conf(
|
||||
pair.value, parent_font, left, right, on_click_template);
|
||||
else if (strcmp(type, "map") == 0)
|
||||
ret = particle_map.from_conf(
|
||||
pair.value, parent_font, left, right, on_click_template);
|
||||
else if (strcmp(type, "progress-bar") == 0)
|
||||
ret = particle_progress_bar.from_conf(
|
||||
pair.value, parent_font, left, right, on_click_template);
|
||||
else if (strcmp(type, "ramp") == 0)
|
||||
ret = particle_ramp.from_conf(
|
||||
pair.value, parent_font, left, right, on_click_template);
|
||||
else if (strcmp(type, "string") == 0)
|
||||
ret = particle_string.from_conf(
|
||||
pair.value, parent_font, left, right, on_click_template);
|
||||
else
|
||||
assert(false);
|
||||
const struct particle_info *info = plugin_load_particle(type);
|
||||
assert(info != NULL);
|
||||
|
||||
struct particle *ret = info->from_conf(
|
||||
pair.value, parent_font, left, right, on_click_template);
|
||||
|
||||
const struct yml_node *deco_node = yml_get_value(pair.value, "deco");
|
||||
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
add_library(module-sdk INTERFACE)
|
||||
target_compile_definitions(module-sdk INTERFACE _GNU_SOURCE)
|
||||
target_compile_options(module-sdk INTERFACE ${CAIRO_CFLAGS_OTHER})
|
||||
target_include_directories(module-sdk INTERFACE ${CAIRO_INCLUDE_DIRS})
|
||||
target_link_libraries(module-sdk INTERFACE ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
pkg_check_modules(ALSA REQUIRED alsa)
|
||||
add_library(alsa MODULE alsa.c)
|
||||
target_compile_options(alsa PRIVATE ${ALSA_CFLAGS_OTHER})
|
||||
|
|
24
particles/CMakeLists.txt
Normal file
24
particles/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
add_library(particle-sdk INTERFACE)
|
||||
target_compile_definitions(particle-sdk INTERFACE _GNU_SOURCE)
|
||||
target_compile_options(particle-sdk INTERFACE ${CAIRO_CFLAGS_OTHER})
|
||||
target_include_directories(particle-sdk INTERFACE ${CAIRO_INCLUDE_DIRS})
|
||||
|
||||
add_library(empty MODULE empty.c empty.h)
|
||||
target_link_libraries(empty particle-sdk)
|
||||
|
||||
add_library(list MODULE list.c list.h)
|
||||
target_link_libraries(list particle-sdk)
|
||||
|
||||
add_library(map MODULE map.c map.h)
|
||||
target_link_libraries(map particle-sdk)
|
||||
|
||||
add_library(progress-bar MODULE progress-bar.c progress-bar.h)
|
||||
target_link_libraries(progress-bar particle-sdk)
|
||||
|
||||
add_library(ramp MODULE ramp.c ramp.h)
|
||||
target_link_libraries(ramp particle-sdk)
|
||||
|
||||
add_library(string MODULE string.c string.h)
|
||||
target_link_libraries(string particle-sdk)
|
|
@ -48,7 +48,7 @@ from_conf(const struct yml_node *node, const struct font *parent_font,
|
|||
return empty_new(left_margin, right_margin, on_click_template);
|
||||
}
|
||||
|
||||
const struct particle_info particle_empty = {
|
||||
const struct particle_info plugin_info = {
|
||||
.from_conf = &from_conf,
|
||||
.attr_count = PARTICLE_COMMON_ATTRS_COUNT + 0,
|
||||
.attrs = {
|
||||
|
|
|
@ -198,7 +198,7 @@ from_conf(const struct yml_node *node, const struct font *parent_font,
|
|||
on_click_template);
|
||||
}
|
||||
|
||||
const struct particle_info particle_list = {
|
||||
const struct particle_info plugin_info = {
|
||||
.from_conf = &from_conf,
|
||||
.attr_count = PARTICLE_COMMON_ATTRS_COUNT + 4,
|
||||
.attrs = {
|
||||
|
|
|
@ -228,7 +228,7 @@ from_conf(const struct yml_node *node, const struct font *parent_font,
|
|||
default_particle, left_margin, right_margin, on_click_template);
|
||||
}
|
||||
|
||||
const struct particle_info particle_map = {
|
||||
const struct particle_info plugin_info = {
|
||||
.from_conf = &from_conf,
|
||||
.attr_count = PARTICLE_COMMON_ATTRS_COUNT + 3,
|
||||
.attrs = {
|
||||
|
|
|
@ -257,7 +257,7 @@ from_conf(const struct yml_node *node, const struct font *parent_font,
|
|||
left_margin, right_margin, on_click_template);
|
||||
}
|
||||
|
||||
const struct particle_info particle_progress_bar = {
|
||||
const struct particle_info plugin_info = {
|
||||
.from_conf = &from_conf,
|
||||
.attr_count = PARTICLE_COMMON_ATTRS_COUNT + 7,
|
||||
.attrs = {
|
||||
|
|
|
@ -178,7 +178,7 @@ from_conf(const struct yml_node *node, const struct font *parent_font,
|
|||
on_click_template);
|
||||
}
|
||||
|
||||
const struct particle_info particle_ramp = {
|
||||
const struct particle_info plugin_info = {
|
||||
.from_conf = &from_conf,
|
||||
.attr_count = PARTICLE_COMMON_ATTRS_COUNT + 2,
|
||||
.attrs = {
|
||||
|
|
|
@ -171,7 +171,7 @@ from_conf(const struct yml_node *node, const struct font *parent_font,
|
|||
fg_color, left_margin, right_margin, on_click_template);
|
||||
}
|
||||
|
||||
const struct particle_info particle_string = {
|
||||
const struct particle_info plugin_info = {
|
||||
.from_conf = &from_conf,
|
||||
.attr_count = PARTICLE_COMMON_ATTRS_COUNT + 5,
|
||||
.attrs = {
|
||||
|
|
28
plugin.c
28
plugin.c
|
@ -9,16 +9,6 @@
|
|||
#include "config.h"
|
||||
#include "tllist.h"
|
||||
|
||||
enum plugin_type { PLUGIN_MODULE, PLUGIN_PARTICLE };
|
||||
|
||||
struct plugin {
|
||||
char *name;
|
||||
enum plugin_type type;
|
||||
|
||||
void *lib;
|
||||
const void *sym;
|
||||
};
|
||||
|
||||
static tll(struct plugin) plugins = tll_init();
|
||||
|
||||
static const char *
|
||||
|
@ -51,15 +41,14 @@ fini(void)
|
|||
tll_free_and_free(plugins, free_plugin);
|
||||
}
|
||||
|
||||
static const void *
|
||||
_load_plugin(const char *name, enum plugin_type type)
|
||||
const struct plugin *
|
||||
plugin_load(const char *name, enum plugin_type type)
|
||||
{
|
||||
/* Have we already loaded it? */
|
||||
tll_foreach(plugins, plug) {
|
||||
if (plug->item.type == type && strcmp(plug->item.name, name) == 0) {
|
||||
LOG_DBG("%s: %s already loaded: %p", type2str(type), name, plug->item.lib);
|
||||
assert(plug->item.sym != NULL);
|
||||
return plug->item.sym;
|
||||
return &plug->item;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +69,7 @@ _load_plugin(const char *name, enum plugin_type type)
|
|||
|
||||
/* TODO: rename to plugin_info or so, in both modules and particles */
|
||||
dlerror(); /* Clear previous error */
|
||||
plug->sym = dlsym(lib, type == PLUGIN_MODULE ? "module_info" : "particle_info");
|
||||
plug->sym = dlsym(lib, type == PLUGIN_MODULE ? "module_info" : "plugin_info");
|
||||
|
||||
const char *dlsym_error = dlerror();
|
||||
if (dlsym_error != NULL) {
|
||||
|
@ -88,18 +77,19 @@ _load_plugin(const char *name, enum plugin_type type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
assert(plug->sym != NULL);
|
||||
return plug->sym;
|
||||
return plug;
|
||||
}
|
||||
|
||||
const struct module_info *
|
||||
plugin_load_module(const char *name)
|
||||
{
|
||||
return _load_plugin(name, PLUGIN_MODULE);
|
||||
const struct plugin *plug = plugin_load(name, PLUGIN_MODULE);
|
||||
return plug != NULL ? plug->sym : NULL;
|
||||
}
|
||||
|
||||
const struct particle_info *
|
||||
plugin_load_particle(const char *name)
|
||||
{
|
||||
return _load_plugin(name, PLUGIN_PARTICLE);
|
||||
const struct plugin *plug = plugin_load(name, PLUGIN_PARTICLE);
|
||||
return plug != NULL ? plug->sym : NULL;
|
||||
}
|
||||
|
|
12
plugin.h
12
plugin.h
|
@ -5,3 +5,15 @@
|
|||
|
||||
const struct module_info *plugin_load_module(const char *name);
|
||||
const struct particle_info *plugin_load_particle(const char *name);
|
||||
|
||||
enum plugin_type { PLUGIN_MODULE, PLUGIN_PARTICLE };
|
||||
|
||||
struct plugin {
|
||||
char *name;
|
||||
enum plugin_type type;
|
||||
|
||||
void *lib;
|
||||
const void *sym;
|
||||
};
|
||||
|
||||
const struct plugin *plugin_load(const char *name, enum plugin_type type);
|
||||
|
|
Loading…
Add table
Reference in a new issue