diff --git a/ChangeLog b/ChangeLog
index a03ed2ac4..832c11966 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2001-11-25  Mike Kestner <mkestner@speakeasy.net>
+
+	* codegen/defs-parse.pl (get_sighandler): gen the helper class. arg
+	  passing and return value handling need beefing up still.
+	* glib/SignalArgs.cs : New arg passing/ return value handling class.
+	* glib/SignalCallback.cs (dtor): kill, this will be gen'd in the 
+	  subclasses. (ctor): prune down to two params.
+
 2001-11-24  Mike Kestner <mkestner@speakeasy.net>
 
 	* codegen/defs-parse.pl : mkdir the glib/generated dir.
diff --git a/codegen/defs-parse.pl b/codegen/defs-parse.pl
index 3ce4f0f69..63bb7330b 100755
--- a/codegen/defs-parse.pl
+++ b/codegen/defs-parse.pl
@@ -525,7 +525,7 @@ sub gen_param_strings
 sub get_sighandler
 {
 	my ($def) = @_;
-	my ($key, $name, $sname, $dname, $dir, $ns, $nspace, $tok);
+	my ($key, $name, $dir, $ns, $nspace, $tok);
 
 	$def =~ /return-type \"(\w+)\"/;
 	my $ret = $1;
@@ -566,8 +566,9 @@ sub get_sighandler
 			die "Whassup with $tok?";
 		}
 	}
-	$sname = $name . "Signal";
-	$dname = $name . "Delegate";
+	my $sname = $name . "Signal";
+	my $dname = $name . "Delegate";
+	my $cbname = $name . "Callback";
 
 	$sighandlers{$key} = $name;
 
@@ -578,9 +579,38 @@ sub get_sighandler
 	foreach $ns (split (/,/, $usings{$nspace})) {
 		print SIGFILE "\tusing $ns;\n";
 	}
-	print SIGFILE "\tpublic delegate $marshaltypes{$ret} ";
+	print SIGFILE "\n\tpublic delegate $marshaltypes{$ret} ";
 	print SIGFILE "$dname($pinv, int key);\n\n";
-	print SIGFILE "}\n";
+	print SIGFILE "\tpublic class $sname : SignalCallback {\n\n";
+	print SIGFILE "\t\tprivate static $dname _Delegate;\n\n";
+	print SIGFILE "\t\tprivate static $maptypes{$ret} ";
+	print SIGFILE "$cbname($pinv, int key)\n\t\t{\n";
+	print SIGFILE "\t\t\tif (!_Instances.Contains(key))\n";
+	print SIGFILE "\t\t\t\tthrow new Exception(\"Unexpected signal key\");";
+	print SIGFILE "\n\n\t\t\t$sname inst = ($sname) _Instances[key];\n";
+	print SIGFILE "\t\t\tSignalArgs args = new SignalArgs ();\n";
+	print SIGFILE "\t\t\tinst._handler (inst._obj, args);\n";
+	if ($ret ne "none") {
+		print SIGFILE "\t\t\treturn ($maptypes{$ret}) args.RetVal;\n";
+	}
+	print SIGFILE "\t\t}\n\n";
+	print SIGFILE "\t\t[DllImport(\"gobject-1.3.dll\", ";
+	print SIGFILE "CharSet=CharSet.Ansi, ";
+	print SIGFILE "CallingConvention=CallingConvention.Cdecl)]\n";
+	print SIGFILE "\t\tstatic extern void g_signal_connect_data(";
+	print SIGFILE "IntPtr obj, IntPtr name, $dname cb, int key, IntPtr p,";
+	print SIGFILE " int flags);\n\n";
+	print SIGFILE "\t\tpublic $sname(GLib.Object obj, IntPtr raw, ";
+	print SIGFILE "String name, EventHandler eh) : base(obj, eh)";
+	print SIGFILE "\n\t\t{\n\t\t\tif (_Delegate == null) {\n";
+	print SIGFILE "\t\t\t\t_Delegate = new $dname($cbname);\n\t\t\t}\n";
+	print SIGFILE "\t\t\tg_signal_connect_data(raw, ";
+	print SIGFILE "Marshal.StringToHGlobalAnsi(name), _Delegate, _key, ";
+	print SIGFILE "new IntPtr(0), 0);\n\t\t}\n\n";
+	print SIGFILE "\t\t~$sname()\n{\t\t\t_Instances.Remove(_key);\n";
+	print SIGFILE "\t\t\tif(_Instances.Count == 0) {\n";
+	print SIGFILE "\t\t\t\t_Delegate = null;\n\t\t\t}\n\t\t}\n";
+	print SIGFILE "\t}\n}\n";
 	close (SIGFILE);
 
 	return $sighandlers{$key};
