diff --git a/generator/Makefile.am b/generator/Makefile.am
index 2fc3aabe7..a45405357 100644
--- a/generator/Makefile.am
+++ b/generator/Makefile.am
@@ -64,6 +64,7 @@ sources = \
StructField.cs \
StructGen.cs \
SymbolTable.cs \
+ UnionGen.cs \
VirtualMethod.cs \
VMSignature.cs \
XmlElementExtensions.cs
diff --git a/generator/Parameters.cs b/generator/Parameters.cs
index 2ea48d260..ae953ab7e 100644
--- a/generator/Parameters.cs
+++ b/generator/Parameters.cs
@@ -93,23 +93,23 @@ namespace GtkSharp.Generation {
if (HasCB || HideData) {
- foreach (Parameter param in param_list) {
- if (param.Closure == idx)
+ if (Parser.GetVersion (elem.OwnerDocument.DocumentElement) >= 3) {
+ foreach (Parameter param in param_list) {
+ if (param.Closure == idx)
+ return true;
+ if (param.DestroyNotify == idx)
+ return true;
+ }
+ } else {
+ if (p.IsUserData && (idx == Count - 1))
return true;
- else if (param.DestroyNotify == idx)
+ if (p.IsUserData && (idx == Count - 2) && this [Count - 1] is ErrorParameter)
+ return true;
+ if (p.IsUserData && idx > 0 && this [idx - 1].Generatable is CallbackGen)
+ return true;
+ if (p.IsDestroyNotify && (idx == Count - 1) && this [idx - 1].IsUserData)
return true;
}
-
- if (p.IsUserData && (idx == Count - 1))
- return true;
- if (p.IsUserData && (idx == Count - 2) && this [Count - 1] is ErrorParameter)
- return true;
- if (p.IsUserData && idx > 0 &&
- this [idx - 1].Generatable is CallbackGen)
- return true;
- if (p.IsDestroyNotify && (idx == Count - 1) &&
- this [idx - 1].IsUserData)
- return true;
}
return false;
@@ -234,7 +234,8 @@ namespace GtkSharp.Generation {
param_list.Add (p);
}
- if (has_cb && Count > 2 && this [Count - 3].Generatable is CallbackGen && this [Count - 2].IsUserData && this [Count - 1].IsDestroyNotify)
+ if (Parser.GetVersion (elem.OwnerDocument.DocumentElement) < 3 &&
+ 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;
diff --git a/generator/Parser.cs b/generator/Parser.cs
index b7bfa5f98..0974d5908 100644
--- a/generator/Parser.cs
+++ b/generator/Parser.cs
@@ -171,6 +171,9 @@ namespace GtkSharp.Generation {
case "class":
result.Add (new ClassGen (ns, elem));
break;
+ case "union":
+ result.Add (new UnionGen (ns, elem));
+ break;
case "struct":
if (is_opaque) {
result.Add (new OpaqueGen (ns, elem));
diff --git a/generator/StructBase.cs b/generator/StructBase.cs
index 6fc7bcde5..9288fc3a4 100644
--- a/generator/StructBase.cs
+++ b/generator/StructBase.cs
@@ -110,6 +110,12 @@ namespace GtkSharp.Generation {
}
}
+ public virtual bool Union {
+ get {
+ return false;
+ }
+ }
+
protected void GenEqualsAndHash (StreamWriter sw)
{
int bitfields = 0;
@@ -172,12 +178,13 @@ namespace GtkSharp.Generation {
{
int bitfields = 0;
bool need_field = true;
+ StreamWriter sw = gen_info.Writer;
foreach (StructField field in fields) {
+ if (Union)
+ sw.WriteLine ("\t\t[FieldOffset(0)]");
if (field.IsBitfield) {
if (need_field) {
- StreamWriter sw = gen_info.Writer;
-
sw.WriteLine ("\t\tprivate uint _bitfield{0};\n", bitfields++);
need_field = false;
}
@@ -221,7 +228,10 @@ namespace GtkSharp.Generation {
sw.WriteLine ("#region Autogenerated code");
if (IsDeprecated)
sw.WriteLine ("\t[Obsolete]");
- sw.WriteLine ("\t[StructLayout(LayoutKind.Sequential)]");
+ if (Union)
+ sw.WriteLine ("\t[StructLayout(LayoutKind.Explicit)]");
+ else
+ sw.WriteLine ("\t[StructLayout(LayoutKind.Sequential)]");
string access = IsInternal ? "internal" : "public";
sw.WriteLine ("\t" + access + " partial struct {0} : IEquatable<{0}> {{", Name);
sw.WriteLine ();
diff --git a/generator/StructField.cs b/generator/StructField.cs
index ac885038e..e0ba545d4 100644
--- a/generator/StructField.cs
+++ b/generator/StructField.cs
@@ -80,7 +80,7 @@ namespace GtkSharp.Generation {
return StudlyName;
else if (IsBitfield)
return Name;
- else if (IsPointer && (gen is StructGen || gen is BoxedGen))
+ else if (IsPointer && (gen is StructGen || gen is BoxedGen || gen is UnionGen))
return Access != "private" ? wrapped_name : Name;
else if (IsPointer && CSType != "string")
return Name;
@@ -148,7 +148,7 @@ namespace GtkSharp.Generation {
acc.WriteAccessors (sw, indent + "\t", Name);
sw.WriteLine (indent + "}");
}
- } else if (IsPointer && (gen is StructGen || gen is BoxedGen)) {
+ } else if (IsPointer && (gen is StructGen || gen is BoxedGen || gen is UnionGen)) {
sw.WriteLine (indent + "private {0} {1};", CSType, Name);
sw.WriteLine ();
if (Access != "private") {
diff --git a/generator/SymbolTable.cs b/generator/SymbolTable.cs
index e4cca25d7..823494a97 100644
--- a/generator/SymbolTable.cs
+++ b/generator/SymbolTable.cs
@@ -292,6 +292,13 @@ namespace GtkSharp.Generation {
return false;
}
+
+ public bool IsUnion (string c_type)
+ {
+ if (this[c_type] is UnionGen)
+ return true;
+ return false;
+ }
public bool IsEnum(string c_type)
{
diff --git a/generator/UnionGen.cs b/generator/UnionGen.cs
new file mode 100644
index 000000000..15589b262
--- /dev/null
+++ b/generator/UnionGen.cs
@@ -0,0 +1,18 @@
+
+using System.Xml;
+
+namespace GtkSharp.Generation
+{
+ public class UnionGen : StructBase {
+
+ public UnionGen (XmlElement ns, XmlElement elem) : base (ns, elem)
+ {
+ }
+
+ public override bool Union {
+ get {
+ return true;
+ }
+ }
+ }
+}
diff --git a/generator/generator.csproj b/generator/generator.csproj
index 41ccce2e6..1d19e62ae 100644
--- a/generator/generator.csproj
+++ b/generator/generator.csproj
@@ -92,6 +92,7 @@
+