X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fplugin.c;fp=openbox%2Fplugin.c;h=d4c19b12081d529059b8aa390418cb7a0fdca95b;hb=4ed3fb89150d05e6fa134798315269c62de1bed9;hp=0000000000000000000000000000000000000000;hpb=cb73f209c9c635866bd79f4eb2b8aa9b4fbcfa6c;p=chaz%2Fopenbox diff --git a/openbox/plugin.c b/openbox/plugin.c new file mode 100644 index 00000000..d4c19b12 --- /dev/null +++ b/openbox/plugin.c @@ -0,0 +1,103 @@ +#include +#include + +typedef void (*PluginStartup)(); +typedef void (*PluginShutdown)(); + +typedef struct { + GModule *module; + char *name; + + PluginStartup startup; + PluginShutdown shutdown; +} Plugin; + +static gpointer load_sym(GModule *module, char *name, char *symbol) +{ + gpointer var = NULL; + if (!g_module_symbol(module, symbol, &var)) + g_warning("Failed to load symbol '%s' from plugin '%s'", symbol, name); + return var; +} + +static Plugin *plugin_new(char *name) +{ + Plugin *p; + char *path; + + p = g_new(Plugin, 1); + + path = g_build_filename(PLUGINDIR, name, NULL); + p->module = g_module_open(path, G_MODULE_BIND_LAZY); + g_free(path); + + if (p->module == NULL) { + path = g_build_filename(g_get_home_dir(), ".openbox", "plugins", name, + NULL); + p->module = g_module_open(path, G_MODULE_BIND_LAZY); + g_free(path); + } + + if (p->module == NULL) { + g_free(p); + return NULL; + } + + p->startup = load_sym(p->module, name, "startup"); + p->shutdown = load_sym(p->module, name, "shutdown"); + + if (p->startup == NULL || p->shutdown == NULL) { + g_module_close(p->module); + g_free(p); + return NULL; + } + + p->name = g_strdup(name); + return p; +} + +static void plugin_free(Plugin *p) +{ + p->shutdown(); + + g_free(p->name); + g_module_close(p->module); +} + + +static GData *plugins = NULL; + +void plugin_startup() +{ + g_datalist_init(&plugins); +} + +void plugin_shutdown() +{ + g_datalist_clear(&plugins); +} + +gboolean plugin_open(char *name) +{ + Plugin *p; + + if (g_datalist_get_data(&plugins, name) != NULL) { + g_warning("plugin '%s' already loaded, can't load again", name); + return TRUE; + } + + p = plugin_new(name); + if (p == NULL) { + g_warning("failed to load plugin '%s'", name); + return FALSE; + } + + g_datalist_set_data_full(&plugins, name, p, (GDestroyNotify) plugin_free); + p->startup(); + return TRUE; +} + +void plugin_close(char *name) +{ + g_datalist_remove_data(&plugins, name); +}