diff --git a/glib/SignalArgs.cs b/glib/SignalArgs.cs
new file mode 100644
index 000000000..eeed49445
--- /dev/null
+++ b/glib/SignalArgs.cs
@@ -0,0 +1,103 @@
+// GtkSharp.SignalArgs.cs - Signal argument class implementation
+//
+// Author: Mike Kestner <mkestner@speakeasy.net>
+//
+// (c) 2001 Mike Kestner
+
+namespace GtkSharp {
+	using System;
+	using System.Collections;
+
+	/// <summary>
+	///	SignalArgs Class
+	/// </summary>
+	///
+	/// <remarks>
+	///	Arguments and return value for signals.
+	/// </remarks>
+
+	public class SignalArgs : EventArgs {
+
+		private object _ret;
+		private object[] _args;
+
+		/// <summary>
+		///	SignalArgs Constructor
+		/// </summary>
+		///
+		/// <remarks>
+		///	Creates a SignalArgs object with no return value and 
+		///	no arguments.
+		/// </remarks>
+
+		public SignalArgs()
+		{
+			_ret = null;
+			_args = null;
+		}
+
+		/// <summary>
+		///	SignalArgs Constructor
+		/// </summary>
+		///
+		/// <remarks>
+		///	Creates a SignalArgs object with a return value and 
+		///	no arguments.
+		/// </remarks>
+
+		public SignalArgs(object retval)
+		{
+			_ret = retval;
+			_args = null;
+		}
+
+		/// <summary>
+		///	SignalArgs Constructor
+		/// </summary>
+		///
+		/// <remarks>
+		///	Creates a SignalArgs object with a return value and 
+		///	a list of arguments.
+		/// </remarks>
+
+		public SignalArgs(object retval, object[] args)
+		{
+			_ret = retval;
+			_args = args;
+		}
+
+		/// <summary>
+		///	Args Property
+		/// </summary>
+		///
+		/// <remarks>
+		///	A list of arguments.
+		/// </remarks>
+
+		public object[] Args {
+			get {
+				return _args;
+			}
+			set {
+				_args = value;
+			}
+		}
+
+		/// <summary>
+		///	RetVal Property
+		/// </summary>
+		///
+		/// <remarks>
+		///	The return value.
+		/// </remarks>
+
+		public object RetVal {
+			get {
+				return _ret;
+			}
+			set {
+				_ret = value;
+			}
+		}
+	}
+}
diff --git a/glib/SignalCallback.cs b/glib/SignalCallback.cs
index 26beabbc9..8dce633a2 100644
--- a/glib/SignalCallback.cs
+++ b/glib/SignalCallback.cs
@@ -39,8 +39,7 @@ namespace GtkSharp {
 		///	Initializes instance data.
 		/// </remarks>
 
-		public SignalCallback (GLib.Object obj, IntPtr raw,
-				     String name, EventHandler eh)
+		public SignalCallback (GLib.Object obj, EventHandler eh)
 		{
 			_key = _NextKey++;
 			_obj = obj;
@@ -48,11 +47,5 @@ namespace GtkSharp {
 			_Instances [_key] = this;
 		}
 
-		// Destructor needed to release references from the instance
-		// table and unpin the delegate if no refs remain.
-		~SignalCallback ()
-		{
-			_Instances.Remove (_key);
-		}
 	}
 }