aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Hooper <adamh@src.gnome.org>2004-09-14 05:52:00 +0800
committerAdam Hooper <adamh@src.gnome.org>2004-09-14 05:52:00 +0800
commit809f1aca44d03364d59d33780684ad8c524a0025 (patch)
tree7bef6e9dc63f82fc2b9318ad1acbaa5f915e979c
parent25a80e3d76c1c74e810271f0cf46832f7b6e127d (diff)
downloadgsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar
gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.gz
gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.bz2
gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.lz
gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.xz
gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.zst
gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.zip
Load/unload extensions based on GConf key
/apps/epiphany/general/active_extensions. Update documentation a bit (i.e., make sure it actually builds).
-rw-r--r--ChangeLog36
-rw-r--r--data/epiphany.schemas.in13
-rw-r--r--doc/reference/Makefile.am2
-rw-r--r--doc/reference/epiphany-docs.sgml1
-rw-r--r--doc/reference/epiphany-sections.txt19
-rw-r--r--doc/reference/epiphany.types2
-rw-r--r--doc/reference/tmpl/ephy-embed-factory.sgml4
-rw-r--r--doc/reference/tmpl/ephy-embed.sgml8
-rw-r--r--doc/reference/tmpl/ephy-extensions-manager.sgml63
-rw-r--r--doc/reference/tmpl/ephy-shell.sgml10
-rw-r--r--doc/reference/tmpl/ephy-window.sgml1
-rw-r--r--doc/reference/tmpl/epiphany-unused.sgml8
-rw-r--r--lib/ephy-module-loader.c20
-rw-r--r--lib/ephy-module-loader.h2
-rw-r--r--src/ephy-extensions-manager.c350
-rw-r--r--src/ephy-extensions-manager.h5
-rw-r--r--src/ephy-shell.c6
17 files changed, 472 insertions, 78 deletions
diff --git a/ChangeLog b/ChangeLog
index 1414b880d..652b04390 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2004-09-13 Adam Hooper <adamh@cvs.gnome.org>
+
+ * data/epiphany.schemas.in:
+ * doc/reference/Makefile.am:
+ * doc/reference/epiphany-docs.sgml:
+ * doc/reference/epiphany-sections.txt:
+ * doc/reference/epiphany.types:
+ * doc/reference/tmpl/ephy-embed-factory.sgml:
+ * doc/reference/tmpl/ephy-embed.sgml:
+ * doc/reference/tmpl/ephy-extensions-manager.sgml:
+ * doc/reference/tmpl/ephy-shell.sgml:
+ * doc/reference/tmpl/ephy-window.sgml:
+ * doc/reference/tmpl/epiphany-unused.sgml:
+ * lib/ephy-module-loader.c: (ephy_module_loader_new),
+ (ephy_module_loader_load), (ephy_module_loader_unload),
+ (ephy_module_loader_get_path):
+ * lib/ephy-module-loader.h:
+ * src/ephy-extensions-manager.c: (free_ext_info),
+ (windows_foreach), (attach_window), (detach_window),
+ (instantiate_extension), (real_load),
+ (ephy_extensions_manager_load), (real_unload),
+ (ephy_extensions_manager_unload), (ephy_extensions_manager_add),
+ (sync_one_extension), (ephy_extensions_manager_sync_gconf),
+ (ephy_extensions_manager_load_file),
+ (ephy_extensions_manager_load_dir), (active_extensions_notifier),
+ (ephy_extensions_manager_init), (ephy_extensions_manager_finalize),
+ (attach_window_to_info), (impl_attach_window),
+ (detach_window_from_info), (impl_detach_window):
+ * src/ephy-extensions-manager.h:
+ * src/ephy-shell.c: (ephy_shell_get_extensions_manager):
+
+ Load/unload extensions based on GConf key
+ /apps/epiphany/general/active_extensions.
+
+ Update documentation a bit (i.e., make sure it actually builds).
+
2004-09-13 Christian Persch <chpe@cvs.gnome.org>
* data/art/epiphany-entry.png:
diff --git a/data/epiphany.schemas.in b/data/epiphany.schemas.in
index 2ad9a52d4..2012d136d 100644
--- a/data/epiphany.schemas.in
+++ b/data/epiphany.schemas.in
@@ -191,6 +191,19 @@
</locale>
</schema>
<schema>
+ <key>/schemas/apps/epiphany/general/active_extensions</key>
+ <applyto>/apps/epiphany/general/active_extensions</applyto>
+ <owner>epiphany</owner>
+ <type>list</type>
+ <list_type>string</list_type>
+ <locale name="C">
+ <short>Loaded extensions</short>
+ <long>Partial filenames of extensions to load. For example, if a desired
+ extension's filename is "libgesturesextension.so", add "gestures" to the
+ list.</long>
+ </locale>
+ </schema>
+ <schema>
<key>/schemas/apps/epiphany/web/default_encoding</key>
<applyto>/apps/epiphany/web/default_encoding</applyto>
<owner>epiphany</owner>
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
index 6abd91db5..1b50546fe 100644
--- a/doc/reference/Makefile.am
+++ b/doc/reference/Makefile.am
@@ -52,7 +52,6 @@ IGNORE_HFILES = \
ephy-thread-helpers.h \
ephy-zoom.h \
ephy-arrow-toolbutton.h \
- ephy-cell-renderer-progress.h \
ephy-label.h \
ephy-location-entry.h \
ephy-node-view.h \
@@ -123,7 +122,6 @@ IGNORE_HFILES = \
ephy-encoding-dialog.h \
ephy-encoding-menu.h \
ephy-extension.h \
- ephy-extensions-manager.h \
ephy-favicon-action.h \
ephy-favorites-menu.h \
ephy-go-action.h \
diff --git a/doc/reference/epiphany-docs.sgml b/doc/reference/epiphany-docs.sgml
index 77f21f012..ba3b13b3c 100644
--- a/doc/reference/epiphany-docs.sgml
+++ b/doc/reference/epiphany-docs.sgml
@@ -18,6 +18,7 @@
<xi:include href="xml/ephy-embed-factory.xml"/>
<xi:include href="xml/ephy-node-db.xml"/>
<xi:include href="xml/ephy-glade.xml"/>
+ <xi:include href="xml/ephy-extensions-manager.xml"/>
</chapter>
<chapter>
<title>Incomplete</title>
diff --git a/doc/reference/epiphany-sections.txt b/doc/reference/epiphany-sections.txt
index 94f6edfa3..5945524ce 100644
--- a/doc/reference/epiphany-sections.txt
+++ b/doc/reference/epiphany-sections.txt
@@ -235,6 +235,25 @@ EPHY_NODE_DB_GET_CLASS
ephy_glade_widget_new
</SECTION>
+<SECTION>
+<FILE>ephy-extensions-manager</FILE>
+<TITLE>EphyExtensionsManager</TITLE>
+ephy_extensions_manager_new
+ephy_extensions_manager_load
+ephy_extensions_manager_unload
+ephy_extensions_manager_load_dir
+ephy_extensions_manager_add
+ephy_extensions_manager_list
+<SUBSECTION Standard>
+EPHY_EXTENSIONS_MANAGER
+EPHY_IS_EXTENSIONS_MANAGER
+EPHY_TYPE_EXTENSIONS_MANAGER
+ephy_extensions_manager_get_type
+EPHY_EXTENSIONS_MANAGER_CLASS
+EPHY_IS_EXTENSIONS_MANAGER_CLASS
+EPHY_EXTENSIONS_MANAGER_GET_CLASS
+</SECTION>
+
<SECTION>
diff --git a/doc/reference/epiphany.types b/doc/reference/epiphany.types
index 58dd8ba78..530f82969 100644
--- a/doc/reference/epiphany.types
+++ b/doc/reference/epiphany.types
@@ -6,7 +6,6 @@
#include <ephy-location-entry.h>
#include <ephy-zoom-action.h>
#include <ephy-zoom-control.h>
-#include <ephy-cell-renderer-progress.h>
ephy_dialog_get_type
ephy_file_chooser_get_type
@@ -16,7 +15,6 @@ ephy_node_filter_get_type
ephy_location_entry_get_type
ephy_zoom_action_get_type
ephy_zoom_control_get_type
-ephy_cell_renderer_progress_get_type
#include <ephy-embed.h>
#include <downloader-view.h>
diff --git a/doc/reference/tmpl/ephy-embed-factory.sgml b/doc/reference/tmpl/ephy-embed-factory.sgml
index f80295416..556730839 100644
--- a/doc/reference/tmpl/ephy-embed-factory.sgml
+++ b/doc/reference/tmpl/ephy-embed-factory.sgml
@@ -25,7 +25,9 @@ To create a new instance of an #EphyEmbed, #EphyEmbedPersist or
</para>
-@object_id:
+@type:
@Returns:
+<!-- # Unused Parameters # -->
+@object_id:
diff --git a/doc/reference/tmpl/ephy-embed.sgml b/doc/reference/tmpl/ephy-embed.sgml
index 8688721b1..da9a9e933 100644
--- a/doc/reference/tmpl/ephy-embed.sgml
+++ b/doc/reference/tmpl/ephy-embed.sgml
@@ -146,6 +146,14 @@ be done by casting).
@:
@:
@:
+@:
+@:
+@:
+@:
+@:
+@:
+@:
+@:
@:
<!-- ##### SIGNAL EphyEmbed::ge-security-change ##### -->
diff --git a/doc/reference/tmpl/ephy-extensions-manager.sgml b/doc/reference/tmpl/ephy-extensions-manager.sgml
new file mode 100644
index 000000000..418123132
--- /dev/null
+++ b/doc/reference/tmpl/ephy-extensions-manager.sgml
@@ -0,0 +1,63 @@
+<!-- ##### SECTION Title ##### -->
+EphyExtensionsManager
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION ephy_extensions_manager_new ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION ephy_extensions_manager_load ##### -->
+<para>
+
+</para>
+
+@manager:
+@filename:
+<!-- # Unused Parameters # -->
+@Returns:
+
+
+<!-- ##### FUNCTION ephy_extensions_manager_unload ##### -->
+<para>
+
+</para>
+
+@manager:
+@filename:
+
+
+<!-- ##### FUNCTION ephy_extensions_manager_load_dir ##### -->
+<para>
+
+</para>
+
+@manager:
+@path:
+
+
+<!-- ##### FUNCTION ephy_extensions_manager_add ##### -->
+<para>
+
+</para>
+
+@manager:
+@type:
+@Returns:
+
+
diff --git a/doc/reference/tmpl/ephy-shell.sgml b/doc/reference/tmpl/ephy-shell.sgml
index 6c9e8b68d..570c6a038 100644
--- a/doc/reference/tmpl/ephy-shell.sgml
+++ b/doc/reference/tmpl/ephy-shell.sgml
@@ -48,7 +48,6 @@ ephy-shell
@EPHY_SHELL_STARTUP_SESSION:
@EPHY_SHELL_STARTUP_IMPORT_BOOKMARKS:
@EPHY_SHELL_STARTUP_ADD_BOOKMARK:
-@EPHY_SHELL_STARTUP_SERVER:
<!-- ##### ENUM EphyNewTabFlags ##### -->
<para>
@@ -94,15 +93,6 @@ ephy-shell
@Returns:
-<!-- ##### FUNCTION ephy_shell_get_active_window ##### -->
-<para>
-
-</para>
-
-@shell:
-@Returns:
-
-
<!-- ##### FUNCTION ephy_shell_new_tab ##### -->
<para>
diff --git a/doc/reference/tmpl/ephy-window.sgml b/doc/reference/tmpl/ephy-window.sgml
index b831ebbe8..218477bd6 100644
--- a/doc/reference/tmpl/ephy-window.sgml
+++ b/doc/reference/tmpl/ephy-window.sgml
@@ -33,7 +33,6 @@ These are restricted to ephy_window_set_zoom() and ephy_window_load_url().
</para>
-@ui_merge: The #GtkUIManager this window uses to merge user interfaces
<!-- ##### ARG EphyWindow:active-tab ##### -->
<para>
diff --git a/doc/reference/tmpl/epiphany-unused.sgml b/doc/reference/tmpl/epiphany-unused.sgml
index aa9f02d89..1dfbb6967 100644
--- a/doc/reference/tmpl/epiphany-unused.sgml
+++ b/doc/reference/tmpl/epiphany-unused.sgml
@@ -154,6 +154,14 @@ mozilla-embed-event
@path:
@gs:
+<!-- ##### FUNCTION ephy_shell_get_active_window ##### -->
+<para>
+
+</para>
+
+@shell:
+@Returns:
+
<!-- ##### FUNCTION ephy_tab_get_window ##### -->
<para>
diff --git a/lib/ephy-module-loader.c b/lib/ephy-module-loader.c
index 99c452927..2cd72fd89 100644
--- a/lib/ephy-module-loader.c
+++ b/lib/ephy-module-loader.c
@@ -96,13 +96,6 @@ ephy_module_loader_new (const char *path)
g_type_module_set_name (G_TYPE_MODULE (result), path);
result->path = g_strdup (path);
- if (!g_type_module_use (G_TYPE_MODULE (result)))
- {
- g_object_unref (result);
-
- return NULL;
- }
-
return result;
}
@@ -110,14 +103,11 @@ static gboolean
ephy_module_loader_load (GTypeModule *module)
{
EphyModuleLoader *loader = EPHY_MODULE_LOADER (module);
- char *module_path;
register_module_fn register_module;
LOG ("ephy_module_loader_load %s", loader->path)
- module_path = g_strdup (loader->path);
- loader->library = g_module_open (module_path, 0);
- g_free (module_path);
+ loader->library = g_module_open (loader->path, 0);
if (!loader->library)
{
@@ -159,6 +149,14 @@ ephy_module_loader_unload (GTypeModule *module)
loader->type = 0;
}
+const char *
+ephy_module_loader_get_path (EphyModuleLoader *loader)
+{
+ g_return_val_if_fail (EPHY_IS_MODULE_LOADER (loader), NULL);
+
+ return loader->path;
+}
+
static void
ephy_module_loader_class_init (EphyModuleLoaderClass *class)
{
diff --git a/lib/ephy-module-loader.h b/lib/ephy-module-loader.h
index 6b5b29a66..fe25712a7 100644
--- a/lib/ephy-module-loader.h
+++ b/lib/ephy-module-loader.h
@@ -38,6 +38,8 @@ GType ephy_module_loader_get_type (void);
EphyModuleLoader *ephy_module_loader_new (const char *path);
+const char *ephy_module_loader_get_path (EphyModuleLoader *loader);
+
GObject *ephy_module_loader_factory (EphyModuleLoader *loader);
G_END_DECLS
diff --git a/src/ephy-extensions-manager.c b/src/ephy-extensions-manager.c
index f8e283e09..7b66f289e 100644
--- a/src/ephy-extensions-manager.c
+++ b/src/ephy-extensions-manager.c
@@ -25,20 +25,34 @@
#include "ephy-extensions-manager.h"
+#include "ephy-shell.h"
+#include "ephy-session.h" /* Weird (session is an extension) but it works */
#include "ephy-module-loader.h"
#include "ephy-debug.h"
+#include "eel-gconf-extensions.h"
+
#include <gmodule.h>
#include <dirent.h>
+#include <string.h>
+
+#define CONF_LOADED_EXTENSIONS "/apps/epiphany/general/active_extensions"
#define EPHY_EXTENSIONS_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerPrivate))
struct EphyExtensionsManagerPrivate
{
- GSList *loaders;
- GSList *extensions;
+ GHashTable *extensions;
+ GSList *internal_extensions;
+ guint active_extensions_notifier_id;
};
+typedef struct
+{
+ EphyModuleLoader *loader; /* NULL if never loaded */
+ EphyExtension *extension; /* NULL if unloaded */
+} ExtInfo;
+
static GObjectClass *parent_class = NULL;
static void ephy_extensions_manager_class_init (EphyExtensionsManagerClass *klass);
@@ -84,9 +98,47 @@ ephy_extensions_manager_get_type (void)
return type;
}
+static void
+free_ext_info (ExtInfo *info)
+{
+ if (info->extension)
+ {
+ g_object_unref (info->extension);
+ }
+ g_free (info);
+}
+
+static void
+windows_foreach (GFunc func, EphyExtension *extension)
+{
+ EphySession *session;
+ GList *windows;
+
+ session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
+
+ windows = ephy_session_get_windows (session);
+
+ g_list_foreach (windows, func, extension);
+
+ g_list_free (windows);
+}
+
+static void
+attach_window (EphyWindow *window,
+ EphyExtension *extension)
+{
+ ephy_extension_attach_window (extension, window);
+}
+
+static void
+detach_window (EphyWindow *window,
+ EphyExtension *extension)
+{
+ ephy_extension_detach_window (extension, window);
+}
+
static EphyExtension *
-ephy_extensions_manager_instantiate_extension (EphyExtensionsManager *manager,
- EphyModuleLoader *loader)
+instantiate_extension (EphyModuleLoader *loader)
{
EphyExtension *extension;
@@ -94,8 +146,7 @@ ephy_extensions_manager_instantiate_extension (EphyExtensionsManager *manager,
if (EPHY_IS_EXTENSION (extension))
{
- manager->priv->extensions =
- g_slist_append (manager->priv->extensions, extension);
+ windows_foreach ((GFunc) attach_window, extension);
return extension;
}
@@ -103,59 +154,116 @@ ephy_extensions_manager_instantiate_extension (EphyExtensionsManager *manager,
return NULL;
}
-EphyExtension *
-ephy_extensions_manager_load (EphyExtensionsManager *manager,
- const char *filename)
+static void
+real_load (ExtInfo *info)
{
- EphyExtension *extension = NULL;
+ if (info->extension != NULL) return;
- if (g_str_has_suffix (filename, G_MODULE_SUFFIX))
+ if (g_type_module_use (G_TYPE_MODULE (info->loader)) == FALSE)
{
- EphyModuleLoader *loader;
-
- loader = ephy_module_loader_new (filename);
-
- if (loader != NULL)
- {
- manager->priv->loaders =
- g_slist_prepend (manager->priv->loaders, loader);
+ g_warning ("Could not load extension file at %s\n",
+ ephy_module_loader_get_path (info->loader));
+ return;
+ }
- extension = ephy_extensions_manager_instantiate_extension
- (manager, loader);
+ info->extension = instantiate_extension (info->loader);
- g_type_module_unuse (G_TYPE_MODULE (loader));
- }
+ if (info->extension == NULL)
+ {
+ g_warning ("Could not load extension at %s\n",
+ ephy_module_loader_get_path (info->loader));
}
- return extension;
+ g_type_module_unuse (G_TYPE_MODULE (info->loader));
}
+/**
+ * ephy_extensions_manager_load:
+ * @manager: an #EphyExtensionsManager
+ * @filename: filename of an extension to load, minus "lib" and "extension.so"
+ *
+ * Loads the @filename extension.
+ **/
void
-ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
- const char *path)
+ephy_extensions_manager_load (EphyExtensionsManager *manager,
+ const char *filename)
{
- DIR *d;
- struct dirent *e;
+ GSList *gconf_exts;
- d = opendir (path);
- if (d == NULL)
+ gconf_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS);
+
+ if (!g_slist_find_custom (gconf_exts, filename, (GCompareFunc) strcmp))
{
- return;
+ gconf_exts = g_slist_prepend (gconf_exts, g_strdup (filename));
+
+ eel_gconf_set_string_list (CONF_LOADED_EXTENSIONS, gconf_exts);
}
- while ((e = readdir (d)) != NULL)
- {
- char *filename;
+ g_slist_foreach (gconf_exts, (GFunc) g_free, NULL);
+ g_slist_free (gconf_exts);
+}
- filename = g_build_filename (path, e->d_name, NULL);
+static void
+real_unload (ExtInfo *info)
+{
+ if (info->extension == NULL) return; /* not loaded */
- ephy_extensions_manager_load (manager, filename);
+ windows_foreach ((GFunc) detach_window, info->extension);
- g_free (filename);
+ /*
+ * Only unref the extension in the idle loop; if the extension has its
+ * own functions queued in the idle loop, the functions must exist in
+ * memory before being called.
+ */
+ g_idle_add ((GSourceFunc) g_object_unref, info->extension);
+ info->extension = NULL;
+}
+
+/**
+ * ephy_extensions_manager_unload:
+ * @manager: an #EphyExtensionsManager
+ * @filename: filename of extension to unload, minus "lib" and "extension.so"
+ *
+ * Unloads the extension specified by @filename.
+ *
+ * The extension with the same filename can afterwards be reloaded. However,
+ * if any GTypes within the extension have changed parent types, Epiphany must
+ * be restarted.
+ **/
+void
+ephy_extensions_manager_unload (EphyExtensionsManager *manager,
+ const char *filename)
+{
+ GSList *gconf_exts;
+ GSList *l;
+
+ gconf_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS);
+
+ l = g_slist_find_custom (gconf_exts, filename, (GCompareFunc) strcmp);
+
+ if (l != NULL)
+ {
+ gconf_exts = g_slist_remove_link (gconf_exts, l);
+ g_free (l->data);
+ g_slist_free_1 (l);
+
+ eel_gconf_set_string_list (CONF_LOADED_EXTENSIONS, gconf_exts);
}
- closedir (d);
+
+ g_slist_foreach (gconf_exts, (GFunc) g_free, NULL);
+ g_slist_free (gconf_exts);
}
+/**
+ * ephy_extensions_manager_add:
+ * @manager: an #EphyExtensionsManager
+ * @type: GType of the extension to add
+ *
+ * Creates a new instance of @type (which must be an #EphyExtension) and adds
+ * it to @manager. This is only used to load internal Epiphany extensions.
+ *
+ * Return value: a new instance of @type
+ **/
EphyExtension *
ephy_extensions_manager_add (EphyExtensionsManager *manager,
GType type)
@@ -172,21 +280,135 @@ ephy_extensions_manager_add (EphyExtensionsManager *manager,
return NULL;
}
- manager->priv->extensions =
- g_slist_append (manager->priv->extensions, extension);
+ manager->priv->internal_extensions =
+ g_slist_append (manager->priv->internal_extensions, extension);
return extension;
}
static void
+sync_one_extension (const char *name,
+ ExtInfo *info,
+ GSList *wanted_exts)
+{
+ if (g_slist_find_custom (wanted_exts, name, (GCompareFunc) strcmp))
+ {
+ real_load (info);
+ }
+ else
+ {
+ real_unload (info);
+ }
+}
+
+static void
+ephy_extensions_manager_sync_gconf (EphyExtensionsManager *manager)
+{
+ GSList *wanted_exts;
+
+ wanted_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS);
+
+ g_hash_table_foreach (manager->priv->extensions,
+ (GHFunc) sync_one_extension,
+ wanted_exts);
+
+ g_slist_foreach (wanted_exts, (GFunc) g_free, NULL);
+ g_slist_free (wanted_exts);
+}
+
+static void
+ephy_extensions_manager_load_file (EphyExtensionsManager *manager,
+ const char *dir,
+ const char *filename)
+{
+ ExtInfo *info;
+ char *name;
+ char *path;
+
+ /* Must match "libBLAHextension.so" */
+ if (!g_str_has_prefix (filename, "lib")
+ || !g_str_has_suffix (filename, "extension." G_MODULE_SUFFIX))
+ {
+ return;
+ }
+
+ name = g_strndup (filename + 3,
+ strlen(filename) - 13 - strlen(G_MODULE_SUFFIX));
+
+ if (g_hash_table_lookup (manager->priv->extensions, name) != NULL)
+ {
+ /* We already have another version stored */
+ g_free (name);
+ return;
+ }
+
+ path = g_build_filename (dir, filename, NULL);
+
+ info = g_new0 (ExtInfo, 1);
+ info->loader = ephy_module_loader_new (path);
+
+ g_free (path);
+
+ g_hash_table_insert (manager->priv->extensions, name, info);
+}
+
+/**
+ * ephy_extensions_manager_load_dir:
+ * @manager: an #EphyExtensionsManager
+ * @path: directory to load
+ *
+ * Searches @path for all files matching the pattern
+ * &quot;libEXTextension.so&quot; and stores them in @manager, ready to be
+ * loaded.
+ **/
+void
+ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
+ const char *path)
+{
+ DIR *d;
+ struct dirent *e;
+
+ d = opendir (path);
+ if (d == NULL)
+ {
+ return;
+ }
+ while ((e = readdir (d)) != NULL)
+ {
+ ephy_extensions_manager_load_file (manager, path, e->d_name);
+ }
+ closedir (d);
+
+ ephy_extensions_manager_sync_gconf (manager);
+}
+
+static void
+active_extensions_notifier (GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ EphyExtensionsManager *manager)
+{
+ ephy_extensions_manager_sync_gconf (manager);
+}
+
+static void
ephy_extensions_manager_init (EphyExtensionsManager *manager)
{
manager->priv = EPHY_EXTENSIONS_MANAGER_GET_PRIVATE (manager);
LOG ("EphyExtensionsManager initialising")
- manager->priv->loaders = NULL;
- manager->priv->extensions = NULL;
+ manager->priv->extensions = g_hash_table_new_full
+ (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, (GDestroyNotify) free_ext_info);
+
+ manager->priv->internal_extensions = NULL;
+
+ manager->priv->active_extensions_notifier_id =
+ eel_gconf_notification_add (CONF_LOADED_EXTENSIONS,
+ (GConfClientNotifyFunc)
+ active_extensions_notifier,
+ manager);
}
static void
@@ -196,15 +418,30 @@ ephy_extensions_manager_finalize (GObject *object)
LOG ("EphyExtensionsManager finalising")
- g_slist_foreach (manager->priv->extensions, (GFunc) g_object_unref, NULL);
- g_slist_free (manager->priv->extensions);
+ g_hash_table_destroy (manager->priv->extensions);
+
+ g_slist_foreach (manager->priv->internal_extensions,
+ (GFunc) g_object_unref, NULL);
+ g_slist_free (manager->priv->internal_extensions);
- g_slist_free (manager->priv->loaders);
+ eel_gconf_notification_remove
+ (manager->priv->active_extensions_notifier_id);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
+attach_window_to_info (const char *key,
+ ExtInfo *info,
+ EphyWindow *window)
+{
+ if (info->extension)
+ {
+ ephy_extension_attach_window (info->extension, window);
+ }
+}
+
+static void
impl_attach_window (EphyExtension *extension,
EphyWindow *window)
{
@@ -212,8 +449,23 @@ impl_attach_window (EphyExtension *extension,
LOG ("multiplexing attach_window")
- g_slist_foreach (manager->priv->extensions,
+ g_slist_foreach (manager->priv->internal_extensions,
(GFunc) ephy_extension_attach_window, window);
+
+ g_hash_table_foreach (manager->priv->extensions,
+ (GHFunc) attach_window_to_info,
+ window);
+}
+
+static void
+detach_window_from_info (const char *key,
+ ExtInfo *info,
+ EphyWindow *window)
+{
+ if (info->extension)
+ {
+ ephy_extension_detach_window (info->extension, window);
+ }
}
static void
@@ -226,9 +478,13 @@ impl_detach_window (EphyExtension *extension,
g_object_ref (window);
- g_slist_foreach (manager->priv->extensions,
+ g_slist_foreach (manager->priv->internal_extensions,
(GFunc) ephy_extension_detach_window, window);
+ g_hash_table_foreach (manager->priv->extensions,
+ (GHFunc) detach_window_from_info,
+ window);
+
g_object_unref (window);
}
diff --git a/src/ephy-extensions-manager.h b/src/ephy-extensions-manager.h
index 22e956a0b..3272ff320 100644
--- a/src/ephy-extensions-manager.h
+++ b/src/ephy-extensions-manager.h
@@ -57,7 +57,10 @@ GType ephy_extensions_manager_get_type (void);
EphyExtensionsManager *ephy_extensions_manager_new (void);
-EphyExtension *ephy_extensions_manager_load (EphyExtensionsManager *manager,
+void ephy_extensions_manager_load (EphyExtensionsManager *manager,
+ const char *filename);
+
+void ephy_extensions_manager_unload (EphyExtensionsManager *manager,
const char *filename);
void ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 792099ddd..8b67e3d40 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -689,13 +689,13 @@ ephy_shell_get_extensions_manager (EphyShell *es)
es->priv->extensions_manager = ephy_extensions_manager_new ();
/* load the extensions */
- ephy_extensions_manager_load_dir (es->priv->extensions_manager,
- EXTENSIONS_DIR);
-
path = g_build_filename (ephy_dot_dir (), "extensions", NULL);
ephy_extensions_manager_load_dir (es->priv->extensions_manager,
path);
g_free (path);
+
+ ephy_extensions_manager_load_dir (es->priv->extensions_manager,
+ EXTENSIONS_DIR);
}
return G_OBJECT (es->priv->extensions_manager);