diff -Naur tmp/gtk-sharp/generator/Ctor.cs generator/Ctor.cs --- tmp/gtk-sharp/generator/Ctor.cs 2009-04-24 10:08:17.000000000 +0200 +++ generator/Ctor.cs 2009-06-02 12:37:47.000000000 +0200 @@ -32,14 +32,16 @@ private bool preferred; private string name; private bool needs_chaining = false; + private bool mini_object = false; public Ctor (XmlElement elem, ClassBase implementor) : base (elem, implementor) { if (elem.HasAttribute ("preferred")) preferred = true; - if (implementor is ObjectGen) + if (implementor is ObjectGen || implementor is MiniObjectGen) needs_chaining = true; name = implementor.Name; + mini_object = implementor is MiniObjectGen; } public bool Preferred { @@ -110,9 +112,14 @@ sw.WriteLine ("\t\t\tif (GetType () != typeof (" + name + ")) {"); if (Parameters.Count == 0) { - sw.WriteLine ("\t\t\t\tCreateNativeObject (new string [0], new GLib.Value[0]);"); + if (mini_object) + sw.WriteLine ("\t\t\t\tCreateNativeObject ();"); + else + sw.WriteLine ("\t\t\t\tCreateNativeObject (new string [0], new GLib.Value[0]);"); sw.WriteLine ("\t\t\t\treturn;"); } else { + if (mini_object) + throw new Exception ("MiniObject subclasses can't have ctors with parameters"); ArrayList names = new ArrayList (); ArrayList values = new ArrayList (); for (int i = 0; i < Parameters.Count; i++) { diff -Naur tmp/gtk-sharp/generator/DefaultSignalHandler.cs generator/DefaultSignalHandler.cs --- tmp/gtk-sharp/generator/DefaultSignalHandler.cs 2009-04-13 19:44:48.000000000 +0200 +++ generator/DefaultSignalHandler.cs 2009-06-02 12:32:24.000000000 +0200 @@ -124,6 +124,8 @@ if (igen is ObjectGen) return "GLib.GType.Object"; + if (igen is MiniObjectGen) + return "Gst.MiniObject.GType"; if (igen is BoxedGen) return retval.CSType + ".GType"; if (igen is EnumGen) diff -Naur tmp/gtk-sharp/generator/FieldBase.cs generator/FieldBase.cs --- tmp/gtk-sharp/generator/FieldBase.cs 2009-05-06 16:58:39.000000000 +0200 +++ generator/FieldBase.cs 2009-05-14 21:32:21.000000000 +0200 @@ -89,7 +89,7 @@ void CheckGlue () { getterName = setterName = getOffsetName = null; - if (Access != "public") + if (DefaultAccess != "public" && (!elem.HasAttribute ("access") || (Access != "public" && Access != "protected" && Access != "internal"))) return; string prefix = (container_type.NS + "Sharp_" + container_type.NS + "_" + container_type.Name).Replace(".", "__").ToLower (); @@ -154,8 +154,9 @@ StreamWriter sw = gen_info.Writer; string modifiers = elem.HasAttribute ("new_flag") ? "new " : ""; bool is_struct = table.IsStruct (CType) || table.IsBoxed (CType); + string access = elem.HasAttribute ("access") ? elem.GetAttribute ("access") : "public"; - sw.WriteLine (indent + "public " + modifiers + CSType + " " + Name + " {"); + sw.WriteLine (indent + access + " " + modifiers + CSType + " " + Name + " {"); if (Getter != null) { sw.Write (indent + "\tget "); diff -Naur tmp/gtk-sharp/generator/Makefile.am generator/Makefile.am --- tmp/gtk-sharp/generator/Makefile.am 2009-07-23 19:18:03.000000000 +0200 +++ generator/Makefile.am 2009-05-27 15:02:46.000000000 +0200 @@ -1,8 +1,4 @@ -assemblydir = $(prefix)/lib/gapi-3.0 -assembly_DATA = gapi_codegen.exe -bin_SCRIPTS = gapi3-codegen -CLEANFILES = gapi_codegen.exe -DISTCLEANFILES = gapi3-codegen +noinst_SCRIPTS = gst-gapi_codegen.exe references = @@ -39,6 +35,7 @@ MethodBase.cs \ MethodBody.cs \ Method.cs \ + MiniObjectGen.cs \ ObjectField.cs \ ObjectBase.cs \ ObjectGen.cs \ @@ -66,6 +63,6 @@ EXTRA_DIST = \ $(dist_sources) -gapi_codegen.exe: $(build_sources) - $(CSC) /out:gapi_codegen.exe $(OFF_T_FLAGS) $(references) $(build_sources) +gst-gapi_codegen.exe: $(build_sources) + $(CSC) -debug -out:gst-gapi_codegen.exe $(OFF_T_FLAGS) $(references) $(build_sources) diff -Naur tmp/gtk-sharp/generator/Method.cs generator/Method.cs --- tmp/gtk-sharp/generator/Method.cs 2009-01-08 19:00:47.000000000 +0100 +++ generator/Method.cs 2009-06-02 12:31:51.000000000 +0200 @@ -118,7 +118,7 @@ if (Name == "ToString" && Parameters.Count == 0) sw.Write("override "); - else if (Name == "GetGType" && container_type is ObjectGen) + else if (Name == "GetGType" && (container_type is ObjectGen || container_type is MiniObjectGen)) sw.Write("new "); else if (Modifiers == "new " || (dup != null && ((dup.Signature != null && Signature != null && dup.Signature.ToString() == Signature.ToString()) || (dup.Signature == null && Signature == null)))) sw.Write("new "); diff -Naur tmp/gtk-sharp/generator/Parameters.cs generator/Parameters.cs --- tmp/gtk-sharp/generator/Parameters.cs 2009-07-13 00:01:52.000000000 +0200 +++ generator/Parameters.cs 2009-06-12 22:13:30.000000000 +0200 @@ -262,10 +262,12 @@ call_parm += CallName; } else if (gen is IManualMarshaler) call_parm = "native_" + CallName; - else if (gen is ObjectBase) - call_parm = (gen as ObjectBase).CallByName (CallName, Owned); + else if (gen is MiniObjectGen) + call_parm = ((MiniObjectGen) gen).CallByName(CallName, Owned); + else if (gen is ObjectGen) + call_parm = ((ObjectGen) gen).CallByName(CallName, Owned); else - call_parm = gen.CallByName (CallName); + call_parm = gen.CallByName(CallName); return call_parm; } @@ -283,7 +285,7 @@ result [i] = (gen as IManualMarshaler).ReleaseNative ("native_" + CallName) + ";"; return result; } else if (PassAs != String.Empty && MarshalType != CSType) - if (gen is HandleBase) + if (gen is HandleBase) return new string [] { CallName + " = " + (gen as HandleBase).FromNative ("native_" + CallName, Owned) + ";" }; else return new string [] { CallName + " = " + gen.FromNative ("native_" + CallName) + ";" }; diff -Naur tmp/gtk-sharp/generator/Parser.cs generator/Parser.cs --- tmp/gtk-sharp/generator/Parser.cs 2009-04-13 19:44:48.000000000 +0200 +++ generator/Parser.cs 2009-05-14 21:40:56.000000000 +0200 @@ -138,6 +138,9 @@ case "object": result.Add (new ObjectGen (ns, elem)); break; + case "mini-object": + result.Add (new MiniObjectGen (ns, elem)); + break; case "class": result.Add (new ClassGen (ns, elem)); break; diff -Naur tmp/gtk-sharp/generator/ReturnValue.cs generator/ReturnValue.cs --- tmp/gtk-sharp/generator/ReturnValue.cs 2009-05-06 18:20:35.000000000 +0200 +++ generator/ReturnValue.cs 2009-06-03 20:59:07.000000000 +0200 @@ -110,7 +110,9 @@ get { if (IGen == null) return String.Empty; - return IGen.ToNativeReturnType + (is_array || is_null_term ? "[]" : String.Empty); + else if (is_null_term) + return "IntPtr"; + return IGen.ToNativeReturnType + (is_array ? "[]" : String.Empty); } } @@ -128,7 +130,7 @@ } else if (IGen is HandleBase) return ((HandleBase)IGen).FromNative (var, owned); else if (is_null_term) - return String.Format ("GLib.Marshaller.NullTermPtrToStringArray ({0}, {1})", var, owned ? "true" : "false"); + return String.Format ("Gst.Marshaller.NullTermPtrToStringArray ({0}, {1})", var, owned ? "true" : "false"); else return IGen.FromNativeReturn (var); } @@ -142,11 +144,11 @@ string args = ", typeof (" + ElementType + "), " + (owned ? "true" : "false") + ", " + (elements_owned ? "true" : "false"); var = "new " + IGen.QualifiedName + "(" + var + args + ")"; } else if (is_null_term) - return String.Format ("GLib.Marshaller.StringArrayToNullTermPointer ({0})", var); + return String.Format ("Gst.Marshaller.StringArrayToNullTermPointer ({0})", var); if (IGen is IManualMarshaler) return (IGen as IManualMarshaler).AllocNative (var); - else if (IGen is ObjectGen && owned) + else if ((IGen is ObjectGen || IGen is MiniObjectGen) && owned) return var + " == null ? IntPtr.Zero : " + var + ".OwnedHandle"; else if (IGen is OpaqueGen && owned) return var + " == null ? IntPtr.Zero : " + var + ".OwnedCopy"; diff -Naur tmp/gtk-sharp/generator/SymbolTable.cs generator/SymbolTable.cs --- tmp/gtk-sharp/generator/SymbolTable.cs 2009-04-13 19:44:48.000000000 +0200 +++ generator/SymbolTable.cs 2009-05-14 21:56:41.000000000 +0200 @@ -116,6 +116,7 @@ // manually wrapped types requiring more complex marshaling AddType (new ManualGen ("GInitiallyUnowned", "GLib.InitiallyUnowned", "GLib.Object.GetObject ({0})")); AddType (new ManualGen ("GObject", "GLib.Object", "GLib.Object.GetObject ({0})")); + AddType (new ManualGen ("GstMiniObject", "Gst.MiniObject", "Gst.MiniObject.GetObject ({0})")); AddType (new ManualGen ("GList", "GLib.List")); AddType (new ManualGen ("GPtrArray", "GLib.PtrArray")); AddType (new ManualGen ("GSList", "GLib.SList")); @@ -338,7 +339,8 @@ public bool IsObject(string c_type) { - if (this[c_type] is ObjectGen) + if ((this[c_type] is ObjectGen) || + (this[c_type] is MiniObjectGen)) return true; return false; --- /dev/null 2009-07-17 07:52:05.502147313 +0200 +++ generator/MiniObjectGen.cs 2009-06-12 22:11:07.000000000 +0200 @@ -0,0 +1,326 @@ +// GtkSharp.Generation.MiniObjectGen.cs - The Mini Object Generatable. +// +// Author: Mike Kestner +// +// Copyright (c) 2001-2003 Mike Kestner +// Copyright (c) 2003-2004 Novell, Inc. +// Copyright (c) 2009 Sebastian Dröge . +// +// 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; + using System.IO; + using System.Text; + using System.Xml; + + public class MiniObjectGen : ObjectBase { + + private ArrayList custom_attrs = new ArrayList(); + private ArrayList strings = new ArrayList(); + private static Hashtable dirs = new Hashtable (); + + public MiniObjectGen (XmlElement ns, XmlElement elem) : base (ns, elem, false) + { + foreach (XmlNode node in elem.ChildNodes) { + if (!(node is XmlElement)) continue; + XmlElement member = (XmlElement) node; + if (member.HasAttribute ("hidden") && member.GetAttribute ("hidden") == "1") continue; + + switch (node.Name) { + case "custom-attribute": + custom_attrs.Add (member.InnerXml); + break; + + case "static-string": + strings.Add (node); + break; + + default: + if (!IsNodeNameHandled (node.Name)) + Console.WriteLine ("Unexpected node " + node.Name + " in " + CName); + break; + } + } + } + + public override bool Validate () + { + ArrayList invalids = new ArrayList (); + + return base.Validate (); + } + + private bool DisableVoidCtor { + get { + return Elem.HasAttribute ("disable_void_ctor"); + } + } + + private bool DisableGTypeCtor { + get { + return Elem.HasAttribute ("disable_gtype_ctor"); + } + } + + private class DirectoryInfo { + public string assembly_name; + public Hashtable objects; + + public DirectoryInfo (string assembly_name) { + this.assembly_name = assembly_name; + objects = new Hashtable (); + } + } + + private static DirectoryInfo GetDirectoryInfo (string dir, string assembly_name) + { + DirectoryInfo result; + + if (dirs.ContainsKey (dir)) { + result = dirs [dir] as DirectoryInfo; + if (result.assembly_name != assembly_name) { + Console.WriteLine ("Can't put multiple assemblies in one directory."); + return null; + } + + return result; + } + + result = new DirectoryInfo (assembly_name); + dirs.Add (dir, result); + + return result; + } + + public override void Generate (GenerationInfo gen_info) + { + gen_info.CurrentType = Name; + + string asm_name = gen_info.AssemblyName.Length == 0 ? NS.ToLower () + "-sharp" : gen_info.AssemblyName; + DirectoryInfo di = GetDirectoryInfo (gen_info.Dir, asm_name); + + StreamWriter sw = gen_info.Writer = gen_info.OpenStream (Name); + + sw.WriteLine ("namespace " + NS + " {"); + sw.WriteLine (); + sw.WriteLine ("\tusing System;"); + sw.WriteLine ("\tusing System.Collections;"); + sw.WriteLine ("\tusing System.Runtime.InteropServices;"); + sw.WriteLine (); + + SymbolTable table = SymbolTable.Table; + + sw.WriteLine ("#region Autogenerated code"); + if (IsDeprecated) + sw.WriteLine ("\t[Obsolete]"); + foreach (string attr in custom_attrs) + sw.WriteLine ("\t" + attr); + sw.Write ("\t{0} {1}class " + Name, IsInternal ? "internal" : "public", IsAbstract ? "abstract " : ""); + string cs_parent = table.GetCSType(Elem.GetAttribute("parent")); + if (cs_parent != "") { + di.objects.Add (CName, QualifiedName); + sw.Write (" : " + cs_parent); + } + foreach (string iface in managed_interfaces) { + if (Parent != null && Parent.Implements (iface)) + continue; + sw.Write (", " + iface); + } + sw.WriteLine (" {"); + sw.WriteLine (); + + GenCtors (gen_info); + GenFields (gen_info); + + GenClassMembers (gen_info, cs_parent); + GenMethods (gen_info, null, null); + + foreach (XmlElement str in strings) { + sw.Write ("\t\tpublic static string " + str.GetAttribute ("name")); + sw.WriteLine (" {\n\t\t\t get { return \"" + str.GetAttribute ("value") + "\"; }\n\t\t}"); + } + + if (cs_parent != String.Empty && GetExpected (CName) != QualifiedName) { + sw.WriteLine (); + sw.WriteLine ("\t\tstatic " + Name + " ()"); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\tGtkSharp." + Studlify (asm_name) + ".ObjectManager.Initialize ();"); + sw.WriteLine ("\t\t}"); + } + + sw.WriteLine ("#endregion"); + AppendCustom (sw, gen_info.CustomDir); + + sw.WriteLine ("\t}"); + sw.WriteLine ("}"); + + sw.Close (); + gen_info.Writer = null; + Statistics.ObjectCount++; + } + + protected override void GenCtors (GenerationInfo gen_info) + { + if (!Elem.HasAttribute("parent")) + return; + + if (!DisableGTypeCtor) { + gen_info.Writer.WriteLine("\t\t[Obsolete]"); + gen_info.Writer.WriteLine("\t\tprotected " + Name + "(GLib.GType gtype) : base(gtype) {}"); + } + gen_info.Writer.WriteLine("\t\tpublic " + Name + "(IntPtr raw) : base(raw) {}"); + if (ctors.Count == 0 && !DisableVoidCtor) { + gen_info.Writer.WriteLine(); + gen_info.Writer.WriteLine("\t\tprotected " + Name + "() : base(IntPtr.Zero)"); + gen_info.Writer.WriteLine("\t\t{"); + gen_info.Writer.WriteLine("\t\t\tCreateNativeObject ();"); + gen_info.Writer.WriteLine("\t\t}"); + } + gen_info.Writer.WriteLine(); + + base.GenCtors (gen_info); + } + + void GenClassMembers (GenerationInfo gen_info, string cs_parent) + { + GenVirtualMethods (gen_info, null); + + if (class_struct_name == null || !CanGenerateClassStruct) return; + StreamWriter sw = gen_info.Writer; + GenerateClassStruct (gen_info); + if (cs_parent == "") + sw.WriteLine ("\t\tstatic uint class_offset = 0;"); + else + sw.WriteLine ("\t\tstatic uint class_offset = ((GLib.GType) typeof ({0})).ClassSize;", cs_parent); + sw.WriteLine ("\t\tstatic Hashtable class_structs;"); + sw.WriteLine (); + sw.WriteLine ("\t\tstatic {0} GetClassStruct (GLib.GType gtype, bool use_cache)", class_struct_name); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\tif (class_structs == null)"); + sw.WriteLine ("\t\t\t\tclass_structs = new Hashtable ();"); + sw.WriteLine (); + sw.WriteLine ("\t\t\tif (use_cache && class_structs.Contains (gtype))"); + sw.WriteLine ("\t\t\t\treturn ({0}) class_structs [gtype];", class_struct_name); + sw.WriteLine ("\t\t\telse {"); + sw.WriteLine ("\t\t\t\tIntPtr class_ptr = new IntPtr (gtype.ClassPtr.ToInt64 () + class_offset);"); + sw.WriteLine ("\t\t\t\t{0} class_struct = ({0}) Marshal.PtrToStructure (class_ptr, typeof ({0}));", class_struct_name); + sw.WriteLine ("\t\t\t\tif (use_cache)"); + sw.WriteLine ("\t\t\t\t\tclass_structs.Add (gtype, class_struct);"); + sw.WriteLine ("\t\t\t\treturn class_struct;"); + sw.WriteLine ("\t\t\t}"); + sw.WriteLine ("\t\t}"); + sw.WriteLine (); + sw.WriteLine ("\t\tstatic void OverrideClassStruct (GLib.GType gtype, {0} class_struct)", class_struct_name); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\tIntPtr class_ptr = new IntPtr (gtype.ClassPtr.ToInt64 () + class_offset);"); + sw.WriteLine ("\t\t\tMarshal.StructureToPtr (class_struct, class_ptr, false);"); + sw.WriteLine ("\t\t}"); + sw.WriteLine (); + } + + /* Keep this in sync with the one in glib/GType.cs */ + private static string GetExpected (string cname) + { + for (int i = 1; i < cname.Length; i++) { + if (Char.IsUpper (cname[i])) { + if (i == 1 && cname[0] == 'G') + return "GLib." + cname.Substring (1); + else + return cname.Substring (0, i) + "." + cname.Substring (i); + } + } + + throw new ArgumentException ("cname doesn't follow the NamespaceType capitalization style: " + cname); + } + + private static bool NeedsMap (Hashtable objs, string assembly_name) + { + foreach (string key in objs.Keys) + if (GetExpected (key) != ((string) objs[key])) + return true; + + return false; + } + + private static string Studlify (string name) + { + string result = ""; + + string[] subs = name.Split ('-'); + foreach (string sub in subs) + result += Char.ToUpper (sub[0]) + sub.Substring (1); + + return result; + } + + public static void GenerateMappers () + { + foreach (string dir in dirs.Keys) { + + DirectoryInfo di = dirs[dir] as DirectoryInfo; + + if (!NeedsMap (di.objects, di.assembly_name)) + continue; + + GenerationInfo gen_info = new GenerationInfo (dir, di.assembly_name); + + GenerateMapper (di, gen_info); + } + } + + private static void GenerateMapper (DirectoryInfo dir_info, GenerationInfo gen_info) + { + StreamWriter sw = gen_info.OpenStream ("ObjectManager"); + + sw.WriteLine ("namespace GtkSharp." + Studlify (dir_info.assembly_name) + " {"); + sw.WriteLine (); + sw.WriteLine ("\tpublic class ObjectManager {"); + sw.WriteLine (); + sw.WriteLine ("\t\tstatic bool initialized = false;"); + sw.WriteLine ("\t\t// Call this method from the appropriate module init function."); + sw.WriteLine ("\t\tpublic static void Initialize ()"); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\tif (initialized)"); + sw.WriteLine ("\t\t\t\treturn;"); + sw.WriteLine (""); + sw.WriteLine ("\t\t\tinitialized = true;"); + + foreach (string key in dir_info.objects.Keys) { + if (GetExpected(key) != ((string) dir_info.objects[key])) + sw.WriteLine ("\t\t\tGLib.GType.Register ({0}.GType, typeof ({0}));", dir_info.objects [key]); + } + + sw.WriteLine ("\t\t}"); + sw.WriteLine ("\t}"); + sw.WriteLine ("}"); + sw.Close (); + } + + public string CallByName (string name, bool owned) + { + return name + " == null ? IntPtr.Zero : " + name + (owned ? ".OwnedHandle" : ".Handle"); + } + + public override string FromNative (string var, bool owned) + { + return "Gst.MiniObject.GetObject(" + var + (owned ? ", true" : "") + ") as " + QualifiedName; + } + } +} +