2004-01-18 Peter Williams <peter@newton.cx>

* glib/Marshaller.cs (ArrayPtrToArgv, ArgvToArrayPtr): new
	functions for marshalling and unmarshalling string arrays
	to/from char **. Not pretty, but lets us call gtk_init()
	in Gtk.

	* gtk/Application.cs (do_init): New helper function to handle
	passing args to Gtk. Uses above functions.
	(Init): Use do_init, take a new progname parameter.
	(InitCheck): Same.

doc/:

2003-01-13  Peter Williams  <peter@newton.cx>

	* en/Gtk/Application.xml: Update Init, InitCheck functions
	for new progname argument. Fix a paste-o in the docs for InitCheck.

svn path=/trunk/gtk-sharp/; revision=22237
This commit is contained in:
Peter Williams 2004-01-19 03:24:25 +00:00
parent 3a849daf89
commit 4feed7bb77
5 changed files with 170 additions and 25 deletions

View File

@ -1,3 +1,15 @@
2004-01-18 Peter Williams <peter@newton.cx>
* glib/Marshaller.cs (ArrayPtrToArgv, ArgvToArrayPtr): new
functions for marshalling and unmarshalling string arrays
to/from char **. Not pretty, but lets us call gtk_init()
in Gtk.
* gtk/Application.cs (do_init): New helper function to handle
passing args to Gtk. Uses above functions.
(Init): Use do_init, take a new progname parameter.
(InitCheck): Same.
2004-01-18 Mike Kestner <mkestner@ximian.com> 2004-01-18 Mike Kestner <mkestner@ximian.com>
* gtk/Gtk.metadata : mark TreeSelection.GetSelectedRows return * gtk/Gtk.metadata : mark TreeSelection.GetSelectedRows return

View File

@ -1,3 +1,8 @@
2003-01-13 Peter Williams <peter@newton.cx>
* en/Gtk/Application.xml: Update Init, InitCheck functions
for new progname argument. Fix a paste-o in the docs for InitCheck.
2004-01-13 John Luke <jluke@cfl.rr.com> 2004-01-13 John Luke <jluke@cfl.rr.com>
* en/Gtk/TreeSelection.xml: add example * en/Gtk/TreeSelection.xml: add example

View File

