[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