diff --git a/addressbook/gui/widgets/eab-config.c b/addressbook/gui/widgets/eab-config.c
index 91056e0544..f47a696195 100644
--- a/addressbook/gui/widgets/eab-config.c
+++ b/addressbook/gui/widgets/eab-config.c
@@ -27,7 +27,6 @@
#include "eab-config.h"
static GObjectClass *ecp_parent_class;
-static GObjectClass *ecph_parent_class;
struct _EABConfigPrivate {
guint source_changed_id;
@@ -143,48 +142,3 @@ eab_config_target_new_source (EABConfig *ecp, struct _ESource *source)
return t;
}
-
-static const EConfigHookTargetMask ecph_no_masks[] = {
- { NULL }
-};
-
-static const EConfigHookTargetMap ecph_targets[] = {
- { "source", EAB_CONFIG_TARGET_SOURCE, ecph_no_masks },
- { NULL },
-};
-
-static void
-ecph_class_init (EPluginHookClass *klass)
-{
- gint i;
-
- klass->id = "org.gnome.evolution.addressbook.config:1.0";
-
- for (i = 0; ecph_targets[i].type; i++) {
- e_config_hook_class_add_target_map ((EConfigHookClass *)klass, &ecph_targets[i]);
- }
-
- ((EConfigHookClass *)klass)->config_class = g_type_class_ref (eab_config_get_type ());
-}
-
-GType
-eab_config_hook_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (EABConfigHookClass),
- NULL, NULL,
- (GClassInitFunc) ecph_class_init,
- NULL, NULL,
- sizeof (EABConfigHook), 0,
- (GInstanceInitFunc) NULL
- };
-
- ecph_parent_class = g_type_class_ref (e_config_hook_get_type ());
- type = g_type_register_static (e_config_hook_get_type (), "EABConfigHook", &info, 0);
- }
-
- return type;
-}
diff --git a/addressbook/gui/widgets/eab-config.h b/addressbook/gui/widgets/eab-config.h
index 8ecc8525bc..fcf6b76f00 100644
--- a/addressbook/gui/widgets/eab-config.h
+++ b/addressbook/gui/widgets/eab-config.h
@@ -60,21 +60,6 @@ EABConfig *eab_config_new (gint type, const gchar *menuid);
EABConfigTargetSource *eab_config_target_new_source (EABConfig *ecp, struct _ESource *source);
-/* ********************************************************************** */
-
-typedef struct _EABConfigHook EABConfigHook;
-typedef struct _EABConfigHookClass EABConfigHookClass;
-
-struct _EABConfigHook {
- EConfigHook hook;
-};
-
-struct _EABConfigHookClass {
- EConfigHookClass hook_class;
-};
-
-GType eab_config_hook_get_type (void);
-
G_END_DECLS
#endif
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index b7bf7f557f..ede213e1ff 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -14,7 +14,6 @@ ecalendarinclude_HEADERS = \
calendar-config-keys.h \
comp-util.h \
e-alarm-list.h \
- e-attachment-handler-calendar.h \
e-cal-config.h \
e-cal-event.h \
e-cal-model-calendar.h \
@@ -96,8 +95,6 @@ libevolution_calendar_la_SOURCES = \
comp-util.h \
e-alarm-list.c \
e-alarm-list.h \
- e-attachment-handler-calendar.c \
- e-attachment-handler-calendar.h \
e-cal-component-preview.c \
e-cal-component-preview.h \
e-cal-config.c \
diff --git a/calendar/gui/e-attachment-handler-calendar.h b/calendar/gui/e-attachment-handler-calendar.h
deleted file mode 100644
index f34cac14c3..0000000000
--- a/calendar/gui/e-attachment-handler-calendar.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * e-attachment-handler-calendar.h
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_ATTACHMENT_HANDLER_CALENDAR_H
-#define E_ATTACHMENT_HANDLER_CALENDAR_H
-
-#include
-
-/* Standard GObject macros */
-#define E_TYPE_ATTACHMENT_HANDLER_CALENDAR \
- (e_attachment_handler_calendar_get_type ())
-#define E_ATTACHMENT_HANDLER_CALENDAR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendar))
-#define E_ATTACHMENT_HANDLER_CALENDAR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendarClass))
-#define E_IS_ATTACHMENT_HANDLER_CALENDAR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR))
-#define E_IS_ATTACHMENT_HANDLER_CALENDAR_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_ATTACHMENT_HANDLER_CALENDAR))
-#define E_ATTACHMENT_HANDLER_CALENDAR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_ATTACHMENT_HANDLER_CALENDAR, EAttachmentHandlerCalendarClass))
-
-G_BEGIN_DECLS
-
-typedef struct _EAttachmentHandlerCalendar EAttachmentHandlerCalendar;
-typedef struct _EAttachmentHandlerCalendarClass EAttachmentHandlerCalendarClass;
-typedef struct _EAttachmentHandlerCalendarPrivate EAttachmentHandlerCalendarPrivate;
-
-struct _EAttachmentHandlerCalendar {
- EAttachmentHandler parent;
- EAttachmentHandlerCalendarPrivate *priv;
-};
-
-struct _EAttachmentHandlerCalendarClass {
- EAttachmentHandlerClass parent_class;
-};
-
-GType e_attachment_handler_calendar_get_type (void);
-
-G_END_DECLS
-
-#endif /* E_ATTACHMENT_HANDLER_CALENDAR_H */
diff --git a/calendar/gui/e-cal-config.c b/calendar/gui/e-cal-config.c
index 33b6bc9c46..a8d2ad169f 100644
--- a/calendar/gui/e-cal-config.c
+++ b/calendar/gui/e-cal-config.c
@@ -28,7 +28,6 @@
#include "e-cal-config.h"
static GObjectClass *ecp_parent_class;
-static GObjectClass *ecph_parent_class;
struct _ECalConfigPrivate {
guint source_changed_id;
@@ -166,49 +165,3 @@ e_cal_config_target_new_prefs (ECalConfig *ecp, struct _GConfClient *gconf)
return t;
}
-
-static const EConfigHookTargetMask ecph_no_masks[] = {
- { NULL }
-};
-
-static const EConfigHookTargetMap ecph_targets[] = {
- { "source", EC_CONFIG_TARGET_SOURCE, ecph_no_masks },
- { "prefs", EC_CONFIG_TARGET_PREFS, ecph_no_masks },
- { NULL },
-};
-
-static void
-ecph_class_init (EPluginHookClass *klass)
-{
- gint i;
-
- klass->id = "org.gnome.evolution.calendar.config:1.0";
-
- for (i = 0; ecph_targets[i].type; i++) {
- e_config_hook_class_add_target_map ((EConfigHookClass *)klass, &ecph_targets[i]);
- }
-
- ((EConfigHookClass *)klass)->config_class = g_type_class_ref (e_cal_config_get_type ());
-}
-
-GType
-e_cal_config_hook_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (ECalConfigHookClass),
- NULL, NULL,
- (GClassInitFunc) ecph_class_init,
- NULL, NULL,
- sizeof (ECalConfigHook), 0,
- (GInstanceInitFunc) NULL
- };
-
- ecph_parent_class = g_type_class_ref (e_config_hook_get_type ());
- type = g_type_register_static (e_config_hook_get_type (), "ECalConfigHook", &info, 0);
- }
-
- return type;
-}
diff --git a/calendar/gui/e-cal-config.h b/calendar/gui/e-cal-config.h
index 52989aa0e2..30e12bbf0c 100644
--- a/calendar/gui/e-cal-config.h
+++ b/calendar/gui/e-cal-config.h
@@ -71,21 +71,6 @@ ECalConfig *e_cal_config_new (gint type, const gchar *menuid);
ECalConfigTargetSource *e_cal_config_target_new_source (ECalConfig *ecp, struct _ESource *source);
ECalConfigTargetPrefs *e_cal_config_target_new_prefs (ECalConfig *ecp, struct _GConfClient *gconf);
-/* ********************************************************************** */
-
-typedef struct _ECalConfigHook ECalConfigHook;
-typedef struct _ECalConfigHookClass ECalConfigHookClass;
-
-struct _ECalConfigHook {
- EConfigHook hook;
-};
-
-struct _ECalConfigHookClass {
- EConfigHookClass hook_class;
-};
-
-GType e_cal_config_hook_get_type (void);
-
G_END_DECLS
#endif
diff --git a/calendar/gui/e-cal-event.c b/calendar/gui/e-cal-event.c
index 5881f5037f..7d0a9d196d 100644
--- a/calendar/gui/e-cal-event.c
+++ b/calendar/gui/e-cal-event.c
@@ -105,59 +105,3 @@ e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESo
return t;
}
-
-/* ********************************************************************** */
-
-static gpointer eceh_parent_class;
-
-static const EEventHookTargetMask eceh_module_masks[] = {
- { "migration", E_CAL_EVENT_MODULE_MIGRATION },
- { NULL },
-};
-
-static const EEventHookTargetMap eceh_targets[] = {
- { "module", E_CAL_EVENT_TARGET_BACKEND, eceh_module_masks },
- { NULL },
-};
-
-static void
-eceh_finalize (GObject *o)
-{
- ((GObjectClass *) eceh_parent_class)->finalize (o);
-}
-
-static void
-eceh_class_init (EPluginHookClass *klass)
-{
- gint i;
-
- ((GObjectClass *)klass)->finalize = eceh_finalize;
- ((EPluginHookClass *)klass)->id = "org.gnome.evolution.calendar.events:1.0";
-
- for (i = 0; eceh_targets[i].type; i++)
- e_event_hook_class_add_target_map ((EEventHookClass *)klass, &eceh_targets[i]);
-
- ((EEventHookClass *)klass)->event = (EEvent *) e_cal_event_peek ();
-}
-
-GType
-e_cal_event_hook_get_type (void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof (ECalEventHookClass),
- NULL, NULL,
- (GClassInitFunc) eceh_class_init,
- NULL, NULL,
- sizeof (ECalEventHook), 0,
- (GInstanceInitFunc) NULL,
- };
-
- eceh_parent_class = g_type_class_ref (e_event_hook_get_type ());
- type = g_type_register_static (e_event_hook_get_type (), "ECalEventHook", &info, 0);
- }
-
- return type;
-}
diff --git a/calendar/gui/e-cal-event.h b/calendar/gui/e-cal-event.h
index 73d27353fa..8d72a93fa5 100644
--- a/calendar/gui/e-cal-event.h
+++ b/calendar/gui/e-cal-event.h
@@ -66,21 +66,6 @@ GType e_cal_event_get_type (void);
ECalEvent* e_cal_event_peek (void);
ECalEventTargetBackend* e_cal_event_target_new_module (ECalEvent *ece, EShellBackend *shell_backend, ESourceList *source_list, guint32 flags);
-/* ********************************************************************** */
-
-typedef struct _ECalEventHook ECalEventHook;
-typedef struct _ECalEventHookClass ECalEventHookClass;
-
-struct _ECalEventHook {
- EEventHook hook;
-};
-
-struct _ECalEventHookClass {
- EEventHookClass hook_class;
-};
-
-GType e_cal_event_hook_get_type (void);
-
G_END_DECLS
#endif /* __E_CAL_EVENT_H__ */
diff --git a/configure.ac b/configure.ac
index 8a2400ae84..e26fe6953d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -956,11 +956,12 @@ AC_ARG_ENABLE([mono],
if test "x${enable_mono}" = "xyes"; then
PKG_CHECK_MODULES([MONO], ["mono"])
AC_DEFINE(ENABLE_MONO,1,[Define if Mono embedding should be enabled])
- MONO_PLUGIN="mono"
fi
AC_SUBST(MONO_CFLAGS)
AC_SUBST(MONO_LIBS)
+AM_CONDITIONAL(ENABLE_MONO, [test "x$enable_mono" = "xyes"])
+
dnl ******************************
dnl Python hooks
dnl This should just define python CFLAGS etc here, it is used later to turn on the python plugin or not.
@@ -988,19 +989,19 @@ if test "x${enable_python}" = "xyes"; then
PY_INCLUDES="-I$PY_PREFIX/include/python$PY_VERSION"
AC_MSG_RESULT([ok])
python_package="python-devel"
- PYTHON_PLUGIN="python"
else
AC_MSG_ERROR([Can't find Python.h])
PY_LIBS=""
PY_INCLUDES=""
python_package=""
- PYTHON_PLUGIN=""
fi
fi
AC_SUBST(PY_LIBS)
AC_SUBST(PY_INCLUDES)
fi
+AM_CONDITIONAL(ENABLE_PYTHON, [test "x$enable_python" = "xyes"])
+
dnl ********************************************************************************
dnl security extension support (SSL and S/MIME)
@@ -1808,8 +1809,8 @@ AC_ARG_ENABLE([plugins],
dnl Add any new plugins here
plugins_base_always="calendar-file calendar-http $CALENDAR_WEATHER itip-formatter plugin-manager default-source addressbook-file startup-wizard mark-all-read groupwise-features groupwise-account-setup publish-calendar caldav imap-features google-account-setup webdav-account-setup"
-plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN $EXCHANGE_PLUGIN $MONO_PLUGIN "
-all_plugins_base="$plugins_base_always sa-junk-plugin bogo-junk-plugin exchange-operations mono"
+plugins_base="$plugins_base_always $SA_JUNK_PLUGIN $BF_JUNK_PLUGIN $EXCHANGE_PLUGIN"
+all_plugins_base="$plugins_base_always sa-junk-plugin bogo-junk-plugin exchange-operations"
plugins_standard_always="bbdb subject-thread save-calendar mail-to-task audio-inline mailing-list-actions default-mailer prefer-plain mail-notification attachment-reminder backup-restore email-custom-header templates pst-import vcard-inline"
@@ -1817,7 +1818,7 @@ plugins_standard="$plugins_standard_always"
all_plugins_standard="$plugins_standard"
plugins_experimental_always="face external-editor hula-account-setup"
-plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS $PYTHON_PLUGIN"
+plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS"
all_plugins_experimental="$plugins_experimental_always ipod-sync tnef-attachments"
dnl Temporary KILL-BONOBO hack
@@ -1829,9 +1830,7 @@ dnl exchange-operations
dnl groupwise-features
dnl ipod-sync
dnl mailing-list-actions
-dnl mono
dnl publish-calendar
-dnl python
dnl save-calendar
case x"$enable_plugins" in
@@ -1873,17 +1872,6 @@ x | xyes)
;;
esac
-if test "x${enable_mono}" = "xyes"; then
- plugins_enabled="$plugins_enabled mono"
- msg_plugins="$msg_plugins (and mono)"
-fi
-
-
-if test "x${enable_python}" = "xyes"; then
- plugins_enabled="$plugins_enabled python"
- msg_plugins="$msg_plugins (and python)"
-fi
-
AC_SUBST(plugins_enabled)
AC_SUBST(all_plugins_base)
AC_SUBST(all_plugins_standard)
@@ -2088,6 +2076,9 @@ modules/Makefile
modules/addressbook/Makefile
modules/calendar/Makefile
modules/mail/Makefile
+modules/plugin-lib/Makefile
+modules/plugin-mono/Makefile
+modules/plugin-python/Makefile
plugins/Makefile
plugins/addressbook-file/Makefile
plugins/attachment-reminder/Makefile
@@ -2116,13 +2107,11 @@ plugins/mail-notification/Makefile
plugins/mail-to-task/Makefile
plugins/mailing-list-actions/Makefile
plugins/mark-all-read/Makefile
-plugins/mono/Makefile
plugins/plugin-manager/Makefile
plugins/prefer-plain/Makefile
plugins/profiler/Makefile
plugins/pst-import/Makefile
plugins/publish-calendar/Makefile
-plugins/python/Makefile
plugins/sa-junk-plugin/Makefile
plugins/save-calendar/Makefile
plugins/startup-wizard/Makefile
diff --git a/e-util/e-plugin.c b/e-util/e-plugin.c
index 3b3d5d215d..5c5e55b147 100644
--- a/e-util/e-plugin.c
+++ b/e-util/e-plugin.c
@@ -72,12 +72,6 @@ static GHashTable *ep_types;
static GSList *ep_path;
/* global table of plugins by plugin.id */
static GHashTable *ep_plugins;
-/* a table of GSLists of plugins by hook class for hooks not loadable yet */
-static GHashTable *ep_plugins_pending_hooks;
-/* list of all cached xml docs:struct _plugin_doc's */
-static EDList ep_plugin_docs = E_DLIST_INITIALISER(ep_plugin_docs);
-/* gconf client */
-static GConfClient *ep_gconf;
/* the list of disabled plugins from gconf */
static GSList *ep_disabled;
@@ -110,6 +104,8 @@ ep_check_enabled (const gchar *id)
static void
ep_set_enabled (const gchar *id, gint state)
{
+ GConfClient *client;
+
/* Bail out if no change to state, when expressed as a boolean: */
if ((state == 0) == (ep_check_enabled(id) == 0))
return;
@@ -126,9 +122,11 @@ ep_set_enabled (const gchar *id, gint state)
} else
ep_disabled = g_slist_prepend (ep_disabled, g_strdup (id));
- gconf_client_set_list(
- ep_gconf, "/apps/evolution/eplugin/disabled",
+ client = gconf_client_get_default ();
+ gconf_client_set_list (
+ client, "/apps/evolution/eplugin/disabled",
GCONF_VALUE_STRING, ep_disabled, NULL);
+ g_object_unref (client);
}
static gint
@@ -182,21 +180,6 @@ ep_construct (EPlugin *ep, xmlNodePtr root)
} else {
ep->hooks = g_slist_append(ep->hooks, hook);
}
- } else {
- gpointer l, oldclass;
-
- if (ep_plugins_pending_hooks == NULL)
- ep_plugins_pending_hooks = g_hash_table_new(g_str_hash, g_str_equal);
- if (!g_hash_table_lookup_extended (ep_plugins_pending_hooks, class, &oldclass, &l)) {
- oldclass = class;
- l = NULL;
- }
- else {
- g_free(class);
- }
- l = g_slist_prepend (l, ep);
- g_hash_table_insert (ep_plugins_pending_hooks, oldclass, l);
- ep->hooks_pending = g_slist_prepend (ep->hooks_pending, node);
}
} else if (strcmp((gchar *)node->name, "description") == 0) {
ep->description = e_plugin_xml_content_domain(node, ep->domain);
@@ -276,7 +259,6 @@ ep_finalize (GObject *object)
g_free (ep->description);
g_free (ep->name);
g_free (ep->domain);
- g_slist_free (ep->hooks_pending);
g_slist_foreach (ep->hooks, (GFunc) g_object_unref, NULL);
g_slist_free (ep->hooks);
@@ -425,9 +407,7 @@ ep_load(const gchar *filename, gint load_level)
{
xmlDocPtr doc;
xmlNodePtr root;
- gint res = -1;
EPlugin *ep = NULL;
- gint cache = FALSE;
struct _plugin_doc *pdoc;
doc = e_xml_parse_file (filename);
@@ -478,80 +458,12 @@ ep_load(const gchar *filename, gint load_level)
g_free (is_system_plugin);
pdoc->plugin_hooks = g_slist_prepend(pdoc->plugin_hooks, ep);
- cache |= (ep->hooks_pending != NULL);
ep = NULL;
}
- cache |= pdoc->plugins != NULL;
}
}
- res = 0;
-
- if (cache) {
- pd(printf("Caching plugin description '%s' for unknown future hooks\n", filename));
- e_dlist_addtail(&ep_plugin_docs, (EDListNode *)pdoc);
- } else {
- pd(printf("freeing plugin description '%s', nothing uses it\n", filename));
- xmlFreeDoc(pdoc->doc);
- g_free(pdoc->filename);
- g_free(pdoc);
- }
-
- return res;
-}
-
-/* This loads a hook that was pending on a given plugin but the type wasn't registered yet */
-/* This works in conjunction with ep_construct and e_plugin_hook_register_type to make sure
- everything works nicely together. Apparently. */
-static gint
-ep_load_pending(EPlugin *ep, EPluginHookClass *type)
-{
- gint res = 0;
- GSList *l, *p;
-
- phd(printf("New hook type registered '%s', loading pending hooks on plugin '%s'\n", type->id, ep->id));
-
- l = ep->hooks_pending;
- p = NULL;
- while (l) {
- GSList *n = l->next;
- xmlNodePtr node = l->data;
- gchar *class = (gchar *)xmlGetProp(node, (const guchar *)"class");
- EPluginHook *hook;
-
- phd(printf(" checking pending hook '%s'\n", class?class:""));
-
- if (class) {
- if (strcmp(class, type->id) == 0) {
- hook = g_object_new(G_OBJECT_CLASS_TYPE(type), NULL);
-
- /* Don't bother loading hooks for plugins that are not anyway enabled */
- if (ep->enabled) {
- res = type->construct(hook, ep, node);
- if (res == -1) {
- g_warning("Plugin '%s' failed to load hook '%s'", ep->name, type->id);
- g_object_unref(hook);
- } else {
- ep->hooks = g_slist_append(ep->hooks, hook);
- }
- }
-
- if (p)
- p->next = n;
- else
- ep->hooks_pending = n;
- g_slist_free_1(l);
- l = p;
- }
-
- xmlFree(class);
- }
-
- p = l;
- l = n;
- }
-
- return res;
+ return 0;
}
/**
@@ -574,6 +486,69 @@ e_plugin_add_load_path(const gchar *path)
ep_path = g_slist_append(ep_path, g_strdup(path));
}
+static void
+plugin_load_subclasses (void)
+{
+ GType *children;
+ guint n_children, ii;
+
+ ep_types = g_hash_table_new (g_str_hash, g_str_equal);
+ eph_types = g_hash_table_new (g_str_hash, g_str_equal);
+ ep_plugins = g_hash_table_new (g_str_hash, g_str_equal);
+
+ /* Load EPlugin subclasses. */
+
+ children = g_type_children (E_TYPE_PLUGIN, &n_children);
+
+ for (ii = 0; ii < n_children; ii++) {
+ EPluginClass *class;
+
+ class = g_type_class_ref (children[ii]);
+ g_hash_table_insert (ep_types, (gpointer) class->type, class);
+ }
+
+ g_free (children);
+
+ /* Load EPluginHook subclasses. */
+
+ children = g_type_children (E_TYPE_PLUGIN_HOOK, &n_children);
+
+ for (ii = 0; ii < n_children; ii++) {
+ EPluginHookClass *hook_class;
+ EPluginHookClass *dupe_class;
+
+ hook_class = g_type_class_ref (children[ii]);
+
+ /* Sanity check the hook class. */
+ if (hook_class->id == NULL || *hook_class->id == '\0') {
+ g_warning (
+ "%s has no hook ID, so skipping",
+ G_OBJECT_CLASS_NAME (hook_class));
+ g_type_class_unref (hook_class);
+ continue;
+ }
+
+ /* Check for class ID collisions. */
+ dupe_class = g_hash_table_lookup (eph_types, hook_class->id);
+ if (dupe_class != NULL) {
+ g_warning (
+ "%s and %s have the same hook "
+ "ID ('%s'), so skipping %s",
+ G_OBJECT_CLASS_NAME (dupe_class),
+ G_OBJECT_CLASS_NAME (hook_class),
+ hook_class->id,
+ G_OBJECT_CLASS_NAME (hook_class));
+ g_type_class_unref (hook_class);
+ continue;
+ }
+
+ g_hash_table_insert (
+ eph_types, (gpointer) hook_class->id, hook_class);
+ }
+
+ g_free (children);
+}
+
/**
* e_plugin_load_plugins:
*
@@ -585,13 +560,23 @@ e_plugin_add_load_path(const gchar *path)
gint
e_plugin_load_plugins(void)
{
+ GConfClient *client;
GSList *l;
gint i;
- if (ep_types == NULL) {
- g_warning("no plugin types defined");
+ if (eph_types != NULL)
return 0;
- }
+
+ /* We require that all GTypes for EPlugin and EPluginHook
+ * subclasses be registered prior to loading any plugins.
+ * It greatly simplifies the loading process. */
+ plugin_load_subclasses ();
+
+ client = gconf_client_get_default ();
+ ep_disabled = gconf_client_get_list (
+ client, "/apps/evolution/eplugin/disabled",
+ GCONF_VALUE_STRING, NULL);
+ g_object_unref (client);
for (i=0; i < 3; i++) {
for (l = ep_path;l;l = g_slist_next(l)) {
@@ -623,70 +608,6 @@ e_plugin_load_plugins(void)
return 0;
}
-/**
- * e_plugin_register_type:
- * @type: The GObject type of the plugin loader.
- *
- * Register a new plugin type with the plugin system. Each type must
- * subclass EPlugin and must override the type member of the
- * EPluginClass with a unique name.
- **/
-void
-e_plugin_register_type(GType type)
-{
- EPluginClass *class;
- struct _plugin_doc *pdoc, *ndoc;
-
- if (ep_types == NULL) {
- ep_types = g_hash_table_new(g_str_hash, g_str_equal);
- ep_plugins = g_hash_table_new(g_str_hash, g_str_equal);
- /* TODO: notify listening */
- ep_gconf = gconf_client_get_default();
- ep_disabled = gconf_client_get_list(ep_gconf, "/apps/evolution/eplugin/disabled", GCONF_VALUE_STRING, NULL);
- }
-
- class = g_type_class_ref(type);
-
- pd(printf("register plugin type '%s'\n", class->type));
-
- g_hash_table_insert(ep_types, (gpointer)class->type, class);
-
- /* check for pending plugins */
- pdoc = (struct _plugin_doc *)ep_plugin_docs.head;
- ndoc = pdoc->next;
- while (ndoc) {
- if (pdoc->plugins) {
- GSList *l, *add = NULL;
-
- for (l=pdoc->plugins;l;l=g_slist_next(l)) {
- xmlNodePtr root = l->data;
- gchar *prop_type;
-
- prop_type = (gchar *)xmlGetProp(root, (const guchar *)"type");
- if (!strcmp(prop_type, class->type))
- add = g_slist_append(add, l->data);
- xmlFree(prop_type);
- }
-
- for (l=add;l;l=g_slist_next(l)) {
- xmlNodePtr root = l->data;
- EPlugin *ep;
-
- pdoc->plugins = g_slist_remove(pdoc->plugins, root);
- ep = ep_load_plugin(root, pdoc);
- if (ep)
- pdoc->plugin_hooks = g_slist_prepend(pdoc->plugin_hooks, ep);
- /* TODO: garbage collect plugin doc? */
- }
-
- g_slist_free(add);
- }
-
- pdoc = ndoc;
- ndoc = ndoc->next;
- }
-}
-
static void
ep_list_plugin(gpointer key, gpointer val, gpointer dat)
{
@@ -973,265 +894,6 @@ e_plugin_xml_content_domain(xmlNodePtr node, const gchar *domain)
/* ********************************************************************** */
-static gpointer epl_parent_class;
-
-/* TODO:
- We need some way to manage lifecycle.
- We need some way to manage state.
-
- Maybe just the g module init method will do, or we could add
- another which returns context.
-
- There is also the question of per-instance context, e.g. for config
- pages.
-*/
-
-static GList *missing_symbols = NULL;
-
-static gint
-epl_loadmodule(EPlugin *ep, gboolean fatal)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibEnableFunc enable;
-
- if (epl->module != NULL)
- return 0;
-
- if ((epl->module = g_module_open(epl->location, 0)) == NULL) {
- if (fatal)
- g_warning("can't load plugin '%s': %s", epl->location, g_module_error());
- else
- missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
- return -1;
- }
-
- if (g_module_symbol(epl->module, "e_plugin_lib_enable", (gpointer)&enable)) {
- if (enable(epl, TRUE) != 0) {
- ep->enabled = FALSE;
- g_module_close(epl->module);
- epl->module = NULL;
- return -1;
- }
- }
-
- return 0;
-}
-
-void
-e_plugin_load_plugins_with_missing_symbols (void)
-{
- GList *list = missing_symbols;
-
- while (list) {
- EPlugin *ep = list->data;
- epl_loadmodule (ep, TRUE);
- g_object_unref (ep);
- list = g_list_next (list);
- }
-
- g_list_free (missing_symbols);
- missing_symbols = NULL;
-}
-
-static gpointer
-epl_invoke(EPlugin *ep, const gchar *name, gpointer data)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibFunc cb;
-
- if (!ep->enabled) {
- g_warning("trying to invoke '%s' on disabled plugin '%s'", name, ep->id);
- return NULL;
- }
-
- if (epl_loadmodule(ep, FALSE) != 0)
- return NULL;
-
- if (!g_module_symbol(epl->module, name, (gpointer)&cb)) {
- g_warning("Cannot resolve symbol '%s' in plugin '%s' (not exported?)", name, epl->location);
- return NULL;
- }
-
- return cb(epl, data);
-}
-
-static gpointer
-epl_get_symbol(EPlugin *ep, const gchar *name)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- gpointer symbol;
-
- if (epl_loadmodule (ep, FALSE) != 0)
- return NULL;
-
- if (!g_module_symbol (epl->module, name, &symbol))
- return NULL;
-
- return symbol;
-}
-
-static gint
-epl_construct(EPlugin *ep, xmlNodePtr root)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
-
- if (E_PLUGIN_CLASS (epl_parent_class)->construct (ep, root) == -1)
- return -1;
-
- epl->location = e_plugin_xml_prop(root, "location");
-
- if (epl->location == NULL) {
- g_warning("Library plugin '%s' has no location", ep->id);
- return -1;
- }
-#ifdef G_OS_WIN32
- {
- gchar *mapped_location =
- e_util_replace_prefix (EVOLUTION_PREFIX,
- e_util_get_prefix (),
- epl->location);
- g_free (epl->location);
- epl->location = mapped_location;
- }
-#endif
- /* If we're enabled, check for the load-on-startup property */
- if (ep->enabled) {
- xmlChar *tmp;
-
- tmp = xmlGetProp(root, (const guchar *)"load-on-startup");
- if (tmp) {
- if (strcmp ((const gchar *)tmp, "after-ui") == 0) {
- missing_symbols = g_list_prepend (missing_symbols, g_object_ref (ep));
- } else {
- if (epl_loadmodule(ep, FALSE) != 0) {
- xmlFree(tmp);
- return -1;
- }
- }
- xmlFree(tmp);
- }
- }
-
- return 0;
-}
-
-static GtkWidget *
-epl_get_configure_widget (EPlugin *ep)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibGetConfigureWidgetFunc get_configure_widget;
-
- pd (printf ("\n epl_get_configure_widget \n"));
-
- if (epl_loadmodule (ep, FALSE) != 0) {
- pd (printf ("\n epl_loadmodule \n"));
- return NULL;
- }
-
- if (g_module_symbol (epl->module, "e_plugin_lib_get_configure_widget", (gpointer)&get_configure_widget)) {
- pd (printf ("\n g_module_symbol is loaded\n"));
- return (GtkWidget*) get_configure_widget (epl);
- }
- return NULL;
-}
-
-static void
-epl_enable(EPlugin *ep, gint state)
-{
- EPluginLib *epl = E_PLUGIN_LIB (ep);
- EPluginLibEnableFunc enable;
-
- E_PLUGIN_CLASS (epl_parent_class)->enable (ep, state);
-
- /* if we're disabling and it isn't loaded, nothing to do */
- if (!state && epl->module == NULL)
- return;
-
- /* this will noop if we're disabling since we tested it above */
- if (epl_loadmodule(ep, FALSE) != 0)
- return;
-
- if (g_module_symbol(epl->module, "e_plugin_lib_enable", (gpointer)&enable)) {
- if (enable(epl, state) != 0)
- return;
- }
-#if 0
- if (!state) {
- g_module_close(epl->module);
- epl->module = NULL;
- }
-#endif
-}
-
-static void
-epl_finalize (GObject *object)
-{
- EPluginLib *epl = E_PLUGIN_LIB (object);
-
- g_free (epl->location);
-
- if (epl->module)
- g_module_close (epl->module);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (epl_parent_class)->finalize (object);
-}
-
-static void
-epl_class_init (EPluginClass *class)
-{
- GObjectClass *object_class;
-
- epl_parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = epl_finalize;
-
- class->construct = epl_construct;
- class->invoke = epl_invoke;
- class->get_symbol = epl_get_symbol;
- class->enable = epl_enable;
- class->get_configure_widget = epl_get_configure_widget;
- class->type = "shlib";
-}
-
-/**
- * e_plugin_lib_get_type:
- *
- * Standard GObject function to retrieve the EPluginLib type. Use to
- * register the type with the plugin system if you want to use shared
- * library plugins.
- *
- * Return value: The EPluginLib type.
- **/
-GType
-e_plugin_lib_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EPluginLibClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) epl_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EPluginLib),
- 0, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- e_plugin_get_type (), "EPluginLib", &type_info, 0);
- }
-
- return type;
-}
-
-/* ********************************************************************** */
-
static gpointer eph_parent_class;
static gint
@@ -1314,83 +976,6 @@ e_plugin_hook_enable (EPluginHook *eph, gint state)
class->enable (eph, state);
}
-/**
- * e_plugin_hook_register_type:
- * @type:
- *
- * Register a new plugin hook type with the plugin system. Each type
- * must subclass EPluginHook and must override the id member of the
- * EPluginHookClass with a unique identification string.
- **/
-void
-e_plugin_hook_register_type(GType type)
-{
- EPluginHookClass *klass, *oldklass;
- GSList *l;
-
- gpointer plugins; /* GSList */
- gpointer class;
-
- if (eph_types == NULL)
- eph_types = g_hash_table_new(g_str_hash, g_str_equal);
-
- klass = g_type_class_ref(type);
-
- oldklass = g_hash_table_lookup(eph_types, (gpointer)klass->id);
- if (oldklass == klass) {
- g_type_class_unref(klass);
- return;
- } else if (oldklass != NULL) {
- g_warning("Trying to re-register hook type '%s'", klass->id);
- return;
- }
-
- phd(printf("register plugin hook type '%s'\n", klass->id));
- g_hash_table_insert(eph_types, (gpointer)klass->id, klass);
-
- /* if we've already loaded a plugin that needed this hook but it didn't exist, re-load it now */
-
- if (ep_plugins_pending_hooks
- && g_hash_table_lookup_extended (ep_plugins_pending_hooks, klass->id, &class, &plugins)) {
- struct _plugin_doc *pdoc, *ndoc;
-
- g_hash_table_remove (ep_plugins_pending_hooks, class);
- g_free (class);
- for (l = plugins; l; l = g_slist_next(l)) {
- EPlugin *ep = l->data;
-
- ep_load_pending (ep, klass);
- }
- g_slist_free (plugins);
-
- /* See if we can now garbage collect the xml definition since its been fully loaded */
-
- /* This is all because libxml doesn't refcount! */
-
- pdoc = (struct _plugin_doc *)ep_plugin_docs.head;
- ndoc = pdoc->next;
- while (ndoc) {
- if (pdoc->doc) {
- gint cache = pdoc->plugins != NULL;
-
- for (l=pdoc->plugin_hooks;!cache && l;l=g_slist_next(l))
- cache |= (((EPlugin *)l->data)->hooks_pending != NULL);
-
- if (!cache) {
- pd(printf("Gargabe collecting plugin description '%s'\n", pdoc->filename));
- e_dlist_remove((EDListNode *)pdoc);
- xmlFreeDoc(pdoc->doc);
- g_free(pdoc->filename);
- g_free(pdoc);
- }
- }
-
- pdoc = ndoc;
- ndoc = ndoc->next;
- }
- }
-}
-
/**
* e_plugin_hook_mask:
* @root: An XML node.
@@ -1478,118 +1063,3 @@ e_plugin_hook_id(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const
return ~0;
}
-
-/* ********************************************************************** */
-/* Plugin plugin */
-
-static gpointer epth_parent_class;
-
-static gint
-epth_load_plugin(gpointer d)
-{
- EPluginHook *eph = d;
- EPluginTypeHook *epth = d;
- GType type;
-
- epth->idle = 0;
-
- type = GPOINTER_TO_UINT(e_plugin_invoke(eph->plugin, epth->get_type, eph->plugin));
- if (type != 0)
- e_plugin_register_type(type);
-
- return FALSE;
-}
-
-static gint
-epth_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root)
-{
- EPluginTypeHook *epth = E_PLUGIN_TYPE_HOOK (eph);
- xmlNodePtr node;
-
- phd(printf("loading plugin hook\n"));
-
- if (((EPluginHookClass *)epth_parent_class)->construct(eph, ep, root) == -1)
- return -1;
-
- node = root->children;
- while (node) {
- if (strcmp((gchar *)node->name, "plugin-type") == 0) {
- epth->get_type = e_plugin_xml_prop(node, "get-type");
- /* We need to run this in an idle handler,
- * since at this point the parent EPlugin wont
- * be fully initialised ... darn */
- if (epth->get_type)
- epth->idle = g_idle_add(epth_load_plugin, epth);
- else
- g_warning("Plugin type plugin missing get-type callback");
- }
- node = node->next;
- }
-
- eph->plugin = ep;
-
- return 0;
-}
-
-static void
-epth_finalize (GObject *object)
-{
- EPluginTypeHook *epth = E_PLUGIN_TYPE_HOOK (object);
-
- if (epth->idle != 0)
- g_source_remove (epth->idle);
-
- g_free (epth->get_type);
-
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (epth_parent_class)->finalize (object);
-}
-
-static void
-epth_class_init (EPluginTypeHookClass *class)
-{
- GObjectClass *object_class;
- EPluginHookClass *hook_class;
-
- epth_parent_class = g_type_class_peek_parent (class);
-
- object_class = G_OBJECT_CLASS (class);
- object_class->finalize = epth_finalize;
-
- hook_class = E_PLUGIN_HOOK_CLASS (class);
- hook_class->construct = epth_construct;
- hook_class->id = "org.gnome.evolution.plugin.type:1.0";
-}
-
-/**
- * e_plugin_type_hook_get_type:
- *
- * Get the type for the plugin plugin hook.
- *
- * Return value: The type of the plugin type hook.
- **/
-GType
-e_plugin_type_hook_get_type(void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (EPluginTypeHookClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) epth_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (EPluginTypeHook),
- 0, /* n_preallocs */
- (GInstanceInitFunc) NULL,
- NULL /* value_table */
- };
-
- type = g_type_register_static (
- E_TYPE_PLUGIN_HOOK, "EPluginTypeHook", &type_info, 0);
- }
-
- return type;
-}
diff --git a/e-util/e-plugin.h b/e-util/e-plugin.h
index 18949bf893..8e24436605 100644
--- a/e-util/e-plugin.h
+++ b/e-util/e-plugin.h
@@ -64,8 +64,6 @@ struct _EPluginAuthor {
* @object: Superclass.
* @id: Unique identifier for plugin instance.
* @path: Filename where the xml definition resides.
- * @hooks_pending: A list hooks which can't yet be loaded. This is
- * the xmlNodePtr to the root node of the hook definition.
* @description: A description of the plugin's purpose.
* @name: The name of the plugin.
* @domain: The translation domain for this plugin.
@@ -82,7 +80,6 @@ struct _EPlugin {
gchar *id;
gchar *path;
- GSList *hooks_pending;
gchar *description;
gchar *name;
@@ -134,11 +131,8 @@ GType e_plugin_get_type(void);
gint e_plugin_construct(EPlugin *ep, xmlNodePtr root);
void e_plugin_add_load_path(const gchar *);
gint e_plugin_load_plugins(void);
-void e_plugin_load_plugins_with_missing_symbols(void);
GSList * e_plugin_list_plugins(void);
-void e_plugin_register_type(GType type);
-
gpointer e_plugin_get_symbol(EPlugin *ep, const gchar *name);
gpointer e_plugin_invoke(EPlugin *ep, const gchar *name, gpointer data);
void e_plugin_enable(EPlugin *eph, gint state);
@@ -153,73 +147,6 @@ gint e_plugin_xml_int(xmlNodePtr node, const gchar *id, gint def);
gchar *e_plugin_xml_content(xmlNodePtr node);
gchar *e_plugin_xml_content_domain(xmlNodePtr node, const gchar *domain);
-/* ********************************************************************** */
-#include
-
-/* Standard GObject macros */
-#define E_TYPE_PLUGIN_LIB \
- (e_plugin_lib_get_type ())
-#define E_PLUGIN_LIB(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST \
- ((obj), E_TYPE_PLUGIN_LIB, EPluginLib))
-#define E_PLUGIN_LIB_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_CAST \
- ((cls), E_TYPE_PLUGIN_LIB, EPluginLibClass))
-#define E_IS_PLUGIN_LIB(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE \
- ((obj), E_TYPE_PLUGIN_LIB))
-#define E_IS_PLUGIN_LIB_CLASS(cls) \
- (G_TYPE_CHECK_CLASS_TYPE \
- ((cls), E_TYPE_PLUGIN_LIB))
-#define E_PLUGIN_LIB_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS \
- ((obj), E_TYPE_PLUGIN_LIB, EPluginLibClass))
-
-typedef struct _EPluginLib EPluginLib;
-typedef struct _EPluginLibClass EPluginLibClass;
-
-/* The callback signature used for epluginlib methods */
-typedef gpointer (*EPluginLibFunc)(EPluginLib *ep, gpointer data);
-/* The setup method, this will be called when the plugin is
- * initialised. In the future it may also be called when the plugin
- * is disabled. */
-typedef gint (*EPluginLibEnableFunc)(EPluginLib *ep, gint enable);
-typedef gpointer (*EPluginLibGetConfigureWidgetFunc)(EPluginLib *ep);
-
-/**
- * struct _EPluginLib -
- *
- * @plugin: Superclass.
- * @location: The filename of the shared object.
- * @module: The GModule once it is loaded.
- *
- * This is a concrete EPlugin class. It loads and invokes dynamically
- * loaded libraries using GModule. The shared object isn't loaded
- * until the first callback is invoked.
- *
- * When the plugin is loaded, and if it exists, "e_plugin_lib_enable"
- * will be invoked to initialise the
- **/
-struct _EPluginLib {
- EPlugin plugin;
-
- gchar *location;
- GModule *module;
-};
-
-/**
- * struct _EPluginLibClass -
- *
- * @plugin_class: Superclass.
- *
- * The plugin library needs no additional class data.
- **/
-struct _EPluginLibClass {
- EPluginClass plugin_class;
-};
-
-GType e_plugin_lib_get_type(void);
-
/* ********************************************************************** */
/* Standard GObject macros */
@@ -323,8 +250,6 @@ struct _EPluginHookClass {
GType e_plugin_hook_get_type(void);
-void e_plugin_hook_register_type(GType type);
-
EPluginHook * e_plugin_hook_new(EPlugin *ep, xmlNodePtr root);
void e_plugin_hook_enable(EPluginHook *eph, gint state);
@@ -332,49 +257,6 @@ void e_plugin_hook_enable(EPluginHook *eph, gint state);
guint32 e_plugin_hook_mask(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const gchar *prop);
guint32 e_plugin_hook_id(xmlNodePtr root, const struct _EPluginHookTargetKey *map, const gchar *prop);
-/* ********************************************************************** */
-
-/* EPluginTypeHook lets a plugin register a new plugin type.
-
-