glib/libgobject/src/genums.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* GObject - GLib Type, Object, Parameter and Signal Library
       
     2  * Copyright (C) 1998-1999, 2000-2001 Tim Janik and 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
       
    16  * Public 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 /*
       
    22  * MT safe
       
    23  */
       
    24 
       
    25 #include        <string.h>
       
    26 
       
    27 #include	"genums.h"
       
    28 
       
    29 #include	"gvalue.h"
       
    30 #include	"gvaluecollector.h"
       
    31 
       
    32 #include	"gobjectalias.h"
       
    33 
       
    34 #ifdef __SYMBIAN32__
       
    35 #include <gobject_wsd.h>
       
    36 #endif /* __SYMBIAN32__ */
       
    37 
       
    38 
       
    39 /* --- prototypes --- */
       
    40 static void	g_enum_class_init		(GEnumClass	*class,
       
    41 						 gpointer	 class_data);
       
    42 static void	g_flags_class_init		(GFlagsClass	*class,
       
    43 						 gpointer	 class_data);
       
    44 static void	value_flags_enum_init		(GValue		*value);
       
    45 static void	value_flags_enum_copy_value	(const GValue	*src_value,
       
    46 						 GValue		*dest_value);
       
    47 static gchar*	value_flags_enum_collect_value  (GValue		*value,
       
    48 						 guint           n_collect_values,
       
    49 						 GTypeCValue    *collect_values,
       
    50 						 guint           collect_flags);
       
    51 static gchar*	value_flags_enum_lcopy_value	(const GValue	*value,
       
    52 						 guint           n_collect_values,
       
    53 						 GTypeCValue    *collect_values,
       
    54 						 guint           collect_flags);
       
    55 
       
    56 /* --- functions --- */
       
    57 #if EMULATOR
       
    58 
       
    59 PLS(initialized ,g_enum_types_init,gboolean)
       
    60 PLS(info,g_enum_types_init,GTypeInfo)
       
    61 
       
    62 #define initialized  (*FUNCTION_NAME(initialized ,g_enum_types_init)())
       
    63 #define info  (*FUNCTION_NAME(info ,g_enum_types_init)())
       
    64 
       
    65 const GTypeValueTable temp_flags_enum_value_table = {
       
    66     value_flags_enum_init,	    /* value_init */
       
    67     NULL,			    /* value_free */
       
    68     value_flags_enum_copy_value,    /* value_copy */
       
    69     NULL,			    /* value_peek_pointer */
       
    70     "i",			    /* collect_format */
       
    71     value_flags_enum_collect_value, /* collect_value */
       
    72     "p",			    /* lcopy_format */
       
    73     value_flags_enum_lcopy_value,   /* lcopy_value */
       
    74   };
       
    75 
       
    76 const GTypeInfo temp_info = {
       
    77     0,                          /* class_size */
       
    78     NULL,                       /* base_init */
       
    79     NULL,                       /* base_destroy */
       
    80     NULL,                       /* class_init */
       
    81     NULL,                       /* class_destroy */
       
    82     NULL,                       /* class_data */
       
    83     0,                          /* instance_size */
       
    84     0,                          /* n_preallocs */
       
    85     NULL,                       /* instance_init */
       
    86     &temp_flags_enum_value_table,    /* value_table */
       
    87   };
       
    88   
       
    89 #endif /* EMULATOR */
       
    90 
       
    91 void
       
    92 g_enum_types_init (void)
       
    93 {
       
    94   static const GTypeValueTable flags_enum_value_table = {
       
    95     value_flags_enum_init,	    /* value_init */
       
    96     NULL,			    /* value_free */
       
    97     value_flags_enum_copy_value,    /* value_copy */
       
    98     NULL,			    /* value_peek_pointer */
       
    99     "i",			    /* collect_format */
       
   100     value_flags_enum_collect_value, /* collect_value */
       
   101     "p",			    /* lcopy_format */
       
   102     value_flags_enum_lcopy_value,   /* lcopy_value */
       
   103   };
       
   104 
       
   105   #if !(EMULATOR)
       
   106   static gboolean initialized = FALSE;
       
   107   static GTypeInfo info = {
       
   108     0,                          /* class_size */
       
   109     NULL,                       /* base_init */
       
   110     NULL,                       /* base_destroy */
       
   111     NULL,                       /* class_init */
       
   112     NULL,                       /* class_destroy */
       
   113     NULL,                       /* class_data */
       
   114     0,                          /* instance_size */
       
   115     0,                          /* n_preallocs */
       
   116     NULL,                       /* instance_init */
       
   117     &flags_enum_value_table,    /* value_table */
       
   118   };
       
   119   #endif /*EMULATOR */
       
   120   
       
   121   static const GTypeFundamentalInfo finfo = {
       
   122     G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE,
       
   123   };
       
   124   GType type;
       
   125   
       
   126   g_return_if_fail (initialized == FALSE);
       
   127   initialized = TRUE;
       
   128   
       
   129   /* G_TYPE_ENUM
       
   130    */
       
   131   info.class_size = sizeof (GEnumClass);
       
   132   type = g_type_register_fundamental (G_TYPE_ENUM, g_intern_static_string ("GEnum"), &info, &finfo,
       
   133 				      G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
       
   134   g_assert (type == G_TYPE_ENUM);
       
   135   
       
   136   /* G_TYPE_FLAGS
       
   137    */
       
   138   info.class_size = sizeof (GFlagsClass);
       
   139   type = g_type_register_fundamental (G_TYPE_FLAGS, g_intern_static_string ("GFlags"), &info, &finfo,
       
   140 				      G_TYPE_FLAG_ABSTRACT | G_TYPE_FLAG_VALUE_ABSTRACT);
       
   141   g_assert (type == G_TYPE_FLAGS);
       
   142 }
       
   143 
       
   144 #if EMULATOR
       
   145 #undef initialized 
       
   146 #undef info
       
   147 #endif /* EMULATOR */
       
   148 
       
   149 static void
       
   150 value_flags_enum_init (GValue *value)
       
   151 {
       
   152   value->data[0].v_long = 0;
       
   153 }
       
   154 
       
   155 static void
       
   156 value_flags_enum_copy_value (const GValue *src_value,
       
   157 			     GValue	  *dest_value)
       
   158 {
       
   159   dest_value->data[0].v_long = src_value->data[0].v_long;
       
   160 }
       
   161 
       
   162 static gchar*
       
   163 value_flags_enum_collect_value (GValue      *value,
       
   164 				guint        n_collect_values,
       
   165 				GTypeCValue *collect_values,
       
   166 				guint        collect_flags)
       
   167 {
       
   168   value->data[0].v_long = collect_values[0].v_int;
       
   169 
       
   170   return NULL;
       
   171 }
       
   172 
       
   173 static gchar*
       
   174 value_flags_enum_lcopy_value (const GValue *value,
       
   175 			      guint         n_collect_values,
       
   176 			      GTypeCValue  *collect_values,
       
   177 			      guint         collect_flags)
       
   178 {
       
   179   gint *int_p = collect_values[0].v_pointer;
       
   180   
       
   181   if (!int_p)
       
   182     return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
       
   183   
       
   184   *int_p = value->data[0].v_long;
       
   185   
       
   186   return NULL;
       
   187 }
       
   188 
       
   189 EXPORT_C GType
       
   190 g_enum_register_static (const gchar	 *name,
       
   191 			const GEnumValue *const_static_values)
       
   192 {
       
   193   GTypeInfo enum_type_info = {
       
   194     sizeof (GEnumClass), /* class_size */
       
   195     NULL,                /* base_init */
       
   196     NULL,                /* base_finalize */
       
   197     (GClassInitFunc) g_enum_class_init,
       
   198     NULL,                /* class_finalize */
       
   199     NULL,                /* class_data */
       
   200     0,                   /* instance_size */
       
   201     0,                   /* n_preallocs */
       
   202     NULL,                /* instance_init */
       
   203     NULL,		 /* value_table */
       
   204   };
       
   205   GType type;
       
   206   
       
   207   g_return_val_if_fail (name != NULL, 0);
       
   208   g_return_val_if_fail (const_static_values != NULL, 0);
       
   209   
       
   210   enum_type_info.class_data = const_static_values;
       
   211   
       
   212   type = g_type_register_static (G_TYPE_ENUM, name, &enum_type_info, 0);
       
   213   
       
   214   return type;
       
   215 }
       
   216 
       
   217 EXPORT_C GType
       
   218 g_flags_register_static (const gchar	   *name,
       
   219 			 const GFlagsValue *const_static_values)
       
   220 {
       
   221   GTypeInfo flags_type_info = {
       
   222     sizeof (GFlagsClass), /* class_size */
       
   223     NULL,                 /* base_init */
       
   224     NULL,                 /* base_finalize */
       
   225     (GClassInitFunc) g_flags_class_init,
       
   226     NULL,                 /* class_finalize */
       
   227     NULL,                 /* class_data */
       
   228     0,                    /* instance_size */
       
   229     0,                    /* n_preallocs */
       
   230     NULL,                 /* instance_init */
       
   231     NULL,		  /* value_table */
       
   232   };
       
   233   GType type;
       
   234   
       
   235   g_return_val_if_fail (name != NULL, 0);
       
   236   g_return_val_if_fail (const_static_values != NULL, 0);
       
   237   
       
   238   flags_type_info.class_data = const_static_values;
       
   239   
       
   240   type = g_type_register_static (G_TYPE_FLAGS, name, &flags_type_info, 0);
       
   241   
       
   242   return type;
       
   243 }
       
   244 
       
   245 EXPORT_C void
       
   246 g_enum_complete_type_info (GType	     g_enum_type,
       
   247 			   GTypeInfo	    *info,
       
   248 			   const GEnumValue *const_values)
       
   249 {
       
   250   g_return_if_fail (G_TYPE_IS_ENUM (g_enum_type));
       
   251   g_return_if_fail (info != NULL);
       
   252   g_return_if_fail (const_values != NULL);
       
   253   
       
   254   info->class_size = sizeof (GEnumClass);
       
   255   info->base_init = NULL;
       
   256   info->base_finalize = NULL;
       
   257   info->class_init = (GClassInitFunc) g_enum_class_init;
       
   258   info->class_finalize = NULL;
       
   259   info->class_data = const_values;
       
   260 }
       
   261 
       
   262 EXPORT_C void
       
   263 g_flags_complete_type_info (GType	       g_flags_type,
       
   264 			    GTypeInfo	      *info,
       
   265 			    const GFlagsValue *const_values)
       
   266 {
       
   267   g_return_if_fail (G_TYPE_IS_FLAGS (g_flags_type));
       
   268   g_return_if_fail (info != NULL);
       
   269   g_return_if_fail (const_values != NULL);
       
   270   
       
   271   info->class_size = sizeof (GFlagsClass);
       
   272   info->base_init = NULL;
       
   273   info->base_finalize = NULL;
       
   274   info->class_init = (GClassInitFunc) g_flags_class_init;
       
   275   info->class_finalize = NULL;
       
   276   info->class_data = const_values;
       
   277 }
       
   278 
       
   279 static void
       
   280 g_enum_class_init (GEnumClass *class,
       
   281 		   gpointer    class_data)
       
   282 {
       
   283   g_return_if_fail (G_IS_ENUM_CLASS (class));
       
   284   
       
   285   class->minimum = 0;
       
   286   class->maximum = 0;
       
   287   class->n_values = 0;
       
   288   class->values = class_data;
       
   289   
       
   290   if (class->values)
       
   291     {
       
   292       GEnumValue *values;
       
   293       
       
   294       class->minimum = class->values->value;
       
   295       class->maximum = class->values->value;
       
   296       for (values = class->values; values->value_name; values++)
       
   297 	{
       
   298 	  class->minimum = MIN (class->minimum, values->value);
       
   299 	  class->maximum = MAX (class->maximum, values->value);
       
   300 	  class->n_values++;
       
   301 	}
       
   302     }
       
   303 }
       
   304 
       
   305 static void
       
   306 g_flags_class_init (GFlagsClass *class,
       
   307 		    gpointer	 class_data)
       
   308 {
       
   309   g_return_if_fail (G_IS_FLAGS_CLASS (class));
       
   310   
       
   311   class->mask = 0;
       
   312   class->n_values = 0;
       
   313   class->values = class_data;
       
   314   
       
   315   if (class->values)
       
   316     {
       
   317       GFlagsValue *values;
       
   318       
       
   319       for (values = class->values; values->value_name; values++)
       
   320 	{
       
   321 	  class->mask |= values->value;
       
   322 	  class->n_values++;
       
   323 	}
       
   324     }
       
   325 }
       
   326 
       
   327 EXPORT_C GEnumValue*
       
   328 g_enum_get_value_by_name (GEnumClass  *enum_class,
       
   329 			  const gchar *name)
       
   330 {
       
   331   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
       
   332   g_return_val_if_fail (name != NULL, NULL);
       
   333   
       
   334   if (enum_class->n_values)
       
   335     {
       
   336       GEnumValue *enum_value;
       
   337       
       
   338       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
       
   339 	if (strcmp (name, enum_value->value_name) == 0)
       
   340 	  return enum_value;
       
   341     }
       
   342   
       
   343   return NULL;
       
   344 }
       
   345 
       
   346 EXPORT_C GFlagsValue*
       
   347 g_flags_get_value_by_name (GFlagsClass *flags_class,
       
   348 			   const gchar *name)
       
   349 {
       
   350   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
       
   351   g_return_val_if_fail (name != NULL, NULL);
       
   352   
       
   353   if (flags_class->n_values)
       
   354     {
       
   355       GFlagsValue *flags_value;
       
   356       
       
   357       for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
       
   358 	if (strcmp (name, flags_value->value_name) == 0)
       
   359 	  return flags_value;
       
   360     }
       
   361   
       
   362   return NULL;
       
   363 }
       
   364 
       
   365 EXPORT_C GEnumValue*
       
   366 g_enum_get_value_by_nick (GEnumClass  *enum_class,
       
   367 			  const gchar *nick)
       
   368 {
       
   369   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
       
   370   g_return_val_if_fail (nick != NULL, NULL);
       
   371   
       
   372   if (enum_class->n_values)
       
   373     {
       
   374       GEnumValue *enum_value;
       
   375       
       
   376       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
       
   377 	if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
       
   378 	  return enum_value;
       
   379     }
       
   380   
       
   381   return NULL;
       
   382 }
       
   383 
       
   384 EXPORT_C GFlagsValue*
       
   385 g_flags_get_value_by_nick (GFlagsClass *flags_class,
       
   386 			   const gchar *nick)
       
   387 {
       
   388   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
       
   389   g_return_val_if_fail (nick != NULL, NULL);
       
   390   
       
   391   if (flags_class->n_values)
       
   392     {
       
   393       GFlagsValue *flags_value;
       
   394       
       
   395       for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
       
   396 	if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
       
   397 	  return flags_value;
       
   398     }
       
   399   
       
   400   return NULL;
       
   401 }
       
   402 
       
   403 EXPORT_C GEnumValue*
       
   404 g_enum_get_value (GEnumClass *enum_class,
       
   405 		  gint	      value)
       
   406 {
       
   407   g_return_val_if_fail (G_IS_ENUM_CLASS (enum_class), NULL);
       
   408   
       
   409   if (enum_class->n_values)
       
   410     {
       
   411       GEnumValue *enum_value;
       
   412       
       
   413       for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
       
   414 	if (enum_value->value == value)
       
   415 	  return enum_value;
       
   416     }
       
   417   
       
   418   return NULL;
       
   419 }
       
   420 
       
   421 EXPORT_C GFlagsValue*
       
   422 g_flags_get_first_value (GFlagsClass *flags_class,
       
   423 			 guint	      value)
       
   424 {
       
   425   g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL);
       
   426   
       
   427   if (flags_class->n_values)
       
   428     {
       
   429       GFlagsValue *flags_value;
       
   430 
       
   431       if (value == 0)
       
   432         {
       
   433           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
       
   434             if (flags_value->value == 0)
       
   435               return flags_value;
       
   436         }
       
   437       else
       
   438         {
       
   439           for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
       
   440             if (flags_value->value != 0 && (flags_value->value & value) == flags_value->value)
       
   441               return flags_value;
       
   442         }      
       
   443     }
       
   444   
       
   445   return NULL;
       
   446 }
       
   447 
       
   448 EXPORT_C void
       
   449 g_value_set_enum (GValue *value,
       
   450 		  gint    v_enum)
       
   451 {
       
   452   g_return_if_fail (G_VALUE_HOLDS_ENUM (value));
       
   453   
       
   454   value->data[0].v_long = v_enum;
       
   455 }
       
   456 
       
   457 EXPORT_C gint
       
   458 g_value_get_enum (const GValue *value)
       
   459 {
       
   460   g_return_val_if_fail (G_VALUE_HOLDS_ENUM (value), 0);
       
   461   
       
   462   return value->data[0].v_long;
       
   463 }
       
   464 
       
   465 EXPORT_C void
       
   466 g_value_set_flags (GValue *value,
       
   467 		   guint   v_flags)
       
   468 {
       
   469   g_return_if_fail (G_VALUE_HOLDS_FLAGS (value));
       
   470   
       
   471   value->data[0].v_ulong = v_flags;
       
   472 }
       
   473 
       
   474 EXPORT_C guint
       
   475 g_value_get_flags (const GValue *value)
       
   476 {
       
   477   g_return_val_if_fail (G_VALUE_HOLDS_FLAGS (value), 0);
       
   478   
       
   479   return value->data[0].v_ulong;
       
   480 }
       
   481 
       
   482 #define __G_ENUMS_C__
       
   483 #include "gobjectaliasdef.c"