From 6ec923833ea7e709761e53bd8a93a79f85a09082 Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Wed, 14 Jan 2004 18:05:50 +0000 Subject: [PATCH] 2004-01-13 Mike Kestner * generator/Signal.cs : use ValueArray to assemble parms arg for g_signal_chain_from_overriden call. Initialize retval GValue for above. * glib/Object.cs : g_signal_chain_from_overridden parms are IntPtrs. * glib/TypeConverter.cs : handle unboxed ValueTypes. * glib/Value.cs : handle unboxed struct types. add ctor for init'd unset Values. * glib/ValueArray.cs : new binding for GValueArray used by VMs. * glue/valuearray.c : field accessors * glue/Makefile.am : add new glue file * glue/makefile.win32 : add new glue file [Fixes #52680] svn path=/trunk/gtk-sharp/; revision=22069 --- ChangeLog | 15 ++++ generator/Signal.cs | 30 +++++-- glib/Object.cs | 2 +- glib/TypeConverter.cs | 20 ++--- glib/Value.cs | 36 ++++++-- glib/ValueArray.cs | 193 ++++++++++++++++++++++++++++++++++++++++++ glue/Makefile.am | 1 + glue/makefile.win32 | 1 + glue/valuearray.c | 24 ++++++ 9 files changed, 296 insertions(+), 26 deletions(-) create mode 100644 glib/ValueArray.cs create mode 100644 glue/valuearray.c diff --git a/ChangeLog b/ChangeLog index 6cef1e1e3..c88967858 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-01-13 Mike Kestner + + * generator/Signal.cs : use ValueArray to assemble parms arg for + g_signal_chain_from_overriden call. Initialize retval GValue for + above. + * glib/Object.cs : g_signal_chain_from_overridden parms are IntPtrs. + * glib/TypeConverter.cs : handle unboxed ValueTypes. + * glib/Value.cs : handle unboxed struct types. add ctor for init'd + unset Values. + * glib/ValueArray.cs : new binding for GValueArray used by VMs. + * glue/valuearray.c : field accessors + * glue/Makefile.am : add new glue file + * glue/makefile.win32 : add new glue file + [Fixes #52680] + 2004-01-13 John Luke * en/Gtk/Dialog.custom: add more Gtk.ResponseType overloads diff --git a/generator/Signal.cs b/generator/Signal.cs index afb8a7188..b27008057 100644 --- a/generator/Signal.cs +++ b/generator/Signal.cs @@ -109,6 +109,26 @@ namespace GtkSharp.Generation { } } + private string ReturnGType { + get { + ClassBase igen = SymbolTable.Table.GetClassGen (elem ["return-type"].GetAttribute("type")); + + if (igen is ObjectGen) + return "GLib.GType.Object"; + + switch (ReturnType) { + case "bool": + return "GLib.GType.Boolean"; + case "string": + return "GLib.GType.String"; + case "int": + return "GLib.GType.Int"; + default: + throw new Exception (ReturnType); + } + } + } + private string ReturnType { get { string ctype = elem ["return-type"].GetAttribute("type"); @@ -155,12 +175,12 @@ namespace GtkSharp.Generation { 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\tGLib.Value ret = new GLib.Value (" + ReturnGType + ");"); - sw.WriteLine ("\t\t\tIntPtr[] args = new IntPtr [" + parms.Count + "];"); + sw.WriteLine ("\t\t\tGLib.ValueArray inst_and_params = new GLib.ValueArray (" + parms.Count + ");"); 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;"); + sw.WriteLine ("\t\t\tinst_and_params.Append (vals [0]);"); string cleanup = ""; for (int i = 1; i < parms.Count; i++) { if (parms [i].PassAs == "out") { @@ -171,10 +191,10 @@ namespace GtkSharp.Generation { else sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value (" + parms [i].Name + ");"); - sw.WriteLine ("\t\t\targs [" + i + "] = vals [" + i + "].Handle;"); + sw.WriteLine ("\t\t\tinst_and_params.Append (vals [" + i + "]);"); } - sw.WriteLine ("\t\t\tg_signal_chain_from_overridden (args, " + (IsVoid ? "IntPtr.Zero" : "ret.Handle") + ");"); + sw.WriteLine ("\t\t\tg_signal_chain_from_overridden (inst_and_params.ArrayPtr, " + (IsVoid ? "IntPtr.Zero" : "ret.Handle") + ");"); if (cleanup != "") sw.WriteLine (cleanup); if (!IsVoid) diff --git a/glib/Object.cs b/glib/Object.cs index 2d13446f9..d7790897f 100644 --- a/glib/Object.cs +++ b/glib/Object.cs @@ -399,7 +399,7 @@ namespace GLib { } [DllImport("libgobject-2.0-0.dll")] - protected static extern void g_signal_chain_from_overridden (IntPtr[] args, IntPtr retval); + protected static extern void g_signal_chain_from_overridden (IntPtr args, IntPtr retval); [DllImport("gtksharpglue")] static extern bool gtksharp_is_object (IntPtr obj); diff --git a/glib/TypeConverter.cs b/glib/TypeConverter.cs index e2c4b316d..0743de29b 100644 --- a/glib/TypeConverter.cs +++ b/glib/TypeConverter.cs @@ -24,16 +24,6 @@ namespace GLibSharp { { if (type.Equals (typeof (string))) return GType.String; - - if (!type.IsValueType) { - if (type.IsSubclassOf (typeof (GLib.Object))) - return GType.Object; - else if (type.IsSubclassOf (typeof (GLib.Boxed))) - return GType.Boxed; - else - return GType.None; - } - if (type.Equals (typeof (bool))) return GType.Boolean; if (type.Equals (typeof (int))) @@ -46,8 +36,14 @@ namespace GLibSharp { return GType.Char; if (type.Equals (typeof (uint))) return GType.UInt; - - return GType.Invalid; + if (type.IsValueType) + return GType.Pointer; + if (type.IsSubclassOf (typeof (GLib.Object))) + return GType.Object; + else if (type.IsSubclassOf (typeof (GLib.Boxed))) + return GType.Boxed; + else + return GType.None; } } } diff --git a/glib/Value.cs b/glib/Value.cs index c33fe9e14..8428cb891 100755 --- a/glib/Value.cs +++ b/glib/Value.cs @@ -45,6 +45,11 @@ namespace GLib { g_free (_val); _val = IntPtr.Zero; } + + if (buf != IntPtr.Zero) { + Marshal.FreeHGlobal (buf); + buf = IntPtr.Zero; + } } @@ -77,6 +82,19 @@ namespace GLib { _val = gtksharp_value_create (GType.Invalid.Val); } + /// + /// Value Constructor + /// + /// + /// + /// Constructs a new empty initialized value that can be used + /// to receive "out" GValue parameters. + /// + + public Value (GLib.GType gtype) { + _val = gtksharp_value_create (gtype.Val); + } + /// /// Value Constructor /// @@ -296,6 +314,11 @@ namespace GLib { g_value_set_enum (_val, (int) wrap); } + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_set_boxed_take_ownership (IntPtr val, IntPtr data); + + IntPtr buf = IntPtr.Zero; + /// /// Value Constructor /// @@ -305,9 +328,6 @@ namespace GLib { /// type. /// - [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_boxed_take_ownership (IntPtr val, IntPtr data); - public Value (object obj) { GType type = TypeConverter.LookupType (obj.GetType ()); @@ -315,8 +335,6 @@ namespace GLib { _val = gtksharp_value_create (ManagedValue.GType.Val); } else if (type == GType.Object) { _val = gtksharp_value_create (((GLib.Object) obj).GetGType ().Val); - } else if (type == GType.Invalid) { - throw new Exception ("Unknown type"); } else { _val = gtksharp_value_create (type.Val); } @@ -339,12 +357,14 @@ namespace GLib { g_value_set_uint (_val, (uint) obj); else if (type == GType.Object) g_value_set_object (_val, ((GLib.Object) obj).Handle); - else + else if (type == GType.Pointer) { + buf = Marshal.AllocHGlobal (Marshal.SizeOf (obj.GetType())); + Marshal.StructureToPtr (obj, buf, false); + g_value_set_pointer (_val, buf); + } else throw new Exception ("Unknown type"); } - - [DllImport("libgobject-2.0-0.dll")] static extern bool g_value_get_boolean (IntPtr val); diff --git a/glib/ValueArray.cs b/glib/ValueArray.cs new file mode 100644 index 000000000..634cc1c52 --- /dev/null +++ b/glib/ValueArray.cs @@ -0,0 +1,193 @@ +// ValueArray.cs - ValueArray wrapper implementation +// +// Authors: Mike Kestner +// +// (c) 2003 Novell, Inc. + +namespace GLib { + + using System; + using System.Collections; + using System.Runtime.InteropServices; + + public class ValueArray : IDisposable, ICollection, ICloneable, IWrapper { + + private IntPtr handle = IntPtr.Zero; + + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_value_array_new (uint n_preallocs); + + public ValueArray (uint n_preallocs) + { + handle = g_value_array_new (n_preallocs); + } + + internal ValueArray (IntPtr raw) + { + handle = raw; + } + + ~ValueArray () + { + Dispose (false); + } + + // IDisposable + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_array_free (IntPtr raw); + + void Dispose (bool disposing) + { + if (Handle == IntPtr.Zero) + return; + + g_value_array_free (Handle); + handle = IntPtr.Zero; + } + + public IntPtr Handle { + get { + return handle; + } + } + + [DllImport("gtksharpglue")] + static extern IntPtr gtksharp_value_array_get_array (IntPtr raw); + + public IntPtr ArrayPtr { + get { + return gtksharp_value_array_get_array (Handle); + } + } + + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_array_append (IntPtr raw, IntPtr val); + + public void Append (GLib.Value val) + { + g_value_array_append (Handle, val.Handle); + } + + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_array_insert (IntPtr raw, uint idx, IntPtr val); + + public void Insert (uint idx, GLib.Value val) + { + g_value_array_insert (Handle, idx, val.Handle); + } + + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_array_prepend (IntPtr raw, IntPtr val); + + public void Prepend (GLib.Value val) + { + g_value_array_prepend (Handle, val.Handle); + } + + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_array_remove (IntPtr raw, uint idx); + + public void Remove (uint idx) + { + g_value_array_remove (Handle, idx); + } + + [DllImport("gtksharpglue")] + static extern int gtksharp_value_array_get_count (IntPtr raw); + + // ICollection + public int Count { + get { + return gtksharp_value_array_get_count (Handle); + } + } + + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_value_array_get_nth (IntPtr raw, uint idx); + + public object this [int index] { + get { + return new GLib.Value (g_value_array_get_nth (Handle, (uint) index), IntPtr.Zero); + } + } + + // Synchronization could be tricky here. Hmm. + public bool IsSynchronized { + get { return false; } + } + + public object SyncRoot { + get { return null; } + } + + public void CopyTo (Array array, int index) + { + if (array == null) + throw new ArgumentNullException ("Array can't be null."); + + if (index < 0) + throw new ArgumentOutOfRangeException ("Index must be greater than 0."); + + if (index + Count < array.Length) + throw new ArgumentException ("Array not large enough to copy into starting at index."); + + for (int i = 0; i < Count; i++) + ((IList) array) [index + i] = this [i]; + } + + private class ListEnumerator : IEnumerator + { + private int current = -1; + private ValueArray vals; + + public ListEnumerator (ValueArray vals) + { + this.vals = vals; + } + + public object Current { + get { + if (current == -1) + return null; + return vals [current]; + } + } + + public bool MoveNext () + { + if (++current >= vals.Count) { + current = -1; + return false; + } + + return true; + } + + public void Reset () + { + current = -1; + } + } + + // IEnumerable + public IEnumerator GetEnumerator () + { + return new ListEnumerator (this); + } + + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_value_array_copy (IntPtr raw); + + // ICloneable + public object Clone () + { + return new ValueArray (g_value_array_copy (Handle)); + } + } +} diff --git a/glue/Makefile.am b/glue/Makefile.am index 8283201f2..8d1d3919b 100644 --- a/glue/Makefile.am +++ b/glue/Makefile.am @@ -22,6 +22,7 @@ BASESOURCES = \ style.c \ type.c \ value.c \ + valuearray.c \ widget.c # Adding a new glue file? diff --git a/glue/makefile.win32 b/glue/makefile.win32 index ad6ae02d1..81aad3219 100755 --- a/glue/makefile.win32 +++ b/glue/makefile.win32 @@ -24,6 +24,7 @@ GLUE_OBJS = \ style.o \ type.o \ value.o \ + valuearray.o \ widget.o \ gladexml.o \ win32dll.o diff --git a/glue/valuearray.c b/glue/valuearray.c new file mode 100644 index 000000000..2e967ca9c --- /dev/null +++ b/glue/valuearray.c @@ -0,0 +1,24 @@ +/* valuearray.c : Glue to access GValueArray fields + * + * Author: Mike Kestner + * + * 2004 Novell, Inc. + */ + +#include + +GValue *gtksharp_value_array_get_array (GValueArray *va); +guint gtksharp_value_array_get_count (GValueArray *va); + +GValue * +gtksharp_value_array_get_array (GValueArray *va) +{ + return va->values; +} + +guint +gtksharp_value_array_get_count (GValueArray *va) +{ + return va->n_values; +} +