#include #include #include "gobject2gtk.h" void g2g_value_unset (GValue *value) { g_return_if_fail (value != NULL); if (value->type == GTK_TYPE_STRING) g_free (GTK_VALUE_STRING (*value)); memset (value, 0, sizeof (*value)); } // GObject dummy implementation static void g_object_set_arg(GtkObject *object, GtkArg *arg, guint id) { ((GObjectClass *)object->klass)->set_property((GObject *)object,id,arg,NULL); } static void g_object_get_arg(GtkObject *object, GtkArg *arg, guint id) { ((GObjectClass *)object->klass)->get_property((GObject *)object,id,arg,NULL); } static void g_object_base_class_init (GObjectClass *klass) { GtkObjectClass *gtkobject_class; gtkobject_class = (GtkObjectClass*) klass; gtkobject_class->set_arg = g_object_set_arg; gtkobject_class->get_arg = g_object_get_arg; } GType g2g_object_get_type (void) { static GType object_type = 0; if (!object_type) { static const GtkTypeInfo object_info = { "GObject", sizeof(GObject), sizeof(GObjectClass), (GtkClassInitFunc)NULL, (GtkObjectInitFunc)NULL, (GtkArgSetFunc)NULL, (GtkArgGetFunc)NULL, (GtkClassInitFunc)g_object_base_class_init, }; object_type = gtk_type_unique(gtk_object_get_type(),&object_info); } return object_type; } guint g2g_type_register_static (GtkType parent_type, gchar *type_name, const GTypeInfo *info, guint flags) { GtkTypeInfo gtkinfo = { type_name, info->instance_size, info->class_size, info->class_init, info->instance_init, NULL, NULL, info->base_init, }; return gtk_type_unique(parent_type,>kinfo); } gpointer g2g_object_new(GtkType type,gpointer blah_varargs_stuff) { return gtk_type_new(type); } void g2g_object_class_install_property(GObjectClass *oclass, guint property_id, GParamSpec *pspec) { GtkObjectClass *gtkoclass; gchar *arg_fullname; gtkoclass = GTK_OBJECT_CLASS (oclass); arg_fullname = g_strdup_printf("%s::%s",gtk_type_name(gtkoclass->type), pspec->name); //fprintf(stderr,"installing arg \"%s\" into class \"%s\"\n",arg_fullname,""); gtk_object_add_arg_type(arg_fullname,pspec->value_type,pspec->flags,property_id); g_free(pspec); } GParamSpec * g2g_object_class_find_property (GObjectClass *oclass, gchar *name) { GtkObjectClass *gtkclass; GtkArgInfo *info; GParamSpec *spec; gtkclass = GTK_OBJECT_CLASS (oclass); //fprintf(stderr,"class name is %s\n",gtk_type_name(class->type)); gtk_object_arg_get_info (gtkclass->type, name, &info); spec = g_new0(GParamSpec,1); if (info) { spec->name = name; spec->value_type = info->type; spec->flags = info->arg_flags; } else { spec->value_type = GTK_TYPE_NONE; } return spec; } GParamSpec ** g2g_object_class_list_properties(GObjectClass *oclass, guint *n_properties) { GtkObjectClass *gtkoclass; GType type = G_OBJECT_CLASS_TYPE (oclass); guint32 *flags; GtkArg *args; gint num_args; GParamSpec **params; int i; gtkoclass = GTK_OBJECT_CLASS (oclass); args = gtk_object_query_args (type, &flags, &num_args); // FIXME: args and flags need to be freed. params = g_new0(GParamSpec *,num_args); for (i=0;iname = args[i].name; params[i]->value_type = args[i].type; params[i]->flags = flags[i]; } *n_properties = num_args; return params; } static guint param_spec_pool_hash (gconstpointer key_spec) { const GParamSpec *key = key_spec; const gchar *p; guint h = key->owner_type; for (p = key->name; *p; p++) h = (h << 5) - h + *p; return h; } static gboolean param_spec_pool_equals (gconstpointer key_spec_1, gconstpointer key_spec_2) { const GParamSpec *key1 = key_spec_1; const GParamSpec *key2 = key_spec_2; return (key1->owner_type == key2->owner_type && strcmp (key1->name, key2->name) == 0); } GParamSpecPool* g2g_param_spec_pool_new (gboolean type_prefixing) { GParamSpecPool *pool = g_new0 (GParamSpecPool, 1); pool->hash_table = g_hash_table_new (param_spec_pool_hash, param_spec_pool_equals); return pool; } void g2g_param_spec_pool_insert (GParamSpecPool *pool, GParamSpec *pspec, GType owner_type) { if (pool && pspec && owner_type > 0 && pspec->owner_type == 0) { pspec->owner_type = owner_type; g_param_spec_ref (pspec); g_hash_table_insert (pool->hash_table, pspec, pspec); } else { g_return_if_fail (pool != NULL); g_return_if_fail (pspec); g_return_if_fail (owner_type > 0); g_return_if_fail (pspec->owner_type == 0); } } static inline GParamSpec* param_spec_ht_lookup (GHashTable *hash_table, const gchar *param_name, GType owner_type, gboolean walk_ancestors) { GParamSpec key, *pspec; key.owner_type = owner_type; key.name = (gchar*) param_name; if (walk_ancestors) do { pspec = g_hash_table_lookup (hash_table, &key); if (pspec) return pspec; key.owner_type = g_type_parent (key.owner_type); } while (key.owner_type); else pspec = g_hash_table_lookup (hash_table, &key); if (!pspec) { /* try canonicalized form */ key.name = g_strdup (param_name); key.owner_type = owner_type; if (walk_ancestors) do { pspec = g_hash_table_lookup (hash_table, &key); if (pspec) { g_free (key.name); return pspec; } key.owner_type = g_type_parent (key.owner_type); } while (key.owner_type); else pspec = g_hash_table_lookup (hash_table, &key); g_free (key.name); } return pspec; } GParamSpec* g2g_param_spec_pool_lookup (GParamSpecPool *pool, const gchar *param_name, GType owner_type, gboolean walk_ancestors) { GParamSpec *pspec; if (!pool || !param_name) { g_return_val_if_fail (pool != NULL, NULL); g_return_val_if_fail (param_name != NULL, NULL); } /* try quick and away, i.e. without prefix */ pspec = param_spec_ht_lookup (pool->hash_table, param_name, owner_type, walk_ancestors); return pspec; } GParamSpec * g2g_param_spec_boolean(gchar *name,gchar *nick,gchar *blurb,gboolean def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_BOOL; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_enum(gchar *name,gchar *nick,gchar *blurb,GtkType e,guint def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = e; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_int(gchar *name,gchar *nick,gchar *blurb,gint min,gint max,gint def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_INT; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_uint(gchar *name,gchar *nick,gchar *blurb,guint min,guint max,guint def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_UINT; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_long(gchar *name,gchar *nick,gchar *blurb,glong min,glong max,glong def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_LONG; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_ulong(gchar *name,gchar *nick,gchar *blurb,gulong min,gulong max,gulong def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_ULONG; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_float(gchar *name,gchar *nick,gchar *blurb,float min,float max,float def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_FLOAT; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_double(gchar *name,gchar *nick,gchar *blurb,double min,double max,double def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_DOUBLE; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_pointer(gchar *name,gchar *nick,gchar *blurb,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_POINTER; spec->flags = flags; return spec; } GParamSpec * g2g_param_spec_string(gchar *name,gchar *nick,gchar *blurb,gchar *def,gint flags) { GParamSpec *spec = g_new0 (GParamSpec,1); spec->name = name; spec->value_type = GTK_TYPE_STRING; spec->flags = flags; return spec; } void g2g_object_get_valist (GObject *object, const gchar *first_property_name, va_list var_args) { GtkObjectClass *objclass; char *name; objclass = GTK_OBJECT_CLASS (gtk_type_class (GTK_OBJECT_TYPE (object))); name = (char *)first_property_name; while (name) { GValue value = { 0, }; GParamSpec *pspec; gchar *error = NULL; pspec = g2g_object_class_find_property (G_OBJECT_CLASS (objclass), name); if (!pspec) break; g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); g_object_get_property (object, name, &value); G_VALUE_LCOPY (&value, var_args, 0, &error); if (error) { g_warning ("%s: %s", G_STRLOC, error); g_free (error); g_value_unset (&value); break; } g_value_unset (&value); name = va_arg (var_args, char *); } } void g2g_object_get (GObject *object, const gchar *first_property_name, ...) { GtkObject *gtkobj; va_list var_args; gtkobj = GTK_OBJECT (object); va_start (var_args, first_property_name); g2g_object_get_valist (object, first_property_name, var_args); va_end (var_args); } guint g2g_signal_new (const gchar *name, GtkType object_type, GtkSignalRunType signal_flags, guint function_offset, gpointer accumulator, // GSignalAccumulator gpointer accu_data, GtkSignalMarshaller marshaller, GType return_val, guint nparams, ...) { GtkType *params; guint i; va_list args; guint signal_id; #define MAX_SIGNAL_PARAMS (31) // from gtksignal.c g_return_val_if_fail (nparams < MAX_SIGNAL_PARAMS, 0); if (nparams > 0) { params = g_new (GtkType, nparams); va_start (args, nparams); for (i = 0; i < nparams; i++) params[i] = va_arg (args, GtkType); va_end (args); } else params = NULL; signal_id = gtk_signal_newv (name, signal_flags, object_type, function_offset, marshaller, return_val, nparams, params); g_free (params); // now register it. gtk_object_class_add_signals(gtk_type_class(object_type), &signal_id, 1); return signal_id; }