openbox/tools/obconf/plugins.c

158 lines
4.7 KiB
C
Raw Normal View History

#include "obconf.h"
#include "plugins/obconf_interface.h"
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <gmodule.h>
typedef struct ConfigPlugin {
GModule *module;
char *fname;
char *name;
char *plugin_name;
PluginStartupFunc start;
PluginShutdownFunc stop;
PluginInterfaceVersionFunc interface;
PluginNameFunc getname;
PluginPluginNameFunc getpname;
PluginIconFunc icon;
PluginToplevelWidgetFunc toplevel;
PluginEditedFunc edited;
PluginLoadFunc load;
PluginSaveFunc save;
} ConfigPlugin;
GSList *plugins_list = NULL;
static gpointer load_sym(GModule *module, char *name, char *symbol,
gboolean allow_fail)
{
gpointer var;
if (!g_module_symbol(module, symbol, &var)) {
if (!allow_fail)
g_warning("Failed to load symbol '%s' from plugin '%s'",
symbol, name);
var = NULL;
}
return var;
}
static void add_plugin(ConfigPlugin *p)
{
GtkTreeIter it;
gtk_list_store_append(obconf_sections_store, &it);
gtk_list_store_set(obconf_sections_store, &it, 0, p->name, -1);
gtk_notebook_append_page(obconf_options, p->toplevel(), NULL);
}
void load_dir(char *path)
{
char *fpath;
DIR *dir;
struct dirent *dirp;
ConfigPlugin *p;
GModule *mod;
GSList *it;
char *suffix;
suffix = g_strconcat("-config.", G_MODULE_SUFFIX, NULL);
if (!(dir = opendir(path)))
return;
while ((dirp = readdir(dir))) {
if (g_strrstr(dirp->d_name, suffix)) {
/* look for duplicates */
for (it = plugins_list; it; it = it->next)
if (!strcmp(((ConfigPlugin*)it->data)->fname, dirp->d_name))
break;
if (!it) {
fpath = g_build_filename(path, dirp->d_name, NULL);
if ((mod = g_module_open(fpath, 0))) {
p = g_new(ConfigPlugin, 1);
p->module = mod;
p->fname = g_strdup(dirp->d_name);
p->interface = (PluginInterfaceVersionFunc)
load_sym(p->module, p->fname,
"plugin_interface_version",
FALSE);
p->start = (PluginStartupFunc)
load_sym(p->module, p->fname, "plugin_startup", FALSE);
p->stop = (PluginShutdownFunc)
load_sym(p->module, p->fname, "plugin_shutdown",FALSE);
p->getname = (PluginNameFunc)
load_sym(p->module, p->fname, "plugin_name", FALSE);
p->getpname = (PluginNameFunc)
load_sym(p->module, p->fname, "plugin_plugin_name",
FALSE);
p->icon = (PluginIconFunc)
load_sym(p->module, p->fname, "plugin_icon", FALSE);
p->toplevel = (PluginToplevelWidgetFunc)
load_sym(p->module, p->fname, "plugin_toplevel_widget",
FALSE);
p->edited = (PluginEditedFunc)
load_sym(p->module, p->fname, "plugin_edited", FALSE);
p->load = (PluginLoadFunc)
load_sym(p->module, p->fname, "plugin_load", FALSE);
p->save = (PluginSaveFunc)
load_sym(p->module, p->fname, "plugin_save", FALSE);
if (!(p->start &&
p->stop &&
p->interface &&
p->name &&
p->icon &&
p->toplevel &&
p->edited &&
p->load &&
p->save)) {
g_module_close(p->module);
g_free(p->fname);
g_free(p);
} else {
p->start();
p->name = p->getname();
p->plugin_name = p->getpname();
plugins_list = g_slist_append(plugins_list, p);
add_plugin(p); /* add to the gui */
}
}
g_free(fpath);
}
}
}
g_free(suffix);
}
void plugins_load()
{
char *path;
path = g_build_filename(g_get_home_dir(), ".openbox", "plugins", NULL);
load_dir(path);
g_free(path);
load_dir(PLUGINDIR);
}
gboolean plugins_edited(ConfigPlugin *p)
{
return p->edited();
}
void plugins_load_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root)
{
p->load(doc, root);
}
void plugins_save_settings(ConfigPlugin *p, xmlDocPtr doc, xmlNodePtr root)
{
p->save(doc, root);
}