From 9c636a83be3c070a3944d61bc83c020d41880764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 12 May 2009 14:31:57 +0200 Subject: [PATCH] Add a Properties property to Gst.Object to get information about the GObject properties --- gstreamer-sharp/Makefile.am | 1 + gstreamer-sharp/Object.custom | 80 +++++++++++++ gstreamer-sharp/PropertyInfo.cs | 76 ++++++++++++ gstreamer-sharp/glue/gobject.c | 111 ++++++++++++++++++ gstreamer-sharp/override/URIHandlerAdapter.cs | 4 +- 5 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 gstreamer-sharp/PropertyInfo.cs diff --git a/gstreamer-sharp/Makefile.am b/gstreamer-sharp/Makefile.am index 39425bf436..605da90eb1 100644 --- a/gstreamer-sharp/Makefile.am +++ b/gstreamer-sharp/Makefile.am @@ -44,6 +44,7 @@ sources = \ AssemblyInfo.cs \ GError.cs \ Value.cs \ + PropertyInfo.cs \ Iterator.cs \ GstSharp.PadQueryTypeFunctionNative.cs \ PadQueryTypeFunction.cs \ diff --git a/gstreamer-sharp/Object.custom b/gstreamer-sharp/Object.custom index ccd5fd0ae6..2cb0f51aa7 100644 --- a/gstreamer-sharp/Object.custom +++ b/gstreamer-sharp/Object.custom @@ -7,6 +7,86 @@ 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); + +[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); + +public PropertyInfo[] Properties { + get { + uint n_properties; + IntPtr klass = Marshal.ReadIntPtr (Handle); + IntPtr properties = g_object_class_list_properties (klass, out n_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].type = (System.Type) new GLib.GType (pspec.ValueType); + + 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 (); + + 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) {} + } + + GLib.Marshaller.Free (properties); + + return ret; + } +} + public void Connect (string signal, DynamicSignalHandler handler) { DynamicSignal.Connect (this, signal, handler); } diff --git a/gstreamer-sharp/PropertyInfo.cs b/gstreamer-sharp/PropertyInfo.cs new file mode 100644 index 0000000000..0ded88e413 --- /dev/null +++ b/gstreamer-sharp/PropertyInfo.cs @@ -0,0 +1,76 @@ +using System; + +namespace Gst { + public struct PropertyInfo { + internal string name; + public string Name { + get { + return name; + } + } + + internal string nick; + public string Nick { + get { + return nick; + } + } + + internal string blurb; + public string Blurb { + get { + return blurb; + } + } + + internal bool readable; + public bool Readable { + get { + return readable; + } + } + + internal bool writeable; + public bool Writeable { + get { + return writeable; + } + } + + internal bool controllable; + public bool Controllable { + get { + return controllable; + } + } + + internal System.Type type; + public System.Type Type { + get { + return type; + } + } + + internal object dflt; + public object Default { + get { + return dflt; + } + } + + internal object min; + public object Min { + get { + return min; + } + } + + internal object max; + public object Max { + get { + return max; + } + } + } + +} diff --git a/gstreamer-sharp/glue/gobject.c b/gstreamer-sharp/glue/gobject.c index 61d2bdea5d..bbe05f7e2a 100644 --- a/gstreamer-sharp/glue/gobject.c +++ b/gstreamer-sharp/glue/gobject.c @@ -1,4 +1,5 @@ #include +#include gint gstsharp_g_closure_sizeof (void) @@ -11,3 +12,113 @@ gstsharp_g_type_from_instance (GTypeInstance * instance) { return G_TYPE_FROM_INSTANCE (instance); } + +gboolean +gstsharp_g_param_spec_get_range (const GParamSpec * pspec, GValue * min, + GValue * max) +{ + switch (pspec->value_type) { + case G_TYPE_CHAR:{ + GParamSpecChar *pchar = G_PARAM_SPEC_CHAR (pspec); + + g_value_set_char (min, pchar->minimum); + g_value_set_char (max, pchar->maximum); + + return TRUE; + } + break; + case G_TYPE_UCHAR:{ + GParamSpecUChar *puchar = G_PARAM_SPEC_UCHAR (pspec); + + g_value_set_uchar (min, puchar->minimum); + g_value_set_uchar (max, puchar->maximum); + + return TRUE; + } + break; + case G_TYPE_INT:{ + GParamSpecInt *pint = G_PARAM_SPEC_INT (pspec); + + g_value_set_int (min, pint->minimum); + g_value_set_int (max, pint->maximum); + + return TRUE; + } + break; + case G_TYPE_UINT:{ + GParamSpecUInt *puint = G_PARAM_SPEC_UINT (pspec); + + g_value_set_uint (min, puint->minimum); + g_value_set_uint (max, puint->maximum); + + return TRUE; + } + break; + case G_TYPE_INT64:{ + GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (pspec); + + g_value_set_int64 (min, pint64->minimum); + g_value_set_int64 (max, pint64->maximum); + + return TRUE; + } + break; + case G_TYPE_UINT64:{ + GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (pspec); + + g_value_set_uint64 (min, puint64->minimum); + g_value_set_uint64 (max, puint64->maximum); + + return TRUE; + } + break; + case G_TYPE_LONG:{ + GParamSpecLong *plong = G_PARAM_SPEC_LONG (pspec); + + g_value_set_long (min, plong->minimum); + g_value_set_long (max, plong->maximum); + + return TRUE; + } + break; + case G_TYPE_ULONG:{ + GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (pspec); + + g_value_set_ulong (min, pulong->minimum); + g_value_set_ulong (max, pulong->maximum); + + return TRUE; + } + break; + case G_TYPE_FLOAT:{ + GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (pspec); + + g_value_set_float (min, pfloat->minimum); + g_value_set_float (max, pfloat->maximum); + + return TRUE; + } + break; + case G_TYPE_DOUBLE:{ + GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (pspec); + + g_value_set_double (min, pdouble->minimum); + g_value_set_double (max, pdouble->maximum); + + return TRUE; + } + break; + default: + if (pspec->value_type == GST_TYPE_FRACTION) { + GstParamSpecFraction *pfraction = GST_PARAM_SPEC_FRACTION (pspec); + + gst_value_set_fraction (min, pfraction->min_num, pfraction->min_den); + gst_value_set_fraction (max, pfraction->max_num, pfraction->max_den); + + return TRUE; + } + break; + } + + return FALSE; +} diff --git a/gstreamer-sharp/override/URIHandlerAdapter.cs b/gstreamer-sharp/override/URIHandlerAdapter.cs index 5cab6b404d..1eb289e18b 100644 --- a/gstreamer-sharp/override/URIHandlerAdapter.cs +++ b/gstreamer-sharp/override/URIHandlerAdapter.cs @@ -44,7 +44,7 @@ namespace Gst { GLib.GType gt = new GLib.GType (gtype); System.Type t = (System.Type) gt; - PropertyInfo pi = t.GetProperty ("Type", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy); + System.Reflection.PropertyInfo pi = t.GetProperty ("Type", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy); Gst.URIType __result = Gst.URIType.Unknown; if (pi != null && pi.PropertyType == typeof (Gst.URIType)) __result = (Gst.URIType) pi.GetValue (null, null); @@ -72,7 +72,7 @@ namespace Gst { return (IntPtr[]) protocols_cache[gtype]; } - PropertyInfo pi = t.GetProperty ("Protocols", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy); + System.Reflection.PropertyInfo pi = t.GetProperty ("Protocols", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy); string[] __result; if (pi != null && pi.PropertyType == typeof (string[])) __result = (string[]) pi.GetValue (null, null);