23 changed files with 1016 additions and 1141 deletions
@ -1,238 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.ComponentModel; |
|
||||
using System.Diagnostics; |
|
||||
using System.IO; |
|
||||
using System.Linq; |
|
||||
using System.Reflection; |
|
||||
using System.Runtime.InteropServices; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
/* OBSOLETE |
|
||||
|
|
||||
//Library loaders were taken from https://github.com/kekekeks/evhttp-sharp/tree/master/EvHttpSharp/Interop (MIT licensed)
|
|
||||
|
|
||||
namespace Perspex.Skia |
|
||||
{ |
|
||||
class MethodTableImpl : MethodTable |
|
||||
{ |
|
||||
public MethodTableImpl() : base(GetMethodTable()) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
class DetectedPlatformInfo |
|
||||
{ |
|
||||
public DetectedPlatformInfo(IDynLoader loader, string name, string cpuArch, string dllExtension) |
|
||||
{ |
|
||||
Loader = loader; |
|
||||
Name = name; |
|
||||
CpuArch = cpuArch; |
|
||||
DllExtension = dllExtension; |
|
||||
} |
|
||||
|
|
||||
public IDynLoader Loader { get; } |
|
||||
public string Name { get; } |
|
||||
public string CpuArch { get;} |
|
||||
public string DllExtension { get; } |
|
||||
} |
|
||||
|
|
||||
static DetectedPlatformInfo DetectPlatform() |
|
||||
{ |
|
||||
var macInfo = new DetectedPlatformInfo(new OsxLoader(), "Darwin", IntPtr.Size == 4 ? "i686" : "x86_64", ".dylib"); |
|
||||
switch (Environment.OSVersion.Platform) |
|
||||
{ |
|
||||
case PlatformID.Unix: |
|
||||
// Well, there are chances MacOSX is reported as Unix instead of MacOSX.
|
|
||||
// Instead of platform check, we'll do a feature checks (Mac specific root folders)
|
|
||||
if (Directory.Exists("/Applications") |
|
||||
& Directory.Exists("/System") |
|
||||
& Directory.Exists("/Users") |
|
||||
& Directory.Exists("/Volumes")) |
|
||||
return macInfo; |
|
||||
else |
|
||||
{ |
|
||||
string cpuArch; |
|
||||
using (var proc = |
|
||||
Process.Start( |
|
||||
(new ProcessStartInfo("uname", "-p") |
|
||||
{ |
|
||||
UseShellExecute = false, |
|
||||
RedirectStandardOutput = true |
|
||||
}))) |
|
||||
{ |
|
||||
proc.WaitForExit(); |
|
||||
cpuArch = proc.StandardOutput.ReadToEnd().Trim(); |
|
||||
} |
|
||||
return new DetectedPlatformInfo(new LinuxLoader(), "Linux", cpuArch, ".so"); |
|
||||
} |
|
||||
|
|
||||
case PlatformID.MacOSX: |
|
||||
return macInfo; |
|
||||
|
|
||||
default: |
|
||||
return new DetectedPlatformInfo(new Win32Loader(), "Windows", IntPtr.Size == 4 ? "i686" : "x86_64", ".dll"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
static IEnumerable<string> GeneratePossiblePaths() |
|
||||
{ |
|
||||
foreach ( |
|
||||
var basePath in |
|
||||
new[] {Assembly.GetEntryAssembly(), typeof (MethodTable).Assembly}.Select( |
|
||||
a => Path.GetDirectoryName(a?.GetModules()?[0]?.FullyQualifiedName)) |
|
||||
.Concat(new[] { Directory.GetCurrentDirectory()})) |
|
||||
{ |
|
||||
if(basePath == null) |
|
||||
continue; |
|
||||
yield return Path.Combine(basePath); |
|
||||
yield return Path.Combine(basePath, "native"); |
|
||||
yield return Path.Combine(basePath, "lib"); |
|
||||
yield return Path.Combine(basePath, "lib", "native"); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
static IntPtr GetMethodTable() |
|
||||
{ |
|
||||
var plat = DetectPlatform(); |
|
||||
|
|
||||
var name = "libperspesk" + plat.DllExtension; |
|
||||
var paths = GeneratePossiblePaths().Select(p => Path.Combine(p, plat.Name, plat.CpuArch, name)).ToList(); |
|
||||
var dll = paths.FirstOrDefault(File.Exists); |
|
||||
var msg = "Unable to find native library in following paths: '" + |
|
||||
string.Join("', '", paths) + "'"; |
|
||||
Console.Error.WriteLine(msg); |
|
||||
if (dll == null) |
|
||||
throw new FileNotFoundException(msg); |
|
||||
IntPtr hLib = plat.Loader.LoadLibrary(dll); |
|
||||
IntPtr pGetMethodTable = plat.Loader.GetProcAddress(hLib, "GetPerspexMethodTable"); |
|
||||
var getTable = (GetPerspexMethodTableDelegate) |
|
||||
Marshal.GetDelegateForFunctionPointer(pGetMethodTable, typeof (GetPerspexMethodTableDelegate)); |
|
||||
return getTable(); |
|
||||
} |
|
||||
|
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
|
||||
delegate IntPtr GetPerspexMethodTableDelegate(); |
|
||||
|
|
||||
|
|
||||
internal interface IDynLoader |
|
||||
{ |
|
||||
IntPtr LoadLibrary(string dll); |
|
||||
IntPtr GetProcAddress(IntPtr dll, string proc); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
class LinuxLoader : IDynLoader |
|
||||
{ |
|
||||
// ReSharper disable InconsistentNaming
|
|
||||
[DllImport("libdl.so.2")] |
|
||||
private static extern IntPtr dlopen(string path, int flags); |
|
||||
|
|
||||
[DllImport("libdl.so.2")] |
|
||||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|
||||
|
|
||||
[DllImport("libdl.so.2")] |
|
||||
private static extern IntPtr dlerror(); |
|
||||
|
|
||||
// ReSharper restore InconsistentNaming
|
|
||||
|
|
||||
static string DlError() |
|
||||
{ |
|
||||
return Marshal.PtrToStringAuto(dlerror()); |
|
||||
} |
|
||||
|
|
||||
public IntPtr LoadLibrary(string dll) |
|
||||
{ |
|
||||
var handle = dlopen(dll, 1); |
|
||||
if (handle == IntPtr.Zero) |
|
||||
throw new Win32Exception(DlError()); |
|
||||
return handle; |
|
||||
} |
|
||||
|
|
||||
public IntPtr GetProcAddress(IntPtr dll, string proc) |
|
||||
{ |
|
||||
var ptr = dlsym(dll, proc); |
|
||||
if (ptr == IntPtr.Zero) |
|
||||
throw new Win32Exception(DlError()); |
|
||||
return ptr; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
internal class Win32Loader : IDynLoader |
|
||||
{ |
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] |
|
||||
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName); |
|
||||
|
|
||||
[DllImport("kernel32", EntryPoint = "LoadLibraryW", SetLastError = true, CharSet = CharSet.Unicode)] |
|
||||
private static extern IntPtr LoadLibrary(string lpszLib); |
|
||||
|
|
||||
[DllImport("kernel32", EntryPoint = "SetDllDirectoryW", SetLastError = true, CharSet = CharSet.Unicode)] |
|
||||
extern static bool SetDllDirectory(string lpPathName); |
|
||||
|
|
||||
[DllImport("kernel32", EntryPoint = "GetDllDirectoryW", SetLastError = true, CharSet = CharSet.Unicode)] |
|
||||
extern static int GetDllDirectory(int nBufferLength, char[] lpBuffer); |
|
||||
|
|
||||
IntPtr IDynLoader.LoadLibrary(string dll) |
|
||||
{ |
|
||||
var buffer = new char[2048]; |
|
||||
int oldLen = GetDllDirectory(buffer.Length, buffer); |
|
||||
var oldDir = new string(buffer, 0, oldLen); |
|
||||
|
|
||||
SetDllDirectory(Path.GetDirectoryName(dll)); |
|
||||
|
|
||||
var handle = LoadLibrary(dll); |
|
||||
if (handle == IntPtr.Zero) |
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error()); |
|
||||
SetDllDirectory(oldDir); |
|
||||
|
|
||||
return handle; |
|
||||
} |
|
||||
|
|
||||
IntPtr IDynLoader.GetProcAddress(IntPtr dll, string proc) |
|
||||
{ |
|
||||
var ptr = GetProcAddress(dll, proc); |
|
||||
if (ptr == IntPtr.Zero) |
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error()); |
|
||||
return ptr; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class OsxLoader : IDynLoader |
|
||||
{ |
|
||||
// ReSharper disable InconsistentNaming
|
|
||||
[DllImport("/usr/lib/libSystem.dylib")] |
|
||||
public static extern IntPtr dlopen(string path, int mode); |
|
||||
|
|
||||
[DllImport("/usr/lib/libSystem.dylib")] |
|
||||
private static extern IntPtr dlsym(IntPtr handle, string symbol); |
|
||||
|
|
||||
[DllImport("/usr/lib/libSystem.dylib")] |
|
||||
private static extern IntPtr dlerror(); |
|
||||
|
|
||||
// ReSharper restore InconsistentNaming
|
|
||||
|
|
||||
static string DlError() |
|
||||
{ |
|
||||
return Marshal.PtrToStringAuto(dlerror()); |
|
||||
} |
|
||||
|
|
||||
public IntPtr LoadLibrary(string dll) |
|
||||
{ |
|
||||
var handle = dlopen(dll, 1); |
|
||||
if (handle == IntPtr.Zero) |
|
||||
throw new Win32Exception(DlError()); |
|
||||
return handle; |
|
||||
} |
|
||||
|
|
||||
public IntPtr GetProcAddress(IntPtr dll, string proc) |
|
||||
{ |
|
||||
var ptr = dlsym(dll, proc); |
|
||||
if (ptr == IntPtr.Zero) |
|
||||
throw new Win32Exception(DlError()); |
|
||||
return ptr; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
*/ |
|
||||
@ -0,0 +1,107 @@ |
|||||
|
using System; |
||||
|
using System.Reflection; |
||||
|
using Perspex.Input; |
||||
|
using Perspex.Input.Platform; |
||||
|
using Perspex.iOS; |
||||
|
using Perspex.Platform; |
||||
|
using Perspex.Shared.PlatformSupport; |
||||
|
using Perspex.Skia; |
||||
|
using UIKit; |
||||
|
|
||||
|
namespace Perspex |
||||
|
{ |
||||
|
public static class iOSApplicationExtensions |
||||
|
{ |
||||
|
public static AppT UseiOS<AppT>(this AppT app) where AppT : Application |
||||
|
{ |
||||
|
Perspex.iOS.iOSPlatform.Initialize(); |
||||
|
return app; |
||||
|
} |
||||
|
|
||||
|
// I wish I could merge this with the SkiaPlatform itself. Might be possible
|
||||
|
// once we switch to SkiaSharp
|
||||
|
public static AppT UseSkiaViewHost<AppT>(this AppT app) where AppT : Application |
||||
|
{ |
||||
|
var window = new UIWindow(UIScreen.MainScreen.Bounds); |
||||
|
var controller = new PerspexViewController(window); |
||||
|
window.RootViewController = controller; |
||||
|
window.MakeKeyAndVisible(); |
||||
|
|
||||
|
PerspexLocator.CurrentMutable |
||||
|
.Bind<IWindowingPlatform>().ToConstant(new WindowingPlatform(controller.PerspexView)); |
||||
|
|
||||
|
SkiaPlatform.Initialize(); |
||||
|
|
||||
|
return app; |
||||
|
} |
||||
|
|
||||
|
public static AppT UseAssetAssembly<AppT>(this AppT app, Assembly assembly) where AppT : Application |
||||
|
{ |
||||
|
// Asset loading searches our own assembly?
|
||||
|
var loader = new AssetLoader(assembly); |
||||
|
PerspexLocator.CurrentMutable.Bind<IAssetLoader>().ToConstant(loader); |
||||
|
|
||||
|
return app; |
||||
|
} |
||||
|
|
||||
|
// This is somewhat generic, could probably put this elsewhere. But I don't think
|
||||
|
// it should part of the iOS App Delegate
|
||||
|
//
|
||||
|
class WindowingPlatform : IWindowingPlatform |
||||
|
{ |
||||
|
private readonly IWindowImpl _window; |
||||
|
|
||||
|
public WindowingPlatform(IWindowImpl window) |
||||
|
{ |
||||
|
_window = window; |
||||
|
} |
||||
|
|
||||
|
public IWindowImpl CreateWindow() |
||||
|
{ |
||||
|
return _window; |
||||
|
} |
||||
|
|
||||
|
public IWindowImpl CreateEmbeddableWindow() |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public IPopupImpl CreatePopup() |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
namespace Perspex.iOS |
||||
|
{ |
||||
|
// TODO: Perhaps we should make this class handle all these interfaces directly, like we
|
||||
|
// do for Win32 and Gtk
|
||||
|
//
|
||||
|
public class iOSPlatform //: IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform
|
||||
|
{ |
||||
|
internal static MouseDevice MouseDevice; |
||||
|
internal static KeyboardDevice KeyboardDevice; |
||||
|
|
||||
|
public static void Initialize() |
||||
|
{ |
||||
|
MouseDevice = new MouseDevice(); |
||||
|
KeyboardDevice = new KeyboardDevice(); |
||||
|
|
||||
|
// refactored
|
||||
|
//SharedPlatform.Register(appType.Assembly);
|
||||
|
|
||||
|
PerspexLocator.CurrentMutable |
||||
|
.Bind<IPclPlatformWrapper>().ToSingleton<PclPlatformWrapper>() |
||||
|
.Bind<IClipboard>().ToTransient<Clipboard>() |
||||
|
//.Bind<ISystemDialogImpl>().ToTransient<SystemDialogImpl>()
|
||||
|
.Bind<IStandardCursorFactory>().ToTransient<CursorFactory>() |
||||
|
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice) |
||||
|
.Bind<IMouseDevice>().ToConstant(MouseDevice) |
||||
|
.Bind<IPlatformSettings>().ToSingleton<PlatformSettings>() |
||||
|
.Bind<IPlatformThreadingInterface>().ToConstant(PlatformThreadingInterface.Instance); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue