1 /*
2  * Copyright (C) 2007-2011 Jordi Mas i Hernàndez <jmas@softcatala.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 using System;
19 using System.Runtime.InteropServices;
20 using System.Text;
21 using System.Globalization;
22 using System.Threading;
23 
24 namespace gbrainy.Core.Platform
25 {
26 	//
27 	// Unix system calls
28 	//
29 	static public class Unix
30 	{
31 		[DllImport("libc")]
localeconv()32 		static extern IntPtr localeconv ();
33 
34 		[DllImport ("libc")] // Linux
prctl(int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5)35 		static extern int prctl (int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5);
36 
37 		[DllImport ("libc")] // BSD
setproctitle(byte [] fmt, byte [] str_arg)38 		static extern void setproctitle (byte [] fmt, byte [] str_arg);
39 
40 		[DllImport("libgtk-3-0.dll")]
gtk_show_uri(IntPtr screen, IntPtr uri, uint timestamp, out IntPtr error)41 		static extern bool gtk_show_uri(IntPtr screen, IntPtr uri, uint timestamp, out IntPtr error);
42 
43 		[DllImport ("libcanberra-gtk3.so.0")]
ca_gtk_play_for_widget(IntPtr widget, uint id, string name1, string prop1, string name2, string prop2, IntPtr nil)44 		static extern void ca_gtk_play_for_widget (IntPtr widget, uint id, string name1, string prop1, string name2, string prop2, IntPtr nil);
45 
46 		/* Taken from locale.h  */
47 		[StructLayout (LayoutKind.Sequential,  Pack = 1, Size = 68)]
48 		struct lconv
49 		{
50 			public string decimal_point;
51 			// 64 bytes follow
52 		}
53 
54 		// Mono supports less locales that Unix systems
55 		// To overcome this limitation we setup the right locale parameters
56 		// when the Mono locale is InvariantCulture, that is, when the user's locale
57 		// has not been identified and the default Mono locale is used
58 		//
59 		// See: https://bugzilla.novell.com/show_bug.cgi?id=420468
60 		//
FixLocaleInfo()61 		static public void FixLocaleInfo ()
62 		{
63 			IntPtr st = IntPtr.Zero;
64 			lconv lv;
65 			int platform = (int) Environment.OSVersion.Platform;
66 
67 			if (platform != 4 && platform != 128) // Only in Unix based systems
68 				return;
69 
70 			if (CultureInfo.CurrentCulture != CultureInfo.InvariantCulture) // Culture well supported
71 				return;
72 
73 			try {
74 				st = localeconv ();
75 				if (st == IntPtr.Zero) return;
76 
77 				lv = (lconv) Marshal.PtrToStructure (st, typeof (lconv));
78 				CultureInfo culture = (CultureInfo) CultureInfo.CurrentCulture.Clone ();
79 				culture.NumberFormat.NumberDecimalSeparator = lv.decimal_point;
80 				Thread.CurrentThread.CurrentCulture = culture;
81 			}
82 			catch (Exception e)
83 			{
84 				Console.WriteLine ("Unix.FixLocaleInfo. Error {0}", e);
85 			}
86 		}
87 
SetProcessName(string name)88 		public static void SetProcessName (string name)
89 		{
90 			int platform = (int) Environment.OSVersion.Platform;
91 			if (platform != 4 && platform != 128)
92 				return;
93 
94 			try {
95 				if (prctl (15 /* PR_SET_NAME */, Encoding.ASCII.GetBytes (name + "\0"),
96 					IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) != 0) {
97 					throw new ApplicationException ("Error setting process name: " +
98 						Mono.Unix.Native.Stdlib.GetLastError ());
99 				}
100 			} catch (EntryPointNotFoundException) {
101 				setproctitle (Encoding.ASCII.GetBytes ("%s\0"),
102 					Encoding.ASCII.GetBytes (name + "\0"));
103 			}
104 		}
105 
ShowUri(Gdk.Screen screen, string uri, uint timestamp)106 		public static bool ShowUri (Gdk.Screen screen, string uri, uint timestamp)
107 		{
108 
109 			bool rslt = false;
110 
111 			try {
112 				IntPtr native_uri = GLib.Marshaller.StringToPtrGStrdup (uri);
113 				IntPtr error = IntPtr.Zero;
114 				rslt = gtk_show_uri(screen == null ? IntPtr.Zero : screen.Handle, native_uri, timestamp, out error);
115 				GLib.Marshaller.Free (native_uri);
116 
117 				if (error != IntPtr.Zero)
118 					throw new GLib.GException (error);
119 			}
120 
121 			catch (Exception e) {
122 				Console.WriteLine ("Unix.ShowUri. Error {0}", e);
123 			}
124 
125 			return rslt;
126 		}
127 
PlaySound(IntPtr widget, string filename)128 		public static void PlaySound(IntPtr widget, string filename)
129 		{
130 			try {
131 				ca_gtk_play_for_widget (widget, 0, "media.name", filename,
132 					"media.filename", filename,  IntPtr.Zero);
133 			}
134 			catch (Exception e) {
135 				Console.WriteLine ("Unix.PlaySound. Error {0}", e);
136 			}
137 		}
138 	}
139 }
140