[gst-cvs] gstreamer-sharp: Add Enum/FlagsInfo to query a GEnum/GFlags type

Sebastian Dröge slomo at kemper.freedesktop.org
Thu May 14 08:16:04 PDT 2009


Module: gstreamer-sharp
Branch: master
Commit: 08ea583412ceaa49a11084e92d542c5f6565f0c9
URL:    http://cgit.freedesktop.org/gstreamer/gstreamer-sharp/commit/?id=08ea583412ceaa49a11084e92d542c5f6565f0c9

Author: Sebastian Dröge <sebastian.droege at collabora.co.uk>
Date:   Tue May 12 15:27:13 2009 +0200

Add Enum/FlagsInfo to query a GEnum/GFlags type

---

 gstreamer-sharp/EnumInfo.cs   |  204 +++++++++++++++++++++++++++++++++++++++++
 gstreamer-sharp/Makefile.am   |    1 +
 gstreamer-sharp/Object.custom |   23 +++--
 3 files changed, 220 insertions(+), 8 deletions(-)

diff --git a/gstreamer-sharp/EnumInfo.cs b/gstreamer-sharp/EnumInfo.cs
new file mode 100644
index 0000000..758c8ac
--- /dev/null
+++ b/gstreamer-sharp/EnumInfo.cs
@@ -0,0 +1,204 @@
+using GLib;
+using Gst;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Gst {
+
+  public struct EnumValue {
+    internal int value;
+    public int Value {
+      get {
+        return value;
+      }
+    }
+
+    internal string value_name;
+    public string Name {
+      get {
+        return value_name;
+      }
+    }
+
+    internal string value_nick;
+    public string Nick {
+      get {
+        return value_nick;
+      }
+    }
+  }
+
+  public struct FlagsValue {
+    internal uint value;
+    public uint Value {
+      get {
+        return value;
+      }
+    }
+
+    internal string value_name;
+    public string Name {
+      get {
+        return value_name;
+      }
+    }
+
+    internal string value_nick;
+    public string Nick {
+      get {
+        return value_nick;
+      }
+    }
+  }
+
+  public struct EnumInfo {
+    [StructLayout (LayoutKind.Sequential) ]
+    struct GTypeClass {
+      IntPtr gtype;
+    }
+
+    [StructLayout (LayoutKind.Sequential) ]
+    struct GEnumClass {
+      GTypeClass gclass;
+      public int minimum;
+      public int maximum;
+      public uint n_values;
+      public IntPtr values;
+    }
+
+    [StructLayout (LayoutKind.Sequential) ]
+    struct GEnumValue {
+      public int value;
+      public IntPtr value_name;
+      public IntPtr value_nick;
+    }
+
+    [DllImport ("libgobject-2.0-0.dll") ]
+    static extern IntPtr g_type_class_ref (IntPtr gtype);
+    [DllImport ("libgobject-2.0-0.dll") ]
+    static extern void g_type_class_unref (IntPtr gclass);
+    [DllImport ("libgobject-2.0-0.dll") ]
+    static extern bool g_type_is_a (IntPtr type, IntPtr is_a_type);
+
+    int min;
+    public int Min {
+      get {
+        return min;
+      }
+    }
+
+    int max;
+    public int Max {
+      get {
+        return max;
+      }
+    }
+
+    EnumValue[] values;
+    public EnumValue[] Values {
+      get {
+        return values;
+      }
+    }
+
+    public static bool IsEnumType (GLib.GType gtype) {
+      return (g_type_is_a (gtype.Val, GType.Enum.Val));
+    }
+
+    public EnumInfo (GLib.GType gtype) {
+      if (!IsEnumType (gtype))
+        throw new ArgumentException ();
+
+      IntPtr class_ptr = g_type_class_ref (gtype.Val);
+      if (class_ptr == IntPtr.Zero)
+        throw new Exception ();
+
+      GEnumClass klass = (GEnumClass) Marshal.PtrToStructure (class_ptr, typeof (GEnumClass));
+      this.min = klass.minimum;
+      this.max = klass.maximum;
+
+      values = new EnumValue[klass.n_values];
+      int unmanaged_struct_size = Marshal.SizeOf (typeof (GEnumValue));
+      for (int i = 0; i < klass.n_values; i++) {
+        GEnumValue gv = (GEnumValue) Marshal.PtrToStructure (new IntPtr (klass.values.ToInt64() + i * unmanaged_struct_size), typeof (GEnumValue));
+        values[i].value = gv.value;
+        values[i].value_name = GLib.Marshaller.Utf8PtrToString (gv.value_name);
+        values[i].value_nick = GLib.Marshaller.Utf8PtrToString (gv.value_nick);
+      }
+
+      g_type_class_unref (class_ptr);
+
+    }
+  }
+
+  public struct FlagsInfo {
+    [StructLayout (LayoutKind.Sequential) ]
+    struct GTypeClass {
+      IntPtr gtype;
+    }
+
+    [StructLayout (LayoutKind.Sequential) ]
+    struct GFlagsClass {
+      GTypeClass gclass;
+      public uint mask;
+      public uint n_values;
+      public IntPtr values;
+    }
+
+    [StructLayout (LayoutKind.Sequential) ]
+    struct GFlagsValue {
+      public uint value;
+      public IntPtr value_name;
+      public IntPtr value_nick;
+    }
+
+    [DllImport ("libgobject-2.0-0.dll") ]
+    static extern IntPtr g_type_class_ref (IntPtr gtype);
+    [DllImport ("libgobject-2.0-0.dll") ]
+    static extern void g_type_class_unref (IntPtr gclass);
+    [DllImport ("libgobject-2.0-0.dll") ]
+    static extern bool g_type_is_a (IntPtr type, IntPtr is_a_type);
+
+    uint mask;
+    public uint Mask {
+      get {
+        return mask;
+      }
+    }
+
+    FlagsValue[] values;
+    public FlagsValue[] Values {
+      get {
+        return values;
+      }
+    }
+
+    public static bool IsFlagsType (GLib.GType gtype) {
+      return (g_type_is_a (gtype.Val, GType.Flags.Val));
+    }
+
+    public FlagsInfo (GLib.GType gtype) {
+      if (!IsFlagsType (gtype))
+        throw new ArgumentException ();
+
+      IntPtr class_ptr = g_type_class_ref (gtype.Val);
+      if (class_ptr == IntPtr.Zero)
+        throw new Exception ();
+
+      GFlagsClass klass = (GFlagsClass) Marshal.PtrToStructure (class_ptr, typeof (GFlagsClass));
+      this.mask = klass.mask;
+
+      values = new FlagsValue[klass.n_values];
+      int unmanaged_struct_size = Marshal.SizeOf (typeof (GFlagsValue));
+      for (int i = 0; i < klass.n_values; i++) {
+        GFlagsValue gv = (GFlagsValue) Marshal.PtrToStructure (new IntPtr (klass.values.ToInt64() + i * unmanaged_struct_size), typeof (GFlagsValue));
+        values[i].value = gv.value;
+        values[i].value_name = GLib.Marshaller.Utf8PtrToString (gv.value_name);
+        values[i].value_nick = GLib.Marshaller.Utf8PtrToString (gv.value_nick);
+      }
+
+      g_type_class_unref (class_ptr);
+    }
+
+  }
+}
diff --git a/gstreamer-sharp/Makefile.am b/gstreamer-sharp/Makefile.am
index 605da90..78716fe 100644
--- a/gstreamer-sharp/Makefile.am
+++ b/gstreamer-sharp/Makefile.am
@@ -45,6 +45,7 @@ sources = \
 	GError.cs \
 	Value.cs \
 	PropertyInfo.cs \
