Add a method to retrieve the property info of a single property

This commit is contained in:
Sebastian Dröge 2009-05-12 15:50:04 +02:00
parent 1811d89b6e
commit a3032c0565
2 changed files with 86 additions and 62 deletions

View file

@ -10,37 +10,24 @@ public object this[string property] {
}
}
[StructLayout (LayoutKind.Sequential) ]
struct GTypeInstance {
public IntPtr g_class;
}
[StructLayout (LayoutKind.Sequential) ]
struct GParamSpec {
public GTypeInstance instance;
IntPtr name;
public int Flags;
public IntPtr ValueType;
public IntPtr OwnerType;
}
[DllImport ("libgobject-2.0-0.dll") ]
static extern IntPtr g_object_class_list_properties (IntPtr klass, out uint n_properties);
[DllImport ("libgobject-2.0-0.dll") ]
static extern IntPtr g_param_spec_get_name (IntPtr pspec);
static extern IntPtr g_object_class_find_property (IntPtr gclass, IntPtr name);
[DllImport ("libgobject-2.0-0.dll") ]
static extern IntPtr g_param_spec_get_nick (IntPtr pspec);
public PropertyInfo GetPropertyInfo (string property) {
IntPtr klass = Marshal.ReadIntPtr (Handle);
[DllImport ("libgobject-2.0-0.dll") ]
static extern IntPtr g_param_spec_get_blurb (IntPtr pspec);
IntPtr native_property = GLib.Marshaller.StringToPtrGStrdup (property);
IntPtr pspec = g_object_class_find_property (klass, native_property);
GLib.Marshaller.Free (native_property);
[DllImport ("libgobject-2.0-0.dll") ]
static extern void g_param_value_set_default (IntPtr pspec, ref GLib.Value val);
if (pspec == IntPtr.Zero)
throw new ArgumentException ("Unknown property");
[DllImport ("gstreamersharpglue-0.10") ]
static extern bool gstsharp_g_param_spec_get_range (IntPtr pspec, ref GLib.Value min, ref GLib.Value max);
return new PropertyInfo (pspec);
}
public PropertyInfo[] Properties {
get {
@ -51,46 +38,8 @@ public PropertyInfo[] Properties {
PropertyInfo[] ret = new PropertyInfo[n_properties];
for (int i = 0; i < n_properties; i++) {
IntPtr pspec_ptr = Marshal.ReadIntPtr (properties, i * IntPtr.Size);
GParamSpec pspec = (GParamSpec) Marshal.PtrToStructure (pspec_ptr, typeof (GParamSpec));
IntPtr name = g_param_spec_get_name (pspec_ptr);
IntPtr nick = g_param_spec_get_nick (pspec_ptr);
IntPtr blurb = g_param_spec_get_blurb (pspec_ptr);
ret[i].name = GLib.Marshaller.Utf8PtrToString (name);
ret[i].nick = GLib.Marshaller.Utf8PtrToString (nick);
ret[i].blurb = GLib.Marshaller.Utf8PtrToString (blurb);
ret[i].readable = ( (pspec.Flags & (1 << 0)) != 0);
ret[i].writeable = ( (pspec.Flags & (1 << 1)) != 0);
ret[i].controllable = ( (pspec.Flags & (1 << 9)) != 0);
/* TODO: Add more flags later, like the mutable flags */
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));
g_param_value_set_default (pspec_ptr, ref v);
ret[i].dflt = v.Val;
v.Dispose ();
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 ();
}
} catch (Exception) {}
ret[i] = new PropertyInfo (pspec_ptr);
}
GLib.Marshaller.Free (properties);
return ret;

View file

@ -1,4 +1,6 @@
using System;
using System.Runtime.InteropServices;
using GLib;
namespace Gst {
public struct PropertyInfo {
@ -78,6 +80,79 @@ namespace Gst {
return max;
}
}
[DllImport ("libgobject-2.0-0.dll") ]
static extern IntPtr g_param_spec_get_name (IntPtr pspec);
[DllImport ("libgobject-2.0-0.dll") ]
static extern IntPtr g_param_spec_get_nick (IntPtr pspec);
[DllImport ("libgobject-2.0-0.dll") ]
static extern IntPtr g_param_spec_get_blurb (IntPtr pspec);
[DllImport ("libgobject-2.0-0.dll") ]
static extern void g_param_value_set_default (IntPtr pspec, ref GLib.Value val);
[DllImport ("gstreamersharpglue-0.10") ]
static extern bool gstsharp_g_param_spec_get_range (IntPtr pspec, ref GLib.Value min, ref GLib.Value max);
[StructLayout (LayoutKind.Sequential) ]
struct GTypeInstance {
public IntPtr g_class;
}
[StructLayout (LayoutKind.Sequential) ]
struct GParamSpec {
public GTypeInstance instance;
IntPtr name;
public int Flags;
public IntPtr ValueType;
public IntPtr OwnerType;
}
internal PropertyInfo (IntPtr pspec_ptr) {
GParamSpec pspec = (GParamSpec) Marshal.PtrToStructure (pspec_ptr, typeof (GParamSpec));
IntPtr name = g_param_spec_get_name (pspec_ptr);
IntPtr nick = g_param_spec_get_nick (pspec_ptr);
IntPtr blurb = g_param_spec_get_blurb (pspec_ptr);
this.name = GLib.Marshaller.Utf8PtrToString (name);
this.nick = GLib.Marshaller.Utf8PtrToString (nick);
this.blurb = GLib.Marshaller.Utf8PtrToString (blurb);
this.readable = ( (pspec.Flags & (1 << 0)) != 0);
this.writeable = ( (pspec.Flags & (1 << 1)) != 0);
this.controllable = ( (pspec.Flags & (1 << 9)) != 0);
/* TODO: Add more flags later, like the mutable flags */
this.gtype = new GLib.GType (pspec.ValueType);
this.type = (System.Type) this.gtype;
this.dflt = this.min = this.max = null;
try {
GLib.Value v = new GLib.Value (new GLib.GType (pspec.ValueType));
g_param_value_set_default (pspec_ptr, ref v);
this.dflt = v.Val;
v.Dispose ();
if (EnumInfo.IsEnumType (this.gtype)) {
EnumInfo ei = new EnumInfo (this.gtype);
this.min = ei.Min;
this.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)) {
this.min = (object) min.Val;
this.max = (object) max.Val;
}
min.Dispose ();
max.Dispose ();
}
} catch (Exception) {}
}
}
}