10 changed files with 456 additions and 0 deletions
@ -0,0 +1,18 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" /> |
||||
|
<ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Folder Include="Bindings\" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Compile Remove="Properties\AssemblyInfo.cs" /> |
||||
|
</ItemGroup> |
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,66 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace Avalonia.Windowing.Bindings |
||||
|
{ |
||||
|
public class EventsLoop : IDisposable |
||||
|
{ |
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern IntPtr winit_events_loop_new(out IntPtr eventsLoopProxyHandle); |
||||
|
|
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern void winit_events_loop_destroy(IntPtr handle); |
||||
|
|
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern void winit_events_loop_run(IntPtr handle); |
||||
|
|
||||
|
public IntPtr Handle { get; private set; } |
||||
|
private readonly EventsLoopProxy _eventsLoopProxy; |
||||
|
|
||||
|
public EventsLoop() |
||||
|
{ |
||||
|
Handle = winit_events_loop_new(out var elpHandle); |
||||
|
_eventsLoopProxy = new EventsLoopProxy(elpHandle); |
||||
|
} |
||||
|
|
||||
|
public void Run() |
||||
|
{ |
||||
|
// We need a delegate callback here to support talking back to the C# code.
|
||||
|
// Send an event type enum and then unsafely construct the event
|
||||
|
winit_events_loop_run(Handle); |
||||
|
} |
||||
|
|
||||
|
public void Wakeup() |
||||
|
{ |
||||
|
_eventsLoopProxy.Wakeup(); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
_eventsLoopProxy.Dispose(); |
||||
|
winit_events_loop_destroy(Handle); |
||||
|
} |
||||
|
|
||||
|
private class EventsLoopProxy : IDisposable |
||||
|
{ |
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern void winit_events_loop_proxy_destroy(IntPtr handle); |
||||
|
|
||||
|
private readonly IntPtr _handle; |
||||
|
public EventsLoopProxy(IntPtr handle) |
||||
|
{ |
||||
|
_handle = handle; |
||||
|
} |
||||
|
|
||||
|
public void Wakeup() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
winit_events_loop_proxy_destroy(_handle); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace Avalonia.Windowing.Bindings |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A window and GL context pair.
|
||||
|
/// Due to platform specific quirks, the ordering of window and context creation must be controlled by winit.
|
||||
|
/// </summary>
|
||||
|
public class GlWindowWrapper : IWindowWrapper |
||||
|
{ |
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern IntPtr winit_gl_window_new(IntPtr eventsLoopHandle); |
||||
|
|
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern IntPtr winit_gl_window_destroy(IntPtr handle); |
||||
|
|
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern IntPtr winit_gl_window_set_title(IntPtr handle, string title); |
||||
|
|
||||
|
private IntPtr _handle; |
||||
|
public GlWindowWrapper(EventsLoop eventsLoop) |
||||
|
{ |
||||
|
_handle = winit_gl_window_new(eventsLoop.Handle); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
winit_gl_window_destroy(_handle); |
||||
|
} |
||||
|
|
||||
|
public void SetTitle(string title) |
||||
|
{ |
||||
|
winit_gl_window_set_title(_handle, title); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using System; |
||||
|
namespace Avalonia.Windowing.Bindings |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// An interface used to abstract between Window and GlWindow.
|
||||
|
/// </summary>
|
||||
|
public interface IWindowWrapper : IDisposable |
||||
|
{ |
||||
|
void SetTitle(string title); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Platform; |
||||
|
|
||||
|
namespace Avalonia.Windowing.Bindings |
||||
|
{ |
||||
|
public class Monitors : IScreenImpl |
||||
|
{ |
||||
|
public int ScreenCount => 1; |
||||
|
public Screen[] AllScreens => new Screen[] { new Screen(Rect.Empty, Rect.Empty, true) }; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace Avalonia.Windowing.Bindings |
||||
|
{ |
||||
|
public class WindowWrapper : IWindowWrapper |
||||
|
{ |
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern IntPtr winit_window_new(IntPtr eventsLoopHandle); |
||||
|
|
||||
|
[DllImport("winit_wrapper")] |
||||
|
private static extern IntPtr winit_window_destroy(IntPtr handle); |
||||
|
|
||||
|
private IntPtr _handle; |
||||
|
public WindowWrapper(EventsLoop eventsLoop) |
||||
|
{ |
||||
|
_handle = winit_window_new(eventsLoop.Handle); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
winit_window_destroy(_handle); |
||||
|
} |
||||
|
|
||||
|
public void SetTitle(string title) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
using System; |
||||
|
using System.IO; |
||||
|
using Avalonia.Platform; |
||||
|
|
||||
|
namespace Avalonia.Windowing |
||||
|
{ |
||||
|
public class WindowIcon : IWindowIconImpl |
||||
|
{ |
||||
|
public void Save(Stream outputStream) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class IconLoader : IPlatformIconLoader |
||||
|
{ |
||||
|
public IconLoader() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public IWindowIconImpl LoadIcon(string fileName) |
||||
|
{ |
||||
|
return new WindowIcon(); |
||||
|
} |
||||
|
|
||||
|
public IWindowIconImpl LoadIcon(Stream stream) |
||||
|
{ |
||||
|
return new WindowIcon(); |
||||
|
} |
||||
|
|
||||
|
public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) |
||||
|
{ |
||||
|
return new WindowIcon(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,93 @@ |
|||||
|
using System; |
||||
|
using System.Reactive.Disposables; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Threading; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Platform; |
||||
|
using Avalonia.Threading; |
||||
|
using Avalonia.Windowing.Bindings; |
||||
|
|
||||
|
namespace Avalonia.Windowing |
||||
|
{ |
||||
|
// Exposing C# Enums to Rust will again prove to be a massive PITA.
|
||||
|
public enum WinitEventType |
||||
|
{ |
||||
|
MouseMove |
||||
|
} |
||||
|
|
||||
|
public struct MouseMoveData |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public class DummyPlatformHandle : IPlatformHandle |
||||
|
{ |
||||
|
public IntPtr Handle => IntPtr.Zero; |
||||
|
|
||||
|
public string HandleDescriptor => "Dummy"; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public class CursorFactory : IStandardCursorFactory |
||||
|
{ |
||||
|
public IPlatformHandle GetCursor(StandardCursorType cursorType) |
||||
|
{ |
||||
|
return new DummyPlatformHandle(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class WindowingPlatform : IPlatformThreadingInterface, IWindowingPlatform |
||||
|
{ |
||||
|
internal static WindowingPlatform Instance { get; private set; } |
||||
|
private readonly EventsLoop _eventsLoop; |
||||
|
|
||||
|
public WindowingPlatform() |
||||
|
{ |
||||
|
_eventsLoop = new EventsLoop(); |
||||
|
} |
||||
|
|
||||
|
public static void Initialize() |
||||
|
{ |
||||
|
Instance = new WindowingPlatform(); |
||||
|
Instance.DoInitialize(); |
||||
|
} |
||||
|
|
||||
|
public void DoInitialize() |
||||
|
{ |
||||
|
AvaloniaLocator.CurrentMutable |
||||
|
.Bind<IWindowingPlatform>().ToConstant(this) |
||||
|
.Bind<IPlatformIconLoader>().ToConstant(new IconLoader()) |
||||
|
.Bind<IStandardCursorFactory>().ToConstant(new CursorFactory()) |
||||
|
.Bind<IPlatformThreadingInterface>().ToConstant(this); |
||||
|
} |
||||
|
|
||||
|
public bool CurrentThreadIsLoopThread => true; |
||||
|
public event Action<DispatcherPriority?> Signaled; |
||||
|
|
||||
|
public IEmbeddableWindowImpl CreateEmbeddableWindow() |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public IPopupImpl CreatePopup() |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public IWindowImpl CreateWindow() => new Window(new GlWindowWrapper(_eventsLoop)); |
||||
|
|
||||
|
public void RunLoop(CancellationToken cancellationToken) |
||||
|
{ |
||||
|
_eventsLoop.Run(); |
||||
|
} |
||||
|
|
||||
|
public void Signal(DispatcherPriority priority) |
||||
|
{ |
||||
|
_eventsLoop.Wakeup(); |
||||
|
} |
||||
|
|
||||
|
public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) |
||||
|
{ |
||||
|
return Disposable.Create(() => { }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,140 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Input; |
||||
|
using Avalonia.Input.Raw; |
||||
|
using Avalonia.Platform; |
||||
|
using Avalonia.Rendering; |
||||
|
using Avalonia.Windowing.Bindings; |
||||
|
|
||||
|
namespace Avalonia.Windowing |
||||
|
{ |
||||
|
public class Window : IWindowImpl |
||||
|
{ |
||||
|
IWindowWrapper _windowWrapper; |
||||
|
|
||||
|
public Window(IWindowWrapper wrapper) |
||||
|
{ |
||||
|
_windowWrapper = wrapper; |
||||
|
} |
||||
|
|
||||
|
public WindowState WindowState { get; set; } |
||||
|
public Action<WindowState> WindowStateChanged { get; set; } |
||||
|
public Func<bool> Closing { get; set; } |
||||
|
public Point Position { get; set; } |
||||
|
public Action<Point> PositionChanged { get; set; } |
||||
|
public Action Deactivated { get; set; } |
||||
|
public Action Activated { get; set; } |
||||
|
|
||||
|
public IPlatformHandle Handle => new DummyPlatformHandle(); |
||||
|
|
||||
|
public Size MaxClientSize => Size.Empty; |
||||
|
|
||||
|
public IScreenImpl Screen => new Monitors(); |
||||
|
|
||||
|
public Size ClientSize => Size.Empty; |
||||
|
public double Scaling => 1.0; |
||||
|
|
||||
|
public IEnumerable<object> Surfaces => new List<object>() { this }; |
||||
|
|
||||
|
public Action<RawInputEventArgs> Input { get; set; } |
||||
|
public Action<Rect> Paint { get; set; } |
||||
|
public Action<Size> Resized { get; set; } |
||||
|
public Action<double> ScalingChanged { get; set; } |
||||
|
public Action Closed { get; set; } |
||||
|
|
||||
|
public IMouseDevice MouseDevice => throw new NotImplementedException(); |
||||
|
|
||||
|
public void Activate() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void BeginMoveDrag() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void BeginResizeDrag(WindowEdge edge) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void CanResize(bool value) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public IRenderer CreateRenderer(IRenderRoot root) |
||||
|
{ |
||||
|
return new ImmediateRenderer(root); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
_windowWrapper.Dispose(); |
||||
|
} |
||||
|
|
||||
|
public void Hide() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void Invalidate(Rect rect) |
||||
|
{ |
||||
|
//Paint?.Invoke(rect);
|
||||
|
} |
||||
|
|
||||
|
public Point PointToClient(Point point) |
||||
|
{ |
||||
|
return point; |
||||
|
} |
||||
|
|
||||
|
public Point PointToScreen(Point point) |
||||
|
{ |
||||
|
return point; |
||||
|
} |
||||
|
|
||||
|
public void Resize(Size clientSize) |
||||
|
{ |
||||
|
// This is where we size the window accordingly..
|
||||
|
} |
||||
|
|
||||
|
public void SetCursor(IPlatformHandle cursor) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void SetIcon(IWindowIconImpl icon) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void SetInputRoot(IInputRoot inputRoot) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void SetMinMaxSize(Size minSize, Size maxSize) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void SetSystemDecorations(bool enabled) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void SetTitle(string title) |
||||
|
{ |
||||
|
_windowWrapper.SetTitle(title); |
||||
|
} |
||||
|
|
||||
|
public void SetTopmost(bool value) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public void Show() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public IDisposable ShowDialog() |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public void ShowTaskbarIcon(bool value) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
using Avalonia.Controls; |
||||
|
|
||||
|
namespace Avalonia |
||||
|
{ |
||||
|
public static class WindowingPlatformExtensions |
||||
|
{ |
||||
|
public static T UseWinit<T>(this T builder, bool? useDeferredRendering = null) where T : AppBuilderBase<T>, new() |
||||
|
{ |
||||
|
// if (useDeferredRendering.HasValue)
|
||||
|
// MonoMac.MonoMacPlatform.UseDeferredRendering = useDeferredRendering.Value;
|
||||
|
return builder.UseWindowingSubsystem(Windowing.WindowingPlatform.Initialize, "Winit"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue