Blame src/e-util/e-plugin.c

Packit Service de44cd
/*
Packit Service de44cd
 * This program is free software; you can redistribute it and/or modify it
Packit Service de44cd
 * under the terms of the GNU Lesser General Public License as published by
Packit Service de44cd
 * the Free Software Foundation.
Packit Service de44cd
 *
Packit Service de44cd
 * This program is distributed in the hope that it will be useful, but
Packit Service de44cd
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit Service de44cd
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit Service de44cd
 * for more details.
Packit Service de44cd
 *
Packit Service de44cd
 * You should have received a copy of the GNU Lesser General Public License
Packit Service de44cd
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit Service de44cd
 *
Packit Service de44cd
 *
Packit Service de44cd
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
Packit Service de44cd
 */
Packit Service de44cd
Packit Service de44cd
#include "evolution-config.h"
Packit Service de44cd
Packit Service de44cd
#include <sys/types.h>
Packit Service de44cd
#include <string.h>
Packit Service de44cd
Packit Service de44cd
#include <glib/gi18n.h>
Packit Service de44cd
Packit Service de44cd
#include <libebackend/libebackend.h>
Packit Service de44cd
Packit Service de44cd
#include "e-plugin.h"
Packit Service de44cd
#include "e-util-private.h"
Packit Service de44cd
#include "e-misc-utils.h"
Packit Service de44cd
Packit Service de44cd
/* plugin debug */
Packit Service de44cd
#define pd(x)
Packit Service de44cd
/* plugin hook debug */
Packit Service de44cd
#define phd(x)
Packit Service de44cd
Packit Service de44cd
/*
Packit Service de44cd
 * 
Packit Service de44cd
 *   class="org.gnome.camel.plugin.provider:1.0"
Packit Service de44cd
 *   id="org.gnome.camel.provider.imap:1.0"
Packit Service de44cd
 *   type="shlib"
Packit Service de44cd
 *   location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
Packit Service de44cd
 *   factory="camel_imap_provider_new">
Packit Service de44cd
 *  <name>imap</name>
Packit Service de44cd
 *  <description>IMAP4 and IMAP4v1 mail store</description>
Packit Service de44cd
 *  
Packit Service de44cd
 *    protocol="imap"
Packit Service de44cd
 *    domain="mail"
Packit Service de44cd
 *    flags="remote,source,storage,ssl"/>
Packit Service de44cd
 * </camel-plugin>
Packit Service de44cd
 * 
Packit Service de44cd
 * 
Packit Service de44cd
 *   class="org.gnome.camel.plugin.sasl:1.0"
Packit Service de44cd
 *   id="org.gnome.camel.sasl.plain:1.0"
Packit Service de44cd
 *   type="shlib"
Packit Service de44cd
 *   location="/opt/gnome2/lib/camel/1.0/libcamelsasl.so"
Packit Service de44cd
 *   factory="camel_sasl_plain_new">
Packit Service de44cd
 *  <name>PLAIN</name>
Packit Service de44cd
 *  <description>SASL PLAIN authentication mechanism</description>
Packit Service de44cd
 * </camel-plugin>
Packit Service de44cd
*/
Packit Service de44cd
Packit Service de44cd
/* EPlugin stuff */
Packit Service de44cd
Packit Service de44cd
/* global table of plugin types by pluginclass.type */
Packit Service de44cd
static GHashTable *ep_types;
Packit Service de44cd
/* global table of plugins by plugin.id */
Packit Service de44cd
static GHashTable *ep_plugins;
Packit Service de44cd
/* the list of disabled plugins from GSettings */
Packit Service de44cd
static GSList *ep_disabled;
Packit Service de44cd
Packit Service de44cd
/* All classes which implement EPluginHooks, by class.id */
Packit Service de44cd
static GHashTable *eph_types;
Packit Service de44cd
Packit Service de44cd
struct _plugin_doc {
Packit Service de44cd
	struct _plugin_doc *next;
Packit Service de44cd
	struct _plugin_doc *prev;
Packit Service de44cd
Packit Service de44cd
	gchar *filename;
Packit Service de44cd
	xmlDocPtr doc;
Packit Service de44cd
};
Packit Service de44cd
Packit Service de44cd
enum {
Packit Service de44cd
	EP_PROP_0,
Packit Service de44cd
	EP_PROP_ENABLED
Packit Service de44cd
};
Packit Service de44cd
Packit Service de44cd
G_DEFINE_TYPE (
Packit Service de44cd
	EPlugin,
Packit Service de44cd
	e_plugin,
Packit Service de44cd
	G_TYPE_OBJECT)
