[ElmSharp] Fix SetNextFocusObject issue (#401)
[platform/core/csapi/tizenfx.git] / external / src / OpenTK / OpenTK / Configuration.cs
1 //
2 // The Open Toolkit Library License
3 //
4 // Copyright (c) 2006 - 2009 the Open Toolkit library.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights to
9 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
10 // the Software, and to permit persons to whom the Software is furnished to do
11 // so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in all
14 // copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 // OTHER DEALINGS IN THE SOFTWARE.
24 //
25
26 using System;
27 using System.Diagnostics;
28 using System.Runtime.InteropServices;
29
30 namespace OpenTK
31 {
32     /// <summary>
33     /// Provides information about the underlying OS and runtime.
34     /// You must call <c>Toolkit.Init</c> before accessing members
35     /// of this class.
36     /// </summary>
37     public sealed class Configuration
38     {
39         private static bool runningOnUnix, runningOnMacOS, runningOnLinux;
40         private volatile static bool initialized;
41         private readonly static object InitLock = new object();
42
43         private Configuration() { }
44
45         /// <summary>Gets a System.Boolean indicating whether OpenTK is running on a Windows platform.</summary>
46         public static bool RunningOnWindows { get; private set; }
47
48         /// <summary>Gets a System.Boolean indicating whether OpenTK is running on an X11 platform.</summary>
49         public static bool RunningOnX11 { get; private set; }
50
51         /// <summary>
52         /// Gets a <see cref="System.Boolean"/> indicating whether OpenTK is running on a Unix platform.
53         /// </summary>
54         public static bool RunningOnUnix
55         {
56             get { return runningOnUnix; }
57         }
58
59         /// <summary>
60         /// Gets a System.Boolean indicating whether OpenTK is running on the SDL2 backend.
61         /// </summary>
62         public static bool RunningOnSdl2
63         {
64             get;
65             private set;
66         }
67
68         /// <summary>Gets a System.Boolean indicating whether OpenTK is running on the Linux kernel.</summary>
69         public static bool RunningOnLinux { get { return runningOnLinux; } }
70
71         /// <summary>Gets a System.Boolean indicating whether OpenTK is running on a MacOS platform.</summary>
72         public static bool RunningOnMacOS { get { return runningOnMacOS; } }
73
74         /// <summary>
75         /// Gets a System.Boolean indicating whether OpenTK is running on the Mono runtime.
76         /// </summary>
77         public static bool RunningOnMono { get; private set; }
78
79         /// <summary>
80         /// Gets a <c>System.Boolean</c> indicating whether
81         /// OpenTK is running on an Android device.
82         /// </summary>
83         public static bool RunningOnAndroid
84         {
85             get
86             {
87 #if ANDROID
88                 return true;
89 #else
90                 return false;
91 #endif
92             }
93         }
94
95         /// <summary>
96         /// Gets a <c>System.Boolean</c> indicating whether
97         /// OpenTK is running on an Android device.
98         /// </summary>
99         public static bool RunningOnIOS
100         {
101             get
102             {
103 #if IPHONE
104                 return true;
105 #else
106                 return false;
107 #endif
108             }
109         }
110
111         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
112         private struct utsname
113         {
114             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
115             public string sysname;
116
117             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
118             public string nodename;
119
120             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
121             public string release;
122
123             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
124             public string version;
125
126             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
127             public string machine;
128
129             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
130             public string extraJustInCase;
131
132         }
133
134         /// <summary>
135         /// Detects the unix kernel by p/invoking uname (libc).
136         /// </summary>
137         /// <returns></returns>
138         private static string DetectUnixKernel()
139         {
140             Debug.Print("Size: {0}", Marshal.SizeOf(typeof(utsname)).ToString());
141             Debug.Flush();
142             utsname uts = new utsname();
143             uname(out uts);
144
145             Debug.WriteLine("System:");
146             Debug.Indent();
147             Debug.WriteLine(uts.sysname);
148             Debug.WriteLine(uts.nodename);
149             Debug.WriteLine(uts.release);
150             Debug.WriteLine(uts.version);
151             Debug.WriteLine(uts.machine);
152             Debug.Unindent();
153
154             return uts.sysname.ToString();
155         }
156
157         [DllImport("libc")]
158         private static extern void uname(out utsname uname_struct);
159
160         private static bool DetectMono()
161         {
162             // Detect the Mono runtime (code taken from http://mono.wikia.com/wiki/Detecting_if_program_is_running_in_Mono).
163             Type t = Type.GetType("Mono.Runtime");
164             return t != null;
165         }
166
167         #if SDL2
168         private static bool DetectSdl2()
169         {
170             bool supported = false;
171
172             // Detect whether SDL2 is supported
173             // We require:
174             // - SDL2 version 2.0.0 or higher (previous beta
175             //   versions are not ABI-compatible)
176             // - Successful SDL2 initialization (sometimes the
177             //   binary exists but fails to initialize correctly)
178             var version = new Platform.SDL2.Version();
179             try
180             {
181                 version = Platform.SDL2.SDL.Version;
182                     if (version.Number >= 2000)
183                 {
184                     if (Platform.SDL2.SDL.WasInit(0))
185                     {
186                         supported = true;
187                     }
188                     else
189                     {
190                         // Attempt to initialize SDL2.
191                         var flags =
192                             Platform.SDL2.SystemFlags.VIDEO |
193                             Platform.SDL2.SystemFlags.TIMER;
194
195                         if (Platform.SDL2.SDL.Init(flags) == 0)
196                         {
197                             supported = true;
198                         }
199                         else
200                         {
201                             Debug.Print("SDL2 init failed with error: {0}",
202                                 Platform.SDL2.SDL.GetError());
203                         }
204                     }
205                 }
206             }
207             catch (Exception e)
208             {
209                 Debug.Print("SDL2 init failed with exception: {0}", e);
210             }
211
212             if (!supported)
213             {
214                 Debug.Print("SDL2 is not supported");
215             }
216             else
217             {
218                 Debug.Print("SDL2 is supported. Version is {0}.{1}.{2}",
219                     version.Major, version.Minor, version.Patch);
220             }
221
222             return supported;
223         }
224         #endif
225
226         private static void DetectUnix(out bool unix, out bool linux, out bool macos)
227         {
228             unix = linux = macos = false;
229
230             string kernel_name = DetectUnixKernel();
231             switch (kernel_name)
232             {
233                 case null:
234                 case "":
235                     throw new PlatformNotSupportedException(
236                         "Unknown platform. Please file a bug report at https://github.com/opentk/opentk/issues");
237
238                 case "Linux":
239                     linux = unix = true;
240                     break;
241
242                 case "Darwin":
243                     macos = unix = true;
244                     break;
245
246                 default:
247                     unix = true;
248                     break;
249             }
250         }
251
252         private static bool DetectWindows()
253         {
254             return
255                 System.Environment.OSVersion.Platform == PlatformID.Win32NT ||
256                 System.Environment.OSVersion.Platform == PlatformID.Win32S ||
257                 System.Environment.OSVersion.Platform == PlatformID.Win32Windows ||
258                 System.Environment.OSVersion.Platform == PlatformID.WinCE;
259         }
260
261         private static bool DetectX11()
262         {
263             #if X11
264             // Detect whether X is present.
265             try { return OpenTK.Platform.X11.API.DefaultDisplay != IntPtr.Zero; }
266             catch { return false; }
267             #else
268             return false;
269             #endif
270         }
271
272         // Detects the underlying OS and runtime.
273         internal static void Init(ToolkitOptions options)
274         {
275             lock (InitLock)
276             {
277                 if (!initialized)
278                 {
279 #if ANDROID || IPHONE
280                     RunningOnMono = true;
281 #else
282                     RunningOnMono = DetectMono();
283                     RunningOnWindows = DetectWindows();
284                     if (!RunningOnWindows)
285                     {
286                         DetectUnix(out runningOnUnix, out runningOnLinux, out runningOnMacOS);
287                     }
288
289                     if (options.Backend == PlatformBackend.Default)
290                     {
291                         RunningOnSdl2 = DetectSdl2();
292                     }
293
294                     if ((runningOnLinux && !RunningOnSdl2) || options.Backend == PlatformBackend.PreferX11)
295                     {
296                         RunningOnX11 = DetectX11();
297                     }
298
299                     initialized = true;
300 #endif
301                     Debug.Print("Detected configuration: {0} / {1}",
302                         RunningOnWindows ? "Windows" : RunningOnLinux ? "Linux" : RunningOnMacOS ? "MacOS" :
303                         runningOnUnix ? "Unix" : RunningOnX11 ? "X11" : "Unknown Platform",
304                         RunningOnMono ? "Mono" : ".Net");
305                 }
306             }
307         }
308     }
309 }