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>
* 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>
* en/Gtk/TreeSelection.xml: add example

View File

@ -143,16 +143,18 @@ void LongComputation ()
</Docs>
</Member>
<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>
<ReturnValue>
<ReturnType>System.Void</ReturnType>
</ReturnValue>
<Parameters>
<Parameter Name="progname" Type="System.String" />
<Parameter Name="args" Type="System.String []&amp;" />
</Parameters>
<Docs>
<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>
<remarks>
<para>
@ -164,7 +166,7 @@ void LongComputation ()
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.
call <see cref="M:Gtk.Application.InitCheck(System.String, System.String []&amp;)" /> instead.
</para>
<para>
The args values will be modified after Gtk has removed the
@ -174,18 +176,20 @@ void LongComputation ()
</Docs>
</Member>
<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>
<ReturnValue>
<ReturnType>System.Boolean</ReturnType>
</ReturnValue>
<Parameters>
<Parameter Name="progname" Type="System.String" />
<Parameter Name="args" Type="System.String []&amp;" />
</Parameters>
<Docs>
<summary>Initializes Gtk# for operation, probes window system.</summary>
<returns>true if the toolkit was initialized, false if the
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>
<remarks>
<para>
@ -196,12 +200,6 @@ void LongComputation ()
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.
</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>
</Docs>
</Member>
@ -224,11 +222,11 @@ void LongComputation ()
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.
call <see cref="M:Gtk.Application.InitCheck(System.String, System.String []&amp;)" /> instead.
</para>
<para>
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.
</para>
</remarks>
@ -268,4 +266,4 @@ void LongComputation ()
</Docs>
</Member>
</Members>
</Type>
</Type>

View File

@ -52,6 +52,107 @@ namespace GLibSharp {
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")]
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 ()
{
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 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)
static bool do_init (string progname, ref string[] args, bool check)
{
int argc = args.Length;
gtk_init (ref argc, ref args);
bool res = false;
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;
return gtk_init_check (ref argc, ref args);
do_init (progname, ref args, false);
}
public static bool InitCheck (string progname, ref string[] args)
{
return do_init (progname, ref args, true);
}
[DllImport("libgtk-win32-2.0-0.dll")]