2009-08-07 Mike Kestner <mkestner@novell.com>

* glib/Log.cs: rework the LogFunc marshaling and add SetDefaultHandler
	binding to override all domains easily. [Fixes #517857]

svn path=/trunk/gtk-sharp/; revision=139599
This commit is contained in:
Mike Kestner 2009-08-08 03:00:35 +00:00
parent 55fca06701
commit 6d885fc351
2 changed files with 123 additions and 18 deletions

View File

@ -1,3 +1,8 @@
2009-08-07 Mike Kestner <mkestner@novell.com>
* glib/Log.cs: rework the LogFunc marshaling and add SetDefaultHandler
binding to override all domains easily. [Fixes #517857]
2009-08-07 Christian Hoff <christian_hoff@gmx.net>
* gtk/glue/clipboard.c: Kill as it is not used any more.

View File

@ -58,12 +58,70 @@ namespace GLib {
public class Log {
static Hashtable handlers;
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
delegate void LogFuncNative (IntPtr log_domain, LogLevelFlags flags, IntPtr message, IntPtr user_data);
static LogFuncNative native_handler;
static void NativeCallback (IntPtr log_domain_native, LogLevelFlags flags, IntPtr message_native, IntPtr user_data)
{
if (user_data == IntPtr.Zero)
return;
string log_domain = Marshaller.Utf8PtrToString (log_domain_native);
string message = Marshaller.Utf8PtrToString (message_native);
GCHandle gch = (GCHandle) user_data;
LogFunc func = gch.Target as LogFunc;
if (func != null)
func (log_domain, flags, message);
}
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
delegate void PrintFuncNative (IntPtr message);
class PrintHelper {
PrintFuncNative native;
PrintFunc managed;
public PrintHelper (PrintFuncNative native)
{
this.native = native;
}
public PrintHelper (PrintFunc managed)
{
this.managed = managed;
GCHandle.Alloc (this);
}
void Callback (IntPtr nmessage)
{
string message = Marshaller.Utf8PtrToString (nmessage);
managed (message);
}
void Invoke (string message)
{
IntPtr nmessage = Marshaller.StringToPtrGStrdup (message);
native (nmessage);
Marshaller.Free (nmessage);
}
public PrintFuncNative Handler {
get { return new PrintFuncNative (Callback); }
}
public PrintFunc Invoker {
get { return new PrintFunc (Invoke); }
}
}
static System.Collections.Generic.Dictionary<uint, GCHandle> handlers;
static void EnsureHash ()
{
if (handlers == null)
handlers = new Hashtable ();
handlers = new System.Collections.Generic.Dictionary<uint, GCHandle> ();
}
[DllImport("libglib-2.0-0.dll")]
@ -79,16 +137,19 @@ namespace GLib {
}
[DllImport("libglib-2.0-0.dll")]
static extern uint g_log_set_handler (IntPtr log_domain, LogLevelFlags flags, LogFunc log_func, IntPtr user_data);
static extern uint g_log_set_handler (IntPtr log_domain, LogLevelFlags flags, LogFuncNative log_func, IntPtr user_data);
public static uint SetLogHandler (string logDomain, LogLevelFlags flags, LogFunc logFunc)
{
if (native_handler == null)
native_handler = new LogFuncNative (NativeCallback);
IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
uint result = g_log_set_handler (ndom, flags, logFunc, IntPtr.Zero);
GCHandle gch = GCHandle.Alloc (logFunc);
uint result = g_log_set_handler (ndom, flags, native_handler, (IntPtr) gch);
Marshaller.Free (ndom);
EnsureHash ();
handlers [result] = logFunc;
handlers [result] = gch;
return result;
}
@ -97,35 +158,36 @@ namespace GLib {
public static void RemoveLogHandler (string logDomain, uint handlerID)
{
if (handlers != null && handlers.ContainsKey (handlerID))
if (handlers != null && handlers.ContainsKey (handlerID)) {
handlers [handlerID].Free ();
handlers.Remove (handlerID);
}
IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
g_log_remove_handler (ndom, handlerID);
Marshaller.Free (ndom);
}
[DllImport("libglib-2.0-0.dll")]
static extern PrintFunc g_set_print_handler (PrintFunc handler);
static extern PrintFuncNative g_set_print_handler (PrintFuncNative handler);
public static PrintFunc SetPrintHandler (PrintFunc handler)
{
EnsureHash ();
handlers ["PrintHandler"] = handler;
return g_set_print_handler (handler);
PrintHelper helper = new PrintHelper (handler);
PrintFuncNative prev = g_set_print_handler (helper.Handler);
helper = new PrintHelper (prev);
return helper.Invoker;
}
[DllImport("libglib-2.0-0.dll")]
static extern PrintFunc g_set_printerr_handler (PrintFunc handler);
static extern PrintFuncNative g_set_printerr_handler (PrintFuncNative handler);
public static PrintFunc SetPrintErrorHandler (PrintFunc handler)
{
EnsureHash ();
handlers ["PrintErrorHandler"] = handler;
return g_set_printerr_handler (handler);
PrintHelper helper = new PrintHelper (handler);
PrintFuncNative prev = g_set_printerr_handler (helper.Handler);
helper = new PrintHelper (prev);
return helper.Invoker;
}
[DllImport("libglib-2.0-0.dll")]
@ -160,6 +222,44 @@ namespace GLib {
return result;
}
class Invoker {
LogFuncNative native;
public Invoker (LogFuncNative native)
{
this.native = native;
}
void Invoke (string log_domain, LogLevelFlags flags, string message)
{
IntPtr ndom = Marshaller.StringToPtrGStrdup (log_domain);
IntPtr nmess = Marshaller.StringToPtrGStrdup (message);
native (ndom, flags, nmess, IntPtr.Zero);
Marshaller.Free (ndom);
Marshaller.Free (nmess);
}
public LogFunc Handler {
get { return new LogFunc (Invoke); }
}
}
[DllImport("libglib-2.0-0.dll")]
extern static LogFuncNative g_log_set_default_handler (LogFuncNative log_func, IntPtr user_data);
public static LogFunc SetDefaultHandler (LogFunc log_func)
{
if (native_handler == null)
native_handler = new LogFuncNative (NativeCallback);
LogFuncNative prev = g_log_set_default_handler (native_handler, (IntPtr) GCHandle.Alloc (log_func));
if (prev == null)
return null;
Invoker invoker = new Invoker (prev);
return invoker.Handler;
}
/*
* Some common logging methods.
*