diff --git a/ChangeLog b/ChangeLog index 529589859..0e9710bb5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2003-12-10 Mike Kestner + + * generator/CallbackGen.cs : kill ref_owned generation + * generator/ClassBase.cs : use simple GetObject w/o ref_owned + * generator/ManagedCallString.cs : new class to generate native + to managed method calls. + * generator/Method.cs : kill ref_owned generation + * generator/MethodBody.cs : kill ref_owned generation + * generator/Property.cs : kill ref_owned generation + * generator/Signal.cs : generate delegates and vtable connect + methods for all signals. Mark VMs with new attr. + * generator/StructBase.cs : kill ref_owned generation + * glib/DefaultSignalHandlerAttribute.cs : new attr to mark + virtual methods. + * glib/Object.cs : add overload for GetObject that defaults + to ref_owned=false. Add extern for VM override glue. + 2003-12-08 Luciano Martorella * gdk/Gdk.metadata : ref/array tags diff --git a/generator/CallbackGen.cs b/generator/CallbackGen.cs index a563c95c9..ab072d026 100644 --- a/generator/CallbackGen.cs +++ b/generator/CallbackGen.cs @@ -103,7 +103,6 @@ namespace GtkSharp.Generation { int count = (parms != null) ? parms.Count : 0; int idx = 0; bool need_sep = false; - bool need_ref_owned = true; string call_str = ""; string cleanup_str = ""; for (int i = 0; i < count; i++) @@ -119,10 +118,6 @@ namespace GtkSharp.Generation { string cstype = parms[i].CSType; ClassBase parm_wrapper = table.GetClassGen (ctype); - if (need_ref_owned && parm_wrapper != null && ((parm_wrapper is ObjectGen) || (parm_wrapper is InterfaceGen))) { - need_ref_owned = false; - sw.WriteLine("\t\t\tbool ref_owned = false;"); - } sw.Write("\t\t\t" + cstype + " _arg" + idx); if (parms[i].PassAs == "out") { sw.WriteLine(";"); diff --git a/generator/ClassBase.cs b/generator/ClassBase.cs index 436663dc4..08e6e8cc9 100644 --- a/generator/ClassBase.cs +++ b/generator/ClassBase.cs @@ -134,7 +134,7 @@ namespace GtkSharp.Generation { public virtual String FromNative(String var) { - return "(" + QualifiedName + ") GLib.Object.GetObject(" + var + ", ref_owned)"; + return "(" + QualifiedName + ") GLib.Object.GetObject(" + var + ")"; } public virtual String FromNativeReturn(String var) diff --git a/generator/ManagedCallString.cs b/generator/ManagedCallString.cs new file mode 100644 index 000000000..d5da388f1 --- /dev/null +++ b/generator/ManagedCallString.cs @@ -0,0 +1,45 @@ +// GtkSharp.Generation.ManagedCallString.cs - The ManagedCallString Class. +// +// Author: Mike Kestner +// +// (c) 2003 Mike Kestner + +namespace GtkSharp.Generation { + + using System; + using System.Collections; + using System.IO; + + public class ManagedCallString { + + ArrayList parms = new ArrayList (); + + public ManagedCallString (Parameters parms) + { + for (int i = 1; i < parms.Count; i ++) { + Parameter p = parms [i]; + if (p.IsLength && parms [i-1].IsString) + continue; + this.parms.Add (p); + } + } + + public override string ToString () + { + if (parms.Count < 1) + return ""; + + string[] result = new string [parms.Count]; + + for (int i = 0; i < parms.Count; i ++) { + Parameter p = parms [i] as Parameter; + IGeneratable igen = p.Generatable; + result [i] = igen is StructGen ? "ref " : (p.PassAs == "" ? "" : p.PassAs + " "); + result [i] += igen.FromNative (p.Name); + } + + return String.Join (", ", result); + } + } +} + diff --git a/generator/Method.cs b/generator/Method.cs index c3fdd989a..4efa871f9 100644 --- a/generator/Method.cs +++ b/generator/Method.cs @@ -353,8 +353,6 @@ namespace GtkSharp.Generation { if (table.IsObject (rettype) || table.IsOpaque (rettype)) { sw.WriteLine(m_ret + " raw_ret = " + cname + call + ";"); - if (table.IsObject (rettype)) - sw.WriteLine(indent + "\t\t\tbool ref_owned = false;"); sw.WriteLine(indent +"\t\t\t" + s_ret + " ret = " + table.FromNativeReturn(rettype, "raw_ret") + ";"); if (table.IsOpaque (rettype)) sw.WriteLine(indent + "\t\t\tif (ret == null) ret = new " + s_ret + "(raw_ret);"); @@ -365,8 +363,6 @@ namespace GtkSharp.Generation { string raw_parms = "raw_ret"; if (element_type != null) raw_parms += ", typeof (" + element_type + ")"; - if (table.IsInterface (rettype)) - sw.WriteLine(indent + "\t\t\tbool ref_owned = false;"); sw.WriteLine(s_ret + " ret = " + table.FromNativeReturn(rettype, raw_parms) + ";"); } } diff --git a/generator/MethodBody.cs b/generator/MethodBody.cs index 33505ec74..372e3ff55 100644 --- a/generator/MethodBody.cs +++ b/generator/MethodBody.cs @@ -140,7 +140,6 @@ namespace GtkSharp.Generation { if (parameters == null) return; - bool ref_owned_needed = true; for (int i = 0; i < parameters.Count; i++) { Parameter p = parameters [i]; @@ -149,10 +148,6 @@ namespace GtkSharp.Generation { } IGeneratable gen = p.Generatable; - if (ref_owned_needed && (gen is ObjectGen || gen is InterfaceGen) && p.PassAs == "out") { - ref_owned_needed = false; - sw.WriteLine(indent + "\t\t\tbool ref_owned = false;"); - } if (p.PassAs == "out" && (UsesHandle (gen) || p.CSType == "GLib.Value")) sw.WriteLine(indent + "\t\t\t" + p.Name + " = " + gen.FromNativeReturn (p.Name + "_handle") + ";"); diff --git a/generator/Property.cs b/generator/Property.cs index e385749c2..9364c5a4f 100644 --- a/generator/Property.cs +++ b/generator/Property.cs @@ -121,8 +121,6 @@ namespace GtkSharp.Generation { sw.WriteLine("\t\t\t\tGetProperty(" + cname + ", val);"); if (table.IsObject (c_type)) { sw.WriteLine("\t\t\t\tSystem.IntPtr raw_ret = (System.IntPtr) {0} val;", v_type); - if (table.IsObject (c_type)) - sw.WriteLine ("\t\t\t\tbool ref_owned = false;"); sw.WriteLine("\t\t\t\t" + cs_type + " ret = " + table.FromNativeReturn(c_type, "raw_ret") + ";"); if (!table.IsBoxed (c_type) && !table.IsObject (c_type)) sw.WriteLine("\t\t\t\tif (ret == null) ret = new " + cs_type + "(raw_ret);"); diff --git a/generator/Signal.cs b/generator/Signal.cs index de22cc157..04826c4f9 100644 --- a/generator/Signal.cs +++ b/generator/Signal.cs @@ -148,31 +148,33 @@ namespace GtkSharp.Generation { sw.Close (); } - private void GenVirtualMethod (StreamWriter sw) + private void GenVirtualMethod (StreamWriter sw, ClassBase implementor) { VMSignature vmsig = new VMSignature (parms); + sw.WriteLine ("\t\t[GLib.DefaultSignalHandler(Type=typeof(" + (implementor != null ? implementor.QualifiedName : container_type.QualifiedName) + "), ConnectionMethod=\"Override" + Name +"\")]"); sw.WriteLine ("\t\tprotected virtual {0} {1} ({2})", ReturnType, "On" + Name, vmsig.ToString ()); sw.WriteLine ("\t\t{"); if (!IsVoid) sw.WriteLine ("\t\t\tGLib.Value ret = new GLib.Value ();"); sw.WriteLine ("\t\t\tIntPtr[] args = new IntPtr [" + parms.Count + "];"); - sw.WriteLine ("\t\t\targs [0] = Handle;"); - sw.WriteLine ("\t\t\tGLib.Value[] vals = new GLib.Value [" + (parms.Count - 1) + "];"); + sw.WriteLine ("\t\t\tGLib.Value[] vals = new GLib.Value [" + parms.Count + "];"); + sw.WriteLine ("\t\t\tvals [0] = new GLib.Value (this);"); + sw.WriteLine ("\t\t\targs [0] = vals [0].Handle;"); string cleanup = ""; for (int i = 1; i < parms.Count; i++) { if (parms [i].PassAs == "out") { - sw.WriteLine ("\t\t\tvals [" + (i - 1) + "] = new GLib.Value ();"); - cleanup += "\t\t\t" + parms [i].Name + " = (" + parms [i].CSType + ") vals [" + (i - 1) + "];\n"; + sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value ();"); + cleanup += "\t\t\t" + parms [i].Name + " = (" + parms [i].CSType + ") vals [" + i + "];\n"; } else if (parms [i].IsLength && parms [i - 1].IsString) - sw.WriteLine ("\t\t\tvals [" + (i - 1) + "] = new GLib.Value (" + parms [i-1].Name + ".Length);"); + sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + parms [i-1].Name + ".Length);"); else - sw.WriteLine ("\t\t\tvals [" + (i - 1) + "] = new GLib.Value (" + parms [i].Name + ");"); + sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + parms [i].Name + ");"); - sw.WriteLine ("\t\t\targs [" + i + "] = vals [" + (i - 1) + "].Handle;"); + sw.WriteLine ("\t\t\targs [" + i + "] = vals [" + i + "].Handle;"); } - sw.WriteLine ("\t\t\tg_signal_chain_from_overridden (args, " + (IsVoid ? "IntPtr.Zero " : "ret.Handle ") + ");"); + sw.WriteLine ("\t\t\tg_signal_chain_from_overridden (args, " + (IsVoid ? "IntPtr.Zero" : "ret.Handle") + ");"); if (cleanup != "") sw.WriteLine (cleanup); if (!IsVoid) @@ -180,6 +182,27 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t}\n"); } + private void GenDefaultHandlerDelegate (StreamWriter sw, ClassBase implementor) + { + ImportSignature isig = new ImportSignature (parms, container_type.NS); + ManagedCallString call = new ManagedCallString (parms); + sw.WriteLine ("\t\tdelegate " + MarshalReturnType + " " + Name + "Delegate (" + isig.ToString () + ");\n"); + sw.WriteLine ("\t\tstatic {0} {1};\n", Name + "Delegate", Name + "Callback"); + sw.WriteLine ("\t\tstatic " + MarshalReturnType + " " + Name.ToLower() + "_cb (" + isig.ToString () + ")"); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\t{0} obj = GLib.Object.GetObject ({1}, false) as {0};", implementor != null ? implementor.Name : container_type.Name, parms[0].Name); + sw.Write ("\t\t\t{0}", IsVoid ? "" : "return "); + sw.WriteLine ("obj.{0} ({1});", "On" + Name, call.ToString ()); + sw.WriteLine ("\t\t}\n"); + string cname = "\"" + elem.GetAttribute("cname") + "\""; + sw.WriteLine ("\t\tprotected static void Override" + Name + " (uint gtype)"); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\tif (" + Name + "Callback == null)"); + sw.WriteLine ("\t\t\t\t" + Name + "Callback = new " + Name + "Delegate (" + Name.ToLower() + "_cb);"); + sw.WriteLine ("\t\t\tgtksharp_override_virtual_method (gtype, " + cname + ", " + Name + "Callback);"); + sw.WriteLine ("\t\t}\n"); + } + public void Generate (GenerationInfo gen_info, ClassBase implementor) { StreamWriter sw = gen_info.Writer; @@ -192,7 +215,8 @@ namespace GtkSharp.Generation { ns = implementor.NS; sig_handler.Generate (ns, gen_info); - GenVirtualMethod (sw); + GenDefaultHandlerDelegate (sw, implementor); + GenVirtualMethod (sw, implementor); string qual_marsh = ns + "Sharp." + sig_handler.Name; sw.WriteLine("\t\t[GLib.Signal("+ cname + ")]"); diff --git a/generator/StructBase.cs b/generator/StructBase.cs index e9c232b85..8fc59856d 100644 --- a/generator/StructBase.cs +++ b/generator/StructBase.cs @@ -179,7 +179,6 @@ namespace GtkSharp.Generation { sw.WriteLine (); sw.WriteLine ("\t\tpublic " + wrapped + " " + wrapped_name + " {"); sw.WriteLine ("\t\t\tget { "); - sw.WriteLine ("\t\t\t\tbool ref_owned = false;"); sw.WriteLine ("\t\t\t\t" + wrapped + " ret = " + table.FromNativeReturn(c_type, name) + ";"); sw.WriteLine ("\t\t\t\treturn ret;"); sw.WriteLine ("\t\t\t}"); diff --git a/glib/DefaultSignalHandlerAttribute.cs b/glib/DefaultSignalHandlerAttribute.cs new file mode 100644 index 000000000..98fbc94b2 --- /dev/null +++ b/glib/DefaultSignalHandlerAttribute.cs @@ -0,0 +1,40 @@ +// +// DefaultSignalHandlerAttribute.cs +// +// Author: Mike Kestner +// +// (C) 2003 Novell, Inc. +// + +namespace GLib { + + using System; + + public sealed class DefaultSignalHandlerAttribute : Attribute + { + private string method; + private Type type; + + public DefaultSignalHandlerAttribute () {} + + public string ConnectionMethod + { + get { + return method; + } + set { + method = value; + } + } + + public Type Type + { + get { + return type; + } + set { + type = value; + } + } + } +} diff --git a/glib/Object.cs b/glib/Object.cs index 839a8d6f0..3e451d235 100644 --- a/glib/Object.cs +++ b/glib/Object.cs @@ -136,6 +136,11 @@ namespace GLib { return obj; } + public static Object GetObject(IntPtr o) + { + return GetObject (o, false); + } + [DllImport("gtksharpglue")] static extern uint gtksharp_register_type (string name, uint parent_type); @@ -361,6 +366,9 @@ namespace GLib { g_object_set_property (Raw, name, val.Handle); } + [DllImport("gtksharpglue")] + protected static extern void gtksharp_override_virtual_method (uint gtype, string name, Delegate cb); + [DllImport("libgobject-2.0-0.dll")] protected static extern void g_signal_chain_from_overridden (IntPtr[] args, IntPtr retval);