Move plugin name and description into a separate struct, which is set
by calling the PLUGIN_INFO() macro - this can be read before the plugin is initialized. Added more comments for plugin authors. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1645 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
fcb06167b4
commit
a549a99c33
@ -1,3 +1,12 @@
|
||||
2007-06-27 Nick Treleaven <nick.treleaven@btinternet.com>
|
||||
|
||||
* plugins/demoplugin.c, src/plugindata.h, src/plugins.c:
|
||||
Move plugin name and description into a separate struct, which is set
|
||||
by calling the PLUGIN_INFO() macro - this can be read before the
|
||||
plugin is initialized.
|
||||
Added more comments for plugin authors.
|
||||
|
||||
|
||||
2007-06-26 Nick Treleaven <nick.treleaven@btinternet.com>
|
||||
|
||||
* plugins/demoplugin.c, plugins/Makefile.am, configure.in,
|
||||
|
||||
@ -38,12 +38,15 @@ static struct
|
||||
local_data;
|
||||
|
||||
|
||||
/* This performs runtime checks that try to ensure:
|
||||
* 1. Geany ABI data types are compatible with this plugin.
|
||||
* 2. Geany sources provide the required API for this plugin. */
|
||||
VERSION_CHECK(1)
|
||||
/* Check that Geany supports plugin API version 2 or later, and check
|
||||
* for binary compatibility. */
|
||||
VERSION_CHECK(2)
|
||||
|
||||
/* All plugins must set name and description */
|
||||
PLUGIN_INFO(_("Demo"), _("Example plugin."))
|
||||
|
||||
|
||||
/* Callback when the menu item is clicked */
|
||||
static void
|
||||
item_activate(GtkMenuItem *menuitem, gpointer gdata)
|
||||
{
|
||||
@ -56,28 +59,35 @@ item_activate(GtkMenuItem *menuitem, gpointer gdata)
|
||||
GTK_BUTTONS_OK,
|
||||
_("Hello World!"));
|
||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
|
||||
_("(From the %s plugin)"), my_data->name);
|
||||
_("(From the %s plugin)"), info()->name);
|
||||
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
|
||||
/* Called by Geany to initialize the plugin */
|
||||
void init(PluginData *data)
|
||||
{
|
||||
my_data = data;
|
||||
my_data->name = g_strdup("Demo");
|
||||
GtkWidget *demo_item;
|
||||
|
||||
local_data.menu_item = gtk_menu_item_new_with_mnemonic(_("_Demo Plugin"));
|
||||
gtk_widget_show(local_data.menu_item);
|
||||
gtk_container_add(GTK_CONTAINER(my_data->tools_menu), local_data.menu_item);
|
||||
g_signal_connect(G_OBJECT(local_data.menu_item), "activate", G_CALLBACK(item_activate), NULL);
|
||||
my_data = data; // keep a pointer to the main application fields & functions
|
||||
|
||||
// Add an item to the Tools menu
|
||||
demo_item = gtk_menu_item_new_with_mnemonic(_("_Demo Plugin"));
|
||||
gtk_widget_show(demo_item);
|
||||
gtk_container_add(GTK_CONTAINER(my_data->tools_menu), demo_item);
|
||||
g_signal_connect(G_OBJECT(demo_item), "activate", G_CALLBACK(item_activate), NULL);
|
||||
|
||||
// keep a pointer to the menu item, so we can remove it when the plugin is unloaded
|
||||
local_data.menu_item = demo_item;
|
||||
}
|
||||
|
||||
|
||||
/* Called by Geany before unloading the plugin.
|
||||
* Here any UI changes should be removed, memory freed and any other finalization done */
|
||||
void cleanup()
|
||||
{
|
||||
// remove the menu item added in init()
|
||||
gtk_widget_destroy(local_data.menu_item);
|
||||
|
||||
g_free(my_data->name);
|
||||
}
|
||||
|
||||
@ -27,14 +27,16 @@
|
||||
|
||||
/* The API version should be incremented whenever any plugin data types below are
|
||||
* modified. */
|
||||
static const gint api_version = 1;
|
||||
static const gint api_version = 2;
|
||||
|
||||
/* The ABI version should be incremented whenever existing fields in the plugin
|
||||
* data types below have to be changed or reordered. It should stay the same if fields
|
||||
* are only appended, as this doesn't affect existing fields. */
|
||||
static const gint abi_version = 1;
|
||||
|
||||
static const gint abi_version = 2;
|
||||
|
||||
/* This performs runtime checks that try to ensure:
|
||||
* 1. Geany ABI data types are compatible with this plugin.
|
||||
* 2. Geany sources provide the required API for this plugin. */
|
||||
/* TODO: if possible, the API version should be checked at compile time, not runtime. */
|
||||
#define VERSION_CHECK(api_required) \
|
||||
gint version_check(gint abi_ver) \
|
||||
@ -47,18 +49,37 @@ static const gint abi_version = 1;
|
||||
}
|
||||
|
||||
|
||||
typedef struct PluginData PluginData;
|
||||
|
||||
struct PluginData
|
||||
typedef struct PluginInfo
|
||||
{
|
||||
gchar *name; // name of plugin
|
||||
gchar *description; // description of plugin
|
||||
}
|
||||
PluginInfo;
|
||||
|
||||
/* Sets the plugin name and a brief description of what it is. */
|
||||
#define PLUGIN_INFO(p_name, p_description) \
|
||||
PluginInfo *info() \
|
||||
{ \
|
||||
static PluginInfo p_info; \
|
||||
\
|
||||
p_info.name = (p_name); \
|
||||
p_info.description = (p_description); \
|
||||
return &p_info; \
|
||||
}
|
||||
|
||||
|
||||
/* These are fields and functions owned by Geany.
|
||||
* Fields will be appended when needed by plugin authors.
|
||||
* Note: Remember to increment api_version (and abi_version if necessary) when
|
||||
* making changes. */
|
||||
typedef struct PluginData
|
||||
{
|
||||
MyApp *app; // Geany application data fields
|
||||
|
||||
/* Almost all plugins should add menu items to the Tools menu only */
|
||||
GtkWidget *tools_menu;
|
||||
};
|
||||
}
|
||||
PluginData;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -42,6 +42,7 @@ struct Plugin
|
||||
gchar *filename; // plugin filename (/path/libname.so)
|
||||
PluginData data;
|
||||
|
||||
PluginInfo* (*info) (); /* Returns plugin name, description */
|
||||
void (*init) (PluginData *data); /* Called when the plugin is enabled */
|
||||
void (*cleanup) (); /* Called when the plugin is disabled or when Geany exits */
|
||||
};
|
||||
@ -102,6 +103,7 @@ plugin_new(const gchar *fname)
|
||||
{
|
||||
Plugin *plugin;
|
||||
GModule *module;
|
||||
PluginInfo* (*info)();
|
||||
|
||||
g_return_val_if_fail(fname, NULL);
|
||||
g_return_val_if_fail(g_module_supported(), NULL);
|
||||
@ -129,7 +131,20 @@ plugin_new(const gchar *fname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_module_symbol(module, "info", (void *) &info);
|
||||
if (info == NULL)
|
||||
{
|
||||
geany_debug("Unknown plugin info for \"%s\"!", fname);
|
||||
|
||||
if (! g_module_close(module))
|
||||
g_warning("%s: %s", fname, g_module_error());
|
||||
return NULL;
|
||||
}
|
||||
geany_debug("Initializing plugin '%s' (%s)",
|
||||
info()->name, info()->description);
|
||||
|
||||
plugin = g_new0(Plugin, 1);
|
||||
plugin->info = info;
|
||||
plugin->filename = g_strdup(fname);
|
||||
plugin->module = module;
|
||||
|
||||
@ -143,7 +158,7 @@ plugin_new(const gchar *fname)
|
||||
plugin->init(&plugin->data);
|
||||
|
||||
geany_debug("Loaded: %s (%s)", fname,
|
||||
NVL(plugin->data.name, "<Unknown>"));
|
||||
NVL(plugin->info()->name, "<Unknown>"));
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user