2007-08-13 Mike Kestner <mkestner@novell.com>

* generator/*.cs : switch to IntPtr marshaling for struct types
	in the managed to native direction.
	* gtk/*.custom : adjust to new gapi struct pinvoke sigs.

svn path=/trunk/gtk-sharp/; revision=83961
This commit is contained in:
Mike Kestner 2007-08-13 14:29:06 +00:00
parent d24e54974d
commit fc06f3829a
19 changed files with 204 additions and 177 deletions

View file

@ -1,3 +1,9 @@
2007-08-13 Mike Kestner <mkestner@novell.com>
* generator/*.cs : switch to IntPtr marshaling for struct types
in the managed to native direction.
* gtk/*.custom : adjust to new gapi struct pinvoke sigs.
2007-08-01 Mike Kestner <mkestner@novell.com>
* generator/CallbackGen.cs : use Parameters.NativeCallbackSignature.

View file

@ -91,6 +91,9 @@ namespace GtkSharp.Generation {
string wrapper = Name + "Native";
string qualname = MarshalType;
if (!Validate ())
return String.Empty;
StreamWriter sw = gen_info.OpenStream (qualname);
sw.WriteLine ("namespace " + NS + "Sharp {");
@ -100,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 + "(" + parms.NativeCallbackSignature + ");");
sw.WriteLine ("\tinternal delegate " + retval.MarshalType + " " + wrapper + "(" + parms.ImportSignature + ");");
sw.WriteLine ();
sw.WriteLine ("\tinternal class " + Name + "Wrapper {");
sw.WriteLine ();
sw.WriteLine ("\t\tpublic " + retval.MarshalType + " NativeCallback (" + parms.NativeCallbackSignature + ")");
sw.WriteLine ("\t\tpublic " + retval.MarshalType + " NativeCallback (" + parms.ImportSignature + ")");
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\ttry {");

View file

@ -281,8 +281,11 @@ namespace GtkSharp.Generation {
}
}
protected bool IgnoreMethod (Method method)
protected bool IgnoreMethod (Method method, ClassBase implementor)
{
if (implementor != null && implementor.QualifiedName != this.QualifiedName && method.IsStatic)
return true;
string mname = method.Name;
return ((method.IsSetter || (method.IsGetter && mname.StartsWith("Get"))) &&
((props != null) && props.ContainsKey(mname.Substring(3)) ||
@ -295,7 +298,7 @@ namespace GtkSharp.Generation {
return;
foreach (Method method in methods.Values) {
if (IgnoreMethod (method))
if (IgnoreMethod (method, implementor))
continue;
string oname = null, oprotection = null;
@ -449,5 +452,12 @@ namespace GtkSharp.Generation {
ctor.Generate (gen_info);
}
public virtual void Finish (StreamWriter sw, string indent)
{
}
public virtual void Prepare (StreamWriter sw, string indent)
{
}
}
}

View file

@ -159,11 +159,14 @@ namespace GtkSharp.Generation {
if (Getter != null) {
sw.Write (indent + "\tget ");
Getter.GenerateBody (gen_info, "\t");
Getter.GenerateBody (gen_info, container_type, "\t");
sw.WriteLine ("");
} else if (getterName != null) {
sw.WriteLine (indent + "\tget {");
sw.WriteLine (indent + "\t\treturn " + table.FromNativeReturn (ctype, getterName + " (" + container_type.CallByName () + ")") + ";");
container_type.Prepare (sw, indent + "\t\t");
sw.WriteLine (indent + "\t\t" + CSType + " result = " + table.FromNativeReturn (ctype, getterName + " (" + container_type.CallByName () + ")") + ";");
container_type.Finish (sw, indent + "\t\t");
sw.WriteLine (indent + "\t\treturn result;");
sw.WriteLine (indent + "\t}");
} else if (Readable && offsetName != null) {
sw.WriteLine (indent + "\tget {");
@ -181,11 +184,13 @@ namespace GtkSharp.Generation {
if (Setter != null) {
sw.Write (indent + "\tset ");
Setter.GenerateBody (gen_info, "\t");
Setter.GenerateBody (gen_info, container_type, "\t");
sw.WriteLine ("");
} else if (setterName != null) {
sw.WriteLine (indent + "\tset {");
container_type.Prepare (sw, indent + "\t\t");
sw.WriteLine (indent + "\t\t" + setterName + " (" + container_type.CallByName () + ", " + table.CallByName (ctype, "value") + ");");
container_type.Finish (sw, indent + "\t\t");
sw.WriteLine (indent + "\t}");
} else if (Writable && offsetName != null) {
sw.WriteLine (indent + "\tset {");

View file

@ -63,12 +63,6 @@ namespace GtkSharp.Generation {
public abstract string MarshalType { get; }
public virtual string NativeCallbackType {
get {
return MarshalType;
}
}
public string Name {
get {
return elem.GetAttribute ("name");

View file

@ -37,10 +37,6 @@ 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;}

View file

@ -287,7 +287,7 @@ namespace GtkSharp.Generation {
}
foreach (Method method in methods.Values) {
if (IgnoreMethod (method))
if (IgnoreMethod (method, this))
continue;
method.GenerateDecl (sw);
}

View file

@ -212,11 +212,12 @@ namespace GtkSharp.Generation {
public void Generate (GenerationInfo gen_info, ClassBase implementor)
{
if (!Validate ())
return;
Method comp = null;
gen_info.CurrentMember = Name;
if (implementor != null && IsStatic)
return;
/* we are generated by the get Method, if there is one */
if (is_set || is_get)
@ -253,10 +254,10 @@ namespace GtkSharp.Generation {
{
gen_info.Writer.Write ("\t\t\t");
gen_info.Writer.Write ((is_get) ? "get" : "set");
GenerateBody (gen_info, "\t");
GenerateBody (gen_info, implementor, "\t");
}
else
GenerateBody (gen_info, "");
GenerateBody (gen_info, implementor, "");
if (is_get || is_set)
{
@ -264,7 +265,7 @@ namespace GtkSharp.Generation {
{
gen_info.Writer.WriteLine ();
gen_info.Writer.Write ("\t\t\tset");
comp.GenerateBody (gen_info, "\t");
comp.GenerateBody (gen_info, implementor, "\t");
}
gen_info.Writer.WriteLine ();
gen_info.Writer.WriteLine ("\t\t}");
@ -277,10 +278,12 @@ namespace GtkSharp.Generation {
Statistics.MethodCount++;
}
public void GenerateBody (GenerationInfo gen_info, string indent)
public void GenerateBody (GenerationInfo gen_info, ClassBase implementor, string indent)
{
StreamWriter sw = gen_info.Writer;
sw.WriteLine(" {");
if (!IsStatic && implementor != null)
implementor.Prepare (sw, indent + "\t\t\t");
if (IsAccessor)
Body.InitAccessor (sw, Signature, indent);
Body.Initialize(gen_info, is_get, is_set, indent);
@ -294,6 +297,8 @@ namespace GtkSharp.Generation {
}
Body.Finish (sw, indent);
if (!IsStatic && implementor != null)
implementor.Finish (sw, indent + "\t\t\t");
Body.HandleException (sw, indent);
if (is_get && Parameters.Count > 0)

View file

@ -155,11 +155,11 @@ namespace GtkSharp.Generation {
}
}
public string MarshalType {
public virtual string MarshalType {
get {
string type = SymbolTable.Table.GetMarshalType( elem.GetAttribute("type"));
if (type == "void")
type = "System.IntPtr";
if (type == "void" || Generatable is IManualMarshaler)
type = "IntPtr";
if (IsArray) {
type += "[]";
type = type.Replace ("ref ", "");
@ -168,18 +168,6 @@ 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"));
@ -192,17 +180,6 @@ namespace GtkSharp.Generation {
}
}
public virtual string NativeCallbackSignature {
get {
string sig = NativeCallbackType + " " + Name;
if (PassAs != String.Empty && !(Generatable is StructBase))
sig = PassAs + " " + sig;
sig = sig.Replace ("out ref", "out");
sig = sig.Replace ("ref ref", "ref");
return sig;
}
}
public virtual string NativeSignature {
get {
string sig = MarshalType + " " + Name;
@ -259,7 +236,7 @@ namespace GtkSharp.Generation {
get {
IGeneratable gen = Generatable;
if (gen is IManualMarshaler) {
string result = " IntPtr native_" + CallName;
string result = "IntPtr native_" + CallName;
if (PassAs != "out")
result += " = " + (gen as IManualMarshaler).AllocNative (CallName);
return new string [] { result + ";" };
@ -279,7 +256,7 @@ namespace GtkSharp.Generation {
return SymbolTable.Table.CallByName (CType, CallName + "_wrapper");
else if (PassAs != String.Empty) {
call_parm = PassAs + " ";
if (CSType != MarshalType && !(gen is StructBase || gen is ByRefGen))
if (CSType != MarshalType && !(gen is ByRefGen))
call_parm += "native_";
call_parm += CallName;
} else if (gen is IManualMarshaler)
@ -336,6 +313,15 @@ namespace GtkSharp.Generation {
public ArrayParameter (XmlElement elem) : base (elem) {}
public override string MarshalType {
get {
if (Generatable is StructBase)
return CSType;
else
return base.MarshalType;
}
}
public override string[] Prepare {
get {
if (CSType == MarshalType)
@ -365,6 +351,9 @@ namespace GtkSharp.Generation {
public override string[] Finish {
get {
if (CSType == MarshalType)
return new string [0];
IGeneratable gen = Generatable;
if (gen is IManualMarshaler) {
string [] result = new string [4];
@ -453,46 +442,57 @@ namespace GtkSharp.Generation {
}
}
public class StructParameter : Parameter {
public StructParameter (XmlElement elem) : base (elem) {}
public override string MarshalType {
get {
return "IntPtr";
}
}
public override string[] Prepare {
get {
if (PassAs == "out")
return new string [] { "IntPtr native_" + CallName + " = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (" + Generatable.QualifiedName + ")));"};
else
return new string [] { "IntPtr native_" + CallName + " = " + (Generatable as IManualMarshaler).AllocNative (CallName) + ";"};
}
}
public override string CallString {
get {
return "native_" + CallName;
}
}
public override string[] Finish {
get {
string[] result = new string [2];
result [0] = CallName + " = " + FromNative ("native_" + CallName) + ";";
result [1] = (Generatable as IManualMarshaler).ReleaseNative ("native_" + CallName) + ";";
return result;
}
}
public override string NativeSignature {
get {
return "IntPtr " + CallName;
}
}
}
public class Parameters : IEnumerable {
ArrayList param_list = new ArrayList ();
XmlElement elem;
public Parameters (XmlElement elem) {
public Parameters (XmlElement elem)
{
if (elem == null)
return;
for (int i = 0; i < elem.ChildNodes.Count; i++) {
XmlElement parm = elem.ChildNodes [i] as XmlElement;
if (parm == null || parm.Name != "parameter")
continue;
Parameter p = new Parameter (parm);
if (p.IsArray) {
p = new ArrayParameter (parm);
if (i < elem.ChildNodes.Count - 1) {
XmlElement next = elem.ChildNodes [i + 1] as XmlElement;
if (next != null || next.Name == "parameter") {
Parameter c = new Parameter (next);
if (c.IsCount) {
p = new ArrayCountPair (parm, next, false);
i++;
}
}
}
} else if (p.IsCount && i < elem.ChildNodes.Count - 1) {
Console.WriteLine (elem.GetAttribute ("name"));
XmlElement next = elem.ChildNodes [i + 1] as XmlElement;
if (next != null || next.Name == "parameter") {
Parameter a = new Parameter (next);
if (a.IsArray) {
p = new ArrayCountPair (next, parm, true);
i++;
}
}
} else if (p.CType == "GError**")
p = new ErrorParameter (parm);
param_list.Add (p);
}
valid = true;
this.elem = elem;
}
public int Count {
@ -564,11 +564,11 @@ namespace GtkSharp.Generation {
set { is_static = value; }
}
bool cleared = false;
void Clear ()
{
cleared = true;
elem = null;
param_list.Clear ();
param_list = null;
}
public IEnumerator GetEnumerator ()
@ -576,18 +576,25 @@ namespace GtkSharp.Generation {
return param_list.GetEnumerator ();
}
bool valid = false;
public bool Validate ()
{
if (cleared)
if (valid)
return true;
if (elem == null)
return false;
for (int i = 0; i < param_list.Count; i++) {
Parameter p = this [i];
for (int i = 0; i < elem.ChildNodes.Count; i++) {
XmlElement parm = elem.ChildNodes [i] as XmlElement;
if (parm == null || parm.Name != "parameter")
continue;
Parameter p = new Parameter (parm);
if (p.IsEllipsis) {
Console.Write("Ellipsis parameter ");
Clear ();
return false;
}
@ -598,15 +605,43 @@ namespace GtkSharp.Generation {
return false;
}
if (p.Generatable is CallbackGen) {
has_cb = true;
if (i == Count - 3 &&
this [i + 1].IsUserData &&
this [i + 2].IsDestroyNotify)
p.Scope = "notified";
IGeneratable gen = p.Generatable;
if (p.IsArray) {
p = new ArrayParameter (parm);
if (i < elem.ChildNodes.Count - 1) {
XmlElement next = elem.ChildNodes [i + 1] as XmlElement;
if (next != null || next.Name == "parameter") {
Parameter c = new Parameter (next);
if (c.IsCount) {
p = new ArrayCountPair (parm, next, false);
i++;
}
}
}
} else if (p.IsCount && i < elem.ChildNodes.Count - 1) {
XmlElement next = elem.ChildNodes [i + 1] as XmlElement;
if (next != null || next.Name == "parameter") {
Parameter a = new Parameter (next);
if (a.IsArray) {
p = new ArrayCountPair (next, parm, true);
i++;
}
}
} else if (p.CType == "GError**")
p = new ErrorParameter (parm);
else if (gen is StructBase) {
p = new StructParameter (parm);
} else if (gen is CallbackGen) {
has_cb = true;
}
param_list.Add (p);
}
if (has_cb && Count > 2 && this [Count - 3].Generatable is CallbackGen && this [Count - 2].IsUserData && this [Count - 1].IsDestroyNotify)
this [Count - 3].Scope = "notified";
valid = true;
return true;
}
@ -658,19 +693,6 @@ namespace GtkSharp.Generation {
return String.Join (", ", result);
}
}
public string NativeCallbackSignature {
get {
if (Count == 0)
return String.Empty;
string[] result = new string [Count];
for (int i = 0; i < Count; i++)
result [i] = this [i].NativeCallbackSignature;
return String.Join (", ", result);
}
}
}
}

View file

@ -135,7 +135,7 @@ namespace GtkSharp.Generation {
if (Getter != null) {
sw.Write(indent + "get ");
Getter.GenerateBody(gen_info, "\t");
Getter.GenerateBody(gen_info, implementor, "\t");
sw.WriteLine();
} else if (Readable) {
sw.WriteLine(indent + "get {");
@ -158,7 +158,7 @@ namespace GtkSharp.Generation {
if (Setter != null) {
sw.Write(indent + "set ");
Setter.GenerateBody(gen_info, "\t");
Setter.GenerateBody(gen_info, implementor, "\t");
sw.WriteLine();
} else if (Writable) {
sw.WriteLine(indent + "set {");

View file

@ -101,7 +101,7 @@ namespace GtkSharp.Generation {
Parameter p = parms [i];
if (p.PassAs != "" && !(p.Generatable is StructBase))
result += p.PassAs + " ";
result += (p.NativeCallbackType + " arg" + i);
result += (p.MarshalType + " arg" + i);
}
result += ", IntPtr gch";
@ -374,9 +374,9 @@ namespace GtkSharp.Generation {
{
ManagedCallString call = new ManagedCallString (parms);
sw.WriteLine ("\t\t[GLib.CDeclCallback]");
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + parms.NativeCallbackSignature + ");\n");
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + parms.ImportSignature + ");\n");
sw.WriteLine ("\t\tstatic {0} {1};\n", Name + "VMDelegate", Name + "VMCallback");
sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + parms.NativeCallbackSignature + ")");
sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + parms.ImportSignature + ")");
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);

View file

@ -64,12 +64,6 @@ namespace GtkSharp.Generation {
}
}
public virtual string NativeCallbackType {
get {
return MarshalType;
}
}
public virtual string MarshalReturnType {
get {
return MarshalType;

View file

@ -27,9 +27,10 @@ namespace GtkSharp.Generation {
using System.Text.RegularExpressions;
using System.Xml;
public abstract class StructBase : ClassBase {
public abstract class StructBase : ClassBase, IManualMarshaler {
new ArrayList fields = new ArrayList ();
bool need_read_native = false;
protected StructBase (XmlElement ns, XmlElement elem) : base (ns, elem)
{
@ -56,51 +57,41 @@ namespace GtkSharp.Generation {
}
public override string MarshalType {
get {
return "ref " + QualifiedName;
}
}
public override string NativeCallbackType {
get {
return "IntPtr";
}
}
public override string MarshalReturnType {
get {
return "IntPtr";
}
}
public override string ToNativeReturnType {
get {
return QualifiedName;
}
}
public override string CallByName (string var_name)
{
return "ref " + var_name;
public override string AssignToName {
get { throw new NotImplementedException (); }
}
public override string CallByName ()
{
return "ref this";
return "this_as_native";
}
public override string AssignToName {
get { return "raw"; }
}
public override string FromNative(string var)
public override string CallByName (string var)
{
return var + "_as_native";
}
public override string FromNative (string var)
{
if (DisableNew)
return var + " == IntPtr.Zero ? " + QualifiedName + ".Zero : (" + QualifiedName + ") System.Runtime.InteropServices.Marshal.PtrToStructure (" + var + ", typeof (" + QualifiedName + "))";
else
return QualifiedName + ".New (" + var + ")";
}
public override string ToNativeReturn(string var)
public string AllocNative (string var)
{
return var;
return "GLib.Marshaller.StructureToPtrAlloc (" + var + ")";
}
public string ReleaseNative (string var)
{
return "Marshal.FreeHGlobal (" +var + ")";
}
private bool DisableNew {
@ -165,10 +156,13 @@ namespace GtkSharp.Generation {
sw.WriteLine ("\tpublic struct " + Name + " {");
sw.WriteLine ();
need_read_native = false;
GenFields (gen_info);
sw.WriteLine ();
GenCtors (gen_info);
GenMethods (gen_info, null, null);
GenMethods (gen_info, null, this);
if (need_read_native)
GenReadNative (sw);
if (!need_close)
return;
@ -203,6 +197,27 @@ namespace GtkSharp.Generation {
base.GenCtors (gen_info);
}
void GenReadNative (StreamWriter sw)
{
sw.WriteLine ("\t\tstatic void ReadNative (IntPtr native, ref {0} target)", QualifiedName);
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\ttarget = New (native);");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
public override void Prepare (StreamWriter sw, string indent)
{
sw.WriteLine (indent + "IntPtr this_as_native = System.Runtime.InteropServices.Marshal.AllocHGlobal (System.Runtime.InteropServices.Marshal.SizeOf (this));");
sw.WriteLine (indent + "System.Runtime.InteropServices.Marshal.StructureToPtr (this, this_as_native, false);");
}
public override void Finish (StreamWriter sw, string indent)
{
need_read_native = true;
sw.WriteLine (indent + "ReadNative (this_as_native, ref this);");
sw.WriteLine (indent + "System.Runtime.InteropServices.Marshal.FreeHGlobal (this_as_native);");
}
}
}

View file

@ -30,8 +30,6 @@
return ret;
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern int gtk_tree_model_iter_n_children (IntPtr raw, IntPtr iter);
public int IterNChildren ()
{
int raw_ret = gtk_tree_model_iter_n_children (Handle, IntPtr.Zero);

View file

@ -48,9 +48,6 @@ public void Delete (TextIter start, TextIter end )
}
// overload to paste clipboard contents at cursor editable by default.
[DllImport("libgtk-win32-2.0-0.dll")]
static extern void gtk_text_buffer_paste_clipboard (IntPtr raw, IntPtr clip, IntPtr iter, bool default_edit);
public void PasteClipboard (Gtk.Clipboard clipboard)
{
gtk_text_buffer_paste_clipboard(Handle, clipboard.Handle, IntPtr.Zero, true);

View file

@ -6,8 +6,6 @@
return ret;
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern int gtk_tree_model_iter_n_children (IntPtr raw, IntPtr iter);
public int IterNChildren () {
int raw_ret = gtk_tree_model_iter_n_children (Handle, IntPtr.Zero);
int ret = raw_ret;

View file

@ -29,8 +29,6 @@
return ret;
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern int gtk_tree_model_iter_n_children (IntPtr raw, IntPtr iter);
public int IterNChildren () {
int raw_ret = gtk_tree_model_iter_n_children (Handle, IntPtr.Zero);
int ret = raw_ret;

View file

@ -201,8 +201,6 @@
return ret;
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern int gtk_tree_model_iter_n_children (IntPtr raw, IntPtr iter);
public int IterNChildren () {
int raw_ret = gtk_tree_model_iter_n_children (Handle, IntPtr.Zero);
int ret = raw_ret;

View file

@ -358,33 +358,21 @@ public Widget[] ListMnemonicLabels ()
return result;
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern void gtk_widget_modify_base (IntPtr raw, int state, IntPtr color);
public void ModifyBase (Gtk.StateType state)
{
gtk_widget_modify_base (Handle, (int) state, IntPtr.Zero);
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern void gtk_widget_modify_bg (IntPtr raw, int state, IntPtr color);
public void ModifyBg (Gtk.StateType state)
{
gtk_widget_modify_bg (Handle, (int) state, IntPtr.Zero);
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern void gtk_widget_modify_fg (IntPtr raw, int state, IntPtr color);
public void ModifyFg (Gtk.StateType state)
{
gtk_widget_modify_fg (Handle, (int) state, IntPtr.Zero);
}
[DllImport("libgtk-win32-2.0-0.dll")]
static extern void gtk_widget_modify_text (IntPtr raw, int state, IntPtr color);
public void ModifyText (Gtk.StateType state)
{
gtk_widget_modify_text (Handle, (int) state, IntPtr.Zero);