diff -r 000000000000 -r e4d67989cc36 glib/libgobject/src/gtypemodule.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glib/libgobject/src/gtypemodule.c Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,458 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 2000 Red Hat, Inc. + * Portions copyright (c) 2006 Nokia Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include "gtypeplugin.h" +#include "gtypemodule.h" +#include "gobjectalias.h" + +#ifdef __SYMBIAN32__ +#include +#endif /* __SYMBIAN32__ */ + +typedef struct _ModuleTypeInfo ModuleTypeInfo; +typedef struct _ModuleInterfaceInfo ModuleInterfaceInfo; + +struct _ModuleTypeInfo +{ + gboolean loaded; + GType type; + GType parent_type; + GTypeInfo info; +}; + +struct _ModuleInterfaceInfo +{ + gboolean loaded; + GType instance_type; + GType interface_type; + GInterfaceInfo info; +}; + +static void g_type_module_use_plugin (GTypePlugin *plugin); +static void g_type_module_complete_type_info (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table); +static void g_type_module_complete_interface_info (GTypePlugin *plugin, + GType instance_type, + GType interface_type, + GInterfaceInfo *info); + +#if EMULATOR + +PLS(parent_class ,gtypemodule,gpointer) +#define parent_class (*FUNCTION_NAME(parent_class,gtypemodule)()) + +#else + +static gpointer parent_class = NULL; + +#endif /* EMULATOR*/ +static void +g_type_module_dispose (GObject *object) +{ + GTypeModule *module = G_TYPE_MODULE (object); + + if (module->type_infos || module->interface_infos) + { + g_warning (G_STRLOC ": unsolicitated invocation of g_object_dispose() on GTypeModule"); + + g_object_ref (object); + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +g_type_module_finalize (GObject *object) +{ + GTypeModule *module = G_TYPE_MODULE (object); + + g_free (module->name); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +g_type_module_class_init (GTypeModuleClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class)); + + gobject_class->dispose = g_type_module_dispose; + gobject_class->finalize = g_type_module_finalize; +} + +static void +g_type_module_iface_init (GTypePluginClass *iface) +{ + iface->use_plugin = g_type_module_use_plugin; + iface->unuse_plugin = (void (*) (GTypePlugin *))g_type_module_unuse; + iface->complete_type_info = g_type_module_complete_type_info; + iface->complete_interface_info = g_type_module_complete_interface_info; +} + +#if EMULATOR + +PLS(type_module_type,g_type_module_get_type ,GType) +#define type_module_type (*FUNCTION_NAME(type_module_type,g_type_module_get_type )()) + +#endif /* EMULATOR */ + + +EXPORT_C GType +g_type_module_get_type (void) +{ + #if !(EMULATOR) + static GType type_module_type = 0; + #endif /* EMULATOR */ + + if (!type_module_type) + { + static const GTypeInfo type_module_info = { + sizeof (GTypeModuleClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) g_type_module_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GTypeModule), + 0, /* n_preallocs */ + NULL, /* instance_init */ + }; + static const GInterfaceInfo iface_info = { + (GInterfaceInitFunc) g_type_module_iface_init, + NULL, /* interface_finalize */ + NULL, /* interface_data */ + }; + + type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), &type_module_info, G_TYPE_FLAG_ABSTRACT); + + g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info); + } + + return type_module_type; +} + +#if EMULATOR +#undef type_module_type +#endif /* EMULATOR */ + + +EXPORT_C void +g_type_module_set_name (GTypeModule *module, + const gchar *name) +{ + g_return_if_fail (G_IS_TYPE_MODULE (module)); + + g_free (module->name); + module->name = g_strdup (name); +} + +static ModuleTypeInfo * +g_type_module_find_type_info (GTypeModule *module, + GType type) +{ + GSList *tmp_list = module->type_infos; + while (tmp_list) + { + ModuleTypeInfo *type_info = tmp_list->data; + if (type_info->type == type) + return type_info; + + tmp_list = tmp_list->next; + } + + return NULL; +} + +static ModuleInterfaceInfo * +g_type_module_find_interface_info (GTypeModule *module, + GType instance_type, + GType interface_type) +{ + GSList *tmp_list = module->interface_infos; + while (tmp_list) + { + ModuleInterfaceInfo *interface_info = tmp_list->data; + if (interface_info->instance_type == instance_type && + interface_info->interface_type == interface_type) + return interface_info; + + tmp_list = tmp_list->next; + } + + return NULL; +} + +EXPORT_C gboolean +g_type_module_use (GTypeModule *module) +{ + g_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE); + + module->use_count++; + if (module->use_count == 1) + { + GSList *tmp_list; + + if (!G_TYPE_MODULE_GET_CLASS (module)->load (module)) + { + module->use_count--; + return FALSE; + } + + tmp_list = module->type_infos; + while (tmp_list) + { + ModuleTypeInfo *type_info = tmp_list->data; + if (!type_info->loaded) + { + g_warning ("plugin '%s' failed to register type '%s'\n", + module->name ? module->name : "(unknown)", + g_type_name (type_info->type)); + return FALSE; + } + + tmp_list = tmp_list->next; + } + } + + return TRUE; +} + +EXPORT_C void +g_type_module_unuse (GTypeModule *module) +{ + g_return_if_fail (G_IS_TYPE_MODULE (module)); + g_return_if_fail (module->use_count > 0); + + module->use_count--; + + if (module->use_count == 0) + { + GSList *tmp_list; + + G_TYPE_MODULE_GET_CLASS (module)->unload (module); + + tmp_list = module->type_infos; + while (tmp_list) + { + ModuleTypeInfo *type_info = tmp_list->data; + type_info->loaded = FALSE; + + tmp_list = tmp_list->next; + } + } +} + +static void +g_type_module_use_plugin (GTypePlugin *plugin) +{ + GTypeModule *module = G_TYPE_MODULE (plugin); + + if (!g_type_module_use (module)) + { + g_warning ("Fatal error - Could not reload previously loaded plugin '%s'\n", + module->name ? module->name : "(unknown)"); + exit (1); + } +} + +static void +g_type_module_complete_type_info (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table) +{ + GTypeModule *module = G_TYPE_MODULE (plugin); + ModuleTypeInfo *module_type_info = g_type_module_find_type_info (module, g_type); + + *info = module_type_info->info; + + if (module_type_info->info.value_table) + *value_table = *module_type_info->info.value_table; +} + +static void +g_type_module_complete_interface_info (GTypePlugin *plugin, + GType instance_type, + GType interface_type, + GInterfaceInfo *info) +{ + GTypeModule *module = G_TYPE_MODULE (plugin); + ModuleInterfaceInfo *module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type); + + *info = module_interface_info->info; +} + +EXPORT_C GType +g_type_module_register_type (GTypeModule *module, + GType parent_type, + const gchar *type_name, + const GTypeInfo *type_info, + GTypeFlags flags) +{ + ModuleTypeInfo *module_type_info = NULL; + GType type; + + g_return_val_if_fail (module != NULL, 0); + g_return_val_if_fail (type_name != NULL, 0); + g_return_val_if_fail (type_info != NULL, 0); + + type = g_type_from_name (type_name); + if (type) + { + GTypePlugin *old_plugin = g_type_get_plugin (type); + + if (old_plugin != G_TYPE_PLUGIN (module)) + { + g_warning ("Two different plugins tried to register '%s'.", type_name); + return 0; + } + } + + if (type) + { + module_type_info = g_type_module_find_type_info (module, type); + + if (module_type_info->parent_type != parent_type) + { + const gchar *parent_type_name = g_type_name (parent_type); + + g_warning ("Type '%s' recreated with different parent type.\n" + "(was '%s', now '%s')", type_name, + g_type_name (module_type_info->parent_type), + parent_type_name ? parent_type_name : "(unknown)"); + return 0; + } + + if (module_type_info->info.value_table) + g_free ((GTypeValueTable *) module_type_info->info.value_table); + } + else + { + module_type_info = g_new (ModuleTypeInfo, 1); + + module_type_info->parent_type = parent_type; + module_type_info->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (module), flags); + + module->type_infos = g_slist_prepend (module->type_infos, module_type_info); + } + + module_type_info->loaded = TRUE; + module_type_info->info = *type_info; + if (type_info->value_table) + module_type_info->info.value_table = g_memdup (type_info->value_table, + sizeof (type_info->value_table)); + + return module_type_info->type; +} + +EXPORT_C void +g_type_module_add_interface (GTypeModule *module, + GType instance_type, + GType interface_type, + const GInterfaceInfo *interface_info) +{ + ModuleInterfaceInfo *module_interface_info = NULL; + + g_return_if_fail (module != NULL); + g_return_if_fail (interface_info != NULL); + + if (g_type_is_a (instance_type, interface_type)) + { + GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type, + interface_type); + + if (!old_plugin) + { + g_warning ("Interface '%s' for '%s' was previously registered statically or for a parent type.", + g_type_name (interface_type), g_type_name (instance_type)); + return; + } + else if (old_plugin != G_TYPE_PLUGIN (module)) + { + g_warning ("Two different plugins tried to register interface '%s' for '%s'.", + g_type_name (interface_type), g_type_name (instance_type)); + return; + } + + module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type); + + g_assert (module_interface_info); + } + else + { + module_interface_info = g_new (ModuleInterfaceInfo, 1); + + module_interface_info->instance_type = instance_type; + module_interface_info->interface_type = interface_type; + + g_type_add_interface_dynamic (instance_type, interface_type, G_TYPE_PLUGIN (module)); + + module->interface_infos = g_slist_prepend (module->interface_infos, module_interface_info); + } + + module_interface_info->loaded = TRUE; + module_interface_info->info = *interface_info; +} + +EXPORT_C GType +g_type_module_register_enum (GTypeModule *module, + const gchar *name, + const GEnumValue *const_static_values) +{ + GTypeInfo enum_type_info = { 0, }; + + g_return_val_if_fail (G_IS_TYPE_MODULE (module), 0); + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (const_static_values != NULL, 0); + + g_enum_complete_type_info (G_TYPE_ENUM, + &enum_type_info, const_static_values); + + return g_type_module_register_type (G_TYPE_MODULE (module), + G_TYPE_ENUM, name, &enum_type_info, 0); +} + +EXPORT_C GType +g_type_module_register_flags (GTypeModule *module, + const gchar *name, + const GFlagsValue *const_static_values) +{ + GTypeInfo flags_type_info = { 0, }; + + g_return_val_if_fail (G_IS_TYPE_MODULE (module), 0); + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (const_static_values != NULL, 0); + + g_flags_complete_type_info (G_TYPE_FLAGS, + &flags_type_info, const_static_values); + + return g_type_module_register_type (G_TYPE_MODULE (module), + G_TYPE_FLAGS, name, &flags_type_info, 0); +} + + +#define __G_TYPE_MODULE_C__ +#include "gobjectaliasdef.c"