2005-02-02 Mike Kestner <mkestner@novell.com>
* generator/Makefile.am : remove source file. * generator/Signal.cs : generate marshaling callbacks and use new GLib.Signal marshaling class for events. * generator/SignalHandler.cs : kill. byebye SignalCallback subclasses. * glib/Makefile.am : update source files. * glib/GLibSharp.voidObjectIntPtrSignal.cs : kill. * glib/Object.cs : mark the old Before/After props Obsolete. Use GLib.Signal for the notify prop methods. * glib/Signal.cs : new signal marshaling class. It manages all the ConnectBefore/After stuff internally and connects itself to the native object using GCHandles and DestroyNotify lifecycle management. * glib/SignalCallback.cs : mark Obsolete. [Fixes #72018 and #69847] svn path=/trunk/gtk-sharp/; revision=40007
This commit is contained in:
parent
a8f16beaa7
commit
6590388024
9 changed files with 362 additions and 335 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2005-02-02 Mike Kestner <mkestner@novell.com>
|
||||
|
||||
* generator/Makefile.am : remove source file.
|
||||
* generator/Signal.cs : generate marshaling callbacks and use new
|
||||
GLib.Signal marshaling class for events.
|
||||
* generator/SignalHandler.cs : kill. byebye SignalCallback subclasses.
|
||||
* glib/Makefile.am : update source files.
|
||||
* glib/GLibSharp.voidObjectIntPtrSignal.cs : kill.
|
||||
* glib/Object.cs : mark the old Before/After props Obsolete. Use
|
||||
GLib.Signal for the notify prop methods.
|
||||
* glib/Signal.cs : new signal marshaling class. It manages all the
|
||||
ConnectBefore/After stuff internally and connects itself to the native
|
||||
object using GCHandles and DestroyNotify lifecycle management.
|
||||
* glib/SignalCallback.cs : mark Obsolete.
|
||||
[Fixes #72018 and #69847]
|
||||
|
||||
2005-02-01 Fredrik Nilsson <jymdman@home.se>
|
||||
|
||||
* glib/Marshaller.cs : DateTime marshaling fix.
|
||||
|
|
|
@ -39,7 +39,6 @@ sources = \
|
|||
Property.cs \
|
||||
ReturnValue.cs \
|
||||
Signal.cs \
|
||||
SignalHandler.cs \
|
||||
Signature.cs \
|
||||
SimpleBase.cs \
|
||||
SimpleGen.cs \
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace GtkSharp.Generation {
|
|||
private ReturnValue retval;
|
||||
private Parameters parms;
|
||||
private ClassBase container_type;
|
||||
SignalHandler sig_handler;
|
||||
|
||||
public Signal (XmlElement elem, ClassBase container_type)
|
||||
{
|
||||
|
@ -43,7 +42,6 @@ namespace GtkSharp.Generation {
|
|||
retval = new ReturnValue (elem ["return-type"]);
|
||||
parms = new Parameters (elem["parameters"]);
|
||||
this.container_type = container_type;
|
||||
sig_handler = new SignalHandler (elem, container_type.NS);
|
||||
}
|
||||
|
||||
public string Name {
|
||||
|
@ -57,7 +55,7 @@ namespace GtkSharp.Generation {
|
|||
|
||||
public bool Validate ()
|
||||
{
|
||||
if (Name == "" || !sig_handler.Validate ()) {
|
||||
if (Name == "") {
|
||||
Console.Write ("bad signal " + Name);
|
||||
Statistics.ThrottledCount++;
|
||||
return false;
|
||||
|
@ -80,9 +78,62 @@ namespace GtkSharp.Generation {
|
|||
sw.WriteLine ("\t\tevent " + EventHandlerQualifiedName + " " + Name + ";");
|
||||
}
|
||||
|
||||
private string BaseName {
|
||||
get {
|
||||
string result = SymbolTable.Table.GetName (retval.CType);
|
||||
foreach (Parameter p in parms) {
|
||||
result += p.PassAs;
|
||||
if (p.Generatable is ObjectGen || p.Generatable is InterfaceGen)
|
||||
result += "Object";
|
||||
else
|
||||
result += SymbolTable.Table.GetName(p.CType);
|
||||
}
|
||||
result = result.Replace ("[]", "Array");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public string CName {
|
||||
get {
|
||||
return "\"" + elem.GetAttribute("cname") + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
public string CallbackName {
|
||||
get {
|
||||
return Name + "SignalCallback";
|
||||
}
|
||||
}
|
||||
|
||||
private string CallbackSig {
|
||||
get {
|
||||
string result = "";
|
||||
for (int i = 0; i < parms.Count; i++) {
|
||||
if (i > 0)
|
||||
result += ", ";
|
||||
|
||||
if (parms[i].PassAs != "")
|
||||
result += parms[i].PassAs + " ";
|
||||
result += (parms[i].MarshalType + " arg" + i);
|
||||
}
|
||||
result += ", IntPtr gch";
|
||||
|
||||
result = result.Replace ("out ref", "out");
|
||||
result = result.Replace ("ref ref", "ref");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public string DelegateName {
|
||||
get {
|
||||
return Name + "SignalDelegate";
|
||||
}
|
||||
}
|
||||
|
||||
private string EventArgsName {
|
||||
get {
|
||||
if (sig_handler.Name == "voidObjectSignal")
|
||||
if (IsEventHandler)
|
||||
return "EventArgs";
|
||||
else
|
||||
return Name + "Args";
|
||||
|
@ -91,7 +142,7 @@ namespace GtkSharp.Generation {
|
|||
|
||||
private string EventArgsQualifiedName {
|
||||
get {
|
||||
if (sig_handler.Name == "voidObjectSignal")
|
||||
if (IsEventHandler)
|
||||
return "System.EventArgs";
|
||||
else
|
||||
return container_type.NS + "." + Name + "Args";
|
||||
|
@ -100,7 +151,7 @@ namespace GtkSharp.Generation {
|
|||
|
||||
private string EventHandlerName {
|
||||
get {
|
||||
if (sig_handler.Name == "voidObjectSignal")
|
||||
if (IsEventHandler)
|
||||
return "EventHandler";
|
||||
else if (SymbolTable.Table [container_type.NS + Name + "Handler"] != null)
|
||||
return Name + "EventHandler";
|
||||
|
@ -111,13 +162,19 @@ namespace GtkSharp.Generation {
|
|||
|
||||
private string EventHandlerQualifiedName {
|
||||
get {
|
||||
if (sig_handler.Name == "voidObjectSignal")
|
||||
if (IsEventHandler)
|
||||
return "System.EventHandler";
|
||||
else
|
||||
return container_type.NS + "." + EventHandlerName;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEventHandler {
|
||||
get {
|
||||
return retval.CSType == "void" && parms.Count == 1 && (parms [0].Generatable is ObjectGen || parms [0].Generatable is InterfaceGen);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsVoid {
|
||||
get {
|
||||
return retval.CSType == "void";
|
||||
|
@ -146,6 +203,52 @@ namespace GtkSharp.Generation {
|
|||
}
|
||||
}
|
||||
|
||||
public void GenCallback (StreamWriter sw)
|
||||
{
|
||||
SymbolTable table = SymbolTable.Table;
|
||||
|
||||
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + DelegateName + " (" + CallbackSig + ");");
|
||||
sw.WriteLine ();
|
||||
sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + CallbackName + " (" + CallbackSig + ")");
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine("\t\t\tGLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal;");
|
||||
sw.WriteLine("\t\t\tif (sig == null)");
|
||||
sw.WriteLine("\t\t\t\tthrow new Exception(\"Unknown signal GC handle received \" + gch);");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\t\t{0} args = new {0} ();", EventArgsQualifiedName);
|
||||
if (parms.Count > 1)
|
||||
sw.WriteLine("\t\t\targs.Args = new object[" + (parms.Count - 1) + "];");
|
||||
string finish = "";
|
||||
for (int idx = 1; idx < parms.Count; idx++) {
|
||||
Parameter p = parms [idx];
|
||||
IGeneratable igen = p.Generatable;
|
||||
if (p.PassAs == "out")
|
||||
finish += "\t\t\targ" + idx + " = " + igen.ToNativeReturn ("((" + p.CSType + ")args.Args[" + (idx - 1) + "])") + ";\n";
|
||||
else if ((igen is ClassBase && !(igen is StructBase)) || igen is ManualGen) {
|
||||
sw.WriteLine("\t\t\tif (arg{0} == IntPtr.Zero)", idx);
|
||||
sw.WriteLine("\t\t\t\targs.Args[{0}] = null;", idx - 1);
|
||||
sw.WriteLine("\t\t\telse {");
|
||||
sw.WriteLine("\t\t\t\targs.Args[" + (idx - 1) + "] = " + igen.FromNative ("arg" + idx) + ";");
|
||||
sw.WriteLine("\t\t\t}");
|
||||
} else
|
||||
sw.WriteLine("\t\t\targs.Args[" + (idx - 1) + "] = " + igen.FromNative ("arg" + idx) + ";");
|
||||
}
|
||||
sw.WriteLine("\t\t\t{0} handler = ({0}) sig.Handler;", EventHandlerQualifiedName);
|
||||
sw.WriteLine("\t\t\thandler (GLib.Object.GetObject (arg0), args);");
|
||||
sw.WriteLine (finish);
|
||||
if (!IsVoid) {
|
||||
sw.WriteLine ("\t\t\tif (args.RetVal == null)");
|
||||
if (retval.CSType == "bool")
|
||||
sw.WriteLine ("\t\t\t\treturn false;");
|
||||
else
|
||||
sw.WriteLine ("\t\t\t\tthrow new Exception(\"args.RetVal unset in callback\");");
|
||||
|
||||
sw.WriteLine("\t\t\treturn " + table.ToNativeReturn (retval.CType, "((" + retval.CSType + ")args.RetVal)") + ";");
|
||||
}
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine();
|
||||
}
|
||||
|
||||
private bool NeedNew (ClassBase implementor)
|
||||
{
|
||||
return elem.HasAttribute ("new_flag") ||
|
||||
|
@ -155,7 +258,7 @@ namespace GtkSharp.Generation {
|
|||
|
||||
public void GenEventHandler (GenerationInfo gen_info)
|
||||
{
|
||||
if (EventHandlerName == "EventHandler")
|
||||
if (IsEventHandler)
|
||||
return;
|
||||
|
||||
string ns = container_type.NS;
|
||||
|
@ -233,8 +336,8 @@ namespace GtkSharp.Generation {
|
|||
{
|
||||
ImportSignature isig = new ImportSignature (parms, container_type.NS);
|
||||
ManagedCallString call = new ManagedCallString (parms);
|
||||
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "Delegate (" + isig.ToString () + ");\n");
|
||||
sw.WriteLine ("\t\tstatic {0} {1};\n", Name + "Delegate", Name + "Callback");
|
||||
sw.WriteLine ("\t\tdelegate " + retval.ToNativeType + " " + Name + "VMDelegate (" + isig.ToString () + ");\n");
|
||||
sw.WriteLine ("\t\tstatic {0} {1};\n", Name + "VMDelegate", Name + "VMCallback");
|
||||
sw.WriteLine ("\t\tstatic " + retval.ToNativeType + " " + Name.ToLower() + "_cb (" + isig.ToString () + ")");
|
||||
sw.WriteLine ("\t\t{");
|
||||
sw.WriteLine ("\t\t\t{0} obj = GLib.Object.GetObject ({1}, false) as {0};", implementor != null ? implementor.Name : container_type.Name, parms[0].Name);
|
||||
|
@ -245,71 +348,39 @@ namespace GtkSharp.Generation {
|
|||
if (!IsVoid && retval.CSType != retval.ToNativeType)
|
||||
sw.WriteLine ("\t\t\treturn {0};", SymbolTable.Table.ToNativeReturn (retval.CType, "raw_ret"));
|
||||
sw.WriteLine ("\t\t}\n");
|
||||
string cname = "\"" + elem.GetAttribute("cname") + "\"";
|
||||
sw.WriteLine ("\t\tprivate static void Override" + Name + " (GLib.GType gtype)");
|
||||
sw.WriteLine ("\t\t{");
|
||||
sw.WriteLine ("\t\t\tif (" + Name + "Callback == null)");
|
||||
sw.WriteLine ("\t\t\t\t" + Name + "Callback = new " + Name + "Delegate (" + Name.ToLower() + "_cb);");
|
||||
sw.WriteLine ("\t\t\tOverrideVirtualMethod (gtype, " + cname + ", " + Name + "Callback);");
|
||||
sw.WriteLine ("\t\t\tif (" + Name + "VMCallback == null)");
|
||||
sw.WriteLine ("\t\t\t\t" + Name + "VMCallback = new " + Name + "VMDelegate (" + Name.ToLower() + "_cb);");
|
||||
sw.WriteLine ("\t\t\tOverrideVirtualMethod (gtype, " + CName + ", " + Name + "VMCallback);");
|
||||
sw.WriteLine ("\t\t}\n");
|
||||
}
|
||||
|
||||
public void Generate (GenerationInfo gen_info, ClassBase implementor)
|
||||
{
|
||||
StreamWriter sw = gen_info.Writer;
|
||||
string cname = "\"" + elem.GetAttribute("cname") + "\"";
|
||||
string ns;
|
||||
if (implementor == null) {
|
||||
ns = container_type.NS;
|
||||
GenEventHandler (gen_info);
|
||||
} else
|
||||
ns = implementor.NS;
|
||||
|
||||
sig_handler.Generate (ns, gen_info);
|
||||
if (implementor == null)
|
||||
GenEventHandler (gen_info);
|
||||
|
||||
if (!IsEventHandler)
|
||||
GenCallback (sw);
|
||||
GenDefaultHandlerDelegate (sw, implementor);
|
||||
GenVirtualMethod (sw, implementor);
|
||||
string qual_marsh = ns + "Sharp." + sig_handler.Name;
|
||||
string marsh = IsEventHandler ? "" : ", new " + DelegateName + "(" + CallbackName + ")";
|
||||
|
||||
sw.WriteLine("\t\t[GLib.Signal("+ cname + ")]");
|
||||
sw.WriteLine("\t\t[GLib.Signal("+ CName + ")]");
|
||||
sw.Write("\t\tpublic ");
|
||||
if (NeedNew (implementor))
|
||||
sw.Write("new ");
|
||||
sw.WriteLine("event " + EventHandlerQualifiedName + " " + Name + " {");
|
||||
sw.WriteLine("\t\t\tadd {");
|
||||
sw.WriteLine("\t\t\t\tif (value.Method.GetCustomAttributes(typeof(GLib.ConnectBeforeAttribute), false).Length > 0) {");
|
||||
sw.WriteLine("\t\t\t\t\tif (BeforeHandlers[" + cname + "] == null)");
|
||||
sw.Write("\t\t\t\t\t\tBeforeSignals[" + cname + "] = new " + qual_marsh);
|
||||
sw.WriteLine("(this, " + cname + ", value, typeof (" + EventArgsQualifiedName + "), 0);");
|
||||
sw.WriteLine("\t\t\t\t\telse");
|
||||
sw.WriteLine("\t\t\t\t\t\t((GLib.SignalCallback) BeforeSignals [{0}]).AddDelegate (value);", cname);
|
||||
sw.WriteLine("\t\t\t\t\tBeforeHandlers.AddHandler(" + cname + ", value);");
|
||||
sw.WriteLine("\t\t\t\t} else {");
|
||||
sw.WriteLine("\t\t\t\t\tif (AfterHandlers[" + cname + "] == null)");
|
||||
sw.Write("\t\t\t\t\t\tAfterSignals[" + cname + "] = new " + qual_marsh);
|
||||
sw.WriteLine("(this, " + cname + ", value, typeof (" + EventArgsQualifiedName + "), 1);");
|
||||
sw.WriteLine("\t\t\t\t\telse");
|
||||
sw.WriteLine("\t\t\t\t\t\t((GLib.SignalCallback) AfterSignals [{0}]).AddDelegate (value);", cname);
|
||||
sw.WriteLine("\t\t\t\t\tAfterHandlers.AddHandler(" + cname + ", value);");
|
||||
sw.WriteLine("\t\t\t\t}");
|
||||
sw.WriteLine("\t\t\t\tGLib.Signal sig = GLib.Signal.Lookup (this, " + CName + marsh + ");");
|
||||
sw.WriteLine("\t\t\t\tsig.AddDelegate (value);");
|
||||
sw.WriteLine("\t\t\t}");
|
||||
sw.WriteLine("\t\t\tremove {");
|
||||
sw.WriteLine("\t\t\t\tSystem.ComponentModel.EventHandlerList event_list = AfterHandlers;");
|
||||
sw.WriteLine("\t\t\t\tHashtable signals = AfterSignals;");
|
||||
sw.WriteLine("\t\t\t\tif (value.Method.GetCustomAttributes(typeof(GLib.ConnectBeforeAttribute), false).Length > 0) {");
|
||||
sw.WriteLine("\t\t\t\t\tevent_list = BeforeHandlers;");
|
||||
sw.WriteLine("\t\t\t\t\tsignals = BeforeSignals;");
|
||||
sw.WriteLine("\t\t\t\t}");
|
||||
sw.WriteLine("\t\t\t\tGLib.SignalCallback cb = signals [{0}] as GLib.SignalCallback;", cname);
|
||||
sw.WriteLine("\t\t\t\tevent_list.RemoveHandler(" + cname + ", value);");
|
||||
sw.WriteLine("\t\t\t\tif (cb == null)");
|
||||
sw.WriteLine("\t\t\t\t\treturn;");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\t\t\tcb.RemoveDelegate (value);");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\t\t\tif (event_list[" + cname + "] == null) {");
|
||||
sw.WriteLine("\t\t\t\t\tsignals.Remove(" + cname + ");");
|
||||
sw.WriteLine("\t\t\t\t\tcb.Dispose ();");
|
||||
sw.WriteLine("\t\t\t\t}");
|
||||
sw.WriteLine("\t\t\t\tGLib.Signal sig = GLib.Signal.Lookup (this, " + CName + marsh + ");");
|
||||
sw.WriteLine("\t\t\t\tsig.RemoveDelegate (value);");
|
||||
sw.WriteLine("\t\t\t}");
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine();
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
// GtkSharp.Generation.SignalHandler.cs - The SignalHandler marshaling Class.
|
||||
//
|
||||
// Author: Mike Kestner <mkestner@ximian.com>
|
||||
//
|
||||
// Copyright (c) 2002-2003 Mike Kestner
|
||||
// Copyright (c) 2004 Novell, Inc.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of version 2 of the GNU General Public
|
||||
// License as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public
|
||||
// License along with this program; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
namespace GtkSharp.Generation {
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
public class SignalHandler {
|
||||
|
||||
XmlElement sig;
|
||||
string ns;
|
||||
ReturnValue retval;
|
||||
Parameters parms = null;
|
||||
|
||||
public SignalHandler (XmlElement sig, string ns)
|
||||
{
|
||||
this.sig = sig;
|
||||
this.ns = ns;
|
||||
retval = new ReturnValue (sig["return-type"]);
|
||||
parms = new Parameters (sig ["parameters"]);
|
||||
}
|
||||
|
||||
public bool Validate ()
|
||||
{
|
||||
if (!retval.Validate ()) {
|
||||
Console.Write(" in signal handler " + Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parms.Validate ()) {
|
||||
Console.Write("Missing parameters ");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private string ISig {
|
||||
get {
|
||||
string result = "";
|
||||
for (int i = 0; i < parms.Count; i++) {
|
||||
if (i > 0)
|
||||
result += ", ";
|
||||
|
||||
if (parms[i].PassAs != "")
|
||||
result += parms[i].PassAs + " ";
|
||||
result += (parms[i].MarshalType + " arg" + i);
|
||||
}
|
||||
|
||||
result = result.Replace ("out ref", "out");
|
||||
result = result.Replace ("ref ref", "ref");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private string BaseName {
|
||||
get {
|
||||
string result = SymbolTable.Table.GetName (retval.CType);
|
||||
foreach (Parameter p in parms) {
|
||||
result += p.PassAs;
|
||||
if (p.Generatable is ObjectGen || p.Generatable is InterfaceGen) {
|
||||
result += "Object";
|
||||
} else {
|
||||
result += SymbolTable.Table.GetName(p.CType);
|
||||
}
|
||||
}
|
||||
result = result.Replace ("[]", "Array");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public string CallbackName {
|
||||
get {
|
||||
return BaseName + "Callback";
|
||||
}
|
||||
}
|
||||
|
||||
public string DelegateName {
|
||||
get {
|
||||
return BaseName + "Delegate";
|
||||
}
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get {
|
||||
return BaseName + "Signal";
|
||||
}
|
||||
}
|
||||
|
||||
public void Generate (string implementor_ns, GenerationInfo gen_info)
|
||||
{
|
||||
SymbolTable table = SymbolTable.Table;
|
||||
|
||||
StreamWriter sw = gen_info.OpenStream (implementor_ns + "Sharp." + Name);
|
||||
|
||||
sw.WriteLine("namespace " + implementor_ns + "Sharp {");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\tusing System;");
|
||||
sw.WriteLine("\tusing System.Runtime.InteropServices;");
|
||||
sw.WriteLine();
|
||||
sw.Write("\tinternal delegate " + retval.ToNativeType + " ");
|
||||
sw.WriteLine(DelegateName + "(" + ISig + ", int key);");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\tinternal class " + Name + " : GLib.SignalCallback {");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\tprivate static " + DelegateName + " _Delegate;");
|
||||
sw.WriteLine();
|
||||
sw.Write("\t\tprivate static " + retval.ToNativeType + " ");
|
||||
sw.WriteLine(CallbackName + "(" + ISig + ", int key)");
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine("\t\t\tif (!_Instances.Contains(key))");
|
||||
sw.WriteLine("\t\t\t\tthrow new Exception(\"Unexpected signal key \" + key);");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\t\t" + Name + " inst = (" + Name + ") _Instances[key];");
|
||||
if ((retval.CSType == "void") && (parms.Count == 1)) {
|
||||
sw.WriteLine("\t\t\tEventHandler h = (EventHandler) inst._handler;");
|
||||
sw.WriteLine("\t\t\th (inst._obj, new EventArgs ());");
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine();
|
||||
} else {
|
||||
sw.WriteLine("\t\t\tGLib.SignalArgs args = (GLib.SignalArgs) Activator.CreateInstance (inst._argstype);");
|
||||
if (parms.Count > 1) {
|
||||
sw.WriteLine("\t\t\targs.Args = new object[" + (parms.Count-1) + "];");
|
||||
}
|
||||
for (int idx=1; idx < parms.Count; idx++) {
|
||||
if (parms[idx].PassAs == "out")
|
||||
continue;
|
||||
|
||||
string ctype = parms[idx].CType;
|
||||
ClassBase wrapper = table.GetClassGen (ctype);
|
||||
if ((wrapper != null && !(wrapper is StructBase)) || table.IsManuallyWrapped (ctype)) {
|
||||
sw.WriteLine("\t\t\tif (arg{0} == IntPtr.Zero)", idx);
|
||||
sw.WriteLine("\t\t\t\targs.Args[{0}] = null;", idx - 1);
|
||||
sw.WriteLine("\t\t\telse {");
|
||||
if ((wrapper != null) && wrapper is ObjectGen)
|
||||
sw.WriteLine("\t\t\t\targs.Args[" + (idx-1) + "] = GLib.Object.GetObject(arg" + idx + ");");
|
||||
else
|
||||
sw.WriteLine("\t\t\t\targs.Args[" + (idx-1) + "] = " + table.FromNative (ctype, "arg" + idx) + ";");
|
||||
sw.WriteLine("\t\t\t}");
|
||||
} else {
|
||||
sw.WriteLine("\t\t\targs.Args[" + (idx-1) + "] = " + table.FromNative (ctype, "arg" + idx) + ";");
|
||||
}
|
||||
}
|
||||
sw.WriteLine("\t\t\tobject[] argv = new object[2];");
|
||||
sw.WriteLine("\t\t\targv[0] = inst._obj;");
|
||||
sw.WriteLine("\t\t\targv[1] = args;");
|
||||
sw.WriteLine("\t\t\tinst._handler.DynamicInvoke(argv);");
|
||||
for (int idx=1; idx < parms.Count; idx++) {
|
||||
if (parms[idx].PassAs != "") {
|
||||
sw.WriteLine ("\t\t\targ" + idx + " = " + table.ToNativeReturn (parms[idx].CType, "((" + parms[idx].CSType + ")args.Args[" + (idx - 1) + "])") + ";");
|
||||
}
|
||||
}
|
||||
if (retval.CSType != "void") {
|
||||
sw.WriteLine ("\t\t\tif (args.RetVal == null)");
|
||||
if (retval.CSType == "bool")
|
||||
sw.WriteLine ("\t\t\t\treturn false;");
|
||||
else
|
||||
sw.WriteLine ("\t\t\t\tthrow new Exception(\"args.RetVal unset in callback\");");
|
||||
|
||||
sw.WriteLine("\t\t\treturn " + table.ToNativeReturn (retval.CType, "((" + retval.CSType + ")args.RetVal)") + ";");
|
||||
}
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine();
|
||||
}
|
||||
sw.Write("\t\tpublic " + Name + "(GLib.Object obj, ");
|
||||
sw.WriteLine("string name, Delegate eh, Type argstype, int connect_flags) : base(obj, eh, argstype)");
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine("\t\t\tif (_Delegate == null) {");
|
||||
sw.WriteLine("\t\t\t\t_Delegate = new " + DelegateName + "(" + CallbackName + ");");
|
||||
sw.WriteLine("\t\t\t}");
|
||||
sw.WriteLine("\t\t\tConnect (name, _Delegate, connect_flags);");
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\tprotected override void Dispose (bool disposing)");
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine("\t\t\t_Instances.Remove(_key);");
|
||||
sw.WriteLine("\t\t\tif(_Instances.Count == 0)");
|
||||
sw.WriteLine("\t\t\t\t_Delegate = null;");
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\t\tDisconnect ();");
|
||||
sw.WriteLine("\t\t\tbase.Dispose (disposing);");
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine("\t}");
|
||||
sw.WriteLine("}");
|
||||
sw.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
// copied from gtk/generated/GtkSharp.voidObjectIntPtrSignal.cs and renamespaced
|
||||
|
||||
// This file was generated by the Gtk# code generator.
|
||||
// Any changes made will be lost if regenerated.
|
||||
|
||||
namespace GLibSharp {
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal delegate void voidObjectIntPtrDelegate(IntPtr arg0, IntPtr arg1, int key);
|
||||
|
||||
internal class voidObjectIntPtrSignal : GLib.SignalCallback {
|
||||
|
||||
private static voidObjectIntPtrDelegate _Delegate;
|
||||
|
||||
private static void voidObjectIntPtrCallback(IntPtr arg0, IntPtr arg1, int key)
|
||||
{
|
||||
if (!_Instances.Contains(key))
|
||||
throw new Exception("Unexpected signal key " + key);
|
||||
|
||||
voidObjectIntPtrSignal inst = (voidObjectIntPtrSignal) _Instances[key];
|
||||
GLib.SignalArgs args = (GLib.SignalArgs) Activator.CreateInstance (inst._argstype);
|
||||
args.Args = new object[1];
|
||||
args.Args[0] = arg1;
|
||||
object[] argv = new object[2];
|
||||
argv[0] = inst._obj;
|
||||
argv[1] = args;
|
||||
inst._handler.DynamicInvoke(argv);
|
||||
}
|
||||
|
||||
public voidObjectIntPtrSignal(GLib.Object obj, string name, Delegate eh, Type argstype, int connect_flags) : base(obj, eh, argstype)
|
||||
{
|
||||
if (_Delegate == null) {
|
||||
_Delegate = new voidObjectIntPtrDelegate(voidObjectIntPtrCallback);
|
||||
}
|
||||
Connect (name, _Delegate, connect_flags);
|
||||
}
|
||||
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
_Instances.Remove(_key);
|
||||
if(_Instances.Count == 0)
|
||||
_Delegate = null;
|
||||
|
||||
Disconnect ();
|
||||
base.Dispose (disposing);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@ sources = \
|
|||
EnumWrapper.cs \
|
||||
FileUtils.cs \
|
||||
GException.cs \
|
||||
GLibSharp.voidObjectIntPtrSignal.cs \
|
||||
GString.cs \
|
||||
Idle.cs \
|
||||
IWrapper.cs \
|
||||
|
@ -37,6 +36,7 @@ sources = \
|
|||
ObjectManager.cs \
|
||||
Opaque.cs \
|
||||
PropertyAttribute.cs \
|
||||
Signal.cs \
|
||||
SignalArgs.cs \
|
||||
SignalAttribute.cs \
|
||||
SignalCallback.cs \
|
||||
|
|
|
@ -245,6 +245,8 @@ namespace GLib {
|
|||
}
|
||||
|
||||
Hashtable before_signals;
|
||||
|
||||
[Obsolete ("Replaced by GLib.Signal marshaling mechanism.")]
|
||||
protected Hashtable BeforeSignals {
|
||||
get {
|
||||
if (before_signals == null)
|
||||
|
@ -254,6 +256,7 @@ namespace GLib {
|
|||
}
|
||||
|
||||
Hashtable after_signals;
|
||||
[Obsolete ("Replaced by GLib.Signal marshaling mechanism.")]
|
||||
protected Hashtable AfterSignals {
|
||||
get {
|
||||
if (after_signals == null)
|
||||
|
@ -263,6 +266,7 @@ namespace GLib {
|
|||
}
|
||||
|
||||
EventHandlerList before_handlers;
|
||||
[Obsolete ("Replaced by GLib.Signal marshaling mechanism.")]
|
||||
protected EventHandlerList BeforeHandlers {
|
||||
get {
|
||||
if (before_handlers == null)
|
||||
|
@ -272,6 +276,7 @@ namespace GLib {
|
|||
}
|
||||
|
||||
EventHandlerList after_handlers;
|
||||
[Obsolete ("Replaced by GLib.Signal marshaling mechanism.")]
|
||||
protected EventHandlerList AfterHandlers {
|
||||
get {
|
||||
if (after_handlers == null)
|
||||
|
@ -280,13 +285,25 @@ namespace GLib {
|
|||
}
|
||||
}
|
||||
|
||||
delegate void NotifyDelegate (IntPtr handle, IntPtr pspec, IntPtr gch);
|
||||
|
||||
void NotifyCallback (IntPtr handle, IntPtr pspec, IntPtr gch)
|
||||
{
|
||||
GLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal;
|
||||
if (sig == null)
|
||||
throw new Exception("Unknown signal GC handle received " + gch);
|
||||
|
||||
NotifyArgs args = new NotifyArgs ();
|
||||
args.Args = new object[1];
|
||||
args.Args[0] = pspec;
|
||||
NotifyHandler handler = (NotifyHandler) sig.Handler;
|
||||
handler (GLib.Object.GetObject (handle), args);
|
||||
}
|
||||
|
||||
void ConnectNotification (string signal, NotifyHandler handler)
|
||||
{
|
||||
if (AfterHandlers[signal] == null)
|
||||
AfterSignals[signal] = new GLibSharp.voidObjectIntPtrSignal (this, signal, handler, typeof (NotifyArgs), 1);
|
||||
else
|
||||
((GLib.SignalCallback) AfterSignals[signal]).AddDelegate (handler);
|
||||
AfterHandlers.AddHandler (signal, handler);
|
||||
Signal sig = Signal.Lookup (this, signal, new NotifyDelegate (NotifyCallback));
|
||||
sig.AddDelegate (handler);
|
||||
}
|
||||
|
||||
public void AddNotification (string property, NotifyHandler handler)
|
||||
|
@ -301,17 +318,8 @@ namespace GLib {
|
|||
|
||||
void DisconnectNotification (string signal, NotifyHandler handler)
|
||||
{
|
||||
GLib.SignalCallback cb = AfterSignals[signal] as GLib.SignalCallback;
|
||||
AfterHandlers.RemoveHandler (signal, handler);
|
||||
|
||||
if (cb == null)
|
||||
return;
|
||||
cb.RemoveDelegate (handler);
|
||||
|
||||
if (AfterHandlers[signal] == null) {
|
||||
AfterSignals.Remove (signal);
|
||||
cb.Dispose ();
|
||||
}
|
||||
Signal sig = Signal.Lookup (this, signal, new NotifyDelegate (NotifyCallback));
|
||||
sig.RemoveDelegate (handler);
|
||||
}
|
||||
|
||||
public void RemoveNotification (string property, NotifyHandler handler)
|
||||
|
|
193
glib/Signal.cs
Normal file
193
glib/Signal.cs
Normal file
|
@ -0,0 +1,193 @@
|
|||
// GLib.Signal.cs - signal marshaling class
|
||||
//
|
||||
// Authors: Mike Kestner <mkestner@novell.com>
|
||||
//
|
||||
// Copyright (c) 2005 Novell, Inc.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of version 2 of the Lesser GNU General
|
||||
// Public License as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
namespace GLib {
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[Flags]
|
||||
internal enum SignalFlags {
|
||||
RunFirst = 1 << 0,
|
||||
RunLast = 1 << 1,
|
||||
RunCleanup = 1 << 2,
|
||||
NoRecurse = 1 << 3,
|
||||
Detailed = 1 << 4,
|
||||
Action = 1 << 5,
|
||||
NoHooks = 1 << 6
|
||||
}
|
||||
|
||||
[StructLayout (LayoutKind.Sequential)]
|
||||
internal struct InvocationHint {
|
||||
public uint signal_id;
|
||||
public uint detail;
|
||||
public SignalFlags run_type;
|
||||
}
|
||||
|
||||
public class Signal {
|
||||
|
||||
GCHandle gc_handle;
|
||||
IntPtr handle;
|
||||
string name;
|
||||
uint before_id = UInt32.MaxValue;
|
||||
uint after_id = UInt32.MaxValue;
|
||||
Delegate marshaler;
|
||||
|
||||
static DestroyNotify notify = new DestroyNotify (OnNativeDestroy);
|
||||
delegate void DestroyNotify (IntPtr data, IntPtr obj);
|
||||
static void OnNativeDestroy (IntPtr data, IntPtr obj)
|
||||
{
|
||||
GCHandle gch = (GCHandle) data;
|
||||
Signal s = gch.Target as Signal;
|
||||
s.DisconnectHandler (s.before_id);
|
||||
s.DisconnectHandler (s.after_id);
|
||||
gch.Free ();
|
||||
}
|
||||
|
||||
private Signal (GLib.Object obj, string signal_name, Delegate marshaler)
|
||||
{
|
||||
handle = obj.Handle;
|
||||
name = signal_name;
|
||||
this.marshaler = marshaler;
|
||||
gc_handle = GCHandle.Alloc (this);
|
||||
g_object_set_data_full (handle, name + "_signal_marshaler", (IntPtr) gc_handle, notify);
|
||||
}
|
||||
|
||||
public static Signal Lookup (GLib.Object obj, string name)
|
||||
{
|
||||
return Lookup (obj, name, EventHandlerDelegate);
|
||||
}
|
||||
|
||||
public static Signal Lookup (GLib.Object obj, string name, Delegate marshaler)
|
||||
{
|
||||
IntPtr data = g_object_get_data (obj.Handle, name + "_signal_marshaler");
|
||||
if (data == IntPtr.Zero)
|
||||
return new Signal (obj, name, marshaler);
|
||||
|
||||
GCHandle gch = (GCHandle) data;
|
||||
return gch.Target as Signal;
|
||||
}
|
||||
|
||||
Delegate before_handler;
|
||||
Delegate after_handler;
|
||||
|
||||
public Delegate Handler {
|
||||
get {
|
||||
InvocationHint hint = (InvocationHint) Marshal.PtrToStructure (g_signal_get_invocation_hint (handle), typeof (InvocationHint));
|
||||
if (hint.run_type == SignalFlags.RunFirst)
|
||||
return before_handler;
|
||||
else
|
||||
return after_handler;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddDelegate (Delegate d)
|
||||
{
|
||||
if (d.Method.IsDefined (typeof (ConnectBeforeAttribute), false)) {
|
||||
if (before_handler == null) {
|
||||
before_handler = d;
|
||||
before_id = g_signal_connect_data (handle, name, marshaler, (IntPtr) gc_handle, IntPtr.Zero, 0);
|
||||
} else
|
||||
before_handler = Delegate.Combine (before_handler, d);
|
||||
} else {
|
||||
if (after_handler == null) {
|
||||
after_handler = d;
|
||||
after_id = g_signal_connect_data (handle, name, marshaler, (IntPtr) gc_handle, IntPtr.Zero, 1);
|
||||
} else
|
||||
after_handler = Delegate.Combine (after_handler, d);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveDelegate (Delegate d)
|
||||
{
|
||||
if (d.Method.IsDefined (typeof (ConnectBeforeAttribute), false)) {
|
||||
before_handler = Delegate.Remove (before_handler, d);
|
||||
if (before_handler == null) {
|
||||
DisconnectHandler (before_id);
|
||||
before_id = UInt32.MaxValue;
|
||||
}
|
||||
} else {
|
||||
after_handler = Delegate.Remove (after_handler, d);
|
||||
if (after_handler == null) {
|
||||
DisconnectHandler (after_id);
|
||||
after_id = UInt32.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (after_id == UInt32.MaxValue && before_id == UInt32.MaxValue)
|
||||
DisconnectObject ();
|
||||
}
|
||||
|
||||
void DisconnectObject ()
|
||||
{
|
||||
g_object_set_data (handle, name + "_signal_marshaler", IntPtr.Zero);
|
||||
}
|
||||
|
||||
void DisconnectHandler (uint handler_id)
|
||||
{
|
||||
if (handler_id != UInt32.MaxValue && g_signal_handler_is_connected (handle, handler_id))
|
||||
g_signal_handler_disconnect (handle, handler_id);
|
||||
}
|
||||
|
||||
delegate void voidObjectDelegate (IntPtr handle, IntPtr gch);
|
||||
|
||||
static void voidObjectCallback (IntPtr handle, IntPtr gch)
|
||||
{
|
||||
Signal sig = ((GCHandle) gch).Target as Signal;
|
||||
if (sig == null)
|
||||
throw new Exception ("Unknown signal class GC handle received.");
|
||||
|
||||
EventHandler handler = (EventHandler) sig.Handler;
|
||||
handler (Object.GetObject (handle), EventArgs.Empty);
|
||||
}
|
||||
|
||||
static voidObjectDelegate event_handler_delegate;
|
||||
static voidObjectDelegate EventHandlerDelegate {
|
||||
get {
|
||||
if (event_handler_delegate == null)
|
||||
event_handler_delegate = new voidObjectDelegate (voidObjectCallback);
|
||||
return event_handler_delegate;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern IntPtr g_object_get_data (IntPtr instance, string key);
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern void g_object_set_data (IntPtr instance, string key, IntPtr data);
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern void g_object_set_data_full (IntPtr instance, string key, IntPtr data, DestroyNotify notify);
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern uint g_signal_connect_data(IntPtr obj, string name, Delegate cb, IntPtr gc_handle, IntPtr dummy, int flags);
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern IntPtr g_signal_get_invocation_hint (IntPtr instance);
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern void g_signal_handler_disconnect (IntPtr instance, uint handler);
|
||||
|
||||
[DllImport("libgobject-2.0-0.dll")]
|
||||
static extern bool g_signal_handler_is_connected (IntPtr instance, uint handler);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ namespace GLib {
|
|||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[Obsolete ("Replaced by GLib.Signal.")]
|
||||
public abstract class SignalCallback : IDisposable {
|
||||
|
||||
// A counter used to produce unique keys for instances.
|
||||
|
|
Loading…
Reference in a new issue