1 // Log.cs - Wrapper for message logging functions
2 //
3 // Authors:
4 //	Gonzalo Paniagua Javier (gonzalo@ximian.com)
5 //
6 //
7 // Copyright (c) 2002 Gonzalo Paniagua
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of version 2 of the Lesser GNU General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this program; if not, write to the
20 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 // Boston, MA 02111-1307, USA.
22 
23 //
24 
25 namespace GLib {
26 
27 	using System;
28 	using System.Collections;
29 	using System.Runtime.InteropServices;
30 
LogFunc(string log_domain, LogLevelFlags log_level, string message)31 	public delegate void LogFunc (string log_domain, LogLevelFlags log_level, string message);
32 
33 	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
LogFunc2(string log_domain, LogLevelFlags log_level, string message, LogFunc user_data)34 	internal delegate void LogFunc2 (string log_domain, LogLevelFlags log_level, string message, LogFunc user_data);
35 
36 	[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
PrintFunc(string message)37 	public delegate void PrintFunc (string message);
38 
39 	[Flags]
40 	public enum LogLevelFlags : int
41 	{
42 		/* log flags */
43 		FlagRecursion          = 1 << 0,
44 		FlagFatal              = 1 << 1,
45 
46 		/* GLib log levels */
47 		Error                  = 1 << 2,       /* always fatal */
48 		Critical               = 1 << 3,
49 		Warning                = 1 << 4,
50 		Message                = 1 << 5,
51 		Info                   = 1 << 6,
52 		Debug                  = 1 << 7,
53 
54 		/* Convenience values */
55 		AllButFatal            = 253,
56 		AllButRecursion        = 254,
57 		All                    = 255,
58 
59 		FlagMask               = 3,
60 		LevelMask              = unchecked ((int) 0xFFFFFFFC)
61 	}
62 
63 	public class Log {
64 
65 		static Hashtable handlers;
66 
EnsureHash()67 		static void EnsureHash ()
68 		{
69 			if (handlers == null)
70 				handlers = new Hashtable ();
71 		}
72 
73 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_logv(IntPtr log_domain, LogLevelFlags flags, IntPtr message)74 		static extern void g_logv (IntPtr log_domain, LogLevelFlags flags, IntPtr message);
75 
Write(string logDomain, LogLevelFlags flags, string format, params object [] args)76 		public static void Write (string logDomain, LogLevelFlags flags, string format, params object [] args)
77 		{
78 			IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
79 			IntPtr nmessage = Marshaller.StringToPtrGStrdup (String.Format (format, args));
80 			g_logv (ndom, flags, nmessage);
81 			Marshaller.Free (ndom);
82 			Marshaller.Free (nmessage);
83 		}
84 
85 		[Obsolete ("Use the static member Write")]
WriteLog(string logDomain, LogLevelFlags flags, string format, params object [] args)86 		public void WriteLog (string logDomain, LogLevelFlags flags, string format, params object [] args)
87 		{
88 			IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
89 			IntPtr nmessage = Marshaller.StringToPtrGStrdup (String.Format (format, args));
90 			g_logv (ndom, flags, nmessage);
91 			Marshaller.Free (ndom);
92 			Marshaller.Free (nmessage);
93 		}
94 
95 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_log_set_handler(IntPtr log_domain, LogLevelFlags flags, LogFunc2 log_func, LogFunc user_data)96 		static extern uint g_log_set_handler (IntPtr log_domain, LogLevelFlags flags, LogFunc2 log_func, LogFunc user_data);
97 
98 		static readonly LogFunc2 LogFuncTrampoline = (string domain, LogLevelFlags level, string message, LogFunc user_data) => {
99                         user_data (domain, level, message);
100                 };
101 
SetLogHandler(string logDomain, LogLevelFlags flags, LogFunc logFunc)102 		public static uint SetLogHandler (string logDomain, LogLevelFlags flags, LogFunc logFunc)
103 		{
104 			IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
105 			uint result = g_log_set_handler (ndom, flags, LogFuncTrampoline, logFunc);
106 			Marshaller.Free (ndom);
107 			EnsureHash ();
108 			handlers [result] = logFunc;
109 
110 			return result;
111 		}
112 
113 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_log_remove_handler(IntPtr log_domain, uint handler_id)114 		static extern uint g_log_remove_handler (IntPtr log_domain, uint handler_id);
115 
RemoveLogHandler(string logDomain, uint handlerID)116 		public static void RemoveLogHandler (string logDomain, uint handlerID)
117 		{
118 			if (handlers != null && handlers.ContainsKey (handlerID))
119 				handlers.Remove (handlerID);
120 
121 			IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
122 			g_log_remove_handler (ndom, handlerID);
123 			Marshaller.Free (ndom);
124 		}
125 
126 
127 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_set_print_handler(PrintFunc handler)128 		static extern PrintFunc g_set_print_handler (PrintFunc handler);
129 
SetPrintHandler(PrintFunc handler)130 		public static PrintFunc SetPrintHandler (PrintFunc handler)
131 		{
132 			EnsureHash ();
133 			handlers ["PrintHandler"] = handler;
134 
135 			return g_set_print_handler (handler);
136 		}
137 
138 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_set_printerr_handler(PrintFunc handler)139 		static extern PrintFunc g_set_printerr_handler (PrintFunc handler);
140 
SetPrintErrorHandler(PrintFunc handler)141 		public static PrintFunc SetPrintErrorHandler (PrintFunc handler)
142 		{
143 			EnsureHash ();
144 			handlers ["PrintErrorHandler"] = handler;
145 
146 			return g_set_printerr_handler (handler);
147 		}
148 
149 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_log_default_handler(IntPtr log_domain, LogLevelFlags log_level, IntPtr message, IntPtr unused_data)150 		static extern void g_log_default_handler (IntPtr log_domain, LogLevelFlags log_level, IntPtr message, IntPtr unused_data);
151 
DefaultHandler(string logDomain, LogLevelFlags logLevel, string message)152 		public static void DefaultHandler (string logDomain, LogLevelFlags logLevel, string message)
153 
154 		{
155 			IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
156 			IntPtr nmess = Marshaller.StringToPtrGStrdup (message);
157 			g_log_default_handler (ndom, logLevel, nmess, IntPtr.Zero);
158 			Marshaller.Free (ndom);
159 			Marshaller.Free (nmess);
160 		}
161 
162 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_log_set_always_fatal(LogLevelFlags fatal_mask)163 		extern static LogLevelFlags g_log_set_always_fatal (LogLevelFlags fatal_mask);
164 
SetAlwaysFatal(LogLevelFlags fatalMask)165 		public static LogLevelFlags SetAlwaysFatal (LogLevelFlags fatalMask)
166 		{
167 			return g_log_set_always_fatal (fatalMask);
168 		}
169 
170 		[DllImport("libglib-2.0-0.dll", CallingConvention=CallingConvention.Cdecl)]
g_log_set_fatal_mask(IntPtr log_domain, LogLevelFlags fatal_mask)171 		extern static LogLevelFlags g_log_set_fatal_mask (IntPtr log_domain, LogLevelFlags fatal_mask);
172 
SetAlwaysFatal(string logDomain, LogLevelFlags fatalMask)173 		public static LogLevelFlags SetAlwaysFatal (string logDomain, LogLevelFlags fatalMask)
174 		{
175 			IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
176 			LogLevelFlags result = g_log_set_fatal_mask (ndom, fatalMask);
177 			Marshaller.Free (ndom);
178 			return result;
179 		}
180 
181 		/*
182 		 * Some common logging methods.
183 		 *
184 		 * Sample usage:
185 		 *
186 		 *	// Print the messages for the NULL domain
187 		 *	LogFunc logFunc = new LogFunc (Log.PrintLogFunction);
188 		 *	Log.SetLogHandler (null, LogLevelFlags.All, logFunc);
189 		 *
190 		 *	// Print messages and stack trace for Gtk critical messages
191 		 *	logFunc = new LogFunc (Log.PrintTraceLogFunction);
192 		 *	Log.SetLogHandler ("Gtk", LogLevelFlags.Critical, logFunc);
193 		 *
194 		 */
195 
PrintLogFunction(string domain, LogLevelFlags level, string message)196 		public static void PrintLogFunction (string domain, LogLevelFlags level, string message)
197 		{
198 			Console.WriteLine ("Domain: '{0}' Level: {1}", domain, level);
199 			Console.WriteLine ("Message: {0}", message);
200 		}
201 
PrintTraceLogFunction(string domain, LogLevelFlags level, string message)202 		public static void PrintTraceLogFunction (string domain, LogLevelFlags level, string message)
203 		{
204 			PrintLogFunction (domain, level, message);
205 			Console.WriteLine ("Trace follows:\n{0}", new System.Diagnostics.StackTrace ());
206 		}
207 	}
208 }
209