@ -143,16 +143,18 @@ void LongComputation ()
</Docs> </Docs>
</Member> </Member>
<Member MemberName="Init"> <Member MemberName="Init">
<MemberSignature Language="C#" Value="public static void Init (ref string [] args);" /> <MemberSignature Language="C#" Value="public static void Init (string progname, ref string [] args);" />
<MemberType>Method</MemberType> <MemberType>Method</MemberType>
<ReturnValue> <ReturnValue>
<ReturnType>System.Void</ReturnType> <ReturnType>System.Void</ReturnType>
</ReturnValue> </ReturnValue>
<Parameters> <Parameters>
<Parameter Name="progname" Type="System.String" />
<Parameter Name="args" Type="System.String []&amp;" /> <Parameter Name="args" Type="System.String []&amp;" />
</Parameters> </Parameters>
<Docs> <Docs>
<summary>Initializes Gtk# for operation.</summary> <summary>Initializes Gtk# for operation.</summary>
<param name="progname">The name of your program</param>
<param name="args">The arguments to pass to the toolkit</param> <param name="args">The arguments to pass to the toolkit</param>
<remarks> <remarks>
<para> <para>
@ -164,7 +166,7 @@ void LongComputation ()
This function will terminate your program if it was unable This function will terminate your program if it was unable
to initialize the GUI for some reason. If you want your to initialize the GUI for some reason. If you want your
program to fall back to a textual interface you want to program to fall back to a textual interface you want to
call <see cref="M:Gtk.Application.InitCheck(System.String []&amp;)" /> instead. call <see cref="M:Gtk.Application.InitCheck(System.String, System.String []&amp;)" /> instead.
</para> </para>
<para> <para>
The args values will be modified after Gtk has removed the The args values will be modified after Gtk has removed the
@ -174,18 +176,20 @@ void LongComputation ()
</Docs> </Docs>
</Member> </Member>
<Member MemberName="InitCheck"> <Member MemberName="InitCheck">
<MemberSignature Language="C#" Value="public static bool InitCheck (ref string [] args);" /> <MemberSignature Language="C#" Value="public static bool InitCheck (string progname, ref string [] args);" />
<MemberType>Method</MemberType> <MemberType>Method</MemberType>
<ReturnValue> <ReturnValue>
<ReturnType>System.Boolean</ReturnType> <ReturnType>System.Boolean</ReturnType>
</ReturnValue> </ReturnValue>
<Parameters> <Parameters>
<Parameter Name="progname" Type="System.String" />
<Parameter Name="args" Type="System.String []&amp;" /> <Parameter Name="args" Type="System.String []&amp;" />
</Parameters> </Parameters>
<Docs> <Docs>
<summary>Initializes Gtk# for operation, probes window system.</summary> <summary>Initializes Gtk# for operation, probes window system.</summary>
<returns>true if the toolkit was initialized, false if the <returns>true if the toolkit was initialized, false if the
windowing system can not be initilized.</returns> windowing system can not be initilized.</returns>
<param name="progname">The name of your program</param>
<param name="args">The arguments to pass to the toolkit</param> <param name="args">The arguments to pass to the toolkit</param>
<remarks> <remarks>
<para> <para>
@ -196,12 +200,6 @@ void LongComputation ()
toolkit could not be initialized. If you do not want to toolkit could not be initialized. If you do not want to
do dual GUI/text applications, you can use <see cref="M:Gtk.Application.Init()" /> instead. do dual GUI/text applications, you can use <see cref="M:Gtk.Application.Init()" /> instead.
</para> </para>
<para>
This function will terminate your program if it was unable
to initialize the GUI for some reason. If you want your
program to fall back to a textual interface you want to
call <see cref="M:Gtk.Application.InitCheck(System.String []&amp;)" /> instead.
</para>
</remarks> </remarks>
</Docs> </Docs>
</Member> </Member>
@ -224,11 +222,11 @@ void LongComputation ()
This function will terminate your program if it was unable This function will terminate your program if it was unable
to initialize the GUI for some reason. If you want your to initialize the GUI for some reason. If you want your
program to fall back to a textual interface you want to program to fall back to a textual interface you want to
call <see cref="M:Gtk.Application.InitCheck(System.String []&amp;)" /> instead. call <see cref="M:Gtk.Application.InitCheck(System.String, System.String []&amp;)" /> instead.
</para> </para>
<para> <para>
If you want to pass arguments from the command line use If you want to pass arguments from the command line use
the <see cref="T:Gtk.Application.Init(System.String []&amp;)" /> the <see cref="T:Gtk.Application.Init(System.String, System.String []&amp;)" />
method instead. method instead.
</para> </para>
</remarks> </remarks>
@ -268,4 +266,4 @@ void LongComputation ()
</Docs> </Docs>
</Member> </Member>
</Members> </Members>
</Type> </Type>

View File

