From 611e5407571e19353a98292d953e90e63073ba61 Mon Sep 17 00:00:00 2001
From: Christian Persch <chpe@cvs.gnome.org>
Date: Sun, 17 Oct 2004 13:39:12 +0000
Subject: 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>
---
 lib/ephy-shlib-loader.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 256 insertions(+)
 create mode 100644 lib/ephy-shlib-loader.c

(limited to 'lib/ephy-shlib-loader.c')

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");
+}
-- 
cgit