From 1ac00ff20556ee07afe53a74e3b4581d802929fa Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Mon, 12 Apr 2004 15:54:57 +0000 Subject: [PATCH] 2004-04-12 Mike Kestner [Rework of a patch from Ben Maurer to turn GLib.Value into a valuetype.] * generator/BoxedGen.cs : fix operators for new valuetype GValues. * generator/ByRefGen.cs : new generatable for byref value types. * generator/Makefile.am : add ByRefGen.cs. * generator/MethodBody.cs : remove GValue special casing. * generator/Property.cs : rework value handling. * generator/Signal.cs : fix base virtual method value passing. * generator/SymbolTable.cs : map GValue to ByRefGen. * glib/Object.cs : rework GetProperty and SetProperty. * glib/Value.cs : make it a value type. * glib/ValueArray.cs : fix GValue passing. * glib/glue/value.c : rework for valuetype GValues. * gnome/Program.custom : fix GValue passing * gtk/Gtk.metadata : make TreeModel.GetValue value param pass_as=ref. * gtk/ListStore.custom : fix GValue passing * gtk/NodeStore.cs : fix GValue passing * gtk/TextTag.custom : fix GValue passing * gtk/TreeModelSort.custom : fix GValue passing * gtk/TreeStore.custom : fix GValue passing svn path=/trunk/gtk-sharp/; revision=25368 --- ChangeLog | 23 ++ generator/BoxedGen.cs | 17 +- generator/ByRefGen.cs | 91 ++++++ generator/Makefile.am | 1 + generator/MethodBody.cs | 9 +- generator/Property.cs | 16 +- generator/Signal.cs | 8 +- generator/SymbolTable.cs | 2 +- glib/Object.cs | 26 +- glib/Value.cs | 628 ++++++++------------------------------- glib/ValueArray.cs | 16 +- glib/glue/value.c | 25 +- gnome/Program.custom | 6 +- gtk/Gtk.metadata | 1 + gtk/ListStore.custom | 4 +- gtk/NodeStore.cs | 11 +- gtk/TextTag.custom | 10 +- gtk/TreeModelSort.custom | 4 +- gtk/TreeStore.custom | 4 +- 19 files changed, 327 insertions(+), 575 deletions(-) create mode 100644 generator/ByRefGen.cs diff --git a/ChangeLog b/ChangeLog index 0cf4e4a43..265fcae11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2004-04-12 Mike Kestner + + [Rework of a patch from Ben Maurer to turn GLib.Value + into a valuetype.] + * generator/BoxedGen.cs : fix operators for new valuetype GValues. + * generator/ByRefGen.cs : new generatable for byref value types. + * generator/Makefile.am : add ByRefGen.cs. + * generator/MethodBody.cs : remove GValue special casing. + * generator/Property.cs : rework value handling. + * generator/Signal.cs : fix base virtual method value passing. + * generator/SymbolTable.cs : map GValue to ByRefGen. + * glib/Object.cs : rework GetProperty and SetProperty. + * glib/Value.cs : make it a value type. + * glib/ValueArray.cs : fix GValue passing. + * glib/glue/value.c : rework for valuetype GValues. + * gnome/Program.custom : fix GValue passing + * gtk/Gtk.metadata : make TreeModel.GetValue value param pass_as=ref. + * gtk/ListStore.custom : fix GValue passing + * gtk/NodeStore.cs : fix GValue passing + * gtk/TextTag.custom : fix GValue passing + * gtk/TreeModelSort.custom : fix GValue passing + * gtk/TreeStore.custom : fix GValue passing + 2004-04-05 Larry Ewing * gnome/Gnome.metadata: Make data an array type so that the image diff --git a/generator/BoxedGen.cs b/generator/BoxedGen.cs index 866d8332c..b87dc430f 100644 --- a/generator/BoxedGen.cs +++ b/generator/BoxedGen.cs @@ -24,27 +24,28 @@ namespace GtkSharp.Generation { { StreamWriter sw = gen_info.Writer = gen_info.OpenStream (Name); base.Generate (gen_info); - sw.WriteLine ("\t\t[DllImport(\"glibsharpglue\")]"); - sw.WriteLine ("\t\tstatic extern IntPtr gtksharp_value_create (GLib.GType gtype);"); + sw.WriteLine ("\t\t[DllImport(\"libgobject-2.0-0.dll\")]"); + sw.WriteLine ("\t\tstatic extern IntPtr g_value_init (ref GLib.Value val, GLib.GType gtype);"); sw.WriteLine (); sw.WriteLine ("\t\t[DllImport(\"libgobject-2.0-0.dll\")]"); - sw.WriteLine ("\t\tstatic extern IntPtr g_value_get_boxed (IntPtr handle);"); + sw.WriteLine ("\t\tstatic extern IntPtr g_value_get_boxed (ref GLib.Value val);"); sw.WriteLine (); sw.WriteLine ("\t\t[DllImport(\"libgobject-2.0-0.dll\")]"); - sw.WriteLine ("\t\tstatic extern void g_value_set_boxed (IntPtr handle, ref " + QualifiedName + " boxed);"); + sw.WriteLine ("\t\tstatic extern void g_value_set_boxed (ref GLib.Value val, ref " + QualifiedName + " boxed);"); sw.WriteLine (); sw.WriteLine ("\t\tpublic static explicit operator GLib.Value (" + QualifiedName + " boxed)"); sw.WriteLine ("\t\t{"); - sw.WriteLine ("\t\t\tIntPtr handle = gtksharp_value_create (" + QualifiedName + ".GType);"); - sw.WriteLine ("\t\t\tg_value_set_boxed (handle, ref boxed);"); - sw.WriteLine ("\t\t\treturn new GLib.Value (handle, IntPtr.Zero);"); + sw.WriteLine ("\t\t\tGLib.Value val = GLib.Value.Empty;"); + sw.WriteLine ("\t\t\tg_value_init (ref val, " + QualifiedName + ".GType);"); + sw.WriteLine ("\t\t\tg_value_set_boxed (ref val, ref boxed);"); + sw.WriteLine ("\t\t\treturn val;"); sw.WriteLine ("\t\t}"); sw.WriteLine (); sw.WriteLine ("\t\tpublic static explicit operator " + QualifiedName + " (GLib.Value val)"); sw.WriteLine ("\t\t{"); - sw.WriteLine ("\t\t\tIntPtr boxed_ptr = g_value_get_boxed (val.Handle);"); + sw.WriteLine ("\t\t\tIntPtr boxed_ptr = g_value_get_boxed (ref val);"); sw.WriteLine ("\t\t\treturn New (boxed_ptr);"); sw.WriteLine ("\t\t}"); diff --git a/generator/ByRefGen.cs b/generator/ByRefGen.cs new file mode 100644 index 000000000..2fe26e1bb --- /dev/null +++ b/generator/ByRefGen.cs @@ -0,0 +1,91 @@ +// GtkSharp.Generation.ByRefGen.cs - The ByRef type Generatable. +// +// Author: Mike Kestner +// +// (c) 2003 Mike Kestner + +namespace GtkSharp.Generation { + + using System; + + public class ByRefGen : IGeneratable { + + string type; + string ctype; + string ns = ""; + + public ByRefGen (string ctype, string type) + { + string[] toks = type.Split('.'); + this.ctype = ctype; + this.type = toks[toks.Length - 1]; + if (toks.Length > 2) + this.ns = String.Join (".", toks, 0, toks.Length - 2); + else if (toks.Length == 2) + this.ns = toks[0]; + } + + public string CName { + get + { + return ctype; + } + } + + public string Name { + get + { + return type; + } + } + + public string QualifiedName { + get + { + return ns + "." + type; + } + } + + public string MarshalType { + get + { + return "ref " + QualifiedName; + } + } + public virtual string MarshalReturnType { + get + { + return QualifiedName; + } + } + + public string CallByName (string var_name) + { + return "ref " + var_name; + } + + public string FromNative(string var) + { + return var; + } + + public virtual string FromNativeReturn(string var) + { + return var; + } + + public virtual string ToNativeReturn(string var) + { + return var; + } + + public void Generate () + { + } + + public void Generate (GenerationInfo gen_info) + { + } + } +} + diff --git a/generator/Makefile.am b/generator/Makefile.am index 22e78b6a5..46b984b38 100644 --- a/generator/Makefile.am +++ b/generator/Makefile.am @@ -9,6 +9,7 @@ references = sources = \ AliasGen.cs \ BoxedGen.cs \ + ByRefGen.cs \ CallbackGen.cs \ ClassBase.cs \ ClassGen.cs \ diff --git a/generator/MethodBody.cs b/generator/MethodBody.cs index 3fbbb3aec..22779535b 100644 --- a/generator/MethodBody.cs +++ b/generator/MethodBody.cs @@ -75,7 +75,7 @@ namespace GtkSharp.Generation { if (igen is EnumGen) call_parm = p.Name + "_as_int"; - else if (UsesHandle (igen) || p.CSType == "GLib.Value") { + else if (UsesHandle (igen)) { call_parm = p.PassAs + " " + call_parm.Replace (".Handle", "_handle"); } } @@ -91,6 +91,7 @@ namespace GtkSharp.Generation { string call_string = String.Join (", ", result); call_string = call_string.Replace ("out ref", "out"); + call_string = call_string.Replace ("out out ", "out "); call_string = call_string.Replace ("ref ref", "ref"); return call_string; } @@ -111,11 +112,11 @@ namespace GtkSharp.Generation { if (is_get) { sw.WriteLine (indent + "\t\t\t" + p.CSType + " " + name + ";"); - if (p.PassAs != "out" && (UsesHandle (gen) || p.CSType == "GLib.Value")) + if (p.PassAs != "out" && UsesHandle (gen)) sw.WriteLine(indent + "\t\t\t" + name + " = new " + p.CSType + "();"); } - if ((is_get || p.PassAs == "out") && (UsesHandle (gen) || p.CSType == "GLib.Value")) + if ((is_get || p.PassAs == "out") && UsesHandle (gen)) sw.WriteLine(indent + "\t\t\tIntPtr " + name + "_handle;"); if (p.PassAs == "out" && gen is EnumGen) @@ -161,7 +162,7 @@ namespace GtkSharp.Generation { IGeneratable gen = p.Generatable; - if (p.PassAs == "out" && (UsesHandle (gen) || p.CSType == "GLib.Value")) + if (p.PassAs == "out" && UsesHandle (gen)) sw.WriteLine(indent + "\t\t\t" + p.Name + " = " + gen.FromNativeReturn (p.Name + "_handle") + ";"); } } diff --git a/generator/Property.cs b/generator/Property.cs index 1b5c5335d..fc1ae4060 100644 --- a/generator/Property.cs +++ b/generator/Property.cs @@ -132,8 +132,7 @@ namespace GtkSharp.Generation { sw.WriteLine(); } else if (elem.HasAttribute("readable")) { sw.WriteLine("\t\t\tget {"); - sw.WriteLine("\t\t\t\tGLib.Value val = new GLib.Value (Handle, " + cname + ");"); - sw.WriteLine("\t\t\t\tGetProperty(" + cname + ", val);"); + sw.WriteLine("\t\t\t\tGLib.Value val = GetProperty (" + cname + ");"); if (table.IsObject (c_type)) { sw.WriteLine("\t\t\t\tSystem.IntPtr raw_ret = (System.IntPtr) {0} val;", v_type); sw.WriteLine("\t\t\t\t" + cs_type + " ret = " + table.FromNativeReturn(c_type, "raw_ret") + ";"); @@ -150,6 +149,7 @@ namespace GtkSharp.Generation { sw.WriteLine("val;"); } + sw.WriteLine("\t\t\t\tval.Dispose ();"); sw.WriteLine("\t\t\t\treturn ret;"); sw.WriteLine("\t\t\t}"); } @@ -160,20 +160,22 @@ namespace GtkSharp.Generation { sw.WriteLine(); } else if (elem.HasAttribute("writeable") && !elem.HasAttribute("construct-only")) { sw.WriteLine("\t\t\tset {"); - sw.Write("\t\t\t\tSetProperty(" + cname + ", "); + sw.Write("\t\t\t\tGLib.Value val = "); if (table.IsEnum(c_type)) { - sw.WriteLine("new GLib.Value(Handle, " + cname + ", new GLib.EnumWrapper ((int) value, {0})));", table.IsEnumFlags (c_type) ? "true" : "false"); + sw.WriteLine("new GLib.Value(Handle, " + cname + ", new GLib.EnumWrapper ((int) value, {0}));", table.IsEnumFlags (c_type) ? "true" : "false"); } else if (table.IsBoxed (c_type)) { - sw.WriteLine("(GLib.Value) (value));"); + sw.WriteLine("(GLib.Value) value;"); } else if (table.IsOpaque (c_type)) { - sw.WriteLine("new GLib.Value(Handle, " + cname + ", value));"); + sw.WriteLine("new GLib.Value(Handle, " + cname + ", value);"); } else { sw.Write("new GLib.Value("); if (v_type != "" && !(table.IsObject (c_type) || table.IsOpaque (c_type))) { sw.Write(v_type + " "); } - sw.WriteLine("value));"); + sw.WriteLine("value);"); } + sw.WriteLine("\t\t\t\tSetProperty(" + cname + ", val);"); + sw.WriteLine("\t\t\t\tval.Dispose ();"); sw.WriteLine("\t\t\t}"); } diff --git a/generator/Signal.cs b/generator/Signal.cs index 304bf6e05..1fcc17ce6 100644 --- a/generator/Signal.cs +++ b/generator/Signal.cs @@ -177,7 +177,9 @@ namespace GtkSharp.Generation { 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) + if (IsVoid) + sw.WriteLine ("\t\t\tGLib.Value ret = GLib.Value.Empty;"); + else sw.WriteLine ("\t\t\tGLib.Value ret = new GLib.Value (" + ReturnGType + ");"); sw.WriteLine ("\t\t\tGLib.ValueArray inst_and_params = new GLib.ValueArray (" + parms.Count + ");"); @@ -187,7 +189,7 @@ namespace GtkSharp.Generation { string cleanup = ""; for (int i = 1; i < parms.Count; i++) { if (parms [i].PassAs == "out") { - sw.WriteLine ("\t\t\tvals [" + i + "] = new GLib.Value ();"); + sw.WriteLine ("\t\t\tvals [" + i + "] = GLib.Value.Empty;"); 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 + "] = new GLib.Value (" + parms [i-1].Name + ".Length);"); @@ -197,7 +199,7 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t\tinst_and_params.Append (vals [" + i + "]);"); } - sw.WriteLine ("\t\t\tg_signal_chain_from_overridden (inst_and_params.ArrayPtr, " + (IsVoid ? "IntPtr.Zero" : "ret.Handle") + ");"); + sw.WriteLine ("\t\t\tg_signal_chain_from_overridden (inst_and_params.ArrayPtr, ref ret);"); if (cleanup != "") sw.WriteLine (cleanup); if (!IsVoid) diff --git a/generator/SymbolTable.cs b/generator/SymbolTable.cs index b8639c364..b9f71fcb2 100644 --- a/generator/SymbolTable.cs +++ b/generator/SymbolTable.cs @@ -93,7 +93,7 @@ namespace GtkSharp.Generation { AddType (new CustomMarshalerGen ("time_t", "System.DateTime", "GLib.time_t_CustomMarshaler")); AddType (new ManualGen ("GSList", "GLib.SList")); AddType (new ManualGen ("GList", "GLib.List")); - AddType (new ManualGen ("GValue", "GLib.Value")); + AddType (new ByRefGen ("GValue", "GLib.Value")); AddType (new ManualGen ("GObject", "GLib.Object")); } diff --git a/glib/Object.cs b/glib/Object.cs index 5dce8738b..e074a6f1e 100644 --- a/glib/Object.cs +++ b/glib/Object.cs @@ -197,11 +197,13 @@ namespace GLib { } } - public GLib.GType GetGType () { - if (_obj == IntPtr.Zero) - return GType.Invalid; + public GLib.GType NativeType { + get { + if (_obj == IntPtr.Zero) + return GType.Invalid; - return new GLib.GType (gtksharp_get_type_id (_obj)); + return new GLib.GType (gtksharp_get_type_id (_obj)); + } } public IntPtr Handle { @@ -261,19 +263,21 @@ namespace GLib { } [DllImport("libgobject-2.0-0.dll")] - static extern void g_object_get_property (IntPtr obj, string name, IntPtr val); + static extern void g_object_get_property (IntPtr obj, string name, ref GLib.Value val); - protected void GetProperty (String name, GLib.Value val) + protected GLib.Value GetProperty (string name) { - g_object_get_property (Raw, name, val.Handle); + Value val = new Value (this, name); + g_object_get_property (Raw, name, ref val); + return val; } [DllImport("libgobject-2.0-0.dll")] - static extern void g_object_set_property (IntPtr obj, string name, IntPtr val); + static extern void g_object_set_property (IntPtr obj, string name, ref GLib.Value val); - protected void SetProperty (String name, GLib.Value val) + protected void SetProperty (string name, GLib.Value val) { - g_object_set_property (Raw, name, val.Handle); + g_object_set_property (Raw, name, ref val); } [DllImport("glibsharpglue")] @@ -285,7 +289,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, ref GLib.Value retval); [DllImport("glibsharpglue")] static extern bool gtksharp_is_object (IntPtr obj); diff --git a/glib/Value.cs b/glib/Value.cs index 1b21ade03..13b2161a2 100755 --- a/glib/Value.cs +++ b/glib/Value.cs @@ -2,7 +2,8 @@ // // Author: Mike Kestner // -// (c) 2001 Mike Kestner, (c) 2003 Novell, Inc. +// Copyright (c) 2001 Mike Kestner +// Copyright (c) 2003-2004 Novell, Inc. namespace GLib { @@ -11,168 +12,55 @@ namespace GLib { using System.Runtime.InteropServices; using GLibSharp; - /// - /// Value Class - /// - /// - /// - /// An arbitrary data type similar to a CORBA Any which is used - /// to get and set properties on Objects. - /// - [StructLayout (LayoutKind.Sequential)] - public class Value : IDisposable { + public struct Value : IDisposable { - IntPtr _val; - bool needs_dispose = true; + GType type; + long pad_1; + long pad_2; - - // Destructor is required since we are allocating unmanaged - // heap resources. - - [DllImport("libglib-2.0-0.dll")] - static extern void g_free (IntPtr mem); + public static Value Empty; [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_unset (IntPtr mem); + static extern void g_value_init (ref GLib.Value val, IntPtr gtype); - ~Value () - { - Dispose (); - } - - static bool idle_queued; - static Queue idle_queue = new Queue (); - - static bool DoDispose () - { - IntPtr [] vals; - - lock (idle_queue){ - vals = new IntPtr [idle_queue.Count]; - idle_queue.CopyTo (vals, 0); - idle_queue.Clear (); - } - lock (typeof (Value)) - idle_queued = false; - - foreach (IntPtr v in vals) { - if (v == IntPtr.Zero) - continue; - - g_value_unset (v); - g_free (v); - } - return false; - } - - public void Dispose () { - if (_val != IntPtr.Zero && needs_dispose) { - - lock (idle_queue) { - idle_queue.Enqueue (_val); - lock (typeof (Value)){ - if (!idle_queued) { - Idle.Add (new IdleHandler (DoDispose)); - idle_queued = true; - } - } - } - _val = IntPtr.Zero; - } - - if (buf != IntPtr.Zero) { - Marshal.FreeHGlobal (buf); - buf = IntPtr.Zero; - } - } - - // import the glue function to allocate values on heap + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_unset (ref GLib.Value val); [DllImport("glibsharpglue")] - static extern IntPtr gtksharp_value_create(IntPtr type); + static extern IntPtr gtksharp_value_create_from_property(ref GLib.Value val, IntPtr obj, string name); - [DllImport("glibsharpglue")] - static extern IntPtr gtksharp_value_create_from_property(IntPtr obj, string name); - - // Constructor to wrap a raw GValue ref. We need the dummy param - // to distinguish this ctor from the TypePointer ctor. - - public Value (IntPtr val, IntPtr dummy) + public void Dispose () { - _val = val; - needs_dispose = false; + g_value_unset (ref this); } - /// - /// Value Constructor - /// - /// - /// - /// Constructs a new empty value that can be used - /// to receive "out" GValue parameters. - /// - - public Value () { - _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 - /// - /// - /// - /// Constructs a Value corresponding to the type of the - /// specified property. - /// - - public Value (IntPtr obj, string prop_name) + public Value (GLib.GType gtype) { - _val = gtksharp_value_create_from_property (obj, prop_name); + type = GType.Invalid; + pad_1 = pad_2 = 0; + g_value_init (ref this, gtype.Val); + } + + public Value (GLib.Object obj, string prop_name) + { + type = GType.Invalid; + pad_1 = pad_2 = 0; + gtksharp_value_create_from_property (ref this, obj.Handle, prop_name); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_boolean (IntPtr val, bool data); + static extern void g_value_set_boolean (ref Value val, bool data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified boolean. - /// - - public Value (bool val) + public Value (bool val) : this (GType.Boolean) { - _val = gtksharp_value_create(GType.Boolean.Val); - g_value_set_boolean (_val, val); + g_value_set_boolean (ref this, val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_boxed (IntPtr val, IntPtr data); + static extern void g_value_set_boxed (ref Value val, IntPtr data); /* - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified boxed type. - /// - public Value (GLib.Boxed val) { _val = gtksharp_value_create(GType.Boxed); @@ -188,481 +76,222 @@ namespace GLib { public Value (IntPtr obj, string prop_name, Opaque val) { - _val = gtksharp_value_create_from_property (obj, prop_name); - g_value_set_boxed (_val, val.Handle); + type = GType.Invalid; + pad_1 = pad_2 = 0; + gtksharp_value_create_from_property (ref this, obj, prop_name); + g_value_set_boxed (ref this, val.Handle); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_double (IntPtr val, double data); + static extern void g_value_set_double (ref Value val, double data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified double. - /// - - public Value (double val) + public Value (double val) : this (GType.Double) { - _val = gtksharp_value_create (GType.Double.Val); - g_value_set_double (_val, val); + g_value_set_double (ref this, val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_float (IntPtr val, float data); + static extern void g_value_set_float (ref Value val, float data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified float. - /// - - public Value (float val) + public Value (float val) : this (GType.Float) { - _val = gtksharp_value_create (GType.Float.Val); - g_value_set_float (_val, val); + g_value_set_float (ref this, val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_int (IntPtr val, int data); + static extern void g_value_set_int (ref Value val, int data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified integer. - /// - - public Value (int val) + public Value (int val) : this (GType.Int) { - _val = gtksharp_value_create (GType.Int.Val); - g_value_set_int (_val, val); + g_value_set_int (ref this, val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_object (IntPtr val, IntPtr data); + static extern void g_value_set_object (ref Value val, IntPtr data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified object. - /// - - public Value (GLib.Object val) + public Value (GLib.Object val) : this (val.NativeType) { - _val = gtksharp_value_create (val.GetGType ().Val); - g_value_set_object (_val, val.Handle); + g_value_set_object (ref this, val.Handle); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_pointer (IntPtr val, IntPtr data); + static extern void g_value_set_pointer (ref Value val, IntPtr data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified pointer. - /// - - public Value (IntPtr val) + public Value (IntPtr val) : this (GType.Pointer) { - _val = gtksharp_value_create (GType.Pointer.Val); - g_value_set_pointer (_val, val); + g_value_set_pointer (ref this, val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_string (IntPtr val, string data); + static extern void g_value_set_string (ref Value val, string data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified string. - /// - - public Value (string val) + public Value (string val) : this (GType.String) { - _val = gtksharp_value_create (GType.String.Val); - g_value_set_string (_val, val); + g_value_set_string (ref this, val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_uint (IntPtr val, uint data); + static extern void g_value_set_uint (ref Value val, uint data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified uint. - /// - - public Value (uint val) + public Value (uint val) : this (GType.UInt) { - _val = gtksharp_value_create (GType.UInt.Val); - g_value_set_uint (_val, val); + g_value_set_uint (ref this, val); } - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified ushort. - /// - - public Value (ushort val) + public Value (ushort val) : this (GType.UInt) { - _val = gtksharp_value_create (GType.UInt.Val); - g_value_set_uint (_val, val); + g_value_set_uint (ref this, val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_enum (IntPtr val, int data); + static extern void g_value_set_enum (ref Value val, int data); [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_flags (IntPtr val, uint data); + static extern void g_value_set_flags (ref Value val, uint data); [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_set_char (IntPtr val, char data); + static extern void g_value_set_char (ref Value val, char data); - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from a specified enum wrapper. - /// - public Value (IntPtr obj, string prop_name, EnumWrapper wrap) { - _val = gtksharp_value_create_from_property (obj, prop_name); + type = GType.Invalid; + pad_1 = pad_2 = 0; + gtksharp_value_create_from_property (ref this, obj, prop_name); if (wrap.flags) - g_value_set_flags (_val, (uint) (int) wrap); + g_value_set_flags (ref this, (uint) (int) wrap); else - g_value_set_enum (_val, (int) wrap); + g_value_set_enum (ref this, (int) wrap); } - [DllImport("libgobject-2.0-0.dll")] - static extern bool g_type_is_a (IntPtr type, IntPtr is_a_type); - - IntPtr buf = IntPtr.Zero; - - /// - /// Value Constructor - /// - /// - /// - /// Constructs a Value from any object, including a managed - /// type. - /// - public Value (object obj) { + type = GType.Invalid; + pad_1 = pad_2 = 0; + GType type = TypeConverter.LookupType (obj.GetType ()); if (type == GType.None) { - _val = gtksharp_value_create (ManagedValue.GType.Val); + g_value_init (ref this, ManagedValue.GType.Val); } else if (type == GType.Object) { - _val = gtksharp_value_create (((GLib.Object) obj).GetGType ().Val); + g_value_init (ref this, ((GLib.Object) obj).NativeType.Val); } else { - _val = gtksharp_value_create (type.Val); + g_value_init (ref this, type.Val); } - if (type == GType.None) - g_value_set_boxed (_val, ManagedValue.WrapObject (obj)); - else if (type == GType.String) - g_value_set_string (_val, (string) obj); - else if (type == GType.Boolean) - g_value_set_boolean (_val, (bool) obj); - else if (type == GType.Int) - g_value_set_int (_val, (int) obj); - else if (type == GType.Double) - g_value_set_double (_val, (double) obj); - else if (type == GType.Float) - g_value_set_float (_val, (float) obj); - else if (type == GType.Char) - g_value_set_char (_val, (char) obj); - else if (type == GType.UInt) - g_value_set_uint (_val, (uint) obj); - else if (type == GType.Object) - g_value_set_object (_val, ((GLib.Object) obj).Handle); - else if (type == GType.Pointer) { - if (obj is IWrapper) { - g_value_set_pointer (_val, ((IWrapper)obj).Handle); - return; - } - buf = Marshal.AllocHGlobal (Marshal.SizeOf (obj.GetType())); - Marshal.StructureToPtr (obj, buf, false); - g_value_set_pointer (_val, buf); - } else if (g_type_is_a (type.Val, GLib.GType.Boxed.Val)) { - if (obj is IWrapper) { - g_value_set_boxed (_val, ((IWrapper)obj).Handle); - return; - } - buf = Marshal.AllocHGlobal (Marshal.SizeOf (obj.GetType())); - Marshal.StructureToPtr (obj, buf, false); - g_value_set_boxed (_val, buf); - } else - throw new Exception ("Unknown type"); + Val = obj; } [DllImport("libgobject-2.0-0.dll")] - static extern bool g_value_get_boolean (IntPtr val); - - /// - /// Value to Boolean Conversion - /// - /// - /// - /// Extracts a bool from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// boolean value. - /// + static extern bool g_value_get_boolean (ref Value val); public static explicit operator bool (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return g_value_get_boolean (val._val); + return g_value_get_boolean (ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern IntPtr g_value_get_boxed (IntPtr val); + static extern IntPtr g_value_get_boxed (ref Value val); public static explicit operator GLib.Opaque (Value val) { - return GLib.Opaque.GetOpaque (g_value_get_boxed (val._val)); + return GLib.Opaque.GetOpaque (g_value_get_boxed (ref val)); } - /// - /// Value to Boxed Conversion - /// - /// - /// - /// Extracts a boxed type from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// boxed type value. - /// - public static explicit operator GLib.Boxed (Value val) { - return new GLib.Boxed (g_value_get_boxed (val._val)); + return new GLib.Boxed (g_value_get_boxed (ref val)); } [DllImport("libgobject-2.0-0.dll")] - static extern double g_value_get_double (IntPtr val); - - /// - /// Value to Double Conversion - /// - /// - /// - /// Extracts a double from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// double value. - /// + static extern double g_value_get_double (ref Value val); public static explicit operator double (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return g_value_get_double (val._val); + return g_value_get_double (ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern float g_value_get_float (IntPtr val); - - /// - /// Value to Float Conversion - /// - /// - /// - /// Extracts a float from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// float value. - /// + static extern float g_value_get_float (ref Value val); public static explicit operator float (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return g_value_get_float (val._val); + return g_value_get_float (ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern int g_value_get_int (IntPtr val); - - /// - /// Value to Integer Conversion - /// - /// - /// - /// Extracts an int from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// integer value. - /// + static extern int g_value_get_int (ref Value val); public static explicit operator int (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return g_value_get_int (val._val); + return g_value_get_int (ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern IntPtr g_value_get_object (IntPtr val); - - /// - /// Value to Object Conversion - /// - /// - /// - /// Extracts an object from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// object value. - /// + static extern IntPtr g_value_get_object (ref Value val); public static explicit operator GLib.Object (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return GLib.Object.GetObject(g_value_get_object (val._val), true); + return GLib.Object.GetObject(g_value_get_object (ref val), true); } - /// - /// Value to Unresolved Object Conversion - /// - /// - /// - /// Extracts an object from a Value without looking up its wrapping - /// class. - /// Note, this method will produce an exception if the Value does - /// not hold a object value. - /// - public static explicit operator GLib.UnwrappedObject (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return new UnwrappedObject(g_value_get_object (val._val)); + return new UnwrappedObject(g_value_get_object (ref val)); } [DllImport("libgobject-2.0-0.dll")] - static extern IntPtr g_value_get_pointer (IntPtr val); - - /// - /// Value to Pointer Conversion - /// - /// - /// - /// Extracts a pointer from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// pointer value. - /// + static extern IntPtr g_value_get_pointer (ref Value val); public static explicit operator IntPtr (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return g_value_get_pointer (val._val); + return g_value_get_pointer (ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern IntPtr g_value_get_string (IntPtr val); - - /// - /// Value to String Conversion - /// - /// - /// - /// Extracts a string from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// string value. - /// + static extern IntPtr g_value_get_string (ref Value val); public static explicit operator String (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - IntPtr str = g_value_get_string (val._val); + IntPtr str = g_value_get_string (ref val); return str == IntPtr.Zero ? null : Marshal.PtrToStringAnsi (str); } [DllImport("libgobject-2.0-0.dll")] - static extern uint g_value_get_uint (IntPtr val); - - /// - /// Value to Unsigned Integer Conversion - /// - /// - /// - /// Extracts an uint from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// unsigned integer value. - /// + static extern uint g_value_get_uint (ref Value val); public static explicit operator uint (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return g_value_get_uint (val._val); + return g_value_get_uint (ref val); } - /// - /// Value to Unsigned Short Conversion - /// - /// - /// - /// Extracts a ushort from a Value. Note, this method - /// will produce an exception if the Value does not hold a - /// unsigned integer value. - /// - public static explicit operator ushort (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. - return (ushort) g_value_get_uint (val._val); + return (ushort) g_value_get_uint (ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern int g_value_get_enum (IntPtr val); + static extern int g_value_get_enum (ref Value val); [DllImport("libgobject-2.0-0.dll")] - static extern uint g_value_get_flags (IntPtr val); - - /// - /// Value to Enum Conversion - /// - /// - /// - /// Extracts an enum from a Value. Note, this method - /// will produce an exception if the Value does not hold an - /// enum value. - /// + static extern uint g_value_get_flags (ref Value val); public static explicit operator EnumWrapper (Value val) { - // FIXME: Insert an appropriate exception here if - // _val.type indicates an error. // FIXME: handle flags - return new EnumWrapper (g_value_get_enum (val._val), false); + return new EnumWrapper (g_value_get_enum (ref val), false); } [DllImport("glibsharpglue")] - static extern IntPtr gtksharp_value_get_value_type (IntPtr val); + static extern IntPtr gtksharp_value_get_value_type (ref Value val); + + [DllImport("libgobject-2.0-0.dll")] + static extern bool g_type_is_a (IntPtr type, IntPtr is_a_type); + [DllImport("libgobject-2.0-0.dll")] + static extern void g_value_take_boxed (ref Value val, IntPtr data); + public object Val { get { - GLib.GType type = new GLib.GType (gtksharp_value_get_value_type (_val)); + GLib.GType type = new GLib.GType (gtksharp_value_get_value_type (ref this)); if (type == ManagedValue.GType) { - return ManagedValue.ObjectForWrapper (g_value_get_boxed (_val)); + return ManagedValue.ObjectForWrapper (g_value_get_boxed (ref this)); } if (type == GType.String) @@ -685,42 +314,45 @@ namespace GLib { throw new Exception ("Unknown type"); } set { + IntPtr buf; GType type = GLibSharp.TypeConverter.LookupType (value.GetType()); if (type == GType.None) - g_value_set_boxed (_val, ManagedValue.WrapObject (value)); + g_value_set_boxed (ref this, ManagedValue.WrapObject (value)); else if (type == GType.String) - g_value_set_string (_val, (string) value); + g_value_set_string (ref this, (string) value); else if (type == GType.Boolean) - g_value_set_boolean (_val, (bool) value); + g_value_set_boolean (ref this, (bool) value); else if (type == GType.Int) - g_value_set_int (_val, (int) value); + g_value_set_int (ref this, (int) value); else if (type == GType.Double) - g_value_set_double (_val, (double) value); + g_value_set_double (ref this, (double) value); else if (type == GType.Float) - g_value_set_float (_val, (float) value); + g_value_set_float (ref this, (float) value); else if (type == GType.Char) - g_value_set_char (_val, (char) value); + g_value_set_char (ref this, (char) value); else if (type == GType.UInt) - g_value_set_uint (_val, (uint) value); + g_value_set_uint (ref this, (uint) value); else if (type == GType.Object) - g_value_set_object (_val, ((GLib.Object) value).Handle); - else + g_value_set_object (ref this, ((GLib.Object) value).Handle); + else if (type == GType.Pointer) { + if (value is IWrapper) { + g_value_set_pointer (ref this, ((IWrapper)value).Handle); + return; + } + buf = Marshal.AllocHGlobal (Marshal.SizeOf (value.GetType())); + Marshal.StructureToPtr (value, buf, false); + g_value_set_pointer (ref this, buf); + } else if (g_type_is_a (type.Val, GLib.GType.Boxed.Val)) { + if (value is IWrapper) { + g_value_set_boxed (ref this, ((IWrapper)value).Handle); + return; + } + buf = Marshal.AllocHGlobal (Marshal.SizeOf (value.GetType())); + Marshal.StructureToPtr (value, buf, false); + g_value_take_boxed (ref this, buf); + } else throw new Exception ("Unknown type"); } } - - /// - /// Handle Property - /// - /// - /// - /// Read only. Accesses a pointer to the raw GValue. - /// - - public IntPtr Handle { - get { - return _val; - } - } } } diff --git a/glib/ValueArray.cs b/glib/ValueArray.cs index 0251bd945..085c675ae 100644 --- a/glib/ValueArray.cs +++ b/glib/ValueArray.cs @@ -67,27 +67,27 @@ namespace GLib { } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_array_append (IntPtr raw, IntPtr val); + static extern void g_value_array_append (IntPtr raw, ref GLib.Value val); public void Append (GLib.Value val) { - g_value_array_append (Handle, val.Handle); + g_value_array_append (Handle, ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_array_insert (IntPtr raw, uint idx, IntPtr val); + static extern void g_value_array_insert (IntPtr raw, uint idx, ref GLib.Value val); public void Insert (uint idx, GLib.Value val) { - g_value_array_insert (Handle, idx, val.Handle); + g_value_array_insert (Handle, idx, ref val); } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_array_prepend (IntPtr raw, IntPtr val); + static extern void g_value_array_prepend (IntPtr raw, ref GLib.Value val); public void Prepend (GLib.Value val) { - g_value_array_prepend (Handle, val.Handle); + g_value_array_prepend (Handle, ref val); } [DllImport("libgobject-2.0-0.dll")] @@ -113,7 +113,9 @@ namespace GLib { public object this [int index] { get { - return new GLib.Value (g_value_array_get_nth (Handle, (uint) index), IntPtr.Zero); + GLib.Value val = Value.Empty; + Marshal.PtrToStructure (g_value_array_get_nth (Handle, (uint) index), val); + return val; } } diff --git a/glib/glue/value.c b/glib/glue/value.c index 971cf952b..cdf6af98c 100644 --- a/glib/glue/value.c +++ b/glib/glue/value.c @@ -8,29 +8,20 @@ #include /* Forward declarations */ -GValue *gtksharp_value_create (GType g_type); -GValue *gtksharp_value_create_from_property (GObject *obj, const gchar* name); +void gtksharp_value_create_from_property (GValue *value, GObject *obj, const gchar* name); +GType gtksharp_value_get_value_type (GValue *value); /* */ -GValue * -gtksharp_value_create (GType g_type) +void +gtksharp_value_create_from_property (GValue *value, GObject *obj, const gchar* name) { - GValue *val = g_new0 (GValue, 1); - if (g_type != G_TYPE_INVALID) - val = g_value_init (val, g_type); - return val; -} - -GValue * -gtksharp_value_create_from_property (GObject *obj, const gchar* name) -{ - GParamSpec *spec = g_object_class_find_property ( - G_OBJECT_GET_CLASS (obj), name); - return gtksharp_value_create (spec->value_type); + GParamSpec *spec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), name); + g_value_init (value, spec->value_type); } GType -gtksharp_value_get_value_type (GValue *value) { +gtksharp_value_get_value_type (GValue *value) +{ g_return_val_if_fail (value != NULL, G_TYPE_INVALID); g_return_val_if_fail (G_IS_VALUE (value), G_TYPE_INVALID); return G_VALUE_TYPE (value); diff --git a/gnome/Program.custom b/gnome/Program.custom index 3f9546821..3a57fcb9e 100644 --- a/gnome/Program.custom +++ b/gnome/Program.custom @@ -14,7 +14,7 @@ static extern void g_type_init (); [StructLayout(LayoutKind.Sequential)] struct PropertyArg { public string name; - public IntPtr value; + public GLib.Value value; } [DllImport("gnomesharpglue")] @@ -42,9 +42,9 @@ public Program (string app_id, string app_version, ModuleInfo module, string[] a else if (type == true.GetType ()) value = new GLib.Value ((bool) prop); else - value = null; + value = GLib.Value.Empty; vals[i] = value; - args[i].value = value.Handle; + args[i].value = value; } /* FIXME: Is there a way to access this in .NET? */ diff --git a/gtk/Gtk.metadata b/gtk/Gtk.metadata index 806759f4b..a930de251 100644 --- a/gtk/Gtk.metadata +++ b/gtk/Gtk.metadata @@ -49,6 +49,7 @@ out out out + ref out out out diff --git a/gtk/ListStore.custom b/gtk/ListStore.custom index 3a28cb13a..04c3a5d87 100644 --- a/gtk/ListStore.custom +++ b/gtk/ListStore.custom @@ -102,8 +102,8 @@ } public object GetValue(Gtk.TreeIter iter, int column) { - GLib.Value val = new GLib.Value (); - GetValue (iter, column, val); + GLib.Value val = GLib.Value.Empty; + GetValue (iter, column, ref val); object ret = val.Val; val.Dispose (); return ret; diff --git a/gtk/NodeStore.cs b/gtk/NodeStore.cs index b33fd4dc0..c113b05d6 100644 --- a/gtk/NodeStore.cs +++ b/gtk/NodeStore.cs @@ -39,7 +39,7 @@ namespace Gtk { delegate IntPtr GetColumnTypeDelegate (int col); delegate bool GetNodeDelegate (out int node_idx, IntPtr path); delegate IntPtr GetPathDelegate (int node_idx); - delegate void GetValueDelegate (int node_idx, int col, IntPtr val); + delegate void GetValueDelegate (int node_idx, int col, ref GLib.Value val); delegate bool NextDelegate (ref int node_idx); delegate bool ChildrenDelegate (out int child, int parent); delegate bool HasChildDelegate (int node_idx); @@ -124,17 +124,16 @@ namespace Gtk { } [DllImport("libgobject-2.0-0.dll")] - static extern void g_value_init (IntPtr handle, IntPtr type); + static extern void g_value_init (ref GLib.Value val, IntPtr type); - void get_value_cb (int node_idx, int col, IntPtr val) + void get_value_cb (int node_idx, int col, ref GLib.Value val) { - GLib.Value gval = new GLib.Value (val, IntPtr.Zero); ITreeNode node = node_hash [node_idx] as ITreeNode; if (node == null) return; - g_value_init (gval.Handle, ctypes [col].Val); + g_value_init (ref val, ctypes [col].Val); object col_val = getters[col].GetValue (node, null); - gval.Val = col_val; + val.Val = col_val; } bool next_cb (ref int node_idx) diff --git a/gtk/TextTag.custom b/gtk/TextTag.custom index 384b20eeb..50eead0ee 100644 --- a/gtk/TextTag.custom +++ b/gtk/TextTag.custom @@ -10,12 +10,14 @@ public Pango.Weight Weight { get { - GLib.Value val = new GLib.Value (); - GetProperty ("weight", val); + GLib.Value val = GetProperty ("weight"); Pango.Weight ret = (Pango.Weight) (int) val; + val.Dispose (); return ret; } set { - SetProperty ("weight", new GLib.Value ((int) value)); + GLib.Value val = new GLib.Value ((int) value); + SetProperty ("weight", val); + val.Dispose (); } - } \ No newline at end of file + } diff --git a/gtk/TreeModelSort.custom b/gtk/TreeModelSort.custom index 1e74e8ac3..0f9e8a26a 100644 --- a/gtk/TreeModelSort.custom +++ b/gtk/TreeModelSort.custom @@ -63,8 +63,8 @@ } public object GetValue (Gtk.TreeIter iter, int column) { - GLib.Value val = new GLib.Value (); - GetValue (iter, column, val); + GLib.Value val = GLib.Value.Empty; + GetValue (iter, column, ref val); object ret = val.Val; val.Dispose (); return ret; diff --git a/gtk/TreeStore.custom b/gtk/TreeStore.custom index cf151957b..192e69052 100644 --- a/gtk/TreeStore.custom +++ b/gtk/TreeStore.custom @@ -148,8 +148,8 @@ } public object GetValue (Gtk.TreeIter iter, int column) { - GLib.Value val = new GLib.Value (); - GetValue (iter, column, val); + GLib.Value val = GLib.Value.Empty; + GetValue (iter, column, ref val); object ret = val.Val; val.Dispose (); return ret;