@ -52,6 +52,107 @@ namespace GLibSharp {
return g_strdup (str); return g_strdup (str);
} }
// Argv marshalling -- unpleasantly complex, but
// don't know of a better way to do it.
//
// Currently, the 64-bit cleanliness is
// hypothetical. It's also ugly, but I don't know of a
// construct to handle both 32 and 64 bitness
// transparently, since we need to alloc buffers of
// [native pointer size] * [count] bytes.
[DllImport("libglib-2.0-0.dll")]
static extern IntPtr g_malloc(ulong size);
static bool check_sixtyfour () {
int szint = Marshal.SizeOf (typeof (int));
int szlong = Marshal.SizeOf (typeof (long));
int szptr = IntPtr.Size;
if (szptr == szint)
return false;
if (szptr == szlong)
return true;
throw new Exception ("Pointers are neither int- nor long-sized???");
}
static IntPtr make_buf_32 (string[] args)
{
int[] ptrs = new int[args.Length];
for (int i = 0; i < args.Length; i++)
ptrs[i] = (int) Marshal.StringToHGlobalAuto (args[i]);
IntPtr buf = g_malloc ((ulong) Marshal.SizeOf(typeof(string)) *
(ulong) args.Length);
Marshal.Copy (ptrs, 0, buf, ptrs.Length);
return buf;
}
static IntPtr make_buf_64 (string[] args)
{
long[] ptrs = new long[args.Length];
for (int i = 0; i < args.Length; i++)
ptrs[i] = (long) Marshal.StringToHGlobalAuto (args[i]);
IntPtr buf = g_malloc ((ulong) Marshal.SizeOf(typeof(string)) *
(ulong) args.Length);
Marshal.Copy (ptrs, 0, buf, ptrs.Length);
return buf;
}
public static IntPtr ArgvToArrayPtr (string[] args)
{
if (args.Length == 0)
return IntPtr.Zero;
if (check_sixtyfour ())
return make_buf_64 (args);
return make_buf_32 (args);
}
// should we be freeing these pointers? they're marshalled
// from our own strings, so I think not ...
static string[] unmarshal_32 (IntPtr buf, int argc)
{
int[] ptrs = new int[argc];
string[] args = new string[argc];
Marshal.Copy (buf, ptrs, 0, argc);
for (int i = 0; i < ptrs.Length; i++)
args[i] = Marshal.PtrToStringAuto ((IntPtr) ptrs[i]);
return args;
}
static string[] unmarshal_64 (IntPtr buf, int argc)
{
long[] ptrs = new long[argc];
string[] args = new string[argc];
Marshal.Copy (buf, ptrs, 0, argc);
for (int i = 0; i < ptrs.Length; i++)
args[i] = Marshal.PtrToStringAuto ((IntPtr) ptrs[i]);
return args;
}
public static string[] ArrayPtrToArgv (IntPtr array, int argc)
{
if (argc == 0)
return new string[0];
if (check_sixtyfour ())
return unmarshal_64 (array, argc);
return unmarshal_32 (array, argc);
}
} }
} }

View File

@ -20,28 +20,57 @@ namespace Gtk {
} }
[DllImport("libgtk-win32-2.0-0.dll")] [DllImport("libgtk-win32-2.0-0.dll")]
static extern void gtk_init (int argc, IntPtr argv); static extern void gtk_init (ref int argc, ref IntPtr argv);
[DllImport("libgtk-win32-2.0-0.dll")]
static extern bool gtk_init_check (ref int argc, ref IntPtr argv);
public static void Init () public static void Init ()
{ {
gtk_init (0, new IntPtr(0)); IntPtr argv = new IntPtr(0);
int argc = 0;
gtk_init (ref argc, ref argv);
} }
[DllImport("libgtk-win32-2.0-0.dll")] static bool do_init (string progname, ref string[] args, bool check)
static extern void gtk_init (ref int argc, ref String[] argv);
[DllImport("libgtk-win32-2.0-0.dll")]
static extern bool gtk_init_check (ref int argc, ref String[] argv);
public static void Init (ref string[] args)
{ {
int argc = args.Length; bool res = false;
gtk_init (ref argc, ref args); string[] progargs = new string[args.Length + 1];
progargs[0] = progname;
args.CopyTo (progargs, 1);
IntPtr buf = GLibSharp.Marshaller.ArgvToArrayPtr (progargs);
int argc = progargs.Length;
if (check)
res = gtk_init_check (ref argc, ref buf);
else
gtk_init (ref argc, ref buf);
// copy back the resulting argv, minus argv[0], which we're
// not interested in.
if (argc == 0)
args = new string[0];
else {
progargs = GLibSharp.Marshaller.ArrayPtrToArgv (buf, argc);
args = new string[argc - 1];
Array.Copy (progargs, 1, args, 0, argc - 1);
}
return res;
} }
public static bool InitCheck (ref string[] args) public static void Init (string progname, ref string[] args)
{ {
int argc = args.Length; do_init (progname, ref args, false);
return gtk_init_check (ref argc, ref args); }
public static bool InitCheck (string progname, ref string[] args)
{
return do_init (progname, ref args, true);
} }
[DllImport("libgtk-win32-2.0-0.dll")] [DllImport("libgtk-win32-2.0-0.dll")]