diff --git a/ChangeLog b/ChangeLog index 963bece40..296bfd65e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2002-10-04 Vladimir Vukicevic + + * glib/ObjectManager.cs, glue/type.c: If there isn't + an exact match for a C GObject class (i.e. BluecurveStyle), + walk up the gobject type hierarchy until we find a type + that we do have a wrapper for, and return that. This means + that you'll always, worst-case, end up with a GObject. + + * glib/Value.cs, glue/value.c: Added default constructor + to GLib.Value() that creates a new value with a type of + INVALID, and changed the glue function to not call + gtk_type_init if INVALID is passed. + 2002-10-02 Vladimir Vukicevic * gtk/TreeView.custom: added TreeView Handle as argument diff --git a/glib/ObjectManager.cs b/glib/ObjectManager.cs index b6238211f..5d874e22c 100644 --- a/glib/ObjectManager.cs +++ b/glib/ObjectManager.cs @@ -26,10 +26,20 @@ namespace GtkSharp { mangled = (string)types[typename]; else mangled = GetExpected (typename); - Type t = Type.GetType (mangled); + + // if null, try to get a parent type if (t == null) + t = GetValidParentType (raw); + + if (t == null) { + // should never get reached since everything should end up at + // GObject. Perhaps throw an exception here instead? + Console.WriteLine ("*** Warning: No C# equivalent for class '" + typename + + "' found, returning null"); return null; + } + return (GLib.Object) Activator.CreateInstance (t, new object[] {raw}); } @@ -51,14 +61,54 @@ namespace GtkSharp { for (int i = 0; i < cname.Length; i++) { if (needs_dot && i > 0 && Char.IsUpper (cname[i])) { - ns = expected.ToString ().ToLower (); - expected.Append ('.'); + // check for initial "G" and mangle to "GLib" if so + // really only necessary for GObject + if (expected.Length == 1 && expected[0] == 'G') { + ns = "glib"; + expected = new StringBuilder ("GLib."); + } else { + ns = expected.ToString ().ToLower (); + expected.Append ('.'); + } needs_dot = false; } expected.Append (cname[i]); } expected.AppendFormat (",{0}-sharp", ns); - return expected.ToString (); + + string expected_string = expected.ToString (); + RegisterType (cname, expected_string); + return expected_string; + } + + [DllImport("gtksharpglue")] + static extern int gtksharp_get_type_id (IntPtr raw); + + [DllImport("gtksharpglue")] + static extern int gtksharp_get_parent_type (int typ); + + [DllImport("gtksharpglue")] + static extern string gtksharp_get_type_name_for_id (int typ); + + static Type GetValidParentType (IntPtr raw) + { + int type_id = gtksharp_get_type_id (raw); + string typename; + string mangled; + Type t; + // We will always end up at GObject and will break this loop + while (true) { + type_id = gtksharp_get_parent_type (type_id); + typename = gtksharp_get_type_name_for_id (type_id); + if (types.ContainsKey (typename)) + mangled = (string)types[typename]; + else + mangled = GetExpected (typename); + t = Type.GetType (mangled); + if (t != null) { + return t; + } + } } } } diff --git a/glib/Value.cs b/glib/Value.cs index c62c8e711..1e3888a67 100755 --- a/glib/Value.cs +++ b/glib/Value.cs @@ -51,6 +51,19 @@ namespace GLib { _val = val; } + /// + /// Value Constructor + /// + /// + /// + /// Constructs a new empty value that can be used + /// to receive "out" GValue parameters. + /// + + public Value () { + _val = gtksharp_value_create (TypeFundamentals.TypeInvalid); + } + /// /// Value Constructor /// diff --git a/glue/type.c b/glue/type.c index 5d39a2580..ec22e49b6 100644 --- a/glue/type.c +++ b/glue/type.c @@ -19,3 +19,20 @@ gtksharp_is_object (gpointer obj) return G_IS_OBJECT (obj); } +GType +gtksharp_get_type_id (GObject *obj) +{ + return G_TYPE_FROM_INSTANCE (obj); +} + +GType +gtksharp_get_parent_type (GType typ) +{ + return g_type_parent (typ); +} + +gchar * +gtksharp_get_type_name_for_id (GType typ) +{ + return g_type_name (typ); +} diff --git a/glue/value.c b/glue/value.c index 56dc72b99..af6cfe80e 100644 --- a/glue/value.c +++ b/glue/value.c @@ -11,7 +11,8 @@ GValue * gtksharp_value_create (GType g_type) { GValue *val = g_new0 (GValue, 1); - val = g_value_init (val, g_type); + if (g_type != G_TYPE_INVALID) + val = g_value_init (val, g_type); return val; }