aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Persch <chpe@cvs.gnome.org>2004-10-17 21:39:12 +0800
committerChristian Persch <chpe@src.gnome.org>2004-10-17 21:39:12 +0800
commit611e5407571e19353a98292d953e90e63073ba61 (patch)
treecc306bde897a303c8f0974c6b9dd2ae0311b3947
parentc21eba3c01185673b2ab4e7ceee995f6f52b6f25 (diff)
downloadgsoc2013-epiphany-611e5407571e19353a98292d953e90e63073ba61.tar
gsoc2013-epiphany-611e5407571e19353a98292d953e90e63073ba61.tar.gz
gsoc2013-epiphany-611e5407571e19353a98292d953e90e63073ba61.tar.bz2
gsoc2013-epiphany-611e5407571e19353a98292d953e90e63073ba61.tar.lz
gsoc2013-epiphany-611e5407571e19353a98292d953e90e63073ba61.tar.xz
gsoc2013-epiphany-611e5407571e19353a98292d953e90e63073ba61.tar.zst
gsoc2013-epiphany-611e5407571e19353a98292d953e90e63073ba61.zip
R lib/ephy-module-loader.c: R lib/ephy-module-loader.h: A
2004-10-17 Christian Persch <chpe@cvs.gnome.org> * lib/Makefile.am: R lib/ephy-module-loader.c: R lib/ephy-module-loader.h: A lib/ephy-module.c: (ephy_module_get_type), (ephy_module_load), (ephy_module_unload), (ephy_module_get_path), (ephy_module_new_object), (ephy_module_init), (ephy_module_finalize), (ephy_module_class_init), (ephy_module_new): A lib/ephy-module.h: s/EphyModuleLoader/EphyModule/g since "loader" now means something different. A lib/ephy-loader.c: (ephy_loader_get_type), (ephy_loader_type), (ephy_loader_get_object), (ephy_loader_release_object): A lib/ephy-loader.h: Generic object loader. A lib/ephy-shlib-loader.c: (ephy_shlib_loader_get_type), (free_loader_data), (ephy_shlib_loader_init), (ephy_shlib_loader_finalize), (find_library), (find_object), (idle_unref), (impl_get_object), (impl_release_object), (ephy_shlib_loader_iface_init), (ephy_shlib_loader_class_init): A lib/ephy-shlib-loader.h: A .so loader. * src/Makefile.am: * src/ephy-extensions-manager.c: (ephy_extensions_manager_load), (ephy_extensions_manager_unload), (ephy_extensions_manager_register), (ephy_extensions_manager_get_extensions), (free_extension_info), (free_loader_info), (find_extension_info), (ephy_extensions_manager_load_file), (find_loader), (get_loader_for_type), (attach_window), (load_extension), (detach_window), (unload_extension), (ephy_extensions_manager_load_dir), (active_extensions_notifier), (ephy_extensions_manager_init), (ephy_extensions_manager_finalize), (impl_attach_window), (impl_detach_window), (ephy_extensions_manager_class_init): * src/ephy-extensions-manager.h: Read extension descriptions from .xml, load them with the specified loader (for now, just only .so is supported). * src/ephy-shell.c: (ephy_shell_finalize), (ephy_shell_get_session), (ephy_shell_get_extensions_manager): Minor API change in extensions manager. * data/epiphany.schemas.in: Add extensions-manager-ui as default active extension. 2004-10-10 Marco Pesenti Gritti <marco@gnome.org>
-rw-r--r--ChangeLog58
-rw-r--r--data/epiphany.schemas.in7
-rw-r--r--lib/Makefile.am9
-rw-r--r--lib/ephy-loader.c71
-rw-r--r--lib/ephy-loader.h66
-rw-r--r--lib/ephy-module-loader.c205
-rw-r--r--lib/ephy-module-loader.h47
-rw-r--r--lib/ephy-module.c205
-rw-r--r--lib/ephy-module.h48
-rw-r--r--lib/ephy-shlib-loader.c256
-rw-r--r--lib/ephy-shlib-loader.h57
-rw-r--r--src/Makefile.am2
-rw-r--r--src/ephy-extensions-manager.c867
-rw-r--r--src/ephy-extensions-manager.h44
-rw-r--r--src/ephy-shell.c38
15 files changed, 1446 insertions, 534 deletions
diff --git a/ChangeLog b/ChangeLog
index 3fb92f670..fce11e0cd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2004-10-17 Christian Persch <chpe@cvs.gnome.org>
+
+ * lib/Makefile.am:
+ R lib/ephy-module-loader.c:
+ R lib/ephy-module-loader.h:
+ A lib/ephy-module.c: (ephy_module_get_type), (ephy_module_load),
+ (ephy_module_unload), (ephy_module_get_path),
+ (ephy_module_new_object), (ephy_module_init),
+ (ephy_module_finalize), (ephy_module_class_init),
+ (ephy_module_new):
+ A lib/ephy-module.h:
+
+ s/EphyModuleLoader/EphyModule/g since "loader" now means something
+ different.
+
+ A lib/ephy-loader.c: (ephy_loader_get_type), (ephy_loader_type),
+ (ephy_loader_get_object), (ephy_loader_release_object):
+ A lib/ephy-loader.h:
+
+ Generic object loader.
+
+ A lib/ephy-shlib-loader.c: (ephy_shlib_loader_get_type),
+ (free_loader_data), (ephy_shlib_loader_init),
+ (ephy_shlib_loader_finalize), (find_library), (find_object),
+ (idle_unref), (impl_get_object), (impl_release_object),
+ (ephy_shlib_loader_iface_init), (ephy_shlib_loader_class_init):
+ A lib/ephy-shlib-loader.h:
+
+ A .so loader.
+
+ * src/Makefile.am:
+ * src/ephy-extensions-manager.c: (ephy_extensions_manager_load),
+ (ephy_extensions_manager_unload),
+ (ephy_extensions_manager_register),
+ (ephy_extensions_manager_get_extensions), (free_extension_info),
+ (free_loader_info), (find_extension_info),
+ (ephy_extensions_manager_load_file), (find_loader),
+ (get_loader_for_type), (attach_window), (load_extension),
+ (detach_window), (unload_extension),
+ (ephy_extensions_manager_load_dir), (active_extensions_notifier),
+ (ephy_extensions_manager_init), (ephy_extensions_manager_finalize),
+ (impl_attach_window), (impl_detach_window),
+ (ephy_extensions_manager_class_init):
+ * src/ephy-extensions-manager.h:
+
+ Read extension descriptions from .xml, load them with the specified
+ loader (for now, just only .so is supported).
+
+ * src/ephy-shell.c: (ephy_shell_finalize),
+ (ephy_shell_get_session), (ephy_shell_get_extensions_manager):
+
+ Minor API change in extensions manager.
+
+ * data/epiphany.schemas.in:
+
+ Add extensions-manager-ui as default active extension.
+
2004-10-10 Marco Pesenti Gritti <marco@gnome.org>
reviewed by: Christian Persch <chpe@cvs.gnome.org>
@@ -636,4 +693,3 @@
Merging pre-gnome-2-10 branch to HEAD.
Splitting ChangeLog.
-
diff --git a/data/epiphany.schemas.in b/data/epiphany.schemas.in
index b51537072..ed72f722f 100644
--- a/data/epiphany.schemas.in
+++ b/data/epiphany.schemas.in
@@ -196,11 +196,10 @@
<owner>epiphany</owner>
<type>list</type>
<list_type>string</list_type>
+ <default>[extensions-manager-ui]</default>
<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>
+ <short>Active extensions</short>
+ <long>Lists the active extensions.</long>
</locale>
</schema>
<schema>
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 8a7c8ff79..c90f51ac3 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -24,16 +24,18 @@ NOINST_H_FILES = \
ephy-gui.h \
ephy-langs.h \
ephy-marshal.h \
- ephy-module-loader.h \
+ ephy-module.h \
ephy-node-filter.h \
ephy-node-common.h \
ephy-prefs.h \
+ ephy-shlib-loader.h \
ephy-string.h \
ephy-stock-icons.h \
ephy-zoom.h
INST_H_FILES = \
ephy-dialog.h \
+ ephy-loader.h \
ephy-node.h \
ephy-node-db.h \
ephy-state.h
@@ -48,7 +50,8 @@ libephymisc_la_SOURCES = \
ephy-glade.c \
ephy-gui.c \
ephy-langs.c \
- ephy-module-loader.c \
+ ephy-loader.c \
+ ephy-module.c \
ephy-marshal.c \
ephy-node.c \
ephy-node.h \
@@ -56,6 +59,7 @@ libephymisc_la_SOURCES = \
ephy-node-common.h \
ephy-node-db.c \
ephy-prefs.h \
+ ephy-shlib-loader.c \
ephy-state.c \
ephy-string.c \
ephy-stock-icons.c \
@@ -75,4 +79,3 @@ ephy-marshal.h: ephy-marshal.list
EXTRA_DIST = \
ephy-marshal.list
-
diff --git a/lib/ephy-loader.c b/lib/ephy-loader.c
new file mode 100644
index 000000000..cbd19fce9
--- /dev/null
+++ b/lib/ephy-loader.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-loader.h"
+
+GType
+ephy_loader_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphyLoaderIface),
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "EphyLoader",
+ &our_info, 0);
+ }
+
+ return type;
+}
+
+const char *
+ephy_loader_type (const EphyLoader *loader)
+{
+ EphyLoaderIface *iface = EPHY_LOADER_GET_IFACE (loader);
+ return iface->type;
+}
+
+GObject *
+ephy_loader_get_object (EphyLoader *loader,
+ GData **attributes)
+{
+ EphyLoaderIface *iface = EPHY_LOADER_GET_IFACE (loader);
+ return iface->get_object (loader, attributes);
+}
+
+void
+ephy_loader_release_object (EphyLoader *loader,
+ GObject *object)
+{
+ EphyLoaderIface *iface = EPHY_LOADER_GET_IFACE (loader);
+ iface->release_object (loader, object);
+}
diff --git a/lib/ephy-loader.h b/lib/ephy-loader.h
new file mode 100644
index 000000000..c987bb636
--- /dev/null
+++ b/lib/ephy-loader.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_LOADER_H
+#define EPHY_LOADER_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_LOADER (ephy_loader_get_type ())
+#define EPHY_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_LOADER, EphyLoader))
+#define EPHY_LOADER_IFACE(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_LOADER, EphyLoaderIface))
+#define EPHY_IS_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_LOADER))
+#define EPHY_IS_LOADER_IFACE(iface) (G_TYPE_CHECK_CLASS_TYPE ((iface), EPHY_TYPE_LOADER))
+#define EPHY_LOADER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EPHY_TYPE_LOADER, EphyLoaderIface))
+
+typedef struct _EphyLoader EphyLoader;
+typedef struct _EphyLoaderIface EphyLoaderIface;
+
+struct _EphyLoaderIface
+{
+ GTypeInterface base_iface;
+
+ /* Identifier */
+ const char *type;
+
+ /* Methods */
+ GObject * (* get_object) (EphyLoader *loader,
+ GData **attributes);
+ void (* release_object) (EphyLoader *loader,
+ GObject *object);
+};
+
+GType ephy_loader_get_type (void);
+
+const char *ephy_loader_type (const EphyLoader *loader);
+
+GObject *ephy_loader_get_object (EphyLoader *loader,
+ GData **attributes);
+
+void ephy_loader_release_object (EphyLoader *loader,
+ GObject *object);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/ephy-module-loader.c b/lib/ephy-module-loader.c
deleted file mode 100644
index 2cd72fd89..000000000
--- a/lib/ephy-module-loader.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2003 Marco Pesenti Gritti
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id$
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "ephy-module-loader.h"
-#include "ephy-file-helpers.h"
-#include "ephy-debug.h"
-
-#include <gmodule.h>
-
-typedef struct _EphyModuleLoaderClass EphyModuleLoaderClass;
-
-struct _EphyModuleLoaderClass
-{
- GTypeModuleClass parent_class;
-};
-
-struct _EphyModuleLoader
-{
- GTypeModule parent_instance;
-
- GModule *library;
-
- char *path;
- GType type;
-};
-
-typedef GType (*register_module_fn) (GTypeModule *);
-
-static void ephy_module_loader_init (EphyModuleLoader *action);
-static void ephy_module_loader_class_init (EphyModuleLoaderClass *class);
-static void ephy_module_loader_finalize (GObject *object);
-
-static GObjectClass *parent_class = NULL;
-
-GType
-ephy_module_loader_get_type (void)
-{
- static GType type = 0;
-
- if (!type)
- {
- static const GTypeInfo type_info =
- {
- sizeof (EphyModuleLoaderClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) ephy_module_loader_class_init,
- (GClassFinalizeFunc) NULL,
- NULL,
- sizeof (EphyModuleLoader),
- 0, /* n_preallocs */
- (GInstanceInitFunc) ephy_module_loader_init,
- };
-
- type = g_type_register_static (G_TYPE_TYPE_MODULE,
- "EphyModuleLoader",
- &type_info, 0);
- }
-
- return type;
-}
-
-EphyModuleLoader *
-ephy_module_loader_new (const char *path)
-{
- EphyModuleLoader *result;
-
- if (path == NULL || path[0] == '\0')
- {
- return NULL;
- }
-
- result = g_object_new (EPHY_TYPE_MODULE_LOADER, NULL);
-
- g_type_module_set_name (G_TYPE_MODULE (result), path);
- result->path = g_strdup (path);
-
- return result;
-}
-
-static gboolean
-ephy_module_loader_load (GTypeModule *module)
-{
- EphyModuleLoader *loader = EPHY_MODULE_LOADER (module);
- register_module_fn register_module;
-
- LOG ("ephy_module_loader_load %s", loader->path)
-
- loader->library = g_module_open (loader->path, 0);
-
- if (!loader->library)
- {
- g_warning (g_module_error());
-
- return FALSE;
- }
-
- /* extract symbols from the lib */
- if (!g_module_symbol (loader->library, "register_module",
- (void *) &register_module))
- {
- g_warning (g_module_error());
- g_module_close (loader->library);
-
- return FALSE;
- }
-
- g_assert (register_module != NULL);
-
- loader->type = register_module (module);
-
- if (loader->type == 0)
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-ephy_module_loader_unload (GTypeModule *module)
-{
- EphyModuleLoader *loader = EPHY_MODULE_LOADER (module);
-
- g_module_close (loader->library);
-
- loader->library = NULL;
- 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)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GTypeModuleClass *loader_class = G_TYPE_MODULE_CLASS (class);
-
- parent_class = (GObjectClass *) g_type_class_peek_parent (class);
-
- object_class->finalize = ephy_module_loader_finalize;
-
- loader_class->load = ephy_module_loader_load;
- loader_class->unload = ephy_module_loader_unload;
-}
-
-static void
-ephy_module_loader_init (EphyModuleLoader *loader)
-{
- LOG ("EphyModuleLoader initialising")
-
- loader->library = NULL;
- loader->path = NULL;
- loader->type = 0;
-}
-
-static void
-ephy_module_loader_finalize (GObject *object)
-{
- EphyModuleLoader *loader = EPHY_MODULE_LOADER (object);
-
- LOG ("EphyModuleLoader finalising")
-
- g_free (loader->path);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-GObject *
-ephy_module_loader_factory (EphyModuleLoader *loader)
-{
- if (loader->type == 0)
- {
- return NULL;
- }
-
- return g_object_new (loader->type, NULL);
-}
diff --git a/lib/ephy-module-loader.h b/lib/ephy-module-loader.h
deleted file mode 100644
index fe25712a7..000000000
--- a/lib/ephy-module-loader.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2003 Marco Pesenti Gritti
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id$
- */
-
-#ifndef EPHY_MODULE_LOADER_H
-#define EPHY_MODULE_LOADER_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define EPHY_TYPE_MODULE_LOADER (ephy_module_loader_get_type ())
-#define EPHY_MODULE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_MODULE_LOADER, EphyModuleLoader))
-#define EPHY_MODULE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_MODULE_LOADER, EphyModuleLoaderClass))
-#define EPHY_IS_MODULE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_MODULE_LOADER))
-#define EPHY_IS_MODULE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_MODULE_LOADER))
-#define EPHY_MODULE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_MODULE_LOADER, EphyModuleLoaderClass))
-
-typedef struct _EphyModuleLoader EphyModuleLoader;
-
-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
-
-#endif
diff --git a/lib/ephy-module.c b/lib/ephy-module.c
new file mode 100644
index 000000000..60c96f1f2
--- /dev/null
+++ b/lib/ephy-module.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-module.h"
+#include "ephy-file-helpers.h"
+#include "ephy-debug.h"
+
+#include <gmodule.h>
+
+typedef struct _EphyModuleClass EphyModuleClass;
+
+struct _EphyModuleClass
+{
+ GTypeModuleClass parent_class;
+};
+
+struct _EphyModule
+{
+ GTypeModule parent_instance;
+
+ GModule *library;
+
+ char *path;
+ GType type;
+};
+
+typedef GType (*EphyModuleRegisterFunc) (GTypeModule *);
+
+static void ephy_module_init (EphyModule *action);
+static void ephy_module_class_init (EphyModuleClass *class);
+
+static GObjectClass *parent_class = NULL;
+
+GType
+ephy_module_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (EphyModuleClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ephy_module_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (EphyModule),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_module_init,
+ };
+
+ type = g_type_register_static (G_TYPE_TYPE_MODULE,
+ "EphyModule",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+static gboolean
+ephy_module_load (GTypeModule *gmodule)
+{
+ EphyModule *module = EPHY_MODULE (gmodule);
+ EphyModuleRegisterFunc register_func;
+
+ LOG ("Loading %s", module->path)
+
+ module->library = g_module_open (module->path, 0);
+
+ if (module->library == NULL)
+ {
+ g_warning (g_module_error());
+
+ return FALSE;
+ }
+
+ /* extract symbols from the lib */
+ if (!g_module_symbol (module->library, "register_module",
+ (void *) &register_func))
+ {
+ g_warning (g_module_error());
+ g_module_close (module->library);
+
+ return FALSE;
+ }
+
+ g_assert (register_func);
+
+ module->type = register_func (gmodule);
+
+ if (module->type == 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+ephy_module_unload (GTypeModule *gmodule)
+{
+ EphyModule *module = EPHY_MODULE (gmodule);
+
+ LOG ("Unloading %s", module->path)
+
+ g_module_close (module->library);
+
+ module->library = NULL;
+ module->type = 0;
+}
+
+const char *
+ephy_module_get_path (EphyModule *module)
+{
+ g_return_val_if_fail (EPHY_IS_MODULE (module), NULL);
+
+ return module->path;
+}
+
+GObject *
+ephy_module_new_object (EphyModule *module)
+{
+ LOG ("Creating object of type %s", g_type_name (module->type))
+
+ if (module->type == 0)
+ {
+ return NULL;
+ }
+
+ return g_object_new (module->type, NULL);
+}
+
+static void
+ephy_module_init (EphyModule *module)
+{
+ LOG ("EphyModule %p initialising", module)
+}
+
+static void
+ephy_module_finalize (GObject *object)
+{
+ EphyModule *module = EPHY_MODULE (object);
+
+ LOG ("EphyModule %p finalising", module)
+
+ g_free (module->path);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+ephy_module_class_init (EphyModuleClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+
+ parent_class = (GObjectClass *) g_type_class_peek_parent (class);
+
+ object_class->finalize = ephy_module_finalize;
+
+ module_class->load = ephy_module_load;
+ module_class->unload = ephy_module_unload;
+}
+
+EphyModule *
+ephy_module_new (const char *path)
+{
+ EphyModule *result;
+
+ if (path == NULL || path[0] == '\0')
+ {
+ return NULL;
+ }
+
+ result = g_object_new (EPHY_TYPE_MODULE, NULL);
+
+ g_type_module_set_name (G_TYPE_MODULE (result), path);
+ result->path = g_strdup (path);
+
+ return result;
+}
diff --git a/lib/ephy-module.h b/lib/ephy-module.h
new file mode 100644
index 000000000..aaacbff63
--- /dev/null
+++ b/lib/ephy-module.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_MODULE_H
+#define EPHY_MODULE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_MODULE (ephy_module_get_type ())
+#define EPHY_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_MODULE, EphyModule))
+#define EPHY_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_MODULE, EphyModuleClass))
+#define EPHY_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_MODULE))
+#define EPHY_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_MODULE))
+#define EPHY_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_MODULE, EphyModuleClass))
+
+typedef struct _EphyModule EphyModule;
+
+GType ephy_module_get_type (void);
+
+EphyModule *ephy_module_new (const char *path);
+
+const char *ephy_module_get_path (EphyModule *module);
+
+GObject *ephy_module_new_object (EphyModule *module);
+
+G_END_DECLS
+
+#endif
diff --git a/lib/ephy-shlib-loader.c b/lib/ephy-shlib-loader.c
new file mode 100644
index 000000000..68276bb67
--- /dev/null
+++ b/lib/ephy-shlib-loader.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-shlib-loader.h"
+#include "ephy-loader.h"
+#include "ephy-module.h"
+#include "ephy-debug.h"
+
+#include <string.h>
+
+#define DATA_KEY "EphyShlibLoader::LoaderData"
+
+typedef struct
+{
+ EphyModule *module;
+ GObject *object;
+} LoaderData;
+
+static GQuark library_quark = 0;
+
+#define EPHY_SHLIB_LOADER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SHLIB_LOADER, EphyShlibLoaderPrivate))
+
+struct _EphyShlibLoaderPrivate
+{
+ GSList *data;
+};
+
+static void ephy_shlib_loader_class_init (EphyShlibLoaderClass *klass);
+static void ephy_shlib_loader_iface_init (EphyLoaderIface *iface);
+static void ephy_shlib_loader_init (EphyShlibLoader *loader);
+
+static GObjectClass *parent_class = NULL;
+
+GType
+ephy_shlib_loader_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphyShlibLoaderClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ephy_shlib_loader_class_init,
+ NULL,
+ NULL, /* class_data */
+ sizeof (EphyShlibLoader),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_shlib_loader_init
+ };
+
+ static const GInterfaceInfo loader_info =
+ {
+ (GInterfaceInitFunc) ephy_shlib_loader_iface_init,
+ NULL,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "EphyShlibLoader",
+ &our_info, 0);
+
+ g_type_add_interface_static (type,
+ EPHY_TYPE_LOADER,
+ &loader_info);
+ }
+
+ return type;
+}
+
+static void
+free_loader_data (LoaderData *data)
+{
+ g_return_if_fail (data != NULL);
+
+ /* data->module must NOT be unreffed! */
+
+ if (data->object != NULL)
+ {
+ g_object_unref (data->object);
+ }
+
+ g_free (data);
+}
+
+static void
+ephy_shlib_loader_init (EphyShlibLoader *loader)
+{
+ loader->priv = EPHY_SHLIB_LOADER_GET_PRIVATE (loader);
+
+ LOG ("EphyShlibLoader initialising")
+}
+
+static void
+ephy_shlib_loader_finalize (GObject *object)
+{
+ EphyShlibLoader *loader = EPHY_SHLIB_LOADER (object);
+
+ LOG ("EphyShlibLoader finalising")
+
+ g_slist_foreach (loader->priv->data, (GFunc) free_loader_data, NULL);
+ g_slist_free (loader->priv->data);
+
+ parent_class->finalize (object);
+}
+
+static int
+find_library (const LoaderData *data,
+ const char *library)
+{
+ return strcmp (ephy_module_get_path (data->module), library);
+}
+
+static int
+find_object (const LoaderData *data,
+ const GObject *object)
+{
+ return data->object != object;
+}
+
+static gboolean
+idle_unref (GObject *object)
+{
+ g_object_unref (object);
+
+ return FALSE;
+}
+
+static GObject *
+impl_get_object (EphyLoader *eloader,
+ GData **attributes)
+{
+ EphyShlibLoader *loader = EPHY_SHLIB_LOADER (eloader);
+ GSList *l;
+ LoaderData *data = NULL;
+ const char *library;
+
+ library = g_datalist_id_get_data (attributes, library_quark);
+ if (library == NULL)
+ {
+ g_warning ("NULL library name!\n");
+ return NULL;
+ }
+
+ l = g_slist_find_custom (loader->priv->data, library,
+ (GCompareFunc) find_library);
+
+ if (l != NULL)
+ {
+ data = l->data;
+ g_return_val_if_fail (data != NULL, NULL);
+
+ if (data->object != NULL)
+ {
+ return g_object_ref (data->object);
+ }
+ }
+ else
+ {
+ data = g_new0 (LoaderData, 1);
+ loader->priv->data = g_slist_prepend (loader->priv->data, data);
+ }
+
+ if (data->module == NULL)
+ {
+ data->module = ephy_module_new (library);
+ }
+
+ g_return_val_if_fail (data->object == NULL, data->object);
+
+ if (g_type_module_use (G_TYPE_MODULE (data->module)) == FALSE)
+ {
+ g_warning ("Could not load extension file at %s\n",
+ ephy_module_get_path (data->module));
+ return NULL;
+ }
+
+ data->object = ephy_module_new_object (data->module);
+
+ g_type_module_unuse (G_TYPE_MODULE (data->module));
+
+ if (data->object != NULL)
+ {
+ g_object_set_data (G_OBJECT (data->object), DATA_KEY, data);
+ }
+
+ return data->object;
+}
+
+static void
+impl_release_object (EphyLoader *eloader,
+ GObject *object)
+{
+ EphyShlibLoader *loader = EPHY_SHLIB_LOADER (eloader);
+ GSList *l;
+ LoaderData *data;
+
+ l = g_slist_find_custom (loader->priv->data, object,
+ (GCompareFunc) find_object);
+ g_return_if_fail (l != NULL);
+ data = l->data;
+
+ /* FIXME: should we consider those extensions broken?
+ * 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) idle_unref, data->object);
+ data->object = NULL;
+}
+
+static void
+ephy_shlib_loader_iface_init (EphyLoaderIface *iface)
+{
+ iface->type = "shlib";
+ iface->get_object = impl_get_object;
+ iface->release_object = impl_release_object;
+}
+
+static void
+ephy_shlib_loader_class_init (EphyShlibLoaderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = ephy_shlib_loader_finalize;
+
+ g_type_class_add_private (object_class, sizeof (EphyShlibLoaderPrivate));
+
+ library_quark = g_quark_from_string ("library");
+}
diff --git a/lib/ephy-shlib-loader.h b/lib/ephy-shlib-loader.h
new file mode 100644
index 000000000..6f3d04977
--- /dev/null
+++ b/lib/ephy-shlib-loader.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_SHLIB_LOADER_H
+#define EPHY_SHLIB_LOADER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_SHLIB_LOADER (ephy_shlib_loader_get_type ())
+#define EPHY_SHLIB_LOADER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_SHLIB_LOADER, EphyShlibLoader))
+#define EPHY_SHLIB_LOADER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_SHLIB_LOADER, EphyShlibLoaderClass))
+#define EPHY_IS_SHLIB_LOADER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_SHLIB_LOADER))
+#define EPHY_IS_SHLIB_LOADER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_SHLIB_LOADER))
+#define EPHY_SHLIB_LOADER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_SHLIB_LOADER, EphyShlibLoaderClass))
+
+typedef struct _EphyShlibLoader EphyShlibLoader;
+typedef struct _EphyShlibLoaderPrivate EphyShlibLoaderPrivate;
+typedef struct _EphyShlibLoaderClass EphyShlibLoaderClass;
+
+struct _EphyShlibLoaderClass
+{
+ GObjectClass parent_class;
+};
+
+struct _EphyShlibLoader
+{
+ GObject parent_instance;
+
+ /*< private >*/
+ EphyShlibLoaderPrivate *priv;
+};
+
+GType ephy_shlib_loader_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 93816cc44..a3c87a061 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,7 +44,6 @@ NOINST_H_FILES = \
ephy-automation.h \
ephy-encoding-dialog.h \
ephy-encoding-menu.h \
- ephy-extensions-manager.h \
ephy-favicon-action.h \
ephy-go-action.h \
ephy-history-window.h \
@@ -61,6 +60,7 @@ NOINST_H_FILES = \
INST_H_FILES = \
ephy-extension.h \
+ ephy-extensions-manager.h \
ephy-notebook.h \
ephy-session.h \
ephy-shell.h \
diff --git a/src/ephy-extensions-manager.c b/src/ephy-extensions-manager.c
index 7b66f289e..0fc15bcbd 100644
--- a/src/ephy-extensions-manager.c
+++ b/src/ephy-extensions-manager.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2003 Marco Pesenti Gritti
- * Copyright (C) 2003 Christian Persch
+ * Copyright (C) 2003, 2004 Christian Persch
+ * Copyright (C) 2004 Adam Hooper
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,12 +26,16 @@
#include "ephy-extensions-manager.h"
+#include "ephy-loader.h"
+#include "ephy-shlib-loader.h"
+
+#include "ephy-node-db.h"
#include "ephy-shell.h"
-#include "ephy-session.h" /* Weird (session is an extension) but it works */
-#include "ephy-module-loader.h"
+#include "eel-gconf-extensions.h"
+#include "ephy-file-helpers.h"
#include "ephy-debug.h"
-#include "eel-gconf-extensions.h"
+#include <libxml/xmlreader.h>
#include <gmodule.h>
#include <dirent.h>
@@ -40,18 +45,46 @@
#define EPHY_EXTENSIONS_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerPrivate))
-struct EphyExtensionsManagerPrivate
+struct _EphyExtensionsManagerPrivate
{
- GHashTable *extensions;
- GSList *internal_extensions;
+ gboolean initialised;
+
+ GList *data;
+ GList *factories;
+ GList *extensions;
+ GList *windows;
guint active_extensions_notifier_id;
};
typedef struct
{
- EphyModuleLoader *loader; /* NULL if never loaded */
- EphyExtension *extension; /* NULL if unloaded */
-} ExtInfo;
+ EphyExtensionInfo info;
+ guint version;
+ gboolean load_deferred;
+ gboolean load_failed;
+
+ xmlChar *gettext_domain;
+ xmlChar *locale_directory;
+ xmlChar *loader_type;
+ GData *loader_attributes;
+
+ EphyLoader *loader; /* NULL if never loaded */
+ GObject *extension; /* NULL if unloaded */
+} ExtensionInfo;
+
+typedef struct
+{
+ char *type;
+ EphyLoader *loader;
+} LoaderInfo;
+
+enum
+{
+ CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
static GObjectClass *parent_class = NULL;
@@ -98,103 +131,29 @@ 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 *
-instantiate_extension (EphyModuleLoader *loader)
-{
- EphyExtension *extension;
-
- extension = EPHY_EXTENSION (ephy_module_loader_factory (loader));
-
- if (EPHY_IS_EXTENSION (extension))
- {
- windows_foreach ((GFunc) attach_window, extension);
-
- return extension;
- }
-
- return NULL;
-}
-
-static void
-real_load (ExtInfo *info)
-{
- if (info->extension != NULL) return;
-
- if (g_type_module_use (G_TYPE_MODULE (info->loader)) == FALSE)
- {
- g_warning ("Could not load extension file at %s\n",
- ephy_module_loader_get_path (info->loader));
- return;
- }
-
- info->extension = instantiate_extension (info->loader);
-
- if (info->extension == NULL)
- {
- g_warning ("Could not load extension at %s\n",
- ephy_module_loader_get_path (info->loader));
- }
-
- 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"
+ * @name: identifier of the extension to load
*
- * Loads the @filename extension.
+ * Loads the @name extension.
**/
void
ephy_extensions_manager_load (EphyExtensionsManager *manager,
- const char *filename)
+ const char *identifier)
{
GSList *gconf_exts;
+ g_return_if_fail (EPHY_IS_EXTENSIONS_MANAGER (manager));
+ g_return_if_fail (identifier != NULL);
+
+ LOG ("Adding '%s' to extensions", identifier)
+
gconf_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS);
- if (!g_slist_find_custom (gconf_exts, filename, (GCompareFunc) strcmp))
+ if (!g_slist_find_custom (gconf_exts, identifier, (GCompareFunc) strcmp))
{
- gconf_exts = g_slist_prepend (gconf_exts, g_strdup (filename));
+ gconf_exts = g_slist_prepend (gconf_exts, g_strdup (identifier));
eel_gconf_set_string_list (CONF_LOADED_EXTENSIONS, gconf_exts);
}
@@ -203,28 +162,12 @@ ephy_extensions_manager_load (EphyExtensionsManager *manager,
g_slist_free (gconf_exts);
}
-static void
-real_unload (ExtInfo *info)
-{
- if (info->extension == NULL) return; /* not loaded */
-
- windows_foreach ((GFunc) detach_window, info->extension);
-
- /*
- * 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"
+ * @name: filename of extension to unload, minus "lib" and "extension.so"
*
- * Unloads the extension specified by @filename.
+ * Unloads the extension specified by @name.
*
* The extension with the same filename can afterwards be reloaded. However,
* if any GTypes within the extension have changed parent types, Epiphany must
@@ -232,14 +175,19 @@ real_unload (ExtInfo *info)
**/
void
ephy_extensions_manager_unload (EphyExtensionsManager *manager,
- const char *filename)
+ const char *identifier)
{
GSList *gconf_exts;
GSList *l;
-
+
+ g_return_if_fail (EPHY_IS_EXTENSIONS_MANAGER (manager));
+ g_return_if_fail (identifier != NULL);
+
+ LOG ("Removing '%s' from extensions", identifier)
+
gconf_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS);
- l = g_slist_find_custom (gconf_exts, filename, (GCompareFunc) strcmp);
+ l = g_slist_find_custom (gconf_exts, identifier, (GCompareFunc) strcmp);
if (l != NULL)
{
@@ -255,119 +203,537 @@ ephy_extensions_manager_unload (EphyExtensionsManager *manager,
}
/**
- * ephy_extensions_manager_add:
+ * ephy_extensions_manager_register:
* @manager: an #EphyExtensionsManager
- * @type: GType of the extension to add
+ * @object: an Extension
*
- * 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
+ * Registers @object with the extensions manager. @object must implement the
+ * #EphyExtension interface.
**/
-EphyExtension *
-ephy_extensions_manager_add (EphyExtensionsManager *manager,
- GType type)
+void
+ephy_extensions_manager_register (EphyExtensionsManager *manager,
+ GObject *object)
{
- EphyExtension *extension;
+ g_return_if_fail (EPHY_IS_EXTENSIONS_MANAGER (manager));
+ g_return_if_fail (EPHY_IS_EXTENSION (object));
- LOG ("adding extensions of type %s", g_type_name (type))
-
- extension = EPHY_EXTENSION (g_object_new (type, NULL));
- if (!EPHY_IS_EXTENSION (extension))
- {
- g_object_unref (extension);
+ LOG ("Registering internal extension of type %s",
+ g_type_name (((GTypeClass *) object)->g_type))
- return NULL;
- }
+ manager->priv->extensions = g_list_prepend (manager->priv->extensions,
+ g_object_ref (object));
+}
- manager->priv->internal_extensions =
- g_slist_append (manager->priv->internal_extensions, extension);
- return extension;
+/**
+ * ephy_extensions_manager_get_extensions:
+ * @manager: an #EphyExtensionsManager
+ *
+ * Returns the list of known extensions.
+ *
+ * Returns: a list of #EphyExtensionInfo
+ **/
+GList *
+ephy_extensions_manager_get_extensions (EphyExtensionsManager *manager)
+{
+ return g_list_copy (manager->priv->data);
}
static void
-sync_one_extension (const char *name,
- ExtInfo *info,
- GSList *wanted_exts)
+free_extension_info (ExtensionInfo *info)
{
- if (g_slist_find_custom (wanted_exts, name, (GCompareFunc) strcmp))
+ EphyExtensionInfo *einfo = (EphyExtensionInfo *) info;
+
+ g_free (einfo->identifier);
+ xmlFree ((xmlChar *) einfo->name);
+ xmlFree ((xmlChar *) einfo->description);
+ g_list_foreach (einfo->authors, (GFunc) xmlFree, NULL);
+ g_list_free (einfo->authors);
+ xmlFree ((xmlChar *) einfo->url);
+ xmlFree ((xmlChar *) info->gettext_domain);
+ xmlFree ((xmlChar *) info->locale_directory);
+ xmlFree ((xmlChar *) info->loader_type);
+ g_datalist_clear (&info->loader_attributes);
+
+ if (info->extension != NULL)
{
- real_load (info);
+ g_return_if_fail (info->loader != NULL);
+
+ ephy_loader_release_object (info->loader, info->extension);
}
- else
+ if (info->loader != NULL)
{
- real_unload (info);
+ g_object_unref (info->loader);
}
+
+ g_free (info);
}
static void
-ephy_extensions_manager_sync_gconf (EphyExtensionsManager *manager)
+free_loader_info (LoaderInfo *info)
{
- 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_free (info->type);
+ g_object_unref (info->loader);
+ g_free (info);
+}
- g_slist_foreach (wanted_exts, (GFunc) g_free, NULL);
- g_slist_free (wanted_exts);
+static int
+find_extension_info (const ExtensionInfo *info,
+ const char *identifier)
+{
+ return strcmp (info->info.identifier, identifier);
}
+typedef enum
+{
+ STATE_START,
+ STATE_STOP,
+ STATE_ERROR,
+ STATE_EXTENSION,
+ STATE_NAME,
+ STATE_DESCRIPTION,
+ STATE_VERSION,
+ STATE_AUTHOR,
+ STATE_URL,
+ STATE_GETTEXT_DOMAIN,
+ STATE_LOCALE_DIRECTORY,
+ STATE_LOADER,
+ STATE_LOADER_ATTRIBUTE,
+ STATE_LOAD_DEFERRED,
+} ParserState;
+
static void
ephy_extensions_manager_load_file (EphyExtensionsManager *manager,
const char *dir,
const char *filename)
{
- ExtInfo *info;
- char *name;
- char *path;
+ xmlTextReaderPtr reader;
+ ParserState state = STATE_START;
+ GQuark attr_quark = 0;
+ EphyExtensionInfo *einfo;
+ ExtensionInfo *info;
+ int ret;
+ char *identifier, *dot, *path;
+
+ LOG ("Loading description file '%s'", filename)
+
+ identifier = g_path_get_basename (filename);
+ dot = strstr (identifier, ".xml");
+ g_return_if_fail (dot != NULL);
+ *dot = '\0';
+
+ if (g_list_find_custom (manager->priv->data, identifier,
+ (GCompareFunc) find_extension_info) != NULL)
+ {
+ g_warning ("Extension description for '%s' already read!\n",
+ identifier);
+ g_free (identifier);
+ return;
+ }
- /* Must match "libBLAHextension.so" */
- if (!g_str_has_prefix (filename, "lib")
- || !g_str_has_suffix (filename, "extension." G_MODULE_SUFFIX))
+ path = g_build_filename (dir, filename, NULL);
+ if (g_file_test (path, G_FILE_TEST_EXISTS) == FALSE)
{
+ g_warning ("'%s' doesn't exist\n", filename);
+ g_free (identifier);
+ g_free (path);
return;
}
+
+ reader = xmlNewTextReaderFilename (path);
+ g_free (path);
- name = g_strndup (filename + 3,
- strlen(filename) - 13 - strlen(G_MODULE_SUFFIX));
+ if (reader == NULL)
+ {
+ g_warning ("Couldn't read '%s'\n", filename);
+ g_free (identifier);
+ return;
+ }
+
+ info = g_new0 (ExtensionInfo, 1);
+ einfo = (EphyExtensionInfo *) info;
+ einfo->identifier = identifier;
+ g_datalist_init (&info->loader_attributes);
- if (g_hash_table_lookup (manager->priv->extensions, name) != NULL)
+ ret = xmlTextReaderRead (reader);
+
+ while (ret == 1)
{
- /* We already have another version stored */
- g_free (name);
+ const xmlChar *tag;
+ xmlReaderTypes type;
+
+ tag = xmlTextReaderConstName (reader);
+ type = xmlTextReaderNodeType (reader);
+
+ if (state == STATE_LOADER &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "attribute"))
+ {
+ xmlChar *name;
+
+ state = STATE_LOADER_ATTRIBUTE;
+
+ name = xmlTextReaderGetAttribute (reader, (const xmlChar *) "name");
+ attr_quark = g_quark_from_string ((const char *) name);
+ xmlFree (name);
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "author"))
+ {
+ state = STATE_AUTHOR;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "description"))
+ {
+ state = STATE_DESCRIPTION;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "gettext-domain"))
+ {
+ state = STATE_GETTEXT_DOMAIN;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "load-deferred"))
+ {
+ state = STATE_LOAD_DEFERRED;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "locale-directory"))
+ {
+ state = STATE_LOCALE_DIRECTORY;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "name"))
+ {
+ state = STATE_NAME;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "url"))
+ {
+ state = STATE_URL;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "version"))
+ {
+ state = STATE_VERSION;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "loader"))
+ {
+ state = STATE_LOADER;
+
+ info->loader_type = xmlTextReaderGetAttribute (reader, (const xmlChar *) "type");
+ }
+ else if (state == STATE_LOADER_ATTRIBUTE &&
+ type == XML_READER_TYPE_TEXT &&
+ attr_quark != 0)
+ {
+ xmlChar *value;
+
+ value = xmlTextReaderValue (reader);
+
+ g_datalist_id_set_data_full (&info->loader_attributes,
+ attr_quark, value,
+ (GDestroyNotify) xmlFree);
+ attr_quark = 0;
+ }
+ else if (state == STATE_LOADER_ATTRIBUTE &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "attribute"))
+ {
+ state = STATE_LOADER;
+ }
+ else if (state == STATE_AUTHOR &&
+ type == XML_READER_TYPE_TEXT)
+ {
+ einfo->authors = g_list_prepend
+ (einfo->authors, xmlTextReaderValue (reader));
+ }
+ else if (state == STATE_DESCRIPTION &&
+ type == XML_READER_TYPE_TEXT)
+ {
+
+ einfo->description = xmlTextReaderValue (reader);
+ }
+ else if (state == STATE_GETTEXT_DOMAIN &&
+ type == XML_READER_TYPE_TEXT)
+ {
+ info->gettext_domain = xmlTextReaderValue (reader);
+ }
+ else if (state == STATE_LOAD_DEFERRED &&
+ type == XML_READER_TYPE_TEXT)
+ {
+ const xmlChar *value;
+
+ value = xmlTextReaderConstValue (reader);
+ info->load_deferred =
+ (value != NULL && xmlStrEqual (value, (const xmlChar *) "true"));
+ }
+ else if (state == STATE_LOCALE_DIRECTORY &&
+ type == XML_READER_TYPE_TEXT)
+ {
+ info->locale_directory = xmlTextReaderValue (reader);
+ }
+ else if (state == STATE_NAME &&
+ type == XML_READER_TYPE_TEXT)
+ {
+ einfo->name = xmlTextReaderValue (reader);
+ }
+ else if (state == STATE_VERSION &&
+ type == XML_READER_TYPE_TEXT)
+ {
+ info->version = (guint) strtol ((const char *) xmlTextReaderConstValue (reader), NULL, 10);
+ }
+ else if (state == STATE_URL &&
+ type == XML_READER_TYPE_TEXT)
+ {
+ einfo->url = xmlTextReaderValue (reader);
+ }
+ else if (state == STATE_AUTHOR &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "author"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_DESCRIPTION &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "description"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_GETTEXT_DOMAIN &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "gettext-domain"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_LOCALE_DIRECTORY &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "locale-directory"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_LOADER &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "loader"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_NAME &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "name"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_URL &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "url"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_VERSION &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "version"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (type == XML_READER_TYPE_SIGNIFICANT_WHITESPACE ||
+ type == XML_READER_TYPE_WHITESPACE ||
+ type == XML_READER_TYPE_TEXT)
+ {
+ /* eat it */
+ }
+ else if (state == STATE_START &&
+ type == XML_READER_TYPE_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "extension"))
+ {
+ state = STATE_EXTENSION;
+ }
+ else if (state == STATE_EXTENSION &&
+ type == XML_READER_TYPE_END_ELEMENT &&
+ xmlStrEqual (tag, (const xmlChar *) "extension"))
+ {
+ state = STATE_STOP;
+ }
+ else
+ {
+ const xmlChar *content;
+
+ content = xmlTextReaderConstValue (reader);
+ g_warning ("tag '%s' of type %d in state %d with content '%s' was unexpected!",
+ tag, type, state, content ? (char *) content : "(null)");
+
+ state = STATE_ERROR;
+ break;
+ }
+
+ ret = xmlTextReaderRead (reader);
+ }
+
+ xmlFreeTextReader (reader);
+
+ /* sanity check */
+ if (ret < 0 || state != STATE_STOP ||
+ einfo->name == NULL || einfo->description == NULL ||
+ info->loader_type == NULL || info->loader_type[0] == '\0')
+ {
+ free_extension_info (info);
return;
}
- path = g_build_filename (dir, filename, NULL);
+ manager->priv->data = g_list_prepend (manager->priv->data, info);
+}
- info = g_new0 (ExtInfo, 1);
- info->loader = ephy_module_loader_new (path);
+static int
+find_loader (const LoaderInfo *info,
+ const char *type)
+{
+ return strcmp (info->type, type);
+}
- g_free (path);
+static EphyLoader *
+get_loader_for_type (EphyExtensionsManager *manager,
+ const char *type)
+{
+ LoaderInfo *info;
+ GList *l;
+
+ LOG ("Looking for loader for type '%s'", type)
- g_hash_table_insert (manager->priv->extensions, name, info);
+ l = g_list_find_custom (manager->priv->factories, type,
+ (GCompareFunc) find_loader);
+ if (l != NULL)
+ {
+ info = (LoaderInfo *) l->data;
+ return g_object_ref (info->loader);
+ }
+
+ if (strcmp (type, "shlib") == 0)
+ {
+ info = g_new (LoaderInfo, 1);
+ info->type = g_strdup (type);
+ info->loader = g_object_new (EPHY_TYPE_SHLIB_LOADER, NULL);
+
+ manager->priv->factories =
+ g_list_append (manager->priv->factories, info);
+
+ return g_object_ref (info->loader);
+ }
+
+ /* try to load a loader */
+ g_return_val_if_reached (NULL);
+
+ return NULL;
}
-/**
- * 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
+
+static void
+attach_window (EphyWindow *window,
+ EphyExtension *extension)
+{
+ ephy_extension_attach_window (extension, window);
+}
+
+static void
+load_extension (EphyExtensionsManager *manager,
+ ExtensionInfo *info)
+{
+
+ EphyLoader *loader;
+
+ g_return_if_fail (info->extension == NULL);
+
+ LOG ("Loading extension '%s'", info->info.identifier)
+
+ /* don't try again */
+ if (info->load_failed) return;
+
+ /* get a loader */
+ loader = get_loader_for_type (manager, info->loader_type);
+ if (loader == NULL)
+ {
+ g_warning ("No loader found for extension '%s' of type '%s'\n",
+ info->info.identifier, info->loader_type);
+ return;
+ }
+
+ info->loader = loader;
+
+ info->extension = ephy_loader_get_object (loader,
+ &info->loader_attributes);
+
+ if (info->extension != NULL)
+ {
+ manager->priv->extensions =
+ g_list_prepend (manager->priv->extensions,
+ g_object_ref (info->extension));
+
+ g_list_foreach (manager->priv->windows, (GFunc) attach_window,
+ info->extension);
+
+ info->info.active = TRUE;
+
+ g_signal_emit (manager, signals[CHANGED], 0, info);
+ }
+ else
+ {
+ info->load_failed = TRUE;
+ }
+}
+
+static void
+detach_window (EphyWindow *window,
+ EphyExtension *extension)
+{
+ ephy_extension_detach_window (extension, window);
+}
+
+static void
+unload_extension (EphyExtensionsManager *manager,
+ ExtensionInfo *info)
+{
+ g_return_if_fail (info->loader != NULL);
+ g_return_if_fail (info->extension != NULL || info->load_failed);
+
+ LOG ("Unloading extension '%s'", info->info.identifier)
+
+ if (info->load_failed) return;
+
+ g_list_foreach (manager->priv->windows, (GFunc) detach_window,
+ info->extension);
+
+ manager->priv->extensions =
+ g_list_remove (manager->priv->extensions, info->extension);
+
+ ephy_loader_release_object (info->loader, G_OBJECT (info->extension));
+ g_object_unref (info->extension);
+
+ info->info.active = FALSE;
+ info->extension = NULL;
+
+ g_signal_emit (manager, signals[CHANGED], 0, info);
+}
+
+static void
ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
const char *path)
{
DIR *d;
struct dirent *e;
+ LOG ("Scanning directory '%s'", path)
+
+ START_PROFILER ("Scanning directory")
+
d = opendir (path);
if (d == NULL)
{
@@ -375,11 +741,14 @@ ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
}
while ((e = readdir (d)) != NULL)
{
- ephy_extensions_manager_load_file (manager, path, e->d_name);
+ if (g_str_has_suffix (e->d_name, ".xml"))
+ {
+ ephy_extensions_manager_load_file (manager, path, e->d_name);
+ }
}
closedir (d);
- ephy_extensions_manager_sync_gconf (manager);
+ STOP_PROFILER ("Scanning directory")
}
static void
@@ -388,57 +757,91 @@ active_extensions_notifier (GConfClient *client,
GConfEntry *entry,
EphyExtensionsManager *manager)
{
- ephy_extensions_manager_sync_gconf (manager);
+ GSList *active_extensions;
+ GList *l;
+ gboolean active;
+ ExtensionInfo *info;
+
+ LOG ("Synching changed list of active extensions")
+
+ active_extensions = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS);
+
+ for (l = manager->priv->data; l != NULL; l = l->next)
+ {
+ info = (ExtensionInfo *) l->data;
+
+ active = (g_slist_find_custom (active_extensions,
+ info->info.identifier,
+ (GCompareFunc) strcmp) != NULL);
+
+ LOG ("Extension '%s' is %sactive and %sloaded",
+ info->info.identifier,
+ active ? "" : "not ",
+ info->info.active ? "" : "not ")
+
+ if (active != info->info.active)
+ {
+ if (active)
+ {
+ load_extension (manager, info);
+ }
+ else
+ {
+ unload_extension (manager, info);
+ }
+ }
+ }
+
+ g_slist_foreach (active_extensions, (GFunc) g_free, NULL);
+ g_slist_free (active_extensions);
}
static void
ephy_extensions_manager_init (EphyExtensionsManager *manager)
{
+ char *path;
+
manager->priv = EPHY_EXTENSIONS_MANAGER_GET_PRIVATE (manager);
LOG ("EphyExtensionsManager initialising")
- manager->priv->extensions = g_hash_table_new_full
- (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free, (GDestroyNotify) free_ext_info);
+ /* load the extensions descriptions */
+ path = g_build_filename (ephy_dot_dir (), "extensions", NULL);
+ ephy_extensions_manager_load_dir (manager, path);
+ g_free (path);
- manager->priv->internal_extensions = NULL;
+ ephy_extensions_manager_load_dir (manager, EXTENSIONS_DIR);
+ active_extensions_notifier (NULL, 0, NULL, manager);
manager->priv->active_extensions_notifier_id =
- eel_gconf_notification_add (CONF_LOADED_EXTENSIONS,
- (GConfClientNotifyFunc)
- active_extensions_notifier,
- manager);
+ eel_gconf_notification_add
+ (CONF_LOADED_EXTENSIONS,
+ (GConfClientNotifyFunc) active_extensions_notifier,
+ manager);
}
static void
ephy_extensions_manager_finalize (GObject *object)
{
EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (object);
+ EphyExtensionsManagerPrivate *priv = manager->priv;
LOG ("EphyExtensionsManager finalising")
- g_hash_table_destroy (manager->priv->extensions);
+ eel_gconf_notification_remove (manager->priv->active_extensions_notifier_id);
- g_slist_foreach (manager->priv->internal_extensions,
- (GFunc) g_object_unref, NULL);
- g_slist_free (manager->priv->internal_extensions);
+ g_list_foreach (priv->extensions, (GFunc) g_object_unref, NULL);
+ g_list_free (priv->extensions);
- eel_gconf_notification_remove
- (manager->priv->active_extensions_notifier_id);
+ g_list_foreach (priv->factories, (GFunc) free_loader_info, NULL);
+ g_list_free (priv->factories);
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
+ g_list_foreach (priv->data, (GFunc) free_extension_info, NULL);
+ g_list_free (priv->data);
-static void
-attach_window_to_info (const char *key,
- ExtInfo *info,
- EphyWindow *window)
-{
- if (info->extension)
- {
- ephy_extension_attach_window (info->extension, window);
- }
+ g_list_free (priv->windows);
+
+ parent_class->finalize (object);
}
static void
@@ -447,25 +850,12 @@ impl_attach_window (EphyExtension *extension,
{
EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
- LOG ("multiplexing attach_window")
+ LOG ("Attach")
- g_slist_foreach (manager->priv->internal_extensions,
- (GFunc) ephy_extension_attach_window, window);
+ g_list_foreach (manager->priv->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);
- }
+ manager->priv->windows = g_list_prepend (manager->priv->windows, window);
}
static void
@@ -474,16 +864,14 @@ impl_detach_window (EphyExtension *extension,
{
EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
- LOG ("multiplexing detach_window")
+ LOG ("Detach")
- g_object_ref (window);
+ manager->priv->windows = g_list_remove (manager->priv->windows, window);
- g_slist_foreach (manager->priv->internal_extensions,
- (GFunc) ephy_extension_detach_window, window);
+ g_object_ref (window);
- g_hash_table_foreach (manager->priv->extensions,
- (GHFunc) detach_window_from_info,
- window);
+ g_list_foreach (manager->priv->extensions,
+ (GFunc) ephy_extension_detach_window, window);
g_object_unref (window);
}
@@ -504,11 +892,16 @@ ephy_extensions_manager_class_init (EphyExtensionsManagerClass *class)
object_class->finalize = ephy_extensions_manager_finalize;
+ signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EphyExtensionsManagerClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER);
+
g_type_class_add_private (object_class, sizeof (EphyExtensionsManagerPrivate));
}
-
-EphyExtensionsManager *
-ephy_extensions_manager_new (void)
-{
- return EPHY_EXTENSIONS_MANAGER (g_object_new (EPHY_TYPE_EXTENSIONS_MANAGER, NULL));
-}
diff --git a/src/ephy-extensions-manager.h b/src/ephy-extensions-manager.h
index 3272ff320..d7bc81dcd 100644
--- a/src/ephy-extensions-manager.h
+++ b/src/ephy-extensions-manager.h
@@ -23,6 +23,7 @@
#define EPHY_EXTENSIONS_MANAGER_H
#include "ephy-extension.h"
+#include "ephy-node.h"
#include <glib.h>
#include <glib-object.h>
@@ -36,16 +37,30 @@ G_BEGIN_DECLS
#define EPHY_IS_EXTENSIONS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_EXTENSIONS_MANAGER))
#define EPHY_EXTENSIONS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerClass))
-typedef struct EphyExtensionsManager EphyExtensionsManager;
-typedef struct EphyExtensionsManagerClass EphyExtensionsManagerClass;
-typedef struct EphyExtensionsManagerPrivate EphyExtensionsManagerPrivate;
+typedef struct _EphyExtensionsManager EphyExtensionsManager;
+typedef struct _EphyExtensionsManagerClass EphyExtensionsManagerClass;
+typedef struct _EphyExtensionsManagerPrivate EphyExtensionsManagerPrivate;
-struct EphyExtensionsManagerClass
+typedef struct
+{
+ char *identifier;
+ char *name;
+ char *description;
+ GList *authors;
+ char *url;
+ gboolean active;
+} EphyExtensionInfo;
+
+struct _EphyExtensionsManagerClass
{
GObjectClass parent_class;
+
+ /* Signals */
+ void (* changed) (EphyExtensionsManager *manager,
+ EphyExtensionInfo *info);
};
-struct EphyExtensionsManager
+struct _EphyExtensionsManager
{
GObject parent_instance;
@@ -53,21 +68,18 @@ struct EphyExtensionsManager
EphyExtensionsManagerPrivate *priv;
};
-GType ephy_extensions_manager_get_type (void);
-
-EphyExtensionsManager *ephy_extensions_manager_new (void);
+GType ephy_extensions_manager_get_type (void);
-void ephy_extensions_manager_load (EphyExtensionsManager *manager,
- const char *filename);
+void ephy_extensions_manager_load (EphyExtensionsManager *manager,
+ const char *identifier);
-void ephy_extensions_manager_unload (EphyExtensionsManager *manager,
- const char *filename);
+void ephy_extensions_manager_unload (EphyExtensionsManager *manager,
+ const char *identifier);
-void ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
- const char *path);
+void ephy_extensions_manager_register (EphyExtensionsManager *manager,
+ GObject *object);
-EphyExtension *ephy_extensions_manager_add (EphyExtensionsManager *manager,
- GType type);
+GList *ephy_extensions_manager_get_extensions (EphyExtensionsManager *manager);
G_END_DECLS
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index b63f49e21..1e049bb3b 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -413,18 +413,27 @@ ephy_shell_finalize (GObject *object)
/* this will unload the extensions */
LOG ("Unref extension manager")
- g_object_unref (shell->priv->extensions_manager);
+ if (shell->priv->extensions_manager)
+ {
+ g_object_unref (shell->priv->extensions_manager);
+ }
+
+ LOG ("Unref session manager")
+ if (shell->priv->session)
+ {
+ g_object_unref (shell->priv->session);
+ }
LOG ("Unref toolbars model")
if (shell->priv->toolbars_model)
{
- g_object_unref (G_OBJECT (shell->priv->toolbars_model));
+ g_object_unref (shell->priv->toolbars_model);
}
LOG ("Unref fullscreen toolbars model")
if (shell->priv->fs_toolbars_model)
{
- g_object_unref (G_OBJECT (shell->priv->fs_toolbars_model));
+ g_object_unref (shell->priv->fs_toolbars_model);
}
LOG ("Unref Bookmarks Editor");
@@ -605,13 +614,12 @@ ephy_shell_get_session (EphyShell *shell)
{
EphyExtensionsManager *manager;
+ shell->priv->session = g_object_new (EPHY_TYPE_SESSION, NULL);
+
manager = EPHY_EXTENSIONS_MANAGER
(ephy_shell_get_extensions_manager (shell));
-
- /* Instantiate internal extensions */
- shell->priv->session =
- EPHY_SESSION (ephy_extensions_manager_add
- (manager, EPHY_TYPE_SESSION));
+ ephy_extensions_manager_register (manager,
+ G_OBJECT (shell->priv->session));
}
return G_OBJECT (shell->priv->session);
@@ -683,19 +691,9 @@ ephy_shell_get_extensions_manager (EphyShell *es)
if (es->priv->extensions_manager == NULL)
{
- char *path;
-
/* Instantiate extensions manager */
- es->priv->extensions_manager = ephy_extensions_manager_new ();
-
- /* load the extensions */
- 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);
+ es->priv->extensions_manager =
+ g_object_new (EPHY_TYPE_EXTENSIONS_MANAGER, NULL);
}
return G_OBJECT (es->priv->extensions_manager);