glib/libgobject/src/gtypemodule.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* GObject - GLib Type, Object, Parameter and Signal Library
       
     2  * Copyright (C) 2000 Red Hat, Inc.
       
     3  * Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Lesser General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Lesser General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Lesser General Public
       
    16  * License along with this library; if not, write to the
       
    17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    18  * Boston, MA 02111-1307, USA.
       
    19  */
       
    20 
       
    21 #include <stdlib.h>
       
    22 
       
    23 #include "gtypeplugin.h"
       
    24 #include "gtypemodule.h"
       
    25 #include "gobjectalias.h"
       
    26 
       
    27 #ifdef __SYMBIAN32__
       
    28 #include <gobject_wsd.h>
       
    29 #endif /* __SYMBIAN32__ */
       
    30 
       
    31 typedef struct _ModuleTypeInfo ModuleTypeInfo;
       
    32 typedef struct _ModuleInterfaceInfo ModuleInterfaceInfo;
       
    33 
       
    34 struct _ModuleTypeInfo 
       
    35 {
       
    36   gboolean  loaded;
       
    37   GType     type;
       
    38   GType     parent_type;
       
    39   GTypeInfo info;
       
    40 };
       
    41 
       
    42 struct _ModuleInterfaceInfo 
       
    43 {
       
    44   gboolean       loaded;
       
    45   GType          instance_type;
       
    46   GType          interface_type;
       
    47   GInterfaceInfo info;
       
    48 };
       
    49 
       
    50 static void g_type_module_use_plugin              (GTypePlugin     *plugin);
       
    51 static void g_type_module_complete_type_info      (GTypePlugin     *plugin,
       
    52 						   GType            g_type,
       
    53 						   GTypeInfo       *info,
       
    54 						   GTypeValueTable *value_table);
       
    55 static void g_type_module_complete_interface_info (GTypePlugin     *plugin,
       
    56 						   GType            instance_type,
       
    57 						   GType            interface_type,
       
    58 						   GInterfaceInfo  *info);
       
    59 
       
    60 #if EMULATOR
       
    61 
       
    62 PLS(parent_class ,gtypemodule,gpointer)
       
    63 #define parent_class  (*FUNCTION_NAME(parent_class,gtypemodule)())
       
    64 
       
    65 #else
       
    66  
       
    67 static gpointer parent_class = NULL;
       
    68 
       
    69 #endif /* EMULATOR*/
       
    70 static void
       
    71 g_type_module_dispose (GObject *object)
       
    72 {
       
    73   GTypeModule *module = G_TYPE_MODULE (object);
       
    74   
       
    75   if (module->type_infos || module->interface_infos)
       
    76     {
       
    77       g_warning (G_STRLOC ": unsolicitated invocation of g_object_dispose() on GTypeModule");
       
    78 	     
       
    79       g_object_ref (object);
       
    80     }
       
    81 
       
    82   G_OBJECT_CLASS (parent_class)->dispose (object);
       
    83 }
       
    84 
       
    85 static void
       
    86 g_type_module_finalize (GObject *object)
       
    87 {
       
    88   GTypeModule *module = G_TYPE_MODULE (object);
       
    89 
       
    90   g_free (module->name);
       
    91 
       
    92   G_OBJECT_CLASS (parent_class)->finalize (object);
       
    93 }
       
    94 
       
    95 static void
       
    96 g_type_module_class_init (GTypeModuleClass *class)
       
    97 {
       
    98   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
       
    99 
       
   100   parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
       
   101   
       
   102   gobject_class->dispose = g_type_module_dispose;
       
   103   gobject_class->finalize = g_type_module_finalize;
       
   104 }
       
   105 
       
   106 static void
       
   107 g_type_module_iface_init (GTypePluginClass *iface)
       
   108 {
       
   109   iface->use_plugin = g_type_module_use_plugin;
       
   110   iface->unuse_plugin = (void (*) (GTypePlugin *))g_type_module_unuse;
       
   111   iface->complete_type_info = g_type_module_complete_type_info;
       
   112   iface->complete_interface_info = g_type_module_complete_interface_info;
       
   113 }
       
   114 
       
   115 #if EMULATOR
       
   116 
       
   117 PLS(type_module_type,g_type_module_get_type ,GType)
       
   118 #define type_module_type (*FUNCTION_NAME(type_module_type,g_type_module_get_type )())
       
   119 
       
   120 #endif /* EMULATOR */
       
   121 
       
   122 
       
   123 EXPORT_C GType
       
   124 g_type_module_get_type (void)
       
   125 {
       
   126   #if !(EMULATOR)
       
   127   static GType type_module_type = 0;
       
   128   #endif /* EMULATOR */
       
   129 
       
   130   if (!type_module_type)
       
   131     {
       
   132       static const GTypeInfo type_module_info = {
       
   133         sizeof (GTypeModuleClass),
       
   134         NULL,           /* base_init */
       
   135         NULL,           /* base_finalize */
       
   136         (GClassInitFunc) g_type_module_class_init,
       
   137         NULL,           /* class_finalize */
       
   138         NULL,           /* class_data */
       
   139         sizeof (GTypeModule),
       
   140         0,              /* n_preallocs */
       
   141         NULL,           /* instance_init */
       
   142       };
       
   143       static const GInterfaceInfo iface_info = {
       
   144         (GInterfaceInitFunc) g_type_module_iface_init,
       
   145         NULL,               /* interface_finalize */
       
   146         NULL,               /* interface_data */
       
   147       };
       
   148 
       
   149       type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), &type_module_info, G_TYPE_FLAG_ABSTRACT);
       
   150 
       
   151       g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info);
       
   152     }
       
   153   
       
   154   return type_module_type;
       
   155 }
       
   156 
       
   157 #if EMULATOR
       
   158 #undef  type_module_type
       
   159 #endif /* EMULATOR */
       
   160 
       
   161 
       
   162 EXPORT_C void
       
   163 g_type_module_set_name (GTypeModule  *module,
       
   164 			const gchar  *name)
       
   165 {
       
   166   g_return_if_fail (G_IS_TYPE_MODULE (module));
       
   167 
       
   168   g_free (module->name);
       
   169   module->name = g_strdup (name);
       
   170 }
       
   171 
       
   172 static ModuleTypeInfo *
       
   173 g_type_module_find_type_info (GTypeModule *module,
       
   174 			      GType        type)
       
   175 {
       
   176   GSList *tmp_list = module->type_infos;
       
   177   while (tmp_list)
       
   178     {
       
   179       ModuleTypeInfo *type_info = tmp_list->data;
       
   180       if (type_info->type == type)
       
   181 	return type_info;
       
   182       
       
   183       tmp_list = tmp_list->next;
       
   184     }
       
   185 
       
   186   return NULL;
       
   187 }
       
   188 
       
   189 static ModuleInterfaceInfo *
       
   190 g_type_module_find_interface_info (GTypeModule *module,
       
   191 				   GType        instance_type,
       
   192 				   GType        interface_type)
       
   193 {
       
   194   GSList *tmp_list = module->interface_infos;
       
   195   while (tmp_list)
       
   196     {
       
   197       ModuleInterfaceInfo *interface_info = tmp_list->data;
       
   198       if (interface_info->instance_type == instance_type &&
       
   199 	  interface_info->interface_type == interface_type)
       
   200 	return interface_info;
       
   201       
       
   202       tmp_list = tmp_list->next;
       
   203     }
       
   204 
       
   205   return NULL;
       
   206 }
       
   207 
       
   208 EXPORT_C gboolean
       
   209 g_type_module_use (GTypeModule *module)
       
   210 {
       
   211   g_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE);
       
   212 
       
   213   module->use_count++;
       
   214   if (module->use_count == 1)
       
   215     {
       
   216       GSList *tmp_list;
       
   217       
       
   218       if (!G_TYPE_MODULE_GET_CLASS (module)->load (module))
       
   219 	{
       
   220 	  module->use_count--;
       
   221 	  return FALSE;
       
   222 	}
       
   223 
       
   224       tmp_list = module->type_infos;
       
   225       while (tmp_list)
       
   226 	{
       
   227 	  ModuleTypeInfo *type_info = tmp_list->data;
       
   228 	  if (!type_info->loaded)
       
   229 	    {
       
   230 	      g_warning ("plugin '%s' failed to register type '%s'\n",
       
   231 			 module->name ? module->name : "(unknown)",
       
   232 			 g_type_name (type_info->type));
       
   233 	      return FALSE;
       
   234 	    }
       
   235 	  
       
   236 	  tmp_list = tmp_list->next;
       
   237 	}
       
   238     }
       
   239  
       
   240   return TRUE;
       
   241 }
       
   242 
       
   243 EXPORT_C void
       
   244 g_type_module_unuse (GTypeModule *module)
       
   245 {
       
   246   g_return_if_fail (G_IS_TYPE_MODULE (module));
       
   247   g_return_if_fail (module->use_count > 0);
       
   248 
       
   249   module->use_count--;
       
   250 
       
   251   if (module->use_count == 0)
       
   252     {
       
   253       GSList *tmp_list;
       
   254 
       
   255       G_TYPE_MODULE_GET_CLASS (module)->unload (module);
       
   256 
       
   257       tmp_list = module->type_infos;
       
   258       while (tmp_list)
       
   259 	{
       
   260 	  ModuleTypeInfo *type_info = tmp_list->data;
       
   261 	  type_info->loaded = FALSE;
       
   262 
       
   263 	  tmp_list = tmp_list->next;
       
   264 	}
       
   265     }
       
   266 }
       
   267 	
       
   268 static void
       
   269 g_type_module_use_plugin (GTypePlugin *plugin)
       
   270 {
       
   271   GTypeModule *module = G_TYPE_MODULE (plugin);
       
   272 
       
   273   if (!g_type_module_use (module))
       
   274     {
       
   275       g_warning ("Fatal error - Could not reload previously loaded plugin '%s'\n",
       
   276 		 module->name ? module->name : "(unknown)");
       
   277       exit (1);
       
   278     }
       
   279 }
       
   280 
       
   281 static void
       
   282 g_type_module_complete_type_info (GTypePlugin     *plugin,
       
   283 				  GType            g_type,
       
   284 				  GTypeInfo       *info,
       
   285 				  GTypeValueTable *value_table)
       
   286 {
       
   287   GTypeModule *module = G_TYPE_MODULE (plugin);
       
   288   ModuleTypeInfo *module_type_info = g_type_module_find_type_info (module, g_type);
       
   289 
       
   290   *info = module_type_info->info;
       
   291   
       
   292   if (module_type_info->info.value_table)
       
   293     *value_table = *module_type_info->info.value_table;
       
   294 }
       
   295 
       
   296 static void 
       
   297 g_type_module_complete_interface_info (GTypePlugin    *plugin,
       
   298 				       GType           instance_type,
       
   299 				       GType           interface_type,
       
   300 				       GInterfaceInfo *info)
       
   301 {
       
   302   GTypeModule *module = G_TYPE_MODULE (plugin);
       
   303   ModuleInterfaceInfo *module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
       
   304 
       
   305   *info = module_interface_info->info;
       
   306 }
       
   307 
       
   308 EXPORT_C GType
       
   309 g_type_module_register_type (GTypeModule     *module,
       
   310 			     GType            parent_type,
       
   311 			     const gchar     *type_name,
       
   312 			     const GTypeInfo *type_info,
       
   313 			     GTypeFlags       flags)
       
   314 {
       
   315   ModuleTypeInfo *module_type_info = NULL;
       
   316   GType type;
       
   317   
       
   318   g_return_val_if_fail (module != NULL, 0);
       
   319   g_return_val_if_fail (type_name != NULL, 0);
       
   320   g_return_val_if_fail (type_info != NULL, 0);
       
   321 
       
   322   type = g_type_from_name (type_name);
       
   323   if (type)
       
   324     {
       
   325       GTypePlugin *old_plugin = g_type_get_plugin (type);
       
   326 
       
   327       if (old_plugin != G_TYPE_PLUGIN (module))
       
   328 	{
       
   329 	  g_warning ("Two different plugins tried to register '%s'.", type_name);
       
   330 	  return 0;
       
   331 	}
       
   332     }
       
   333 
       
   334   if (type)
       
   335     {
       
   336       module_type_info = g_type_module_find_type_info (module, type);
       
   337 
       
   338       if (module_type_info->parent_type != parent_type)
       
   339 	{
       
   340 	  const gchar *parent_type_name = g_type_name (parent_type);
       
   341 	  
       
   342 	  g_warning ("Type '%s' recreated with different parent type.\n"
       
   343 		     "(was '%s', now '%s')", type_name,
       
   344 		     g_type_name (module_type_info->parent_type),
       
   345 		     parent_type_name ? parent_type_name : "(unknown)");
       
   346 	  return 0;
       
   347 	}
       
   348 
       
   349       if (module_type_info->info.value_table)
       
   350 	g_free ((GTypeValueTable *) module_type_info->info.value_table);
       
   351     }
       
   352   else
       
   353     {
       
   354       module_type_info = g_new (ModuleTypeInfo, 1);
       
   355       
       
   356       module_type_info->parent_type = parent_type;
       
   357       module_type_info->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (module), flags);
       
   358       
       
   359       module->type_infos = g_slist_prepend (module->type_infos, module_type_info);
       
   360     }
       
   361 
       
   362   module_type_info->loaded = TRUE;
       
   363   module_type_info->info = *type_info;
       
   364   if (type_info->value_table)
       
   365     module_type_info->info.value_table = g_memdup (type_info->value_table,
       
   366 						   sizeof (type_info->value_table));
       
   367 
       
   368   return module_type_info->type;
       
   369 }
       
   370 
       
   371 EXPORT_C void
       
   372 g_type_module_add_interface (GTypeModule          *module,
       
   373 			     GType                 instance_type,
       
   374 			     GType                 interface_type,
       
   375 			     const GInterfaceInfo *interface_info)
       
   376 {
       
   377   ModuleInterfaceInfo *module_interface_info = NULL;
       
   378   
       
   379   g_return_if_fail (module != NULL);
       
   380   g_return_if_fail (interface_info != NULL);
       
   381 
       
   382   if (g_type_is_a (instance_type, interface_type))
       
   383     {
       
   384       GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type,
       
   385 							     interface_type);
       
   386 
       
   387       if (!old_plugin)
       
   388 	{
       
   389 	  g_warning ("Interface '%s' for '%s' was previously registered statically or for a parent type.",
       
   390 		     g_type_name (interface_type), g_type_name (instance_type));
       
   391 	  return;
       
   392 	}
       
   393       else if (old_plugin != G_TYPE_PLUGIN (module))
       
   394 	{
       
   395 	  g_warning ("Two different plugins tried to register interface '%s' for '%s'.",
       
   396 		     g_type_name (interface_type), g_type_name (instance_type));
       
   397 	  return;
       
   398 	}
       
   399       
       
   400       module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
       
   401 
       
   402       g_assert (module_interface_info);
       
   403     }
       
   404   else
       
   405     {
       
   406       module_interface_info = g_new (ModuleInterfaceInfo, 1);
       
   407       
       
   408       module_interface_info->instance_type = instance_type;
       
   409       module_interface_info->interface_type = interface_type;
       
   410       
       
   411       g_type_add_interface_dynamic (instance_type, interface_type, G_TYPE_PLUGIN (module));
       
   412       
       
   413       module->interface_infos = g_slist_prepend (module->interface_infos, module_interface_info);
       
   414     }
       
   415   
       
   416   module_interface_info->loaded = TRUE;
       
   417   module_interface_info->info = *interface_info;
       
   418 }
       
   419 
       
   420 EXPORT_C GType
       
   421 g_type_module_register_enum (GTypeModule      *module,
       
   422                              const gchar      *name,
       
   423                              const GEnumValue *const_static_values)
       
   424 {
       
   425   GTypeInfo enum_type_info = { 0, };
       
   426 
       
   427   g_return_val_if_fail (G_IS_TYPE_MODULE (module), 0);
       
   428   g_return_val_if_fail (name != NULL, 0);
       
   429   g_return_val_if_fail (const_static_values != NULL, 0);
       
   430 
       
   431   g_enum_complete_type_info (G_TYPE_ENUM,
       
   432                              &enum_type_info, const_static_values);
       
   433 
       
   434   return g_type_module_register_type (G_TYPE_MODULE (module),
       
   435                                       G_TYPE_ENUM, name, &enum_type_info, 0);
       
   436 }
       
   437 
       
   438 EXPORT_C GType
       
   439 g_type_module_register_flags (GTypeModule      *module,
       
   440                              const gchar       *name,
       
   441                              const GFlagsValue *const_static_values)
       
   442 {
       
   443   GTypeInfo flags_type_info = { 0, };
       
   444 
       
   445   g_return_val_if_fail (G_IS_TYPE_MODULE (module), 0);
       
   446   g_return_val_if_fail (name != NULL, 0);
       
   447   g_return_val_if_fail (const_static_values != NULL, 0);
       
   448 
       
   449   g_flags_complete_type_info (G_TYPE_FLAGS,
       
   450                              &flags_type_info, const_static_values);
       
   451 
       
   452   return g_type_module_register_type (G_TYPE_MODULE (module),
       
   453                                       G_TYPE_FLAGS, name, &flags_type_info, 0);
       
   454 }
       
   455 
       
   456 
       
   457 #define __G_TYPE_MODULE_C__
       
   458 #include "gobjectaliasdef.c"