From 4de7ad49141f1493f38e7343c82f3d3e80e0a3e6 Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Wed, 29 Oct 2008 21:41:57 +0000 Subject: [PATCH] 2008-10-29 Mike Kestner * glib/Signal.cs : custom marshaling hooks * glib/SignalClosure.cs : support for custom marshalers. svn path=/trunk/gtk-sharp/; revision=117424 --- ChangeLog | 5 +++++ glib/Signal.cs | 13 ++++++++++--- glib/SignalClosure.cs | 20 +++++++++++++++++++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2a9b5224b..5fc271e4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-10-29 Mike Kestner + + * glib/Signal.cs : custom marshaling hooks + * glib/SignalClosure.cs : support for custom marshalers. + 2008-10-28 Stephane Delcroix * gtk/Gtk.Metadata: hide ConnectSignals. diff --git a/glib/Signal.cs b/glib/Signal.cs index d3e21cf45..9b656abf5 100644 --- a/glib/Signal.cs +++ b/glib/Signal.cs @@ -127,12 +127,14 @@ namespace GLib { Type args_type; SignalClosure before_closure; SignalClosure after_closure; + Delegate marshaler; private Signal (GLib.Object obj, string signal_name, Delegate marshaler) { tref = obj.ToggleRef; name = signal_name; tref.Signals [name] = this; + this.marshaler = marshaler; } private Signal (GLib.Object obj, string signal_name, Type args_type) @@ -207,7 +209,6 @@ namespace GLib { return Lookup (obj, name, typeof (EventArgs)); } - [Obsolete ("Replaced by Lookup (Object obj, string name, Type args_type)")] public static Signal Lookup (GLib.Object obj, string name, Delegate marshaler) { Signal result = obj.ToggleRef.Signals [name] as Signal; @@ -243,7 +244,10 @@ namespace GLib { if (d.Method.IsDefined (typeof (ConnectBeforeAttribute), false)) { tref.Target.BeforeSignals [name] = Delegate.Combine (tref.Target.BeforeSignals [name] as Delegate, d); if (before_closure == null) { - before_closure = new SignalClosure (tref.Handle, name, args_type); + if (marshaler == null) + before_closure = new SignalClosure (tref.Handle, name, args_type); + else + before_closure = new SignalClosure (tref.Handle, name, marshaler, this); before_closure.Disposed += ClosureDisposedHandler; before_closure.Invoked += ClosureInvokedHandler; before_closure.Connect (false); @@ -251,7 +255,10 @@ namespace GLib { } else { tref.Target.AfterSignals [name] = Delegate.Combine (tref.Target.AfterSignals [name] as Delegate, d); if (after_closure == null) { - after_closure = new SignalClosure (tref.Handle, name, args_type); + if (marshaler == null) + after_closure = new SignalClosure (tref.Handle, name, args_type); + else + after_closure = new SignalClosure (tref.Handle, name, marshaler, this); after_closure.Disposed += ClosureDisposedHandler; after_closure.Invoked += ClosureInvokedHandler; after_closure.Connect (true); diff --git a/glib/SignalClosure.cs b/glib/SignalClosure.cs index 82bed1aa2..3331e25b9 100644 --- a/glib/SignalClosure.cs +++ b/glib/SignalClosure.cs @@ -25,7 +25,7 @@ namespace GLib { using System.Collections; using System.Runtime.InteropServices; - internal class ClosureInvokedArgs : EventArgs { + internal class ClosureInvokedArgs : EventArgs { EventArgs args; GLib.Object obj; @@ -59,6 +59,8 @@ namespace GLib { string name; uint id = UInt32.MaxValue; System.Type args_type; + Delegate custom_marshaler; + GCHandle gch; static Hashtable closures = new Hashtable (); @@ -71,6 +73,16 @@ namespace GLib { this.args_type = args_type; } + public SignalClosure (IntPtr obj, string signal_name, Delegate custom_marshaler, Signal signal) + { + gch = GCHandle.Alloc (signal); + raw_closure = g_cclosure_new (custom_marshaler, (IntPtr) gch, Notify); + closures [raw_closure] = this; + handle = obj; + name = signal_name; + this.custom_marshaler = custom_marshaler; + } + public event EventHandler Disposed; public event ClosureInvokedHandler Invoked; @@ -91,6 +103,9 @@ namespace GLib { { Disconnect (); closures.Remove (raw_closure); + if (custom_marshaler != null) + gch.Free (); + custom_marshaler = null; if (Disposed != null) Disposed (this, EventArgs.Empty); GC.SuppressFinalize (this); @@ -181,6 +196,9 @@ namespace GLib { [DllImport("glibsharpglue-2")] static extern IntPtr glibsharp_closure_new (ClosureMarshal marshaler, ClosureNotify notify, IntPtr gch); + [DllImport("libgobject-2.0-0.dll")] + static extern IntPtr g_cclosure_new (Delegate cb, IntPtr user_data, ClosureNotify notify); + [DllImport("libgobject-2.0-0.dll")] static extern uint g_signal_connect_closure (IntPtr obj, IntPtr name, IntPtr closure, bool is_after);