From 611e5407571e19353a98292d953e90e63073ba61 Mon Sep 17 00:00:00 2001 From: Christian Persch 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 * 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 --- lib/Makefile.am | 9 +- lib/ephy-loader.c | 71 +++++++++++++ lib/ephy-loader.h | 66 ++++++++++++ lib/ephy-module-loader.c | 205 ------------------------------------- lib/ephy-module-loader.h | 47 --------- lib/ephy-module.c | 205 +++++++++++++++++++++++++++++++++++++ lib/ephy-module.h | 48 +++++++++ lib/ephy-shlib-loader.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++ lib/ephy-shlib-loader.h | 57 +++++++++++ 9 files changed, 709 insertions(+), 255 deletions(-) create mode 100644 lib/ephy-loader.c create mode 100644 lib/ephy-loader.h delete mode 100644 lib/ephy-module-loader.c delete mode 100644 lib/ephy-module-loader.h create mode 100644 lib/ephy-module.c create mode 100644 lib/ephy-module.h create mode 100644 lib/ephy-shlib-loader.c create mode 100644 lib/ephy-shlib-loader.h (limited to 'lib') 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 +#include + +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 - -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 *) ®ister_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 - -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 + +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 *) ®ister_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 + +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 + +#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 + +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 -- cgit v1.2.3