Packit Service de44cd
Packit Service de44cd
static gboolean
Packit Service de44cd
ep_check_enabled (const gchar *id)
Packit Service de44cd
{
Packit Service de44cd
	/* Return TRUE if 'id' is NOT in the disabled list. */
Packit Service de44cd
	return !g_slist_find_custom (ep_disabled, id, (GCompareFunc) strcmp);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
ep_set_enabled (const gchar *id,
Packit Service de44cd
                gint state)
Packit Service de44cd
{
Packit Service de44cd
	GSettings *settings;
Packit Service de44cd
	GSList *link;
Packit Service de44cd
	GPtrArray *array;
Packit Service de44cd
Packit Service de44cd
	/* Bail out if no change to state, when expressed as a boolean: */
Packit Service de44cd
	if ((state == 0) == (ep_check_enabled (id) == 0))
Packit Service de44cd
		return;
Packit Service de44cd
Packit Service de44cd
	if (state) {
Packit Service de44cd
		GSList *link;
Packit Service de44cd
Packit Service de44cd
		link = g_slist_find_custom (
Packit Service de44cd
			ep_disabled, id, (GCompareFunc) strcmp);
Packit Service de44cd
		if (link != NULL) {
Packit Service de44cd
			g_free (link->data);
Packit Service de44cd
			ep_disabled = g_slist_remove_link (ep_disabled, link);
Packit Service de44cd
		}
Packit Service de44cd
	} else
Packit Service de44cd
		ep_disabled = g_slist_prepend (ep_disabled, g_strdup (id));
Packit Service de44cd
Packit Service de44cd
	settings = e_util_ref_settings ("org.gnome.evolution");
Packit Service de44cd
	array = g_ptr_array_new ();
Packit Service de44cd
	for (link = ep_disabled; link != NULL; link = link->next)
Packit Service de44cd
		g_ptr_array_add (array, link->data);
Packit Service de44cd
	g_ptr_array_add (array, NULL);
Packit Service de44cd
	g_settings_set_strv (
Packit Service de44cd
		settings, "disabled-eplugins",
Packit Service de44cd
		(const gchar * const *) array->pdata);
Packit Service de44cd
	g_ptr_array_free (array, TRUE);
Packit Service de44cd
	g_object_unref (settings);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static gint
Packit Service de44cd
ep_construct (EPlugin *ep,
Packit Service de44cd
              xmlNodePtr root)
Packit Service de44cd
{
Packit Service de44cd
	xmlNodePtr node;
Packit Service de44cd
	gint res = -1;
Packit Service de44cd
	gchar *localedir;
Packit Service de44cd
Packit Service de44cd
	ep->domain = e_plugin_xml_prop (root, "domain");
Packit Service de44cd
	if (ep->domain
Packit Service de44cd
	    && (localedir = e_plugin_xml_prop (root, "localedir"))) {
Packit Service de44cd
#ifdef G_OS_WIN32
Packit Service de44cd
		gchar *mapped_localedir =
Packit Service de44cd
			e_util_replace_prefix (
Packit Service de44cd
				EVOLUTION_PREFIX,
Packit Service de44cd
				e_util_get_prefix (),
Packit Service de44cd
				localedir);
Packit Service de44cd
		g_free (localedir);
Packit Service de44cd
		localedir = mapped_localedir;
Packit Service de44cd
#endif
Packit Service de44cd
		bindtextdomain (ep->domain, localedir);
Packit Service de44cd
		g_free (localedir);
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	ep->name = e_plugin_xml_prop_domain (root, "name", ep->domain);
Packit Service de44cd
Packit Service de44cd
	node = root->children;
Packit Service de44cd
	while (node) {
Packit Service de44cd
		if (strcmp ((gchar *) node->name, "hook") == 0) {
Packit Service de44cd
			EPluginHook *hook;
Packit Service de44cd
			EPluginHookClass *type;
Packit Service de44cd
			gchar *class = e_plugin_xml_prop (node, "class");
Packit Service de44cd
Packit Service de44cd
			if (class == NULL) {
Packit Service de44cd
				g_warning (
Packit Service de44cd
					"Plugin '%s' load failed in '%s', "
Packit Service de44cd
					"missing class property for hook",
Packit Service de44cd
					ep->id, ep->path);
Packit Service de44cd
				goto fail;
Packit Service de44cd
			}
Packit Service de44cd
Packit Service de44cd
			if (ep->enabled
Packit Service de44cd
			    && eph_types != NULL
Packit Service de44cd
				&& (type = g_hash_table_lookup (
Packit Service de44cd
					eph_types, class)) != NULL) {
Packit Service de44cd
				g_free (class);
Packit Service de44cd
				hook = g_object_new (G_OBJECT_CLASS_TYPE (type), NULL);
Packit Service de44cd
				res = type->construct (hook, ep, node);
Packit Service de44cd
				if (res == -1) {
Packit Service de44cd
					g_warning (
Packit Service de44cd
						"Plugin '%s' failed to "
Packit Service de44cd
						"load hook", ep->name);
Packit Service de44cd
					g_object_unref (hook);
Packit Service de44cd
					goto fail;
Packit Service de44cd
				} else {
Packit Service de44cd
					ep->hooks = g_slist_append (ep->hooks, hook);
Packit Service de44cd
				}
Packit Service de44cd
			} else {
Packit Service de44cd
				g_free (class);
Packit Service de44cd
			}
Packit Service de44cd
		} else if (strcmp ((gchar *) node->name, "description") == 0) {
Packit Service de44cd
			ep->description =
Packit Service de44cd
				e_plugin_xml_content_domain (node, ep->domain);
Packit Service de44cd
		} else if (strcmp ((gchar *) node->name, "author") == 0) {
Packit Service de44cd
			gchar *name = e_plugin_xml_prop (node, "name");
Packit Service de44cd
			gchar *email = e_plugin_xml_prop (node, "email");
Packit Service de44cd
Packit Service de44cd
			if (name || email) {
Packit Service de44cd
				EPluginAuthor *epa = g_malloc0 (sizeof (*epa));
Packit Service de44cd
Packit Service de44cd
				epa->name = name;
Packit Service de44cd
				epa->email = email;
Packit Service de44cd
				ep->authors = g_slist_append (ep->authors, epa);
Packit Service de44cd
			}
Packit Service de44cd
		}
Packit Service de44cd
		node = node->next;
Packit Service de44cd
	}
Packit Service de44cd
	res = 0;
Packit Service de44cd
fail:
Packit Service de44cd
	return res;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
ep_enable (EPlugin *ep,
Packit Service de44cd
           gint state)
Packit Service de44cd
{
Packit Service de44cd
	GSList *iter;
Packit Service de44cd
Packit Service de44cd
	ep->enabled = state;
Packit Service de44cd
	for (iter = ep->hooks; iter != NULL; iter = iter->next) {
Packit Service de44cd
		EPluginHook *hook = iter->data;
Packit Service de44cd
		e_plugin_hook_enable (hook, state);
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	ep_set_enabled (ep->id, state);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
ep_set_property (GObject *object,
Packit Service de44cd
                 guint property_id,
Packit Service de44cd
                 const GValue *value,
Packit Service de44cd
                 GParamSpec *pspec)
Packit Service de44cd
{
Packit Service de44cd
	switch (property_id) {
Packit Service de44cd
		case EP_PROP_ENABLED:
Packit Service de44cd
			e_plugin_enable (
Packit Service de44cd
				E_PLUGIN (object),
Packit Service de44cd
				g_value_get_boolean (value));
Packit Service de44cd
			return;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
ep_get_property (GObject *object,
Packit Service de44cd
                 guint property_id,
Packit Service de44cd
                 GValue *value,
Packit Service de44cd
                 GParamSpec *pspec)
Packit Service de44cd
{
Packit Service de44cd
	EPlugin *ep = E_PLUGIN (object);
Packit Service de44cd
Packit Service de44cd
	switch (property_id) {
Packit Service de44cd
		case EP_PROP_ENABLED:
Packit Service de44cd
			g_value_set_boolean (value, ep->enabled);
Packit Service de44cd
			return;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
ep_finalize (GObject *object)
Packit Service de44cd
{
Packit Service de44cd
	EPlugin *ep = E_PLUGIN (object);
Packit Service de44cd
Packit Service de44cd
	g_free (ep->id);
Packit Service de44cd
	g_free (ep->description);
Packit Service de44cd
	g_free (ep->name);
Packit Service de44cd
	g_free (ep->domain);
Packit Service de44cd
Packit Service de44cd
	g_slist_foreach (ep->hooks, (GFunc) g_object_unref, NULL);
Packit Service de44cd
	g_slist_free (ep->hooks);
Packit Service de44cd
Packit Service de44cd
	/* Chain up to parent's finalize() method. */
Packit Service de44cd
	G_OBJECT_CLASS (e_plugin_parent_class)->finalize (object);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_plugin_class_init (EPluginClass *class)
Packit Service de44cd
{
Packit Service de44cd
	GObjectClass *object_class;
Packit Service de44cd
Packit Service de44cd
	object_class = G_OBJECT_CLASS (class);
Packit Service de44cd
	object_class->set_property = ep_set_property;
Packit Service de44cd
	object_class->get_property = ep_get_property;
Packit Service de44cd
	object_class->finalize = ep_finalize;
Packit Service de44cd
Packit Service de44cd
	class->construct = ep_construct;
Packit Service de44cd
	class->enable = ep_enable;
Packit Service de44cd
Packit Service de44cd
	g_object_class_install_property (
Packit Service de44cd
		object_class,
Packit Service de44cd
		EP_PROP_ENABLED,
Packit Service de44cd
		g_param_spec_boolean (
Packit Service de44cd
			"enabled",
Packit Service de44cd
			"Enabled",
Packit Service de44cd
			"Whether the plugin is enabled",
Packit Service de44cd
			TRUE,
Packit Service de44cd
			G_PARAM_READWRITE));
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_plugin_init (EPlugin *ep)
Packit Service de44cd
{
Packit Service de44cd
	ep->enabled = TRUE;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static EPlugin *
Packit Service de44cd
ep_load_plugin (xmlNodePtr root,
Packit Service de44cd
                struct _plugin_doc *pdoc)
Packit Service de44cd
{
Packit Service de44cd
	gchar *prop, *id;
Packit Service de44cd
	EPluginClass *class;
Packit Service de44cd
	EPlugin *ep;
Packit Service de44cd
Packit Service de44cd
	id = e_plugin_xml_prop (root, "id");
Packit Service de44cd
	if (id == NULL) {
Packit Service de44cd
		g_warning ("Invalid e-plugin entry in '%s': no id", pdoc->filename);
Packit Service de44cd
		return NULL;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	if (g_hash_table_lookup (ep_plugins, id)) {
Packit Service de44cd
		g_warning ("Plugin '%s' already defined", id);
Packit Service de44cd
		g_free (id);
Packit Service de44cd
		return NULL;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	prop = (gchar *) xmlGetProp (root, (const guchar *)"type");
Packit Service de44cd
	if (prop == NULL) {
Packit Service de44cd
		g_free (id);
Packit Service de44cd
		g_warning ("Invalid e-plugin entry in '%s': no type", pdoc->filename);
Packit Service de44cd
		return NULL;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	/* If we can't find a plugin, add it to a pending list
Packit Service de44cd
	 * which is checked when a new type is registered. */
Packit Service de44cd
	class = g_hash_table_lookup (ep_types, prop);
Packit Service de44cd
	if (class == NULL) {
Packit Service de44cd
		g_free (id);
Packit Service de44cd
		xmlFree (prop);
Packit Service de44cd
		return NULL;
Packit Service de44cd
	}
Packit Service de44cd
	xmlFree (prop);
Packit Service de44cd
Packit Service de44cd
	ep = g_object_new (G_TYPE_FROM_CLASS (class), NULL);
Packit Service de44cd
	ep->id = id;
Packit Service de44cd
	ep->path = g_strdup (pdoc->filename);
Packit Service de44cd
	ep->enabled = ep_check_enabled (id);
Packit Service de44cd
	if (e_plugin_construct (ep, root) == -1)
Packit Service de44cd
		e_plugin_enable (ep, FALSE);
Packit Service de44cd
	g_hash_table_insert (ep_plugins, ep->id, ep);
Packit Service de44cd
Packit Service de44cd
	return ep;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static gint
Packit Service de44cd
ep_load (const gchar *filename,
Packit Service de44cd
         gint load_level)
Packit Service de44cd
{
Packit Service de44cd
	xmlDocPtr doc;
Packit Service de44cd
	xmlNodePtr root;
Packit Service de44cd
	EPlugin *ep = NULL;
Packit Service de44cd
	struct _plugin_doc *pdoc;
Packit Service de44cd
Packit Service de44cd
	doc = e_xml_parse_file (filename);
Packit Service de44cd
	if (doc == NULL)
Packit Service de44cd
		return -1;
Packit Service de44cd
Packit Service de44cd
	root = xmlDocGetRootElement (doc);
Packit Service de44cd
	if (strcmp ((gchar *) root->name, "e-plugin-list") != 0) {
Packit Service de44cd
		g_warning ("No <e-plugin-list> root element: %s", filename);
Packit Service de44cd
		xmlFreeDoc (doc);
Packit Service de44cd
		return -1;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	pdoc = g_malloc0 (sizeof (*pdoc));
Packit Service de44cd
	pdoc->doc = doc;
Packit Service de44cd
	pdoc->filename = g_strdup (filename);
Packit Service de44cd
Packit Service de44cd
	for (root = root->children; root; root = root->next) {
Packit Service de44cd
		if (strcmp ((gchar *) root->name, "e-plugin") == 0) {
Packit Service de44cd
			gchar *plugin_load_level, *is_system_plugin;
Packit Service de44cd
Packit Service de44cd
			plugin_load_level = NULL;
Packit Service de44cd
			plugin_load_level = e_plugin_xml_prop (root, "load_level");
Packit Service de44cd
			if (plugin_load_level) {
Packit Service de44cd
				if ((atoi (plugin_load_level) == load_level)) {
Packit Service de44cd
					ep = ep_load_plugin (root, pdoc);
Packit Service de44cd
Packit Service de44cd
					if (ep && load_level == 1)
Packit Service de44cd
						e_plugin_invoke (
Packit Service de44cd
							ep, "load_plugin_type_register_function", NULL);
Packit Service de44cd
				}
Packit Service de44cd
			} else if (load_level == 2) {
Packit Service de44cd
				ep = ep_load_plugin (root, pdoc);
Packit Service de44cd
			}
Packit Service de44cd
Packit Service de44cd
			if (ep) {
Packit Service de44cd
				/* README: Maybe we can use load_levels to
Packit Service de44cd
				 * achieve the same thing.  But it may be
Packit Service de44cd
				 * confusing for a plugin writer. */
Packit Service de44cd
				is_system_plugin =
Packit Service de44cd
					e_plugin_xml_prop (root, "system_plugin");
Packit Service de44cd
				if (g_strcmp0 (is_system_plugin, "true") == 0) {
Packit Service de44cd
					e_plugin_enable (ep, TRUE);
Packit Service de44cd
					ep->flags |= E_PLUGIN_FLAGS_SYSTEM_PLUGIN;
Packit Service de44cd
				} else
Packit Service de44cd
					ep->flags &= ~E_PLUGIN_FLAGS_SYSTEM_PLUGIN;
Packit Service de44cd
				g_free (is_system_plugin);
Packit Service de44cd
Packit Service de44cd
				ep = NULL;
Packit Service de44cd
			}
Packit Service de44cd
		}
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	xmlFreeDoc (pdoc->doc);
Packit Service de44cd
	g_free (pdoc->filename);
Packit Service de44cd
	g_free (pdoc);
Packit Service de44cd
Packit Service de44cd
	return 0;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
plugin_load_subclass (GType type,
Packit Service de44cd
                      GHashTable *hash_table)
Packit Service de44cd
{
Packit Service de44cd
	EPluginClass *class;
Packit Service de44cd
Packit Service de44cd
	class = g_type_class_ref (type);
Packit Service de44cd
	g_hash_table_insert (hash_table, (gpointer) class->type, class);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
plugin_hook_load_subclass (GType type,
Packit Service de44cd
                           GHashTable *hash_table)
Packit Service de44cd
{
Packit Service de44cd
	EPluginHookClass *hook_class;
Packit Service de44cd
	EPluginHookClass *dupe_class;
Packit Service de44cd
	gpointer key;
Packit Service de44cd
Packit Service de44cd
	hook_class = g_type_class_ref (type);
Packit Service de44cd
Packit Service de44cd
	/* Sanity check the hook class. */
Packit Service de44cd
	if (hook_class->id == NULL || *hook_class->id == '\0') {
Packit Service de44cd
		g_warning (
Packit Service de44cd
			"%s has no hook ID, so skipping",
Packit Service de44cd
			G_OBJECT_CLASS_NAME (hook_class));
Packit Service de44cd
		g_type_class_unref (hook_class);
Packit Service de44cd
		return;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	/* Check for class ID collisions. */
Packit Service de44cd
	dupe_class = g_hash_table_lookup (hash_table, hook_class->id);
Packit Service de44cd
	if (dupe_class != NULL) {
Packit Service de44cd
		g_warning (
Packit Service de44cd
			"%s and %s have the same hook "
Packit Service de44cd
			"ID ('%s'), so skipping %s",
Packit Service de44cd
			G_OBJECT_CLASS_NAME (dupe_class),
Packit Service de44cd
			G_OBJECT_CLASS_NAME (hook_class),
Packit Service de44cd
			hook_class->id,
Packit Service de44cd
			G_OBJECT_CLASS_NAME (hook_class));
Packit Service de44cd
		g_type_class_unref (hook_class);
Packit Service de44cd
		return;
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	key = (gpointer) hook_class->id;
Packit Service de44cd
	g_hash_table_insert (hash_table, key, hook_class);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_load_plugins:
Packit Service de44cd
 *
Packit Service de44cd
 * Scan the search path, looking for plugin definitions, and load them
Packit Service de44cd
 * into memory.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: Returns -1 if an error occurred.
Packit Service de44cd
 **/
Packit Service de44cd
gint
Packit Service de44cd
e_plugin_load_plugins (void)
Packit Service de44cd
{
Packit Service de44cd
	GSettings *settings;
Packit Service de44cd
	gchar **strv;
Packit Service de44cd
	gint i;
Packit Service de44cd
Packit Service de44cd
	if (eph_types != NULL)
Packit Service de44cd
		return 0;
Packit Service de44cd
Packit Service de44cd
	ep_types = g_hash_table_new (g_str_hash, g_str_equal);
Packit Service de44cd
	eph_types = g_hash_table_new (g_str_hash, g_str_equal);
Packit Service de44cd
	ep_plugins = g_hash_table_new (g_str_hash, g_str_equal);
Packit Service de44cd
Packit Service de44cd
	/* We require that all GTypes for EPlugin and EPluginHook
Packit Service de44cd
	 * subclasses be registered prior to loading any plugins.
Packit Service de44cd
	 * It greatly simplifies the loading process. */
Packit Service de44cd
	e_type_traverse (
Packit Service de44cd
		E_TYPE_PLUGIN, (ETypeFunc)
Packit Service de44cd
		plugin_load_subclass, ep_types);
Packit Service de44cd
	e_type_traverse (
Packit Service de44cd
		E_TYPE_PLUGIN_HOOK, (ETypeFunc)
Packit Service de44cd
		plugin_hook_load_subclass, eph_types);
Packit Service de44cd
Packit Service de44cd
	settings = e_util_ref_settings ("org.gnome.evolution");
Packit Service de44cd
	strv = g_settings_get_strv (settings, "disabled-eplugins");
Packit Service de44cd
	for (i = 0, ep_disabled = NULL; strv[i] != NULL; i++)
Packit Service de44cd
		ep_disabled = g_slist_append (ep_disabled, g_strdup (strv[i]));
Packit Service de44cd
	g_strfreev (strv);
Packit Service de44cd
	g_object_unref (settings);
Packit Service de44cd
Packit Service de44cd
	for (i = 0; i < 3; i++) {
Packit Service de44cd
		GDir *dir;
Packit Service de44cd
		const gchar *d;
Packit Service de44cd
		const gchar *path = EVOLUTION_PLUGINDIR;
Packit Service de44cd
Packit Service de44cd
		pd (printf ("scanning plugin dir '%s'\n", path));
Packit Service de44cd
Packit Service de44cd
		dir = g_dir_open (path, 0, NULL);
Packit Service de44cd
		if (dir == NULL) {
Packit Service de44cd
			/*g_warning("Could not find plugin path: %s", path);*/
Packit Service de44cd
			continue;
Packit Service de44cd
		}
Packit Service de44cd
Packit Service de44cd
		while ((d = g_dir_read_name (dir))) {
Packit Service de44cd
			if (g_str_has_suffix  (d, ".eplug")) {
Packit Service de44cd
				gchar *name;
Packit Service de44cd
Packit Service de44cd
				name = g_build_filename (path, d, NULL);
Packit Service de44cd
				ep_load (name, i);
Packit Service de44cd
				g_free (name);
Packit Service de44cd
			}
Packit Service de44cd
		}
Packit Service de44cd
Packit Service de44cd
		g_dir_close (dir);
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	return 0;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
ep_list_plugin (gpointer key,
Packit Service de44cd
                gpointer val,
Packit Service de44cd
                gpointer dat)
Packit Service de44cd
{
Packit Service de44cd
	GSList **l = (GSList **) dat;
Packit Service de44cd
Packit Service de44cd
	*l = g_slist_prepend(*l, g_object_ref(val));
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_list_plugins: List all plugins.
Packit Service de44cd
 *
Packit Service de44cd
 * Static class method to retrieve a list of all current plugins.  They
Packit Service de44cd
 * are listed in no particular order.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: A GSList of all plugins, they must be
Packit Service de44cd
 * g_object_unref'd and the list freed.
Packit Service de44cd
 **/
Packit Service de44cd
GSList *
Packit Service de44cd
e_plugin_list_plugins (void)
Packit Service de44cd
{
Packit Service de44cd
	GSList *l = NULL;
Packit Service de44cd
Packit Service de44cd
	if (ep_plugins)
Packit Service de44cd
		g_hash_table_foreach (ep_plugins, ep_list_plugin, &l);
Packit Service de44cd
Packit Service de44cd
	return l;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_construct:
Packit Service de44cd
 * @plugin: an #EPlugin
Packit Service de44cd
 * @root: The XML root node of the sub-tree containing the plugin
Packit Service de44cd
 * definition.
Packit Service de44cd
 *
Packit Service de44cd
 * Helper to invoke the construct virtual method.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: The return from the construct virtual method.
Packit Service de44cd
 **/
Packit Service de44cd
gint
Packit Service de44cd
e_plugin_construct (EPlugin *plugin,
Packit Service de44cd
                    xmlNodePtr root)
Packit Service de44cd
{
Packit Service de44cd
	EPluginClass *class;
Packit Service de44cd
Packit Service de44cd
	g_return_val_if_fail (E_IS_PLUGIN (plugin), -1);
Packit Service de44cd
Packit Service de44cd
	class = E_PLUGIN_GET_CLASS (plugin);
Packit Service de44cd
	g_return_val_if_fail (class != NULL, -1);
Packit Service de44cd
	g_return_val_if_fail (class->construct != NULL, -1);
Packit Service de44cd
Packit Service de44cd
	return class->construct (plugin, root);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_invoke:
Packit Service de44cd
 * @plugin: an #EPlugin
Packit Service de44cd
 * @name: The name of the function to invoke. The format of this name
Packit Service de44cd
 * will depend on the EPlugin type and its language conventions.
Packit Service de44cd
 * @data: The argument to the function. Its actual type depends on
Packit Service de44cd
 * the hook on which the function resides. It is up to the called
Packit Service de44cd
 * function to get this right.
Packit Service de44cd
 *
Packit Service de44cd
 * Helper to invoke the invoke virtual method.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: The return of the plugin invocation.
Packit Service de44cd
 **/
Packit Service de44cd
gpointer
Packit Service de44cd
e_plugin_invoke (EPlugin *plugin,
Packit Service de44cd
                 const gchar *name,
Packit Service de44cd
                 gpointer data)
Packit Service de44cd
{
Packit Service de44cd
	EPluginClass *class;
Packit Service de44cd
Packit Service de44cd
	g_return_val_if_fail (E_IS_PLUGIN (plugin), NULL);
Packit Service de44cd
	g_return_val_if_fail (name != NULL, NULL);
Packit Service de44cd
Packit Service de44cd
	/* Prevent invocation on a disabled plugin. */
Packit Service de44cd
	g_return_val_if_fail (plugin->enabled, NULL);
Packit Service de44cd
Packit Service de44cd
	class = E_PLUGIN_GET_CLASS (plugin);
Packit Service de44cd
	g_return_val_if_fail (class != NULL, NULL);
Packit Service de44cd
	g_return_val_if_fail (class->invoke != NULL, NULL);
Packit Service de44cd
Packit Service de44cd
	return class->invoke (plugin, name, data);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_get_symbol:
Packit Service de44cd
 * @plugin: an #EPlugin
Packit Service de44cd
 * @name: The name of the symbol to fetch. The format of this name
Packit Service de44cd
 * will depend on the EPlugin type and its language conventions.
Packit Service de44cd
 *
Packit Service de44cd
 * Helper to fetch a symbol name from a plugin.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: the symbol value, or %NULL if not found
Packit Service de44cd
 **/
Packit Service de44cd
gpointer
Packit Service de44cd
e_plugin_get_symbol (EPlugin *plugin,
Packit Service de44cd
                     const gchar *name)
Packit Service de44cd
{
Packit Service de44cd
	EPluginClass *class;
Packit Service de44cd
Packit Service de44cd
	g_return_val_if_fail (E_IS_PLUGIN (plugin), NULL);
Packit Service de44cd
Packit Service de44cd
	class = E_PLUGIN_GET_CLASS (plugin);
Packit Service de44cd
	g_return_val_if_fail (class != NULL, NULL);
Packit Service de44cd
	g_return_val_if_fail (class->get_symbol != NULL, NULL);
Packit Service de44cd
Packit Service de44cd
	return class->get_symbol (plugin, name);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_enable:
Packit Service de44cd
 * @plugin: an #EPlugin
Packit Service de44cd
 * @state: %TRUE to enable, %FALSE to disable
Packit Service de44cd
 *
Packit Service de44cd
 * Set the enable state of a plugin.
Packit Service de44cd
 *
Packit Service de44cd
 * THIS IS NOT FULLY IMPLEMENTED YET
Packit Service de44cd
 **/
Packit Service de44cd
void
Packit Service de44cd
e_plugin_enable (EPlugin *plugin,
Packit Service de44cd
                 gint state)
Packit Service de44cd
{
Packit Service de44cd
	EPluginClass *class;
Packit Service de44cd
Packit Service de44cd
	g_return_if_fail (E_IS_PLUGIN (plugin));
Packit Service de44cd
Packit Service de44cd
	if ((plugin->enabled == 0) == (state == 0))
Packit Service de44cd
		return;
Packit Service de44cd
Packit Service de44cd
	class = E_PLUGIN_GET_CLASS (plugin);
Packit Service de44cd
	g_return_if_fail (class != NULL);
Packit Service de44cd
	g_return_if_fail (class->enable != NULL);
Packit Service de44cd
Packit Service de44cd
	class->enable (plugin, state);
Packit Service de44cd
Packit Service de44cd
	g_object_notify (G_OBJECT (plugin), "enabled");
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_get_configure_widget
Packit Service de44cd
 * @plugin: an #EPlugin
Packit Service de44cd
 *
Packit Service de44cd
 * Plugin itself should have implemented "e_plugin_lib_get_configure_widget"
Packit Service de44cd
 * function * of prototype EPluginLibGetConfigureWidgetFunc.
Packit Service de44cd
 *
Packit Service de44cd
 * Returns: Configure widget or %NULL
Packit Service de44cd
 **/
Packit Service de44cd
GtkWidget *
Packit Service de44cd
e_plugin_get_configure_widget (EPlugin *plugin)
Packit Service de44cd
{
Packit Service de44cd
	EPluginClass *class;
Packit Service de44cd
Packit Service de44cd
	g_return_val_if_fail (E_IS_PLUGIN (plugin), NULL);
Packit Service de44cd
Packit Service de44cd
	class = E_PLUGIN_GET_CLASS (plugin);
Packit Service de44cd
	g_return_val_if_fail (class != NULL, NULL);
Packit Service de44cd
Packit Service de44cd
	if (class->get_configure_widget == NULL)
Packit Service de44cd
		return NULL;
Packit Service de44cd
Packit Service de44cd
	return class->get_configure_widget (plugin);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_xml_prop:
Packit Service de44cd
 * @node: An XML node.
Packit Service de44cd
 * @id: The name of the property to retrieve.
Packit Service de44cd
 *
Packit Service de44cd
 * A static helper function to look up a property on an XML node, and
Packit Service de44cd
 * ensure it is allocated in GLib system memory.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: The property, allocated in GLib memory, or NULL if no
Packit Service de44cd
 * such property exists.
Packit Service de44cd
 **/
Packit Service de44cd
gchar *
Packit Service de44cd
e_plugin_xml_prop (xmlNodePtr node,
Packit Service de44cd
                   const gchar *id)
Packit Service de44cd
{
Packit Service de44cd
	xmlChar *xml_prop;
Packit Service de44cd
	gchar *glib_prop = NULL;
Packit Service de44cd
Packit Service de44cd
	xml_prop = xmlGetProp (node, (xmlChar *) id);
Packit Service de44cd
Packit Service de44cd
	if (xml_prop != NULL) {
Packit Service de44cd
		glib_prop = g_strdup ((gchar *) xml_prop);
Packit Service de44cd
		xmlFree (xml_prop);
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	return glib_prop;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_xml_prop_domain:
Packit Service de44cd
 * @node: An XML node.
Packit Service de44cd
 * @id: The name of the property to retrieve.
Packit Service de44cd
 * @domain: The translation domain for this string.
Packit Service de44cd
 *
Packit Service de44cd
 * A static helper function to look up a property on an XML node, and
Packit Service de44cd
 * translate it based on @domain.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: The property, allocated in GLib memory, or NULL if no
Packit Service de44cd
 * such property exists.
Packit Service de44cd
 **/
Packit Service de44cd
gchar *
Packit Service de44cd
e_plugin_xml_prop_domain (xmlNodePtr node,
Packit Service de44cd
                          const gchar *id,
Packit Service de44cd
                          const gchar *domain)
Packit Service de44cd
{
Packit Service de44cd
	gchar *p, *out;
Packit Service de44cd
Packit Service de44cd
	p = (gchar *) xmlGetProp (node, (const guchar *) id);
Packit Service de44cd
	if (p == NULL)
Packit Service de44cd
		return NULL;
Packit Service de44cd
Packit Service de44cd
	out = g_strdup (dgettext (domain, p));
Packit Service de44cd
	xmlFree (p);
Packit Service de44cd
Packit Service de44cd
	return out;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_xml_int:
Packit Service de44cd
 * @node: An XML node.
Packit Service de44cd
 * @id: The name of the property to retrieve.
Packit Service de44cd
 * @def: A default value if the property doesn't exist.  Can be used
Packit Service de44cd
 * to determine if the property isn't set.
Packit Service de44cd
 *
Packit Service de44cd
 * A static helper function to look up a property on an XML node as an
Packit Service de44cd
 * integer.  If the property doesn't exist, then @def is returned as a
Packit Service de44cd
 * default value instead.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: The value if set, or @def if not.
Packit Service de44cd
 **/
Packit Service de44cd
gint
Packit Service de44cd
e_plugin_xml_int (xmlNodePtr node,
Packit Service de44cd
                  const gchar *id,
Packit Service de44cd
                  gint def)
Packit Service de44cd
{
Packit Service de44cd
	gchar *p = (gchar *) xmlGetProp (node, (const guchar *) id);
Packit Service de44cd
Packit Service de44cd
	if (p)
Packit Service de44cd
		return atoi (p);
Packit Service de44cd
	else
Packit Service de44cd
		return def;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_xml_content:
Packit Service de44cd
 * @node:
Packit Service de44cd
 *
Packit Service de44cd
 * A static helper function to retrieve the entire textual content of
Packit Service de44cd
 * an XML node, and ensure it is allocated in GLib system memory.  If
Packit Service de44cd
 * GLib isn't using the system malloc them it must copy the content.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: The node content, allocated in GLib memory.
Packit Service de44cd
 **/
Packit Service de44cd
gchar *
Packit Service de44cd
e_plugin_xml_content (xmlNodePtr node)
Packit Service de44cd
{
Packit Service de44cd
	gchar *p = (gchar *) xmlNodeGetContent (node);
Packit Service de44cd
Packit Service de44cd
	if (g_mem_is_system_malloc ()) {
Packit Service de44cd
		return p;
Packit Service de44cd
	} else {
Packit Service de44cd
		gchar * out = g_strdup (p);
Packit Service de44cd
Packit Service de44cd
		if (p)
Packit Service de44cd
			xmlFree (p);
Packit Service de44cd
		return out;
Packit Service de44cd
	}
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_xml_content_domain:
Packit Service de44cd
 * @node:
Packit Service de44cd
 * @domain:
Packit Service de44cd
 *
Packit Service de44cd
 * A static helper function to retrieve the entire textual content of
Packit Service de44cd
 * an XML node, and ensure it is allocated in GLib system memory.  If
Packit Service de44cd
 * GLib isn't using the system malloc them it must copy the content.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: The node content, allocated in GLib memory.
Packit Service de44cd
 **/
Packit Service de44cd
gchar *
Packit Service de44cd
e_plugin_xml_content_domain (xmlNodePtr node,
Packit Service de44cd
                             const gchar *domain)
Packit Service de44cd
{
Packit Service de44cd
	gchar *p, *out;
Packit Service de44cd
Packit Service de44cd
	p = (gchar *) xmlNodeGetContent (node);
Packit Service de44cd
	if (p == NULL)
Packit Service de44cd
		return NULL;
Packit Service de44cd
Packit Service de44cd
	out = g_strdup (dgettext (domain, p));
Packit Service de44cd
	xmlFree (p);
Packit Service de44cd
Packit Service de44cd
	return out;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/* ********************************************************************** */
Packit Service de44cd
Packit Service de44cd
G_DEFINE_TYPE (
Packit Service de44cd
	EPluginHook,
Packit Service de44cd
	e_plugin_hook,
Packit Service de44cd
	G_TYPE_OBJECT)
Packit Service de44cd
Packit Service de44cd
static gint
Packit Service de44cd
plugin_hook_construct (EPluginHook *plugin_hook,
Packit Service de44cd
                       EPlugin *plugin,
Packit Service de44cd
                       xmlNodePtr root)
Packit Service de44cd
{
Packit Service de44cd
	plugin_hook->plugin = plugin;
Packit Service de44cd
Packit Service de44cd
	return 0;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
plugin_hook_enable (EPluginHook *plugin_hook,
Packit Service de44cd
                    gint state)
Packit Service de44cd
{
Packit Service de44cd
	/* NOOP */
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_plugin_hook_class_init (EPluginHookClass *class)
Packit Service de44cd
{
Packit Service de44cd
	class->construct = plugin_hook_construct;
Packit Service de44cd
	class->enable = plugin_hook_enable;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
static void
Packit Service de44cd
e_plugin_hook_init (EPluginHook *hook)
Packit Service de44cd
{
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_hook_enable:
Packit Service de44cd
 * @plugin_hook:
Packit Service de44cd
 * @state:
Packit Service de44cd
 *
Packit Service de44cd
 * Set the enabled state of the plugin hook.  This is called by the
Packit Service de44cd
 * plugin code.
Packit Service de44cd
 *
Packit Service de44cd
 * THIS IS NOT FULY IMEPLEMENTED YET
Packit Service de44cd
 **/
Packit Service de44cd
void
Packit Service de44cd
e_plugin_hook_enable (EPluginHook *plugin_hook,
Packit Service de44cd
                      gint state)
Packit Service de44cd
{
Packit Service de44cd
	EPluginHookClass *class;
Packit Service de44cd
Packit Service de44cd
	g_return_if_fail (E_IS_PLUGIN_HOOK (plugin_hook));
Packit Service de44cd
Packit Service de44cd
	class = E_PLUGIN_HOOK_GET_CLASS (plugin_hook);
Packit Service de44cd
	g_return_if_fail (class != NULL);
Packit Service de44cd
	g_return_if_fail (class->enable != NULL);
Packit Service de44cd
Packit Service de44cd
	class->enable (plugin_hook, state);
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_hook_mask:
Packit Service de44cd
 * @root: An XML node.
Packit Service de44cd
 * @map: A zero-fill terminated array of EPluginHookTargeKeys used to
Packit Service de44cd
 * map a string with a bit value.
Packit Service de44cd
 * @prop: The property name.
Packit Service de44cd
 *
Packit Service de44cd
 * This is a static helper function which looks up a property @prop on
Packit Service de44cd
 * the XML node @root, and then uses the @map table to convert it into
Packit Service de44cd
 * a bitmask.  The property value is a comma separated list of
Packit Service de44cd
 * enumeration strings which are indexed into the @map table.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: A bitmask representing the inclusive-or of all of the
Packit Service de44cd
 * integer values of the corresponding string id's stored in the @map.
Packit Service de44cd
 **/
Packit Service de44cd
guint32
Packit Service de44cd
e_plugin_hook_mask (xmlNodePtr root,
Packit Service de44cd
                    const EPluginHookTargetKey *map,
Packit Service de44cd
                    const gchar *prop)
Packit Service de44cd
{
Packit Service de44cd
	gchar *val, *p, *start, c;
Packit Service de44cd
	guint32 mask = 0;
Packit Service de44cd
Packit Service de44cd
	val = (gchar *) xmlGetProp (root, (const guchar *) prop);
Packit Service de44cd
	if (val == NULL)
Packit Service de44cd
		return 0;
Packit Service de44cd
Packit Service de44cd
	p = val;
Packit Service de44cd
	do {
Packit Service de44cd
		start = p;
Packit Service de44cd
		while (*p && *p != ',')
Packit Service de44cd
			p++;
Packit Service de44cd
		c = *p;
Packit Service de44cd
		*p = 0;
Packit Service de44cd
		if (start != p) {
Packit Service de44cd
			gint i;
Packit Service de44cd
Packit Service de44cd
			for (i = 0; map[i].key; i++) {
Packit Service de44cd
				if (!strcmp (map[i].key, start)) {
Packit Service de44cd
					mask |= map[i].value;
Packit Service de44cd
					break;
Packit Service de44cd
				}
Packit Service de44cd
			}
Packit Service de44cd
		}
Packit Service de44cd
		*p++ = c;
Packit Service de44cd
	} while (c);
Packit Service de44cd
Packit Service de44cd
	xmlFree (val);
Packit Service de44cd
Packit Service de44cd
	return mask;
Packit Service de44cd
}
Packit Service de44cd
Packit Service de44cd
/**
Packit Service de44cd
 * e_plugin_hook_id:
Packit Service de44cd
 * @root:
Packit Service de44cd
 * @map:
Packit Service de44cd
 * @prop:
Packit Service de44cd
 *
Packit Service de44cd
 * This is a static helper function which looks up a property @prop on
Packit Service de44cd
 * the XML node @root, and then uses the @map table to convert it into
Packit Service de44cd
 * an integer.
Packit Service de44cd
 *
Packit Service de44cd
 * This is used as a helper wherever you need to represent an
Packit Service de44cd
 * enumerated value in the XML.
Packit Service de44cd
 *
Packit Service de44cd
 * Return value: If the @prop value is in @map, then the corresponding
Packit Service de44cd
 * integer value, if not, then ~0.
Packit Service de44cd
 **/
Packit Service de44cd
guint32
Packit Service de44cd
e_plugin_hook_id (xmlNodePtr root,
Packit Service de44cd
                  const EPluginHookTargetKey *map,
Packit Service de44cd
                  const gchar *prop)
Packit Service de44cd
{
Packit Service de44cd
	gchar *val;
Packit Service de44cd
	gint i;
Packit Service de44cd
Packit Service de44cd
	val = (gchar *) xmlGetProp (root, (const guchar *) prop);
Packit Service de44cd
	if (val == NULL)
Packit Service de44cd
		return ~0;
Packit Service de44cd
Packit Service de44cd
	for (i = 0; map[i].key; i++) {
Packit Service de44cd
		if (!strcmp (map[i].key, val)) {
Packit Service de44cd
			xmlFree (val);
Packit Service de44cd
			return map[i].value;
Packit Service de44cd
		}
Packit Service de44cd
	}
Packit Service de44cd
Packit Service de44cd
	xmlFree (val);
Packit Service de44cd
Packit Service de44cd
	return ~0;
Packit Service de44cd
}