+	EnumInfo.cs \
 	Iterator.cs \
 	GstSharp.PadQueryTypeFunctionNative.cs \
 	PadQueryTypeFunction.cs \
diff --git a/gstreamer-sharp/Object.custom b/gstreamer-sharp/Object.custom
index 2cb0f51..5e38ce7 100644
--- a/gstreamer-sharp/Object.custom
+++ b/gstreamer-sharp/Object.custom
@@ -62,7 +62,8 @@ public PropertyInfo[] Properties {
       ret[i].controllable = ( (pspec.Flags & (1 << 9)) != 0);
       /* TODO: Add more flags later, like the mutable flags */
 
-      ret[i].type = (System.Type) new GLib.GType (pspec.ValueType);
+      ret[i].gtype = new GLib.GType (pspec.ValueType);
+      ret[i].type = (System.Type) ret[i].gtype;
 
       try {
         GLib.Value v = new GLib.Value (new GLib.GType (pspec.ValueType));
@@ -70,14 +71,20 @@ public PropertyInfo[] Properties {
         ret[i].dflt = v.Val;
         v.Dispose ();
 
-        GLib.Value min = new GLib.Value (new GLib.GType (pspec.ValueType));
-        GLib.Value max = new GLib.Value (new GLib.GType (pspec.ValueType));
-        if (gstsharp_g_param_spec_get_range (pspec_ptr, ref min, ref max)) {
-          ret[i].min = (object) min.Val;
-          ret[i].max = (object) max.Val;
+        if (EnumInfo.IsEnumType (ret[i].gtype)) {
+          EnumInfo ei = new EnumInfo (ret[i].gtype);
+          ret[i].min = ei.Min;
+          ret[i].max = ei.Max;
+        } else {
+          GLib.Value min = new GLib.Value (new GLib.GType (pspec.ValueType));
+          GLib.Value max = new GLib.Value (new GLib.GType (pspec.ValueType));
+          if (gstsharp_g_param_spec_get_range (pspec_ptr, ref min, ref max)) {
+            ret[i].min = (object) min.Val;
+            ret[i].max = (object) max.Val;
+          }
+          min.Dispose ();
+          max.Dispose ();
         }
-        min.Dispose ();
-        max.Dispose ();
       } catch (Exception) {}
     }
 





More information about the Gstreamer-commits mailing list