mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-20 02:50:16 +00:00
73ed037fa4
* gstreamer-sharp/BindingHelper.cs: Static helper class to assist in making element bindings (delegate manipulation/invocation) * gstreamer-sharp/DynamicSignal.cs: Updated DynamicSignalArgs so they can more easily be derived * gstreamer-sharp/Makefile.am: Updated build * sample/HelloWorld.cs: More cleaning * sample/Makefile.am: * sample/TypeFind.cs: Added typefind sample * gstreamer-sharp.mdp: Updated MonoDevelop project * gstreamer-sharp/plugins-base/DecodeBin.cs: Signal support rewritten to use BindingHelper/DynamicSignal * gstreamer-sharp/plugins-base/TypeFindElement.cs: New typefind element wrapper using BindingHelper/DynamicSignal * gstreamer-sharp/Element.custom: Fixed property getter/setter methods and added indexer wrapper for property lookup for syntax convenience git-svn-id: svn://anonsvn.mono-project.com/source/branches/abock/gstreamer-sharp@62570 e3ebcda4-bce8-0310-ba0a-eca2169e7518
160 lines
5.8 KiB
C#
160 lines
5.8 KiB
C#
//
|
|
// DynamicSignal.cs: C# bindings to g_dynamic_signal to provide
|
|
// dynamic runtime signal binding for GObject
|
|
//
|
|
// Authors:
|
|
// Aaron Bockover (abockover@novell.com)
|
|
//
|
|
// (C) 2006 Novell, Inc.
|
|
//
|
|
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace GLib
|
|
{
|
|
public delegate void DynamicSignalHandler(object o, DynamicSignalArgs args);
|
|
|
|
public class DynamicSignalArgs : EventArgs
|
|
{
|
|
private GLib.Object sender;
|
|
private object [] args;
|
|
|
|
public DynamicSignalArgs()
|
|
{
|
|
}
|
|
|
|
public DynamicSignalArgs(DynamicSignalArgs args)
|
|
{
|
|
Sender = args.Sender;
|
|
Args = args.Args;
|
|
}
|
|
|
|
public object this[int index] {
|
|
get { return Args[index]; }
|
|
}
|
|
|
|
public GLib.Object Sender {
|
|
get { return sender; }
|
|
internal set { sender = value; }
|
|
}
|
|
|
|
public object [] Args {
|
|
get { return args; }
|
|
internal set { args = value; }
|
|
}
|
|
}
|
|
|
|
public static class DynamicSignal
|
|
{
|
|
private delegate void DynamicSignalNativeHandler(IntPtr objectPtr, uint argc,
|
|
IntPtr argsPtr, IntPtr userdata);
|
|
|
|
private static DynamicSignalNativeHandler dynamic_signal_handler =
|
|
new DynamicSignalNativeHandler(OnDynamicSignalRaised);
|
|
|
|
private static readonly int gvalue_struct_size = Marshal.SizeOf(typeof(GLib.Value));
|
|
|
|
public static void Connect(GLib.Object o, string name, DynamicSignalHandler handler)
|
|
{
|
|
Connect(o, name, false, handler);
|
|
}
|
|
|
|
public static void Connect(GLib.Object o, string name, bool after,
|
|
DynamicSignalHandler handler)
|
|
{
|
|
IntPtr entry_ptr = FindRegisteredEntry(o, name);
|
|
if(entry_ptr == IntPtr.Zero) {
|
|
g_dynamic_signal_connect(o.Handle, name, dynamic_signal_handler,
|
|
after, (IntPtr)GCHandle.Alloc(handler));
|
|
return;
|
|
}
|
|
|
|
Delegate registered_handler = GetEntryHandler(entry_ptr);
|
|
if(registered_handler != null) {
|
|
Delegate new_handler = Delegate.Combine(registered_handler, handler);
|
|
if(new_handler != registered_handler) {
|
|
g_dynamic_signal_update_entry_userdata(entry_ptr,
|
|
(IntPtr)GCHandle.Alloc(new_handler));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Disconnect(GLib.Object o, string name, DynamicSignalHandler handler)
|
|
{
|
|
IntPtr entry_ptr = FindRegisteredEntry(o, name);
|
|
if(entry_ptr == IntPtr.Zero) {
|
|
return;
|
|
}
|
|
|
|
Delegate registered_handler = GetEntryHandler(entry_ptr);
|
|
Delegate new_handler = Delegate.Remove(registered_handler, handler);
|
|
if(new_handler == null || handler == null) {
|
|
g_dynamic_signal_disconnect(o.Handle, name);
|
|
return;
|
|
} else if(new_handler != null && registered_handler != new_handler) {
|
|
g_dynamic_signal_update_entry_userdata(entry_ptr,
|
|
(IntPtr)GCHandle.Alloc(new_handler));
|
|
}
|
|
}
|
|
|
|
private static IntPtr FindRegisteredEntry(GLib.Object o, string name)
|
|
{
|
|
return g_dynamic_signal_find_registration(o.Handle, name);
|
|
}
|
|
|
|
private static DynamicSignalHandler GetEntryHandler(IntPtr entryPtr)
|
|
{
|
|
IntPtr handler_ptr = Marshal.ReadIntPtr(entryPtr, Marshal.SizeOf(typeof(IntPtr)));
|
|
return (DynamicSignalHandler)((GCHandle)handler_ptr).Target;
|
|
}
|
|
|
|
private static void OnDynamicSignalRaised(IntPtr objectPtr, uint argc,
|
|
IntPtr argsPtr, IntPtr userdata)
|
|
{
|
|
GLib.Object gobject = GLib.Object.GetObject(objectPtr, false);
|
|
object [] args = new object[argc];
|
|
|
|
for(int i = 0; i < argc; i++) {
|
|
IntPtr struct_ptr = (IntPtr)((long)argsPtr + (i * gvalue_struct_size));
|
|
GLib.Value argument = (GLib.Value)Marshal.PtrToStructure(
|
|
struct_ptr, typeof(GLib.Value));
|
|
Type type = GType.LookupType(g_value_type(struct_ptr));
|
|
|
|
if(type.IsSubclassOf(typeof(GLib.Opaque))) {
|
|
args[i] = GLib.Opaque.GetOpaque(g_value_peek_pointer(struct_ptr), type, true);
|
|
} else {
|
|
args[i] = argument.Val;
|
|
}
|
|
}
|
|
|
|
DynamicSignalHandler handler = (DynamicSignalHandler)((GCHandle)userdata).Target;
|
|
if(handler != null) {
|
|
DynamicSignalArgs dargs = new DynamicSignalArgs();
|
|
dargs.Sender = gobject;
|
|
dargs.Args = args;
|
|
handler(gobject, dargs);
|
|
}
|
|
}
|
|
|
|
[DllImport("gstreamersharpglue-0.10")]
|
|
private static extern uint g_dynamic_signal_connect(IntPtr o, string name,
|
|
DynamicSignalNativeHandler callback, bool swapped, IntPtr userdata);
|
|
|
|
[DllImport("gstreamersharpglue-0.10")]
|
|
private static extern void g_dynamic_signal_disconnect(IntPtr o, string name);
|
|
|
|
[DllImport("gstreamersharpglue-0.10")]
|
|
private static extern IntPtr g_dynamic_signal_find_registration(IntPtr o, string name);
|
|
|
|
[DllImport("gstreamersharpglue-0.10")]
|
|
private static extern void g_dynamic_signal_update_entry_userdata(IntPtr entry, IntPtr userdata);
|
|
|
|
[DllImport("gstreamersharpglue-0.10")]
|
|
private static extern IntPtr g_value_type(IntPtr value);
|
|
|
|
[DllImport("libgobject-2.0-0.dll")]
|
|
private static extern IntPtr g_value_peek_pointer(IntPtr value);
|
|
}
|
|
}
|
|
|