diff --git a/ChangeLog b/ChangeLog index c310dfd22..4c66a5c24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2007-04-20 Mike Kestner + + * generator/CallbackGen.cs : switch to NativeCallbackSignature. + * generator/GenBase.cs : add NativeCallbackType member. + * generator/IGeneratable.cs : add NativeCallbackType member. + * generator/ManagedCallString.cs : add guarded post call struct + marshaling back to the native struct. + * generator/NativeCallbackSignature.cs : new parallel to ImportSignature + but using NativeCallbackType instead of MarshalType. + * generator/Signal.cs : switch vm and sig marshaler callbacks to + NativeCallbackSignature. Perform guarding post call struct marshaling + back to the native struct. + * generator/Parameters.cs : add NativeCallbackType member. + * generator/SimpleBase.cs : add NativeCallbackType member. + * generator/StructBase.cs : add NativeCallbackType member using IntPtr + to support NULL handling. + * gtk/NodeCellDataFunc.cs : update native marshaler sig. + 2007-04-17 Mike Kestner * gtk/Gtk.metadata : hide TreeModel.RowsReordered signal so we can do diff --git a/generator/CallbackGen.cs b/generator/CallbackGen.cs index a0388fe16..48dec9681 100644 --- a/generator/CallbackGen.cs +++ b/generator/CallbackGen.cs @@ -30,7 +30,7 @@ namespace GtkSharp.Generation { private Parameters parms; private Signature sig = null; - private ImportSignature isig = null; + private NativeCallbackSignature native_sig = null; private ReturnValue retval; private bool valid = true; @@ -92,7 +92,7 @@ namespace GtkSharp.Generation { string wrapper = Name + "Native"; string qualname = MarshalType; - isig = new ImportSignature (parms); + native_sig = new NativeCallbackSignature (parms); StreamWriter sw = gen_info.OpenStream (qualname); @@ -103,11 +103,11 @@ namespace GtkSharp.Generation { sw.WriteLine (); sw.WriteLine ("#region Autogenerated code"); sw.WriteLine ("\t[GLib.CDeclCallback]"); - sw.WriteLine ("\tinternal delegate " + retval.MarshalType + " " + wrapper + "(" + isig + ");"); + sw.WriteLine ("\tinternal delegate " + retval.MarshalType + " " + wrapper + "(" + native_sig + ");"); sw.WriteLine (); sw.WriteLine ("\tinternal class " + Name + "Wrapper {"); sw.WriteLine (); - sw.WriteLine ("\t\tpublic " + retval.MarshalType + " NativeCallback (" + isig + ")"); + sw.WriteLine ("\t\tpublic " + retval.MarshalType + " NativeCallback (" + native_sig + ")"); sw.WriteLine ("\t\t{"); sw.WriteLine ("\t\t\ttry {"); diff --git a/generator/GenBase.cs b/generator/GenBase.cs index d858407d0..7526fddc7 100644 --- a/generator/GenBase.cs +++ b/generator/GenBase.cs @@ -63,6 +63,12 @@ namespace GtkSharp.Generation { public abstract string MarshalType { get; } + public virtual string NativeCallbackType { + get { + return MarshalType; + } + } + public string Name { get { return elem.GetAttribute ("name"); diff --git a/generator/IGeneratable.cs b/generator/IGeneratable.cs index 001bc0afc..ae2e4f066 100644 --- a/generator/IGeneratable.cs +++ b/generator/IGeneratable.cs @@ -1,8 +1,9 @@ // GtkSharp.Generation.IGeneratable.cs - Interface to generate code for a type. // -// Author: Mike Kestner +// Author: Mike Kestner // // Copyright (c) 2001 Mike Kestner +// Copyright (c) 2007 Novell, Inc. // // This program is free software; you can redistribute it and/or // modify it under the terms of version 2 of the GNU General Public @@ -36,6 +37,10 @@ namespace GtkSharp.Generation { // signature when passing this generatable to unmanaged code string MarshalType {get;} + // The type to use in the native delegate signature when marshaling to + // managed code from a native callback. + string NativeCallbackType {get;} + // The type to use as the return type in an import signature when // receiving this generatable back from unmanaged code string MarshalReturnType {get;} diff --git a/generator/Makefile.am b/generator/Makefile.am index a753ff065..d1e0a3bb0 100644 --- a/generator/Makefile.am +++ b/generator/Makefile.am @@ -36,6 +36,7 @@ sources = \ MethodBase.cs \ MethodBody.cs \ Method.cs \ + NativeCallbackSignature.cs \ ObjectField.cs \ ObjectBase.cs \ ObjectGen.cs \ diff --git a/generator/ManagedCallString.cs b/generator/ManagedCallString.cs index e1a720936..dfecc4da5 100644 --- a/generator/ManagedCallString.cs +++ b/generator/ManagedCallString.cs @@ -94,7 +94,10 @@ namespace GtkSharp.Generation { Parameter p = parms [i] as Parameter; IGeneratable igen = p.Generatable; - ret += indent + p.Name + " = " + igen.CallByName ("my" + p.Name) + ";\n"; + if (igen is StructBase) + ret += indent + String.Format ("if ({0} != IntPtr.Zero) System.Runtime.InteropServices.Marshal.StructureToPtr (my{0}, {0}, false);\n", p.Name); + else + ret += indent + p.Name + " = " + igen.ToNativeReturn ("my" + p.Name) + ";\n"; } return ret; diff --git a/generator/NativeCallbackSignature.cs b/generator/NativeCallbackSignature.cs new file mode 100644 index 000000000..d62fb390c --- /dev/null +++ b/generator/NativeCallbackSignature.cs @@ -0,0 +1,58 @@ +// GtkSharp.Generation.NativeCallbackSignature.cs - The NativeCallbackSignature Generation Class. +// +// Author: Mike Kestner +// +// Copyright (c) 2007 Novell, Inc. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of version 2 of the GNU General Public +// License as published by the Free Software Foundation. +// +// This program 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 +// General Public License for more details. +// +// You should have received a copy of the GNU General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + + +namespace GtkSharp.Generation { + + using System; + using System.Collections; + + public class NativeCallbackSignature { + + Parameters parameters; + + public NativeCallbackSignature (Parameters parms) + { + parameters = parms; + } + + public override string ToString () + { + if (parameters.Count == 0) + return ""; + + string[] parms = new string [parameters.Count]; + for (int i = 0; i < parameters.Count; i++) { + Parameter p = parameters [i]; + + parms [i] = ""; + if (p.CType == "GError**") + parms [i] += "out "; + else if (p.PassAs != "") + parms [i] += p.PassAs + " "; + parms [i] += p.NativeCallbackType + " " + p.Name; + } + + string import_sig = String.Join (", ", parms); + return import_sig; + } + } +} + diff --git a/generator/Parameters.cs b/generator/Parameters.cs index 564b3678f..9d53b535e 100644 --- a/generator/Parameters.cs +++ b/generator/Parameters.cs @@ -155,6 +155,18 @@ namespace GtkSharp.Generation { } } + public string NativeCallbackType { + get { + string type = Generatable.NativeCallbackType; + if (type == "void") + type = "System.IntPtr"; + if (IsArray) { + type += "[]"; + type = type.Replace ("ref ", ""); + } + return type; + } + } public string Name { get { return SymbolTable.Table.MangleName (elem.GetAttribute("name")); diff --git a/generator/Signal.cs b/generator/Signal.cs index 7af990823..92c9c18b4 100644 --- a/generator/Signal.cs +++ b/generator/Signal.cs @@ -100,13 +100,10 @@ namespace GtkSharp.Generation { if (parms[i].PassAs != "") result += parms[i].PassAs + " "; - result += (parms[i].MarshalType + " arg" + i); + result += (parms[i].NativeCallbackType + " arg" + i); } result += ", IntPtr gch"; - result = result.Replace ("out ref", "out"); - result = result.Replace ("ref ref", "ref"); - return result; } } @@ -232,7 +229,9 @@ namespace GtkSharp.Generation { } else sw.WriteLine("\t\t\t\targs.Args[" + (idx - 1) + "] = " + p.FromNative ("arg" + idx) + ";"); } - if (p.PassAs != "") + if (igen is StructBase) + finish += "\t\t\t\tif (arg" + idx + " != IntPtr.Zero) System.Runtime.InteropServices.Marshal.StructureToPtr (args.Args[" + (idx-1) + "], arg" + idx + ", false);\n"; + else if (p.PassAs != "") finish += "\t\t\t\targ" + idx + " = " + igen.ToNativeReturn ("((" + p.CSType + ")args.Args[" + (idx - 1) + "])") + ";\n"; } sw.WriteLine("\t\t\t\t{0} handler = ({0}) sig.Handler;", EventHandlerQualifiedName); @@ -372,12 +371,12 @@ namespace GtkSharp.Generation { private void GenDefaultHandlerDelegate (StreamWriter sw, ClassBase implementor) { - ImportSignature isig = new ImportSignature (parms); + NativeCallbackSignature sig = new NativeCallbackSignature (parms); ManagedCallString call = new ManagedCallString (parms); sw.WriteLine ("\t\t[GLib.CDeclCallback]"); - sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + isig.ToString () + ");\n"); + sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + sig.ToString () + ");\n"); sw.WriteLine ("\t\tstatic {0} {1};\n", Name + "VMDelegate", Name + "VMCallback"); - sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + isig.ToString () + ")"); + sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + sig.ToString () + ")"); sw.WriteLine ("\t\t{"); sw.WriteLine ("\t\t\ttry {"); sw.WriteLine ("\t\t\t\t{0} {1}_managed = GLib.Object.GetObject ({1}, false) as {0};", implementor != null ? implementor.Name : container_type.Name, parms[0].Name); diff --git a/generator/SimpleBase.cs b/generator/SimpleBase.cs index b30513778..b9f145141 100644 --- a/generator/SimpleBase.cs +++ b/generator/SimpleBase.cs @@ -64,6 +64,12 @@ namespace GtkSharp.Generation { } } + public virtual string NativeCallbackType { + get { + return MarshalType; + } + } + public virtual string MarshalReturnType { get { return MarshalType; diff --git a/generator/StructBase.cs b/generator/StructBase.cs index bb056c361..57fc410a9 100644 --- a/generator/StructBase.cs +++ b/generator/StructBase.cs @@ -56,22 +56,25 @@ namespace GtkSharp.Generation { } public override string MarshalType { - get - { + get { return "ref " + QualifiedName; } } + public override string NativeCallbackType { + get { + return "IntPtr"; + } + } + public override string MarshalReturnType { - get - { + get { return "IntPtr"; } } public override string ToNativeReturnType { - get - { + get { return QualifiedName; } } @@ -91,18 +94,12 @@ namespace GtkSharp.Generation { } public override string FromNative(string var) - { - return var; - } - - public override string FromNativeReturn(string var) { return QualifiedName + ".New (" + var + ")"; } - + public override string ToNativeReturn(string var) { - // FIXME return var; } diff --git a/gtk/NodeCellDataFunc.cs b/gtk/NodeCellDataFunc.cs index e79bcf3d9..5c1b3b193 100644 --- a/gtk/NodeCellDataFunc.cs +++ b/gtk/NodeCellDataFunc.cs @@ -28,11 +28,12 @@ namespace Gtk { internal class NodeCellDataFuncWrapper { - public void NativeCallback (IntPtr tree_column, IntPtr cell, IntPtr tree_model, ref Gtk.TreeIter iter, IntPtr data) + public void NativeCallback (IntPtr tree_column, IntPtr cell, IntPtr tree_model, IntPtr iter_ptr, IntPtr data) { TreeViewColumn col = (Gtk.TreeViewColumn) GLib.Object.GetObject(tree_column); CellRenderer renderer = (Gtk.CellRenderer) GLib.Object.GetObject(cell); NodeStore store = (NodeStore) GLib.Object.GetObject(tree_model); + TreeIter iter = TreeIter.New (iter_ptr); managed (col, renderer, store.GetNode (iter)); }