X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fplugin.c;h=e95d03e9444a4100ce8f64552766e9352ef4cb3f;hb=c90da6da781932c2d178bfb7e39ec1d5003543b7;hp=281b1cdec08ea344bc1cd76c3b2bd5754ed3ba17;hpb=5d7d6038ca46f6d92fcfa1d46f4ebe76ebc9b2e2;p=chaz%2Fopenbox diff --git a/openbox/plugin.c b/openbox/plugin.c index 281b1cde..e95d03e9 100644 --- a/openbox/plugin.c +++ b/openbox/plugin.c @@ -1,10 +1,8 @@ +#include "plugins/interface.h" + #include #include -typedef void (*PluginSetupConfig)(); -typedef void (*PluginStartup)(); -typedef void (*PluginShutdown)(); - typedef struct { GModule *module; char *name; @@ -12,14 +10,18 @@ typedef struct { PluginSetupConfig config; PluginStartup startup; PluginShutdown shutdown; + PluginCreate create; + PluginDestroy destroy; } Plugin; -static gpointer load_sym(GModule *module, char *name, char *symbol) +static gpointer load_sym(GModule *module, char *name, char *symbol, + gboolean allow_fail) { gpointer var; if (!g_module_symbol(module, symbol, &var)) { - g_warning("Failed to load symbol '%s' from plugin '%s'", - symbol, name); + if (!allow_fail) + g_warning("Failed to load symbol '%s' from plugin '%s'", + symbol, name); var = NULL; } return var; @@ -44,14 +46,20 @@ static Plugin *plugin_new(char *name) } if (p->module == NULL) { + g_warning(g_module_error()); g_free(p); return NULL; } p->config = (PluginSetupConfig)load_sym(p->module, name, - "plugin_setup_config"); - p->startup = (PluginStartup)load_sym(p->module, name, "plugin_startup"); - p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown"); + "plugin_setup_config", FALSE); + p->startup = (PluginStartup)load_sym(p->module, name, "plugin_startup", + FALSE); + p->shutdown = (PluginShutdown)load_sym(p->module, name, "plugin_shutdown", + FALSE); + p->create = (PluginCreate)load_sym(p->module, name, "plugin_create", TRUE); + p->destroy = (PluginDestroy)load_sym(p->module, name, "plugin_destroy", + TRUE); if (p->config == NULL || p->startup == NULL || p->shutdown == NULL) { g_module_close(p->module); @@ -84,12 +92,13 @@ void plugin_shutdown() g_datalist_clear(&plugins); } -gboolean plugin_open(char *name) +gboolean plugin_open_full(char *name, gboolean reopen) { Plugin *p; if (g_datalist_get_data(&plugins, name) != NULL) { - g_warning("plugin '%s' already loaded, can't load again", name); + if (!reopen) + g_warning("plugin '%s' already loaded, can't load again", name); return TRUE; } @@ -104,6 +113,14 @@ gboolean plugin_open(char *name) return TRUE; } +gboolean plugin_open(char *name) { + return plugin_open_full(name, FALSE); +} + +gboolean plugin_open_reopen(char *name) { + return plugin_open_full(name, TRUE); +} + void plugin_close(char *name) { g_datalist_remove_data(&plugins, name); @@ -139,19 +156,58 @@ void plugin_loadall() if (io == NULL) { /* load the default plugins */ - plugin_open("focus"); - plugin_open("keyboard"); - plugin_open("mouse"); plugin_open("placement"); plugin_open("resistance"); + + /* XXX rm me when the parser loads me magically */ + plugin_open("client_menu"); } else { /* load the plugins in the rc file */ while (g_io_channel_read_line(io, &name, NULL, NULL, &err) == G_IO_STATUS_NORMAL) { g_strstrip(name); - plugin_open(name); + if (name[0] != '\0' && name[0] != '#') + plugin_open(name); g_free(name); } g_io_channel_unref(io); } } + +void *plugin_create(char *name, void *data) +{ + Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name); + + if (p == NULL) { + g_warning("Unable to find plugin for create: %s", name); + return NULL; + } + + if (p->create == NULL || p->destroy == NULL) { + g_critical("Unsupported create/destroy: %s", name); + return NULL; + } + + return p->create(data); +} + +void plugin_destroy(char *name, void *data) +{ + Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name); + + if (p == NULL) { + g_critical("Unable to find plugin for destroy: %s", name); + /* really shouldn't happen, but attempt to free something anyway? */ + g_free(data); + return; + } + + if (p->destroy == NULL || p->create == NULL) { + g_critical("Unsupported create/destroy: %s", name); + /* really, really shouldn't happen, but attempt to free anyway? */ + g_free(data); + return; + } + + p->destroy(data); +}