1 //
2 // SystemManager.cs
3 //
4 // Author:
5 //       Jonathan Pobst <monkey@jpobst.com>
6 //
7 // Copyright (c) 2010 Jonathan Pobst
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26 
27 using System;
28 using System.Collections.Generic;
29 using System.Linq;
30 using System.Text;
31 using System.IO;
32 using System.Runtime.InteropServices;
33 using Mono.Addins;
34 using Gtk;
35 
36 namespace Pinta.Core
37 {
38 	public class SystemManager
39 	{
40 		private static OS operating_system;
41 
42 		private string last_dialog_directory;
43 		private RecentData recent_data;
44 
45 		public ImageConverterManager ImageFormats { get; private set; }
46 		public PaletteFormats PaletteFormats { get; private set; }
47 		public FontManager Fonts { get; private set; }
48 		public int RenderThreads { get; set; }
49 		public OS OperatingSystem { get { return operating_system; } }
50 
SystemManager()51 		public SystemManager ()
52 		{
53 			ImageFormats = new ImageConverterManager ();
54 			PaletteFormats = new PaletteFormats ();
55 			RenderThreads = Environment.ProcessorCount;
56 			Fonts = new FontManager ();
57 
58 			last_dialog_directory = DefaultDialogDirectory;
59 
60 			recent_data = new RecentData ();
61 			recent_data.AppName = "Pinta";
62 			recent_data.AppExec = GetExecutablePathName ();
63 			recent_data.MimeType = "image/*";
64 		}
65 
SystemManager()66 		static SystemManager ()
67 		{
68 			if (Path.DirectorySeparatorChar == '\\')
69 				operating_system = OS.Windows;
70 			else if (IsRunningOnMac ())
71 				operating_system = OS.Mac;
72 			else if (Environment.OSVersion.Platform == PlatformID.Unix)
73 				operating_system = OS.X11;
74 			else
75 				operating_system = OS.Other;
76 		}
77 
78 		#region Public Properties
79 		public string LastDialogDirectory {
80 			get { return last_dialog_directory; }
81 			set {
82 				// The file chooser dialog may return null for the current folder in certain cases,
83 				// such as the Recently Used pane in the Gnome file chooser.
84 				if (value != null)
85 					last_dialog_directory = value;
86 			}
87 		}
88 
89 		public string DefaultDialogDirectory {
90 			get { return System.Environment.GetFolderPath (Environment.SpecialFolder.MyPictures); }
91 		}
92 
93 		public RecentData RecentData { get { return recent_data; } }
94 		#endregion
95 
96         /// <summary>
97         /// Returns a directory for use in a dialog. The last dialog directory is
98         /// returned if it exists, otherwise the default directory is used.
99         /// </summary>
GetDialogDirectory()100         public string GetDialogDirectory ()
101         {
102             return Directory.Exists (LastDialogDirectory) ? LastDialogDirectory : DefaultDialogDirectory;
103         }
104 
GetExecutablePathName()105 		public static string GetExecutablePathName ()
106 		{
107 			string executablePathName = System.Environment.GetCommandLineArgs ()[0];
108 			executablePathName = System.IO.Path.GetFullPath (executablePathName);
109 
110 			return executablePathName;
111 		}
112 
GetExecutableDirectory()113 		public static string GetExecutableDirectory ()
114 		{
115 			return Path.GetDirectoryName (GetExecutablePathName ());
116 		}
117 
118 		/// <summary>
119 		/// Return the root directory to search under for translations, documentation, etc.
120 		/// </summary>
GetDataRootDirectory()121 		public static string GetDataRootDirectory ()
122 		{
123 			string app_dir = SystemManager.GetExecutableDirectory ();
124 			bool devel_mode = File.Exists (Path.Combine (Path.Combine (app_dir, ".."), "Pinta.sln"));
125 
126 			if (GetOperatingSystem () != OS.X11 || devel_mode)
127 				return app_dir;
128 			else {
129 				// From MonoDevelop:
130 				// Pinta is located at $prefix/lib/pinta
131 				// adding "../.." should give us $prefix
132 				string prefix = Path.Combine (Path.Combine (app_dir, ".."), "..");
133 				//normalise it
134 				prefix = Path.GetFullPath (prefix);
135 				return Path.Combine (prefix, "share");
136 			}
137 		}
138 
GetOperatingSystem()139 		public static OS GetOperatingSystem ()
140 		{
141 			return operating_system;
142 		}
143 
GetExtensions()144 		public T[] GetExtensions<T> ()
145 		{
146 			return AddinManager.GetExtensionObjects<T> ();
147 		}
148 
149 		//From Managed.Windows.Forms/XplatUI
150 		[DllImport ("libc")]
uname(IntPtr buf)151 		static extern int uname (IntPtr buf);
152 
IsRunningOnMac()153 		static bool IsRunningOnMac ()
154 		{
155 			IntPtr buf = IntPtr.Zero;
156 			try {
157 				buf = Marshal.AllocHGlobal (8192);
158 				// This is a hacktastic way of getting sysname from uname ()
159 				if (uname (buf) == 0) {
160 					string os = Marshal.PtrToStringAnsi (buf);
161 					if (os == "Darwin")
162 						return true;
163 				}
164 			} catch {
165 			} finally {
166 				if (buf != IntPtr.Zero)
167 					Marshal.FreeHGlobal (buf);
168 			}
169 			return false;
170 		}
171 	}
172 
173 	public enum OS
174 	{
175 		Windows,
176 		Mac,
177 		X11,
178 		Other
179 	}
180 }
181