X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=src%2Fgrits-plugin.c;h=12ca5edef1194651244b94883f2e14087a77043e;hb=5c17e7d79895982036139dcffb5c17cefb1d4d9f;hp=9eb2d2180fca0f84f686e772740db2b81dd20b63;hpb=4bef8517366b0195e321add06250e7d659434661;p=grits diff --git a/src/grits-plugin.c b/src/grits-plugin.c index 9eb2d21..12ca5ed 100644 --- a/src/grits-plugin.c +++ b/src/grits-plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2010 Andy Spencer + * Copyright (C) 2009-2011 Andy Spencer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,23 +16,27 @@ */ /** - * SECTION:gis-plugin + * SECTION:grits-plugin * @short_description: Plugin support * - * A plugin in libgis is a GObject which implements the GisPlugin interface. Additionally, each - * plugin is compiled to a separate shared object and loaded conditionally at runtime when the - * plugin is enabled. Each such shared object should define a GisPluginConstructor() function named - * gis_plugin_NAME_new which will be called when loading the plugin. - * - * Almost all libgis functionality is provided by a set of plugins. Each plugin can how however much - * it likes. The interface between plugins and the rest of libgis is intentionally very thin. Since - * libgis is the library, plugins must manually do everything. For instance, to draw something in - * the world, the plugin must add an object to the viewer. Likewise, plugins need to register - * callbacks on the viewer in order to receive updates, very little happens automagically. - * - * That being said, one thing that plugins do do automagically, is provide a configuration area. - * Since the plugin doesn't know what application is is being loaded form, it is better for the - * application to ask the plugin for it's confirmation area, not the other way around. + * A plugin in grits is a GObject which implements the GritsPlugin interface. + * Additionally, each plugin is compiled to a separate shared object and loaded + * conditionally at runtime when the plugin is enabled. Each such shared object + * should define a GritsPluginConstructor() function named + * grits_plugin_NAME_new which will be called when loading the plugin. + * + * Almost all grits functionality is provided by a set of plugins. Each plugin + * can how however much it likes. The interface between plugins and the rest of + * grits is intentionally very thin. Since grits is the library, plugins must + * manually do everything. For instance, to draw something in the world, the + * plugin must add an object to the viewer. Likewise, plugins need to + * register callbacks on the viewer in order to receive updates, very little + * happens automagically. + * + * That being said, one thing that plugins do do automagically, is provide a + * configuration area. Since the plugin doesn't know what application is is + * being loaded form, it is better for the application to ask the plugin for + * it's confirmation area, not the other way around. */ #include @@ -40,12 +44,12 @@ #include -#include "gis-plugin.h" +#include "grits-plugin.h" /******************** * Plugin interface * ********************/ -static void gis_plugin_base_init(gpointer g_class) +static void grits_plugin_base_init(gpointer g_class) { static gboolean is_initialized = FALSE; if (!is_initialized) { @@ -54,23 +58,23 @@ static void gis_plugin_base_init(gpointer g_class) } } -GType gis_plugin_get_type() +GType grits_plugin_get_type() { static GType type = 0; if (type == 0) { static const GTypeInfo info = { - sizeof(GisPluginInterface), - gis_plugin_base_init, + sizeof(GritsPluginInterface), + grits_plugin_base_init, NULL, }; type = g_type_register_static(G_TYPE_INTERFACE, - "GisPlugin", &info, 0); + "GritsPlugin", &info, 0); } return type; } /** - * gis_plugin_get_name: + * grits_plugin_get_name: * @plugin: the plugin * * Get a short human readable name for a plugin, this is not necessarily the @@ -78,43 +82,43 @@ GType gis_plugin_get_type() * * Returns: a short name for the plugin */ -const gchar *gis_plugin_get_name(GisPlugin *plugin) +const gchar *grits_plugin_get_name(GritsPlugin *plugin) { - if (!GIS_IS_PLUGIN(plugin)) + if (!GRITS_IS_PLUGIN(plugin)) return NULL; - return GIS_PLUGIN_GET_INTERFACE(plugin)->name; + return GRITS_PLUGIN_GET_INTERFACE(plugin)->name; } /** - * gis_plugin_get_description: + * grits_plugin_get_description: * @plugin: the plugin * * Get a description of a plugin * * Returns: a description of the plugin */ -const gchar *gis_plugin_get_description(GisPlugin *plugin) +const gchar *grits_plugin_get_description(GritsPlugin *plugin) { - if (!GIS_IS_PLUGIN(plugin)) + if (!GRITS_IS_PLUGIN(plugin)) return NULL; - return GIS_PLUGIN_GET_INTERFACE(plugin)->description; + return GRITS_PLUGIN_GET_INTERFACE(plugin)->description; } /** - * gis_plugin_get_config: + * grits_plugin_get_config: * @plugin: the plugin * - * Each plugin can provide a configuration area. Applications using libgis + * Each plugin can provide a configuration area. Applications using grits * should display this configuration area to the user so they can modify the * behavior of the plugin. * * Returns: a configuration widget for the plugin */ -GtkWidget *gis_plugin_get_config(GisPlugin *plugin) +GtkWidget *grits_plugin_get_config(GritsPlugin *plugin) { - if (!GIS_IS_PLUGIN(plugin)) + if (!GRITS_IS_PLUGIN(plugin)) return NULL; - GisPluginInterface *iface = GIS_PLUGIN_GET_INTERFACE(plugin); + GritsPluginInterface *iface = GRITS_PLUGIN_GET_INTERFACE(plugin); return iface->get_config ? iface->get_config(plugin) : NULL; } @@ -123,47 +127,54 @@ GtkWidget *gis_plugin_get_config(GisPlugin *plugin) * Plugins API * ***************/ typedef struct { - gchar *name; - GisPlugin *plugin; -} GisPluginStore; + gchar *name; + GritsPlugin *plugin; + GModule *module; +} GritsPluginStore; /** - * gis_plugins_new: + * grits_plugins_new: * @dir: the directory to search for plugins in - * @prefs: a #GisPrefs to save the state of plugins, or NULL + * @prefs: a #GritsPrefs to save the state of plugins, or NULL * * Create a new plugin source. If @prefs is not %NULL, the state of the plugins * will be saved when they are either enabled or disabled. * * Returns: the new plugin source */ -GisPlugins *gis_plugins_new(const gchar *dir, GisPrefs *prefs) +GritsPlugins *grits_plugins_new(const gchar *dir, GritsPrefs *prefs) { - g_debug("GisPlugins: new - dir=%s", dir); - GisPlugins *plugins = g_new0(GisPlugins, 1); + g_debug("GritsPlugins: new - dir=%s", dir); + GritsPlugins *plugins = g_new0(GritsPlugins, 1); plugins->prefs = prefs; if (dir) plugins->dir = g_strdup(dir); return plugins; } +static void grits_plugins_free_store(GritsPluginStore *store) +{ + g_object_unref(store->plugin); + //g_module_close(store->module); + g_free(store->name); + g_free(store); +} + /** - * gis_plugins_free: - * @plugins: the #GisPlugins to free + * grits_plugins_free: + * @plugins: the #GritsPlugins to free * * Free data used by a plugin source */ -void gis_plugins_free(GisPlugins *plugins) +void grits_plugins_free(GritsPlugins *plugins) { - g_debug("GisPlugins: free"); + g_debug("GritsPlugins: free"); for (GList *cur = plugins->plugins; cur; cur = cur->next) { - GisPluginStore *store = cur->data; - g_debug("GisPlugin: freeing %s refs=%d->%d", store->name, + GritsPluginStore *store = cur->data; + g_debug("GritsPlugins: freeing %s refs=%d->%d", store->name, G_OBJECT(store->plugin)->ref_count, G_OBJECT(store->plugin)->ref_count-1); - g_object_unref(store->plugin); - g_free(store->name); - g_free(store); + grits_plugins_free_store(store); } g_list_free(plugins->plugins); if (plugins->dir) @@ -172,7 +183,7 @@ void gis_plugins_free(GisPlugins *plugins) } /** - * gis_plugins_available: + * grits_plugins_available: * @plugins: the plugin source * * Search the plugin directory for shared objects which can be loaded as @@ -180,9 +191,9 @@ void gis_plugins_free(GisPlugins *plugins) * * Returns: the list of available plugins */ -GList *gis_plugins_available(GisPlugins *plugins) +GList *grits_plugins_available(GritsPlugins *plugins) { - g_debug("GisPlugins: available"); + g_debug("GritsPlugins: available"); GList *list = NULL; gchar *dirs[] = {plugins->dir, PLUGINSDIR}; g_debug("pluginsdir=%s", PLUGINSDIR); @@ -214,31 +225,31 @@ GList *gis_plugins_available(GisPlugins *plugins) } /** - * gis_plugins_load: + * grits_plugins_load: * @plugins: the plugins source * @name: the name of the plugin to load - * @viewer: a #GisViewer to pass to the plugins constructor - * @prefs: a #GisPrefs to pass to the plugins constructor + * @viewer: a #GritsViewer to pass to the plugins constructor + * @prefs: a #GritsPrefs to pass to the plugins constructor * * @name should be the name of the shared object without the file extension. - * This is the same as what is returned by gis_plugins_available(). + * This is the same as what is returned by grits_plugins_available(). * - * When loading plugins, the @prefs argument is used, not the #GisPrefs stored + * When loading plugins, the @prefs argument is used, not the #GritsPrefs stored * in @plugins. * * Returns: the new plugin */ -GisPlugin *gis_plugins_load(GisPlugins *plugins, const char *name, - GisViewer *viewer, GisPrefs *prefs) +GritsPlugin *grits_plugins_load(GritsPlugins *plugins, const char *name, + GritsViewer *viewer, GritsPrefs *prefs) { - g_debug("GisPlugins: load %s", name); + g_debug("GritsPlugins: load %s", name); gchar *path = g_strdup_printf("%s/%s.%s", plugins->dir, name, G_MODULE_SUFFIX); - g_debug("GisPlugins: load - trying %s", path); + g_debug("GritsPlugins: load - trying %s", path); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { g_free(path); path = g_strdup_printf("%s/%s.%s", PLUGINSDIR, name, G_MODULE_SUFFIX); } - g_debug("GisPlugins: load - trying %s", path); + g_debug("GritsPlugins: load - trying %s", path); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { g_warning("Module %s not found", name); g_free(path); @@ -252,7 +263,7 @@ GisPlugin *gis_plugins_load(GisPlugins *plugins, const char *name, } gpointer constructor_ptr; // GCC 4.1 fix? - gchar *constructor_str = g_strconcat("gis_plugin_", name, "_new", NULL); + gchar *constructor_str = g_strconcat("grits_plugin_", name, "_new", NULL); if (!g_module_symbol(module, constructor_str, &constructor_ptr)) { g_warning("Unable to load symbol %s from %s: %s", constructor_str, name, g_module_error()); @@ -261,57 +272,58 @@ GisPlugin *gis_plugins_load(GisPlugins *plugins, const char *name, return NULL; } g_free(constructor_str); - GisPluginConstructor constructor = constructor_ptr; + GritsPluginConstructor constructor = constructor_ptr; - GisPluginStore *store = g_new0(GisPluginStore, 1); + GritsPluginStore *store = g_new0(GritsPluginStore, 1); store->name = g_strdup(name); store->plugin = constructor(viewer, prefs); + store->module = module; plugins->plugins = g_list_prepend(plugins->plugins, store); return store->plugin; } /** - * gis_plugins_enable: + * grits_plugins_enable: * @plugins: the plugins source * @name: the name of the plugin to load - * @viewer: a #GisViewer to pass to the plugins constructor - * @prefs: a #GisPrefs to pass to the plugins constructor + * @viewer: a #GritsViewer to pass to the plugins constructor + * @prefs: a #GritsPrefs to pass to the plugins constructor * - * Load a plugin and save it's loaded/unloaded state in the #GisPrefs stored in + * Load a plugin and save it's loaded/unloaded state in the #GritsPrefs stored in * #plugins. * - * See also: gis_plugins_load() + * See also: grits_plugins_load() * * Returns: the new plugin */ -GisPlugin *gis_plugins_enable(GisPlugins *plugins, const char *name, - GisViewer *viewer, GisPrefs *prefs) +GritsPlugin *grits_plugins_enable(GritsPlugins *plugins, const char *name, + GritsViewer *viewer, GritsPrefs *prefs) { - GisPlugin *plugin = gis_plugins_load(plugins, name, viewer, prefs); - gis_prefs_set_boolean_v(plugins->prefs, "plugins", name, TRUE); + GritsPlugin *plugin = grits_plugins_load(plugins, name, viewer, prefs); + grits_prefs_set_boolean_v(plugins->prefs, "plugins", name, TRUE); return plugin; } /** - * gis_plugins_load_enabled: + * grits_plugins_load_enabled: * @plugins: the plugins source - * @viewer: a #GisViewer to pass to the plugins constructor - * @prefs: a #GisPrefs to pass to the plugins constructor + * @viewer: a #GritsViewer to pass to the plugins constructor + * @prefs: a #GritsPrefs to pass to the plugins constructor * * Load all enabled which have previously been enabled. * - * See also: gis_plugins_load() + * See also: grits_plugins_load() * * Returns: a list of all loaded plugins */ -GList *gis_plugins_load_enabled(GisPlugins *plugins, - GisViewer *viewer, GisPrefs *prefs) +GList *grits_plugins_load_enabled(GritsPlugins *plugins, + GritsViewer *viewer, GritsPrefs *prefs) { GList *loaded = NULL; - for (GList *cur = gis_plugins_available(plugins); cur; cur = cur->next) { + for (GList *cur = grits_plugins_available(plugins); cur; cur = cur->next) { gchar *name = cur->data; - if (gis_prefs_get_boolean_v(plugins->prefs, "plugins", name, NULL)) { - GisPlugin *plugin = gis_plugins_load(plugins, name, viewer, prefs); + if (grits_prefs_get_boolean_v(plugins->prefs, "plugins", name, NULL)) { + GritsPlugin *plugin = grits_plugins_load(plugins, name, viewer, prefs); loaded = g_list_prepend(loaded, plugin); } } @@ -319,7 +331,7 @@ GList *gis_plugins_load_enabled(GisPlugins *plugins, } /** - * gis_plugins_unload: + * grits_plugins_unload: * @plugins: the plugins source * @name: the name of the plugin to unload * @@ -327,57 +339,56 @@ GList *gis_plugins_load_enabled(GisPlugins *plugins, * * Returns: %FALSE */ -gboolean gis_plugins_unload(GisPlugins *plugins, const char *name) +gboolean grits_plugins_unload(GritsPlugins *plugins, const char *name) { - g_debug("GisPlugins: unload %s", name); + g_debug("GritsPlugins: unload %s", name); for (GList *cur = plugins->plugins; cur; cur = cur->next) { - GisPluginStore *store = cur->data; + GritsPluginStore *store = cur->data; if (g_str_equal(store->name, name)) { - g_object_unref(store->plugin); - g_free(store->name); - g_free(store); plugins->plugins = g_list_delete_link(plugins->plugins, cur); + grits_plugins_free_store(store); + break; } } return FALSE; } /** - * gis_plugins_disable: + * grits_plugins_disable: * @plugins: the plugins source * @name: the name of the plugin to unload * - * Unload a plugin and save it's loaded/unloaded state in the #GisPrefs stored + * Unload a plugin and save it's loaded/unloaded state in the #GritsPrefs stored * in #plugins. * - * See also: gis_plugins_unload() + * See also: grits_plugins_unload() * * Returns: %FALSE */ -gboolean gis_plugins_disable(GisPlugins *plugins, const char *name) +gboolean grits_plugins_disable(GritsPlugins *plugins, const char *name) { - gis_prefs_set_boolean_v(plugins->prefs, "plugins", name, FALSE); - gis_plugins_unload(plugins, name); + grits_prefs_set_boolean_v(plugins->prefs, "plugins", name, FALSE); + grits_plugins_unload(plugins, name); return FALSE; } /** - * gis_plugins_foreach: + * grits_plugins_foreach: * @plugins: the plugins source * @callback: a function to call on each plugin * @user_data: user data to pass to the function * * Iterate over all plugins loaded by the plugins source */ -void gis_plugins_foreach(GisPlugins *plugins, GCallback _callback, gpointer user_data) +void grits_plugins_foreach(GritsPlugins *plugins, GCallback _callback, gpointer user_data) { - g_debug("GisPlugins: foreach"); + g_debug("GritsPlugins: foreach"); if (plugins == NULL) return; - typedef void (*CBFunc)(GisPlugin *, const gchar *, gpointer); + typedef void (*CBFunc)(GritsPlugin *, const gchar *, gpointer); CBFunc callback = (CBFunc)_callback; for (GList *cur = plugins->plugins; cur; cur = cur->next) { - GisPluginStore *store = cur->data; + GritsPluginStore *store = cur->data; callback(store->plugin, store->name, user_data); } }