From faaccd7e0be7242ca1f5d2b98577eab697ea5871 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 16 Dec 2004 23:38:35 +0000 Subject: [PATCH] * generator/ManagedCallString.cs (Setup, Finish, ToString): Add new methods to allow arbitrary setup and teardown code around the managed call. When passing a type with "complicated" marshalling requirements as a ref or out param, first assign the value to a temporary variable (in Setup), then pass the temp as the ref or out param (in ToString), and then assign the new value back to the original argument (in Finish). * generator/Signal.cs: * generator/SignalHandler.cs: Update to generate correct glue for signals with "ref" or "out" params. (#70566) * generator/VirtualMethod.cs: Update for ManagedCallString change * generator/IGeneratable.cs: add comments explaining what each member does * gtk/Gtk.metadata: mark Editable.InsertText's "position" arg * pass-by-ref * sample/Size.cs: connect to the SizeRequested event and override it, to test/demo the changes svn path=/trunk/gtk-sharp/; revision=37854 --- ChangeLog | 28 +++++++++++++-- doc/ChangeLog | 14 ++++++++ doc/en/Gtk/Entry.xml | 4 +-- doc/en/Gtk/InputArgs.xml | 6 ++-- doc/en/Gtk/RowsReorderedArgs.xml | 2 +- doc/en/Gtk/SizeRequestedArgs.xml | 14 ++++++-- doc/en/Gtk/TextInsertedArgs.xml | 4 +-- doc/en/Gtk/ToggleSizeRequestedArgs.xml | 6 ++-- generator/IGeneratable.cs | 27 +++++++++++---- generator/ManagedCallString.cs | 48 +++++++++++++++++++++++++- generator/Signal.cs | 15 ++++++-- generator/SignalHandler.cs | 15 ++++++++ generator/VirtualMethod.cs | 2 ++ gtk/Gtk.metadata | 1 + sample/Size.cs | 9 +++++ 15 files changed, 169 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5257d355..f3c534eda 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2004-12-16 Dan Winship + + * generator/ManagedCallString.cs (Setup, Finish, ToString): Add + new methods to allow arbitrary setup and teardown code around the + managed call. When passing a type with "complicated" marshalling + requirements as a ref or out param, first assign the value to a + temporary variable (in Setup), then pass the temp as the ref or + out param (in ToString), and then assign the new value back to the + original argument (in Finish). + + * generator/Signal.cs: + * generator/SignalHandler.cs: Update to generate correct glue for + signals with "ref" or "out" params. (#70566) + + * generator/VirtualMethod.cs: Update for ManagedCallString change + + * generator/IGeneratable.cs: add comments explaining what each + member does + + * gtk/Gtk.metadata: mark Editable.InsertText's "position" arg pass-by-ref + + * sample/Size.cs: connect to the SizeRequested event and override + it, to test/demo the changes + 2004-12-16 Dan Winship * parser/gapi_pp.pl: Don't strip out /*< public >*/ and @@ -19,8 +43,8 @@ wrapper properties for private fields, since the only code that could use them is the generated code, which won't. - See doc/ChangeLog for the (very minimal) fallout from these - changes. + Part of #69514. See doc/ChangeLog for the (very minimal) fallout + from these changes. 2004-12-16 Mike Kestner diff --git a/doc/ChangeLog b/doc/ChangeLog index 327279643..81685ec58 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,17 @@ +2004-12-16 Dan Winship + + * en/Gtk/InputArgs.xml (NewValue): + * en/Gtk/ToggleSizeRequestedArgs.xml (Requisition): now write-only + rather than read-only + + * en/Gtk/SizeRequestedArgs.xml (Requisition): + * en/Gtk/TextInsertedArgs.xml (Position): now read-write + + * en/Gtk/Entry.xml (OnTextInserted): "position" is now "ref" + rather than "out" + + * en/Gtk/RowsReorderedArgs.xml (NewOrder): changed, but still broken + 2004-12-16 Dan Winship * en/Art/AlphaGamma.xml: diff --git a/doc/en/Gtk/Entry.xml b/doc/en/Gtk/Entry.xml index bc5c88adf..e1eaddcdd 100644 --- a/doc/en/Gtk/Entry.xml +++ b/doc/en/Gtk/Entry.xml @@ -955,14 +955,14 @@ class EntrySample - + Method System.Void - + Default handler for the event. diff --git a/doc/en/Gtk/InputArgs.xml b/doc/en/Gtk/InputArgs.xml index 03c5531ba..a02040831 100644 --- a/doc/en/Gtk/InputArgs.xml +++ b/doc/en/Gtk/InputArgs.xml @@ -33,14 +33,14 @@ - + Property System.Double - The new value given as input. - A + The new value + a diff --git a/doc/en/Gtk/RowsReorderedArgs.xml b/doc/en/Gtk/RowsReorderedArgs.xml index 773a8d5cc..1b8bcd4cf 100644 --- a/doc/en/Gtk/RowsReorderedArgs.xml +++ b/doc/en/Gtk/RowsReorderedArgs.xml @@ -52,7 +52,7 @@ - + Property System.Int32 diff --git a/doc/en/Gtk/SizeRequestedArgs.xml b/doc/en/Gtk/SizeRequestedArgs.xml index 6bef522b8..6ac3145d0 100644 --- a/doc/en/Gtk/SizeRequestedArgs.xml +++ b/doc/en/Gtk/SizeRequestedArgs.xml @@ -33,15 +33,25 @@ - + Property Gtk.Requisition + The width and height this widget would like to have. A - + + + Requisition req = args.Requisition; +req.Width = 100; +req.Height = 200; + +// NB: You must assign the value back to args.Requisition +args.Requisition = req; + + diff --git a/doc/en/Gtk/TextInsertedArgs.xml b/doc/en/Gtk/TextInsertedArgs.xml index 1dc669483..b8b081bad 100644 --- a/doc/en/Gtk/TextInsertedArgs.xml +++ b/doc/en/Gtk/TextInsertedArgs.xml @@ -52,13 +52,13 @@ - + Property System.Int32 - The position within the widget text where the text was inserted. + The position at which to insert the new text. On return, it should point to the position after the inserted text. An integer, the insert position. diff --git a/doc/en/Gtk/ToggleSizeRequestedArgs.xml b/doc/en/Gtk/ToggleSizeRequestedArgs.xml index aa8838035..85f7750ca 100644 --- a/doc/en/Gtk/ToggleSizeRequestedArgs.xml +++ b/doc/en/Gtk/ToggleSizeRequestedArgs.xml @@ -33,14 +33,14 @@ - + Property System.Int32 - The size that was requested. - A + The requested toggle size + a diff --git a/generator/IGeneratable.cs b/generator/IGeneratable.cs index 4b9c540bb..28864d30f 100644 --- a/generator/IGeneratable.cs +++ b/generator/IGeneratable.cs @@ -23,24 +23,37 @@ namespace GtkSharp.Generation { public interface IGeneratable { + // The C name of the generatable string CName {get;} - string MarshalType {get;} - - string MarshalReturnType {get;} - - string ToNativeReturnType {get;} - + // The (short) C# name of the generatable string Name {get;} + // The fully-qualified C# name of the generatable string QualifiedName {get;} + // The type (possibly including "ref" or "out") to use in the import + // signature when passing this generatable to unmanaged code + string MarshalType {get;} + + // The type to use as the return type in an import signature when + // receiving this generatable back from unmanaged code + string MarshalReturnType {get;} + + // The type to use in a managed callback signature when returning this + // generatable to unmanaged code + string ToNativeReturnType {get;} + + // Generates an expression to convert var_name to MarshalType string CallByName (string var_name); - + + // Generates an expression to convert var from MarshalType string FromNative (string var); + // Generates an expression to convert var from MarshalReturnType string FromNativeReturn (string var); + // Generates an expression to convert var to ToNativeReturnType string ToNativeReturn (string var); void Generate (); diff --git a/generator/ManagedCallString.cs b/generator/ManagedCallString.cs index d8de8bc3a..90be9febc 100644 --- a/generator/ManagedCallString.cs +++ b/generator/ManagedCallString.cs @@ -28,6 +28,7 @@ namespace GtkSharp.Generation { public class ManagedCallString { ArrayList parms = new ArrayList (); + ArrayList special = new ArrayList (); public ManagedCallString (Parameters parms) { @@ -36,9 +37,37 @@ namespace GtkSharp.Generation { if (p.IsLength && parms [i-1].IsString) continue; this.parms.Add (p); + + IGeneratable igen = p.Generatable; + if ((igen is StructGen || p.PassAs != "") && + (p.Name != igen.FromNative (p.Name))) + this.special.Add (true); + else + this.special.Add (false); } } + public string Setup (string indent) + { + string ret = ""; + + for (int i = 0; i < parms.Count; i ++) { + if ((bool)special[i] == false) + continue; + + Parameter p = parms [i] as Parameter; + IGeneratable igen = p.Generatable; + string pass_as = igen is StructGen ? "ref" : p.PassAs; + + ret += indent + igen.QualifiedName + " my" + p.Name; + if (igen is StructGen || p.PassAs == "ref") + ret += " = " + igen.FromNative (p.Name); + ret += ";\n"; + } + + return ret; + } + public override string ToString () { if (parms.Count < 1) @@ -50,11 +79,28 @@ namespace GtkSharp.Generation { Parameter p = parms [i] as Parameter; IGeneratable igen = p.Generatable; result [i] = igen is StructGen ? "ref " : (p.PassAs == "" ? "" : p.PassAs + " "); - result [i] += igen.FromNative (p.Name); + result [i] += ((bool)special[i]) ? "my" + p.Name : igen.FromNative (p.Name); } return String.Join (", ", result); } + + public string Finish (string indent) + { + string ret = ""; + + for (int i = 0; i < parms.Count; i ++) { + if ((bool)special[i] == false) + continue; + + Parameter p = parms [i] as Parameter; + IGeneratable igen = p.Generatable; + + ret += indent + p.Name + " = " + igen.CallByName ("my" + p.Name) + ";\n"; + } + + return ret; + } } } diff --git a/generator/Signal.cs b/generator/Signal.cs index 0a279b141..1ed4c2275 100644 --- a/generator/Signal.cs +++ b/generator/Signal.cs @@ -165,9 +165,16 @@ namespace GtkSharp.Generation { if (parms != null) { for (int i = 1; i < parms.Count; i++) { sw.WriteLine ("\t\tpublic " + parms[i].CSType + " " + parms[i].StudlyName + "{"); - sw.WriteLine ("\t\t\tget {"); - sw.WriteLine ("\t\t\t\treturn (" + parms[i].CSType + ") Args[" + (i - 1) + "];"); - sw.WriteLine ("\t\t\t}"); + if (parms[i].PassAs != "out") { + sw.WriteLine ("\t\t\tget {"); + sw.WriteLine ("\t\t\t\treturn (" + parms[i].CSType + ") Args[" + (i - 1) + "];"); + sw.WriteLine ("\t\t\t}"); + } + if (parms[i].PassAs != "") { + sw.WriteLine ("\t\t\tset {"); + sw.WriteLine ("\t\t\t\tArgs[" + (i - 1) + "] = (" + parms[i].CSType + ")value;"); + sw.WriteLine ("\t\t\t}"); + } sw.WriteLine ("\t\t}"); sw.WriteLine (); } @@ -222,8 +229,10 @@ namespace GtkSharp.Generation { 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); + sw.Write (call.Setup ("\t\t\t")); sw.Write ("\t\t\t{0}", IsVoid ? "" : "return "); sw.WriteLine ("obj.{0} ({1});", "On" + Name, call.ToString ()); + sw.Write (call.Finish ("\t\t\t")); sw.WriteLine ("\t\t}\n"); string cname = "\"" + elem.GetAttribute("cname") + "\""; sw.WriteLine ("\t\tprivate static void Override" + Name + " (GLib.GType gtype)"); diff --git a/generator/SignalHandler.cs b/generator/SignalHandler.cs index 79efd828e..cc2c6b5c9 100644 --- a/generator/SignalHandler.cs +++ b/generator/SignalHandler.cs @@ -65,8 +65,14 @@ namespace GtkSharp.Generation { 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; } } @@ -75,6 +81,7 @@ namespace GtkSharp.Generation { get { string result = SymbolTable.Table.GetName (retval.CType); for (int i = 0; i < parms.Count; i++) { + result += parms[i].PassAs; if (parms[i].Generatable is ObjectGen || parms[i].Generatable is InterfaceGen) { result += "Object"; } else { @@ -140,6 +147,9 @@ namespace GtkSharp.Generation { 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)) { @@ -159,6 +169,11 @@ namespace GtkSharp.Generation { 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") diff --git a/generator/VirtualMethod.cs b/generator/VirtualMethod.cs index b24167692..56cb985db 100644 --- a/generator/VirtualMethod.cs +++ b/generator/VirtualMethod.cs @@ -81,11 +81,13 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\tstatic " + MarshalReturnType + " " + Name + "Callback (" + isig + ")"); sw.WriteLine ("\t\t{"); sw.WriteLine ("\t\t\t" + type + " __obj = GLib.Object.GetObject (" + name + ", false) as " + type + ";"); + sw.Write (call.Setup ("\t\t\t")); if (retval.CSType == "void") sw.WriteLine ("\t\t\t" + call_string + ";"); else { sw.WriteLine ("\t\t\treturn " + SymbolTable.Table.ToNativeReturn (retval.CType, call_string) + ";"); } + sw.Write (call.Finish ("\t\t\t")); sw.WriteLine ("\t\t}"); } diff --git a/gtk/Gtk.metadata b/gtk/Gtk.metadata index 7b897d4bc..072c0118d 100644 --- a/gtk/Gtk.metadata +++ b/gtk/Gtk.metadata @@ -69,6 +69,7 @@ ref SetIsEditable TextDeleted + ref TextInserted 1 1 diff --git a/sample/Size.cs b/sample/Size.cs index 671996bb2..c63e83091 100644 --- a/sample/Size.cs +++ b/sample/Size.cs @@ -18,6 +18,7 @@ namespace GtkSamples { Gtk.Window win = new Gtk.Window ("Gtk# Hello World"); win.DeleteEvent += new DeleteEventHandler (Window_Delete); win.SizeAllocated += new SizeAllocatedHandler (Size_Allocated); + win.SizeRequested += new SizeRequestedHandler (Size_Requested); win.ShowAll (); Application.Run (); return 0; @@ -29,6 +30,14 @@ namespace GtkSamples { args.RetVal = true; } + static void Size_Requested (object obj, SizeRequestedArgs args) + { + Requisition req = args.Requisition; + Console.WriteLine ("Requesting 100 x 100"); + req.Width = req.Height = 100; + args.Requisition = req; + } + static void Size_Allocated (object obj, SizeAllocatedArgs args) { Rectangle rect = args.Allocation;