Browse Source

Extracted interop bits from GTK3 backend to Avalonia.Base and IRuntimePlatform

Nikita Tsukanov 7 years ago
parent
commit
add3e81095

+ 26 - 0
Avalonia.sln

@@ -186,6 +186,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Designer.HostApp.N
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.UnitTests", "tests\Avalonia.Skia.UnitTests\Avalonia.Skia.UnitTests.csproj", "{E1240B49-7B4B-4371-A00E-068778C5CF0B}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.OpenGL", "src\Avalonia.OpenGL\Avalonia.OpenGL.csproj", "{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}"
+EndProject
 Global
 	GlobalSection(SharedMSBuildProjectFiles) = preSolution
 		src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
@@ -1663,6 +1665,30 @@ Global
 		{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhone.Build.0 = Release|Any CPU
 		{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
 		{E1240B49-7B4B-4371-A00E-068778C5CF0B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhone.Build.0 = Release|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{7CCAEFC4-135D-401D-BDDD-896B9B7D3569}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 1 - 0
src/Avalonia.Base/Avalonia.Base.csproj

@@ -3,6 +3,7 @@
     <TargetFramework>netstandard2.0</TargetFramework>
     <AssemblyName>Avalonia.Base</AssemblyName>
     <RootNamespace>Avalonia</RootNamespace>
+    <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
   </PropertyGroup>
   <Import Project="..\..\build\Base.props" />
   <Import Project="..\..\build\Binding.props" />

+ 18 - 0
src/Avalonia.Base/Platform/Interop/IDynamicLibraryLoader.cs

@@ -0,0 +1,18 @@
+using System;
+
+namespace Avalonia.Platform.Interop
+{
+    public interface IDynamicLibraryLoader
+    {
+        IntPtr LoadLibrary(string dll);
+        IntPtr GetProcAddress(IntPtr dll, string proc, bool optional);
+    }
+
+    public class DynamicLibraryLoaderException : Exception
+    {
+        public DynamicLibraryLoaderException(string message) : base(message)
+        {
+            
+        }
+    }
+}

+ 2 - 2
src/Gtk/Avalonia.Gtk3/Interop/Utf8Buffer.cs → src/Avalonia.Base/Platform/Interop/Utf8Buffer.cs

@@ -2,9 +2,9 @@
 using System.Runtime.InteropServices;
 using System.Text;
 
-namespace Avalonia.Gtk3.Interop
+namespace Avalonia.Platform.Interop
 {
-    class Utf8Buffer : SafeHandle
+    public class Utf8Buffer : SafeHandle
     {
         private GCHandle _gchandle;
         private byte[] _data;

+ 1 - 0
src/Gtk/Avalonia.Gtk3/ClipboardImpl.cs

@@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 using Avalonia.Gtk3.Interop;
 using Avalonia.Input.Platform;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Gtk3
 {

+ 1 - 0
src/Gtk/Avalonia.Gtk3/CursorFactory.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using Avalonia.Gtk3.Interop;
 using Avalonia.Input;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 using CursorType = Avalonia.Gtk3.GdkCursorType;
 namespace Avalonia.Gtk3
 {

+ 1 - 0
src/Gtk/Avalonia.Gtk3/Gtk3Platform.cs

@@ -8,6 +8,7 @@ using Avalonia.Gtk3.Interop;
 using Avalonia.Input;
 using Avalonia.Input.Platform;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 using Avalonia.Rendering;
 using Avalonia.Threading;
 

+ 1 - 0
src/Gtk/Avalonia.Gtk3/Interop/GException.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Runtime.InteropServices;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Gtk3.Interop
 {

+ 1 - 0
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@@ -2,6 +2,7 @@
 using System;
 using System.Runtime.InteropServices;
 using Avalonia.Controls;
+using Avalonia.Platform.Interop;
 using gdouble = System.Double;
 using gint = System.Int32;
 using gint16 = System.Int16;

+ 1 - 0
src/Gtk/Avalonia.Gtk3/Interop/Pixbuf.cs

@@ -2,6 +2,7 @@
 using System.IO;
 using System.Runtime.InteropServices;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Gtk3.Interop
 {

+ 3 - 2
src/Gtk/Avalonia.Gtk3/Interop/Resolver.cs

@@ -5,6 +5,7 @@ using System.Linq;
 using System.Reflection;
 using System.Runtime.InteropServices;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Gtk3.Interop
 {
@@ -82,7 +83,7 @@ namespace Avalonia.Gtk3.Interop
             }
         }
 
-        static IntPtr LoadDll(IDynLoader  loader, GtkDll dll)
+        static IntPtr LoadDll(IDynamicLibraryLoader  loader, GtkDll dll)
         {
             
             var exceptions = new List<Exception>();
@@ -118,7 +119,7 @@ namespace Avalonia.Gtk3.Interop
 
         public static void Resolve(string basePath = null)
         {
-            var loader = Platform.Value == OperatingSystemType.WinNT ? (IDynLoader)new Win32Loader() : new UnixLoader();
+            var loader = AvaloniaLocator.Current.GetService<IDynamicLibraryLoader>();
 
             var dlls = Enum.GetValues(typeof(GtkDll)).Cast<GtkDll>().ToDictionary(x => x, x => LoadDll(loader, x));
             

+ 1 - 0
src/Gtk/Avalonia.Gtk3/Interop/Signal.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Runtime.InteropServices;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Gtk3.Interop
 {

+ 1 - 0
src/Gtk/Avalonia.Gtk3/SystemDialogs.cs

@@ -7,6 +7,7 @@ using Avalonia.Controls;
 using Avalonia.Controls.Platform;
 using Avalonia.Gtk3.Interop;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Gtk3
 {

+ 1 - 0
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@@ -8,6 +8,7 @@ using Avalonia.Gtk3.Interop;
 using Avalonia.Input;
 using Avalonia.Input.Raw;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 using Avalonia.Rendering;
 using Avalonia.Threading;
 

+ 1 - 0
src/Gtk/Avalonia.Gtk3/WindowImpl.cs

@@ -2,6 +2,7 @@
 using Avalonia.Controls;
 using Avalonia.Gtk3.Interop;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Gtk3
 {

+ 29 - 23
src/Gtk/Avalonia.Gtk3/Interop/DynLoader.cs → src/Shared/PlatformSupport/DynLoader.cs

@@ -1,22 +1,12 @@
-using System;
+using System;
 using System.Runtime.InteropServices;
+using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 
-/*
- * Source code imported from https://github.com/kekekeks/evhttp-sharp
- * Source is provided under MIT license for Avalonia project and derived works
- */
-
-
-namespace Avalonia.Gtk3.Interop
+namespace Avalonia.Shared.PlatformSupport
 {
-    internal interface IDynLoader
-    {
-        IntPtr LoadLibrary(string dll);
-        IntPtr GetProcAddress(IntPtr dll, string proc, bool optional);
-
-    }
-
-    class UnixLoader : IDynLoader
+#if !__IOS__
+    class UnixLoader : IDynamicLibraryLoader
     {
         // ReSharper disable InconsistentNaming
         static class LinuxImports
@@ -37,6 +27,7 @@ namespace Avalonia.Gtk3.Interop
                 DlError = dlerror;
             }
         }
+        
         static class OsXImports
         {
             
@@ -86,7 +77,7 @@ namespace Avalonia.Gtk3.Interop
         {
             var handle = DlOpen(dll, 1);
             if (handle == IntPtr.Zero)
-                throw new NativeException(DlErrorString());
+                throw new DynamicLibraryLoaderException(DlErrorString());
             return handle;
         }
 
@@ -94,12 +85,12 @@ namespace Avalonia.Gtk3.Interop
         {
             var ptr = DlSym(dll, proc);
             if (ptr == IntPtr.Zero && !optional)
-                throw new NativeException(DlErrorString());
+                throw new DynamicLibraryLoaderException(DlErrorString());
             return ptr;
         }
     }
 
-    internal class Win32Loader : IDynLoader
+    internal class Win32Loader : IDynamicLibraryLoader
     {
         [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
         private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
@@ -107,22 +98,37 @@ namespace Avalonia.Gtk3.Interop
         [DllImport("kernel32", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)]
         private static extern IntPtr LoadLibrary(string lpszLib);
 
-        IntPtr IDynLoader.LoadLibrary(string dll)
+        IntPtr IDynamicLibraryLoader.LoadLibrary(string dll)
         {
             var handle = LoadLibrary(dll);
             if (handle != IntPtr.Zero)
                 return handle;
             var err = Marshal.GetLastWin32Error();
 
-            throw new NativeException("Error loading " + dll + " error " + err);
+            throw new DynamicLibraryLoaderException("Error loading " + dll + " error " + err);
         }
 
-        IntPtr IDynLoader.GetProcAddress(IntPtr dll, string proc, bool optional)
+        IntPtr IDynamicLibraryLoader.GetProcAddress(IntPtr dll, string proc, bool optional)
         {
             var ptr = GetProcAddress(dll, proc);
             if (ptr == IntPtr.Zero && !optional)
-                throw new NativeException("Error " + Marshal.GetLastWin32Error());
+                throw new DynamicLibraryLoaderException("Error " + Marshal.GetLastWin32Error());
             return ptr;
         }
     }
+    
+#else
+    internal class IOSLoader : IDynamicLibraryLoader
+    {
+        IntPtr IDynamicLibraryLoader.LoadLibrary(string dll)
+        {
+            throw new PlatformNotSupportedException();
+        }
+
+        IntPtr IDynamicLibraryLoader.GetProcAddress(IntPtr dll, string proc, bool optional)
+        {
+            throw new PlatformNotSupportedException();
+        }
+    }
+#endif
 }

+ 1 - 0
src/Shared/PlatformSupport/PlatformSupport.projitems

@@ -10,6 +10,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="$(MSBuildThisFileDirectory)AssetLoader.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)DynLoader.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)StandardRuntimePlatform.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)StandardRuntimePlatformServices.cs" />
   </ItemGroup>

+ 14 - 2
src/Shared/PlatformSupport/StandardRuntimePlatformServices.cs

@@ -1,5 +1,7 @@
 using System.Reflection;
+using System.Runtime.InteropServices;
 using Avalonia.Platform;
+using Avalonia.Platform.Interop;
 
 namespace Avalonia.Shared.PlatformSupport
 {
@@ -7,9 +9,19 @@ namespace Avalonia.Shared.PlatformSupport
     {
         public static void Register(Assembly assembly = null)
         {
+            var standardPlatform = new StandardRuntimePlatform();
             AvaloniaLocator.CurrentMutable
-                .Bind<IRuntimePlatform>().ToSingleton<StandardRuntimePlatform>()
-                .Bind<IAssetLoader>().ToConstant(new AssetLoader(assembly));
+                .Bind<IRuntimePlatform>().ToConstant(standardPlatform)
+                .Bind<IAssetLoader>().ToConstant(new AssetLoader(assembly))
+                .Bind<IDynamicLibraryLoader>().ToConstant(
+#if __IOS__
+                    new IOSLoader()
+#else
+                    standardPlatform.GetRuntimeInfo().OperatingSystem == OperatingSystemType.WinNT
+                        ? (IDynamicLibraryLoader)new Win32Loader()
+                        : new UnixLoader()
+#endif
+                );
         }
     }
 }