SF.net SVN: geany: [1645] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Wed Jun 27 15:56:43 UTC 2007


Revision: 1645
          http://svn.sourceforge.net/geany/?rev=1645&view=rev
Author:   ntrel
Date:     2007-06-27 08:56:42 -0700 (Wed, 27 Jun 2007)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/plugins/demoplugin.c
    trunk/src/plugindata.h
    trunk/src/plugins.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-06-26 18:08:00 UTC (rev 1644)
+++ trunk/ChangeLog	2007-06-27 15:56:42 UTC (rev 1645)
@@ -1,3 +1,12 @@
+2007-06-27  Nick Treleaven  <nick.treleaven at 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 at btinternet.com>
 
  * plugins/demoplugin.c, plugins/Makefile.am, configure.in,

Modified: trunk/plugins/demoplugin.c
===================================================================
--- trunk/plugins/demoplugin.c	2007-06-26 18:08:00 UTC (rev 1644)
+++ trunk/plugins/demoplugin.c	2007-06-27 15:56:42 UTC (rev 1645)
@@ -38,12 +38,15 @@
 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 @@
 		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);
 }

Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h	2007-06-26 18:08:00 UTC (rev 1644)
+++ trunk/src/plugindata.h	2007-06-27 15:56:42 UTC (rev 1645)
@@ -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 @@
 	}
 
 
-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

Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c	2007-06-26 18:08:00 UTC (rev 1644)
+++ trunk/src/plugins.c	2007-06-27 15:56:42 UTC (rev 1645)
@@ -42,6 +42,7 @@
 	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 *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 @@
 		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->init(&plugin->data);
 
 	geany_debug("Loaded:   %s (%s)", fname,
-		NVL(plugin->data.name, "<Unknown>"));
+		NVL(plugin->info()->name, "<Unknown>"));
 	return plugin;
 }
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list