]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkarg.c
marshaller fixes.
[~andy/gtk] / gtk / gtkarg.c
index c61bc95d07d21be1cbf0b940073b34d5041b2471..20ba7cd025ff937f387b0660d6a875bfe3b6f577 100644 (file)
@@ -2,20 +2,28 @@
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * 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
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
+ * 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.
  */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
 #include <stdarg.h>
 #include <string.h>
 #include "gtkobject.h"
@@ -39,7 +47,7 @@ struct _GtkArgQueryData
 
 
 /* --- functions --- */
-void
+GtkArgInfo*
 gtk_arg_type_new_static (GtkType      base_class_type,
                         const gchar *arg_name,
                         guint        class_n_args_offset,
@@ -56,14 +64,14 @@ gtk_arg_type_new_static (GtkType      base_class_type,
   guint *n_args_p;
   gchar *p;
 
-  g_return_if_fail (arg_name != NULL);
-  g_return_if_fail (GTK_FUNDAMENTAL_TYPE (base_class_type) == GTK_TYPE_OBJECT);
-  g_return_if_fail (class_n_args_offset != 0);
-  g_return_if_fail (arg_info_hash_table != NULL);
-  g_return_if_fail (arg_type > GTK_TYPE_NONE);
-  g_return_if_fail (arg_id > 0);
-  g_return_if_fail ((arg_flags & GTK_ARG_READWRITE) != 0);
-  /* g_return_if_fail ((arg_flags & GTK_ARG_CHILD_ARG) == 0); */
+  g_return_val_if_fail (arg_name != NULL, NULL);
+  g_return_val_if_fail (GTK_TYPE_IS_OBJECT (base_class_type), NULL);
+  g_return_val_if_fail (class_n_args_offset != 0, NULL);
+  g_return_val_if_fail (arg_info_hash_table != NULL, NULL);
+  g_return_val_if_fail (arg_type > GTK_TYPE_NONE, NULL);
+  g_return_val_if_fail (arg_id > 0, NULL);
+  g_return_val_if_fail ((arg_flags & GTK_ARG_READWRITE) != 0, NULL);
+  /* g_return_val_if_fail ((arg_flags & GTK_ARG_CHILD_ARG) == 0, NULL); */
   
   arg_flags &= GTK_ARG_MASK;
 
@@ -71,7 +79,7 @@ gtk_arg_type_new_static (GtkType      base_class_type,
   if (!arg_part || (arg_part[0] != ':') || (arg_part[1] != ':'))
     {
       g_warning ("gtk_arg_type_new(): invalid arg name: \"%s\"\n", arg_name);
-      return;
+      return NULL;
     }
 
   class_offset = (guint) (arg_part - arg_name);
@@ -84,7 +92,7 @@ gtk_arg_type_new_static (GtkType      base_class_type,
       g_warning ("gtk_arg_type_new(): argument class in \"%s\" is not in the `%s' ancestry",
                 arg_name,
                 gtk_type_name (base_class_type));
-      return;
+      return NULL;
     }
 
   p = gtk_type_class (class_type);
@@ -102,6 +110,8 @@ gtk_arg_type_new_static (GtkType      base_class_type,
   info->seq_id = *n_args_p;
 
   g_hash_table_insert (arg_info_hash_table, info, info);
+
+  return info;
 }
 
 gchar*
@@ -204,7 +214,7 @@ gtk_arg_get_info (GtkType       object_type,
   else
     {
       otype = object_type;
-      while (!*info_p && GTK_FUNDAMENTAL_TYPE (otype) == GTK_TYPE_OBJECT)
+      while (!*info_p && GTK_TYPE_IS_OBJECT (otype))
        {
          GtkArgInfo info;
          
@@ -233,12 +243,12 @@ gtk_args_collect (GtkType   object_type,
                  GHashTable     *arg_info_hash_table,
                  GSList        **arg_list_p,
                  GSList        **info_list_p,
-                 gpointer        var_args_p)
+                 const gchar   *first_arg_name,
+                 va_list        var_args)
 {
   GSList *arg_list;
   GSList *info_list;
-  gchar *arg_name;
-  va_list *var_args = var_args_p;
+  const gchar *arg_name;
 
   g_return_val_if_fail (arg_list_p != NULL, NULL);
   *arg_list_p = NULL;
@@ -248,7 +258,7 @@ gtk_args_collect (GtkType     object_type,
 
   arg_list = NULL;
   info_list = NULL;
-  arg_name = va_arg (*var_args, gchar*);
+  arg_name = first_arg_name;
   while (arg_name)
     {
       GtkArgInfo *info = NULL;
@@ -262,8 +272,8 @@ gtk_args_collect (GtkType     object_type,
          info_list = g_slist_prepend (info_list, info);
 
          arg = gtk_arg_new (info->type);
-         arg->name = arg_name;
-         error = gtk_arg_collect_value (GTK_FUNDAMENTAL_TYPE (arg->type), arg, var_args);
+         arg->name = (gchar*) arg_name;
+         GTK_ARG_COLLECT_VALUE (arg, var_args, error);
          arg_list = g_slist_prepend (arg_list, arg);
        }
       if (error)
@@ -273,7 +283,7 @@ gtk_args_collect (GtkType     object_type,
          return error;
        }
 
-      arg_name = va_arg (*var_args, gchar*);
+      arg_name = va_arg (var_args, gchar*);
     }
 
   *arg_list_p = g_slist_reverse (arg_list);
@@ -405,24 +415,41 @@ gtk_arg_copy (GtkArg         *src_arg,
   dest_arg->type = src_arg->type;
   dest_arg->d = src_arg->d;
 
-  if (src_arg->type == GTK_TYPE_STRING)
+  if (GTK_FUNDAMENTAL_TYPE (src_arg->type) == GTK_TYPE_STRING)
     GTK_VALUE_STRING (*dest_arg) = g_strdup (GTK_VALUE_STRING (*src_arg));
 
   return dest_arg;
 }
 
 void
-gtk_arg_free (GtkArg        *arg,
-             gboolean       free_contents)
+gtk_arg_free (GtkArg  *arg,
+             gboolean free_contents)
 {
   g_return_if_fail (arg != NULL);
 
-  if (free_contents &&
-      GTK_FUNDAMENTAL_TYPE (arg->type) == GTK_TYPE_STRING)
-    g_free (GTK_VALUE_STRING (*arg));
+  if (free_contents)
+    gtk_arg_reset (arg);
   g_free (arg);
 }
 
+void
+gtk_arg_reset (GtkArg *arg)
+{
+  GtkType fundamental_type;
+
+  g_return_if_fail (arg != NULL);
+
+  fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type);
+
+  if (fundamental_type == GTK_TYPE_STRING)
+    {
+      g_free (GTK_VALUE_STRING (*arg));
+      arg->type = GTK_TYPE_INVALID;
+    }
+  else if (arg->type != GTK_TYPE_INVALID)
+    arg->type = GTK_TYPE_INVALID;
+}
+
 gint
 gtk_arg_info_equal (gconstpointer arg_info_1,
                    gconstpointer arg_info_2)
@@ -456,3 +483,157 @@ gtk_arg_info_hash (gconstpointer arg_info)
   
   return h;
 }
+
+gboolean
+gtk_arg_values_equal (const GtkArg *arg1,
+                     const GtkArg *arg2)
+{
+  GtkType fundamental_type;
+  gboolean equal;
+  
+  g_return_val_if_fail (arg1 != NULL, FALSE);
+  g_return_val_if_fail (arg2 != NULL, FALSE);
+  g_return_val_if_fail (GTK_FUNDAMENTAL_TYPE (arg1->type) ==
+                       GTK_FUNDAMENTAL_TYPE (arg2->type), FALSE);
+  
+  fundamental_type = GTK_FUNDAMENTAL_TYPE (arg1->type);
+  
+  switch (fundamental_type)
+    {
+    case GTK_TYPE_INVALID:
+      equal = TRUE;
+      break;
+    case GTK_TYPE_CHAR:
+      equal = GTK_VALUE_CHAR (*arg1) == GTK_VALUE_CHAR (*arg2);
+      break;
+    case GTK_TYPE_BOOL:
+      equal = (GTK_VALUE_BOOL (*arg1) != FALSE) == (GTK_VALUE_BOOL (*arg2) != FALSE);
+      break;
+    case GTK_TYPE_INT:
+      equal = GTK_VALUE_INT (*arg1) == GTK_VALUE_INT (*arg2);
+      break;
+    case GTK_TYPE_UINT:
+      equal = GTK_VALUE_UINT (*arg1) == GTK_VALUE_UINT (*arg2);
+      break;
+    case GTK_TYPE_LONG:
+      equal = GTK_VALUE_LONG (*arg1) == GTK_VALUE_LONG (*arg2);
+      break;
+    case GTK_TYPE_ULONG:
+      equal = GTK_VALUE_ULONG (*arg1) == GTK_VALUE_ULONG (*arg2);
+      break;
+    case GTK_TYPE_FLOAT:
+      equal = GTK_VALUE_FLOAT (*arg1) == GTK_VALUE_FLOAT (*arg2);
+      break;
+    case GTK_TYPE_DOUBLE:
+      equal = GTK_VALUE_DOUBLE (*arg1) == GTK_VALUE_DOUBLE (*arg2);
+      break;
+    case GTK_TYPE_STRING:
+      if (!GTK_VALUE_STRING (*arg1) ||
+         !GTK_VALUE_STRING (*arg2))
+       equal = GTK_VALUE_STRING (*arg1) == GTK_VALUE_STRING (*arg2);
+      else
+       equal = g_str_equal (GTK_VALUE_STRING (*arg1), GTK_VALUE_STRING (*arg2));
+      break;
+    case GTK_TYPE_ENUM:
+      equal = GTK_VALUE_ENUM (*arg1) == GTK_VALUE_ENUM (*arg2);
+      break;
+    case GTK_TYPE_FLAGS:
+      equal = GTK_VALUE_FLAGS (*arg1) == GTK_VALUE_FLAGS (*arg2);
+      break;
+    case GTK_TYPE_BOXED:
+      equal = GTK_VALUE_BOXED (*arg1) == GTK_VALUE_BOXED (*arg2);
+      break;
+    case G_TYPE_OBJECT:
+      equal = GTK_VALUE_OBJECT (*arg1) == GTK_VALUE_OBJECT (*arg2);
+      break;
+    case GTK_TYPE_POINTER:
+      equal = GTK_VALUE_POINTER (*arg1) == GTK_VALUE_POINTER (*arg2);
+      break;
+    default:
+      g_warning ("gtk_arg_values_equal() used with unknown type `%s'", gtk_type_name (arg1->type));
+      equal = FALSE;
+      break;
+    }
+  
+  return equal;
+}
+
+void
+gtk_arg_to_valueloc (GtkArg  *arg,
+                    gpointer value_pointer)
+{
+  GtkType fundamental_type;
+  
+  g_return_if_fail (arg != NULL);
+  g_return_if_fail (value_pointer != NULL);
+  
+  fundamental_type = GTK_FUNDAMENTAL_TYPE (arg->type);
+  
+  switch (fundamental_type)
+    {
+      gchar *p_char;
+      guchar *p_uchar;
+      gboolean *p_boolean;
+      gint *p_int;
+      guint *p_uint;
+      glong *p_long;
+      gulong *p_ulong;
+      gfloat *p_float;
+      gdouble *p_double;
+      gpointer *p_pointer;
+    case GTK_TYPE_CHAR:
+      p_char = value_pointer;
+      *p_char = GTK_VALUE_CHAR (*arg);
+      break;
+    case GTK_TYPE_UCHAR:
+      p_uchar = value_pointer;
+      *p_uchar = GTK_VALUE_UCHAR (*arg);
+      break;
+    case GTK_TYPE_BOOL:
+      p_boolean = value_pointer;
+      *p_boolean = GTK_VALUE_BOOL (*arg);
+      break;
+    case GTK_TYPE_INT:
+    case GTK_TYPE_ENUM:
+      p_int = value_pointer;
+      *p_int = GTK_VALUE_INT (*arg);
+      break;
+    case GTK_TYPE_UINT:
+    case GTK_TYPE_FLAGS:
+      p_uint = value_pointer;
+      *p_uint = GTK_VALUE_UINT (*arg);
+      break;
+    case GTK_TYPE_LONG:
+      p_long = value_pointer;
+      *p_long = GTK_VALUE_LONG (*arg);
+      break;
+    case GTK_TYPE_ULONG:
+      p_ulong = value_pointer;
+      *p_ulong = GTK_VALUE_ULONG (*arg);
+      break;
+    case GTK_TYPE_FLOAT:
+      p_float = value_pointer;
+      *p_float = GTK_VALUE_FLOAT (*arg);
+      break;
+    case GTK_TYPE_DOUBLE:
+      p_double = value_pointer;
+      *p_double = GTK_VALUE_DOUBLE (*arg);
+      break;
+    case GTK_TYPE_STRING:
+    case GTK_TYPE_POINTER:
+    case GTK_TYPE_BOXED:
+    case G_TYPE_OBJECT:
+      p_pointer = value_pointer;
+      *p_pointer = GTK_VALUE_POINTER (*arg);
+      break;
+    case GTK_TYPE_NONE:
+    case GTK_TYPE_INVALID:
+      /* it doesn't make much sense to retrive these values,
+       * they either are always read-only args, or require
+       * multiple pointers.
+       */
+      g_warning ("gtk_arg_fill_retloc(): unsupported argument type `%s'",
+                gtk_type_name (arg->type));
+      break;
+    }
+}