Преглед на файлове

Reimplement WpfAvaloniaHost to use HwndHost

Max Katz преди 2 години
родител
ревизия
d97b9acb47

+ 1 - 2
src/Windows/Avalonia.Win32.Interoperability/Avalonia.Win32.Interoperability.csproj

@@ -4,16 +4,15 @@
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <UseWpf>true</UseWpf>
     <UseWindowsForms>true</UseWindowsForms>
-    <UseDirect3D9>true</UseDirect3D9>
     <EnableWindowsTargeting>true</EnableWindowsTargeting>
   </PropertyGroup>
+
   <ItemGroup>
     <ProjectReference Include="..\..\..\packages\Avalonia\Avalonia.csproj" />
     <ProjectReference Include="..\Avalonia.Win32\Avalonia.Win32.csproj" />
     <ProjectReference Include="..\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
   </ItemGroup>
 
-  <Import Project="..\..\..\build\SharpDX.props" />
   <Import Project="..\..\..\build\NullableEnable.props" />
   <Import Project="..\..\..\build\DevAnalyzers.props" />
   <Import Project="..\..\..\build\TrimmingEnable.props" />

+ 0 - 35
src/Windows/Avalonia.Win32.Interoperability/Wpf/CursorShim.cs

@@ -1,35 +0,0 @@
-using System;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Windows.Input;
-
-namespace Avalonia.Win32.Interoperability.Wpf
-{
-    internal static class CursorShim
-    {
-        public static Cursor? FromHCursor(IntPtr hcursor)
-        {
-            var field = typeof(Cursor).GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
-                .FirstOrDefault(f => f.FieldType == typeof(SafeHandle));
-            if (field == null)
-                return null;
-            var rv = (Cursor) FormatterServices.GetUninitializedObject(typeof(Cursor));
-            field.SetValue(rv, new SafeHandleShim(hcursor));
-            return rv;
-        }
-
-        private class SafeHandleShim : SafeHandle
-        {
-            public SafeHandleShim(IntPtr hcursor) : base(new IntPtr(-1), false)
-            {
-                this.handle = hcursor;
-            }
-
-            protected override bool ReleaseHandle() => true;
-
-            public override bool IsInvalid => false;
-        }
-    }
-}

+ 0 - 206
src/Windows/Avalonia.Win32.Interoperability/Wpf/Direct2DImageSurface.cs

@@ -1,206 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Windows;
-using System.Windows.Interop;
-using Avalonia.Direct2D1;
-using SharpDX.Direct2D1;
-using SharpDX.Direct3D11;
-using SharpDX.Direct3D9;
-using SharpDX.DXGI;
-using AlphaMode = SharpDX.Direct2D1.AlphaMode;
-using Device = SharpDX.Direct3D11.Device;
-using Format = SharpDX.DXGI.Format;
-using Query = SharpDX.Direct3D11.Query;
-using QueryType = SharpDX.Direct3D11.QueryType;
-using RenderTarget = SharpDX.Direct2D1.RenderTarget;
-using Surface = SharpDX.DXGI.Surface;
-using Usage = SharpDX.Direct3D9.Usage;
-
-namespace Avalonia.Win32.Interoperability.Wpf
-{
-    internal class Direct2DImageSurface : IExternalDirect2DRenderTargetSurface, IDisposable
-    {
-        private class SwapBuffer: IDisposable
-        {
-            private readonly Query _event;
-            private readonly SharpDX.Direct3D11.Resource _resource;
-            private readonly SharpDX.Direct3D11.Resource _sharedResource;
-            public SharpDX.Direct3D9.Surface Texture { get; }
-            public RenderTarget Target { get;}
-            public IntSize Size { get; }
-
-            public SwapBuffer(IntSize size, Vector dpi)
-            {
-                int width = (int) size.Width;
-                int height = (int) size.Height;
-                _event = new Query(s_dxDevice, new QueryDescription {Type = QueryType.Event});
-                using (var texture = new Texture2D(s_dxDevice, new Texture2DDescription
-                {
-                    Width = width,
-                    Height = height,
-                    ArraySize = 1,
-                    MipLevels = 1,
-                    Format = Format.B8G8R8A8_UNorm,
-                    Usage = ResourceUsage.Default,
-                    SampleDescription = new SampleDescription(2, 0),
-                    BindFlags = BindFlags.RenderTarget,
-                }))
-                using (var surface = texture.QueryInterface<Surface>())
-                
-                {
-                    _resource = texture.QueryInterface<SharpDX.Direct3D11.Resource>();
-                    
-                    Target = new RenderTarget(Direct2D1Platform.Direct2D1Factory, surface,
-                        new RenderTargetProperties
-                        {
-                            DpiX = (float) dpi.X,
-                            DpiY = (float) dpi.Y,
-                            MinLevel = FeatureLevel.Level_10,
-                            PixelFormat = new PixelFormat(Format.B8G8R8A8_UNorm, AlphaMode.Premultiplied),
-
-                        });
-                }
-                using (var texture = new Texture2D(s_dxDevice, new Texture2DDescription
-                {
-                    Width = width,
-                    Height = height,
-                    ArraySize = 1,
-                    MipLevels = 1,
-                    Format = Format.B8G8R8A8_UNorm,
-                    Usage = ResourceUsage.Default,
-                    SampleDescription = new SampleDescription(1, 0),
-                    BindFlags = BindFlags.RenderTarget|BindFlags.ShaderResource,
-                    OptionFlags = ResourceOptionFlags.Shared,
-                }))
-                using (var resource = texture.QueryInterface<SharpDX.DXGI.Resource>())
-                {
-                    _sharedResource = texture.QueryInterface<SharpDX.Direct3D11.Resource>();
-                    var handle = resource.SharedHandle;
-                    using (var texture9 = new Texture(s_d3DDevice, texture.Description.Width,
-                        texture.Description.Height, 1,
-                        Usage.RenderTarget, SharpDX.Direct3D9.Format.A8R8G8B8, Pool.Default, ref handle))
-                        Texture = texture9.GetSurfaceLevel(0);
-                }
-                Size = size;
-            }
-
-            public void Dispose()
-            {
-                Texture?.Dispose();
-                Target?.Dispose();
-                _resource?.Dispose();
-                _sharedResource?.Dispose();
-                _event?.Dispose();
-            }
-
-            public void Flush()
-            {
-                s_dxDevice!.ImmediateContext.ResolveSubresource(_resource, 0, _sharedResource, 0, Format.B8G8R8A8_UNorm);
-                s_dxDevice.ImmediateContext.Flush();
-                s_dxDevice.ImmediateContext.End(_event);
-                s_dxDevice.ImmediateContext.GetData(_event).Dispose();
-            }
-        }
-
-        private D3DImage? _image;
-        private SwapBuffer? _backBuffer;
-        private readonly WpfTopLevelImpl _impl;
-        private static Device? s_dxDevice;
-        private static Direct3DEx? s_d3DContext;
-        private static DeviceEx? s_d3DDevice;
-        private Vector _oldDpi;
-
-
-        [DllImport("user32.dll", SetLastError = false)]
-        private static extern IntPtr GetDesktopWindow();
-
-        private static void EnsureDirectX()
-        {
-            if(s_d3DDevice != null)
-                return;
-            s_d3DContext = new Direct3DEx();
-
-            SharpDX.Direct3D9.PresentParameters presentparams = new SharpDX.Direct3D9.PresentParameters
-            {
-                Windowed = true,
-                SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard,
-                DeviceWindowHandle = GetDesktopWindow(),
-                PresentationInterval = PresentInterval.Default
-            };
-            s_dxDevice = s_dxDevice ?? AvaloniaLocator.Current.GetRequiredService<SharpDX.DXGI.Device>()
-                             .QueryInterface<SharpDX.Direct3D11.Device>();
-            s_d3DDevice = new DeviceEx(s_d3DContext, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, presentparams);
-
-        }
-
-        public Direct2DImageSurface(WpfTopLevelImpl impl)
-        {
-            _impl = impl;
-        }
-
-        public RenderTarget? GetOrCreateRenderTarget()
-        {
-            EnsureDirectX();
-            var scale = _impl.GetScaling();
-            var size = new IntSize(_impl.ActualWidth * scale.X, _impl.ActualHeight * scale.Y);
-            var dpi = scale * 96;
-
-            if (_backBuffer!=null && _backBuffer.Size == size)
-                return _backBuffer.Target;
-
-            if (_image == null || _oldDpi.X != dpi.X || _oldDpi.Y != dpi.Y)
-            {
-                _image = new D3DImage(dpi.X, dpi.Y);
-                _oldDpi = dpi;
-            }
-            _impl.ImageSource = _image;
-
-            RemoveAndDispose(ref _backBuffer);
-            if (size == default)
-            {
-                _image.Lock();
-                _image.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero);
-                _image.Unlock();
-                return null;
-            }
-            _backBuffer = new SwapBuffer(size, dpi);
-
-            return _backBuffer.Target;
-        }
-
-        private static void RemoveAndDispose<T>(ref T? d) where T : IDisposable
-        {
-            d?.Dispose();
-            d = default;
-        }
-
-        private void Swap()
-        {
-            _backBuffer?.Flush();
-            if (_image is not null)
-            {
-                _image.Lock();
-                _image.SetBackBuffer(D3DResourceType.IDirect3DSurface9,
-                    _backBuffer?.Texture?.NativePointer ?? IntPtr.Zero, true);
-                _image.AddDirtyRect(new Int32Rect(0, 0, _image.PixelWidth, _image.PixelHeight));
-                _image.Unlock();
-            }
-        }
-
-        public void DestroyRenderTarget()
-        {
-            RemoveAndDispose(ref _backBuffer);
-        }
-
-        public void BeforeDrawing()
-        {
-            
-        }
-
-        public void AfterDrawing() => Swap();
-        public void Dispose()
-        {
-            RemoveAndDispose(ref _backBuffer);
-        }
-    }
-}

+ 0 - 9
src/Windows/Avalonia.Win32.Interoperability/Wpf/IntSize.cs

@@ -1,9 +0,0 @@
-namespace Avalonia.Win32.Interoperability.Wpf;
-
-internal record struct IntSize(double Width, double Height)
-{
-    public static implicit  operator IntSize(System.Windows.Size size)
-    {
-        return new IntSize {Width = (int) size.Width, Height = (int) size.Height};
-    }
-}

+ 58 - 108
src/Windows/Avalonia.Win32.Interoperability/Wpf/WpfAvaloniaHost.cs

@@ -1,134 +1,84 @@
 using System;
-using System.Threading;
+using System.Runtime.InteropServices;
 using System.Windows;
+using System.Windows.Interop;
 using System.Windows.Markup;
-using Avalonia.Win32.Interoperability.Wpf;
+using Avalonia.Controls.Embedding;
+using Avalonia.Win32.Interop;
 using AvControl = Avalonia.Controls.Control;
 
-namespace Avalonia.Win32.Interoperability
+namespace Avalonia.Win32.Interoperability;
+
+/// <summary>
+/// An element that allows you to host a Avalonia control on a WPF page.
+/// </summary>
+[ContentProperty("Content")]
+public class WpfAvaloniaHost : HwndHost
 {
+    private EmbeddableControlRoot? _root;
+    private AvControl? _content;
+
     /// <summary>
-    /// An element that allows you to host a Avalonia control on a WPF page.
+    /// Initializes a new instance of the <see cref="WpfAvaloniaHost"/> class.
     /// </summary>
-    [ContentProperty("Content")]
-    public class WpfAvaloniaHost : FrameworkElement, IDisposable, IAddChild
+    public WpfAvaloniaHost()
     {
-        private WpfTopLevelImpl? _impl;
-        private readonly SynchronizationContext _sync;
-        private bool _hasChildren;
+        DataContextChanged += AvaloniaHwndHost_DataContextChanged;
+    }
 
-        private WpfTopLevelImpl Impl => _impl ?? throw new ObjectDisposedException("WpfAvaloniaHost was already disposed.");
-        
-        /// <summary>
-        /// Initializes a new instance of the <see cref="WpfAvaloniaHost"/> class.
-        /// </summary>
-        public WpfAvaloniaHost()
+    private void AvaloniaHwndHost_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
+    {
+        if (Content != null)
         {
-            _sync = SynchronizationContext.Current!;
-            _impl = new WpfTopLevelImpl();
-            _impl.ControlRoot.Prepare();
-            _impl.Visibility = Visibility.Visible;
-            SnapsToDevicePixels = true;
-            UseLayoutRounding = true;
-            PresentationSource.AddSourceChangedHandler(this, OnSourceChanged);
+            Content.DataContext = e.NewValue;
         }
+    }
 
-        private void OnSourceChanged(object sender, SourceChangedEventArgs e)
+    /// <summary>
+    /// Gets or sets the Avalonia control hosted by the <see cref="WpfAvaloniaHost"/> element.
+    /// </summary>
+    public AvControl? Content
+    {
+        get => _content;
+        set
         {
-            if (e.NewSource != null && !_hasChildren)
-            {
-                AddLogicalChild(_impl);
-                AddVisualChild(_impl);
-                _hasChildren = true;
-            }
-            else
+            if (_content != value)
             {
-                RemoveVisualChild(_impl);
-                RemoveLogicalChild(_impl);
-                _hasChildren = false;
+                _content = value;
+                if (_root is not null)
+                {
+                    _root.Content = value;
+                }
+                if (value != null)
+                {
+                    value.DataContext = DataContext;
+                }
             }
         }
+    }
 
-        /// <summary>
-        /// Gets or sets the Avalonia control hosted by the <see cref="WpfAvaloniaHost"/> element.
-        /// </summary>
-        public AvControl? Content
-        {
-            get => (AvControl?)Impl.ControlRoot.Content;
-            set => Impl.ControlRoot.Content = value;
-        }
-
-        //Separate class is needed to prevent accidental resurrection
-        private class Disposer
-        {
-            private readonly WpfTopLevelImpl _impl;
-
-            public Disposer(WpfTopLevelImpl impl)
-            {
-                _impl = impl;
-            }
-
-            public void Callback(object? state)
-            {
-                _impl.Dispose();
-            }
-        }
+    /// <inheritdoc />
+    protected override HandleRef BuildWindowCore(HandleRef hwndParent)
+    {
+        _root = new EmbeddableControlRoot();
+        _root.Content = _content;
+        _root.Prepare();
+        _root.Renderer.Start();
 
-        /// <inheritdoc />
-        protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
-        {
-            var impl = Impl;
-            impl.InvalidateMeasure();
-            impl.Measure(constraint);
-            return impl.DesiredSize;
-        }
+        var handle = _root.TryGetPlatformHandle()?.Handle
+                     ?? throw new InvalidOperationException("WpfAvaloniaHost is unable to create EmbeddableControlRoot.");
 
-        /// <inheritdoc />
-        protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize)
+        if (PresentationSource.FromVisual(this) is HwndSource source)
         {
-            Impl.Arrange(new System.Windows.Rect(arrangeSize));
-            return arrangeSize;
+            _ = UnmanagedMethods.SetParent(handle, source.Handle);
         }
         
-        /// <inheritdoc />
-        protected override int VisualChildrenCount => 1;
-
-        /// <inheritdoc />
-        protected override System.Windows.Media.Visual GetVisualChild(int index) => Impl;
-
-        ~WpfAvaloniaHost()
-        {
-            if (_impl != null)
-                _sync.Post(new Disposer(_impl).Callback, null);
-        }
-
-        /// <inheritdoc />
-        public void Dispose()
-        {
-            if (_impl != null)
-            {
-                RemoveVisualChild(_impl);
-                RemoveLogicalChild(_impl);
-                _impl.Dispose();
-                _impl = null;
-                GC.SuppressFinalize(this);
-            }
-        }
-
-        void IAddChild.AddChild(object value)
-        {
-            if (Content == null)
-                if (value is AvControl avControl)
-                    Content = avControl;
-                else
-                    throw new InvalidOperationException("WpfAvaloniaHost.Content only accepts value of Avalonia.Controls.Control type.");
-            else
-                throw new InvalidOperationException("WpfAvaloniaHost.Content was already set.");
-        }
+        return new HandleRef(_root, handle);
+    }
 
-        void IAddChild.AddText(string text)
-        {
-            //
-        }
+    /// <inheritdoc />
+    protected override void DestroyWindowCore(HandleRef hwnd)
+    {
+        _root?.Dispose();
     }
 }

+ 0 - 12
src/Windows/Avalonia.Win32.Interoperability/Wpf/WpfInteropExtensions.cs

@@ -1,12 +0,0 @@
-namespace Avalonia.Win32.Interoperability.Wpf
-{
-    internal static class WpfInteropExtensions
-    {
-        public static System.Windows.Point ToWpfPoint(this Point pt) => new System.Windows.Point(pt.X, pt.Y);
-        public static System.Windows.Point ToWpfPoint(this PixelPoint pt) => new System.Windows.Point(pt.X, pt.Y);
-        public static Point ToAvaloniaPoint(this System.Windows.Point pt) => new Point(pt.X, pt.Y);
-        public static PixelPoint ToAvaloniaPixelPoint(this System.Windows.Point pt) => new PixelPoint((int)pt.X, (int)pt.Y);
-        public static System.Windows.Size ToWpfSize(this Size pt) => new System.Windows.Size(pt.Width, pt.Height);
-        public static Size ToAvaloniaSize(this System.Windows.Size pt) => new Size(pt.Width, pt.Height);
-    }
-}

+ 0 - 39
src/Windows/Avalonia.Win32.Interoperability/Wpf/WpfMouseDevice.cs

@@ -1,39 +0,0 @@
-using System;
-using Avalonia.Controls.Embedding;
-using Avalonia.Input;
-using Avalonia.VisualTree;
-
-namespace Avalonia.Win32.Interoperability.Wpf
-{
-    internal class WpfMouseDevice : MouseDevice
-    {
-        private readonly WpfTopLevelImpl _impl;
-
-        public WpfMouseDevice(WpfTopLevelImpl impl) : base(new WpfMousePointer(impl))
-        {
-            _impl = impl;
-        }
-
-        private class WpfMousePointer : Pointer
-        {
-            private readonly WpfTopLevelImpl _impl;
-
-            public WpfMousePointer(WpfTopLevelImpl impl) : base(Pointer.GetNextFreeId(), PointerType.Mouse, true)
-            {
-                _impl = impl;
-            }
-
-            protected override void PlatformCapture(IInputElement? control)
-            {
-                if (control == null)
-                {
-                    System.Windows.Input.Mouse.Capture(null);
-                }
-                else if (((control as Visual)?.GetVisualRoot() as EmbeddableControlRoot)?.PlatformImpl != _impl)
-                    throw new ArgumentException("Visual belongs to unknown toplevel");
-                else
-                    System.Windows.Input.Mouse.Capture(_impl);
-            }
-        }
-    }
-}

+ 0 - 261
src/Windows/Avalonia.Win32.Interoperability/Wpf/WpfTopLevelImpl.cs

@@ -1,261 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Windows;
-using System.Windows.Input;
-using System.Windows.Interop;
-using System.Windows.Media;
-using Avalonia.Controls;
-using Avalonia.Controls.Embedding;
-using Avalonia.Input;
-using Avalonia.Input.Raw;
-using Avalonia.Layout;
-using Avalonia.Platform;
-using Avalonia.Rendering;
-using Avalonia.Rendering.Composition;
-using Avalonia.Win32.Interop;
-using Key = Avalonia.Input.Key;
-using KeyEventArgs = System.Windows.Input.KeyEventArgs;
-using MouseButton = System.Windows.Input.MouseButton;
-
-namespace Avalonia.Win32.Interoperability.Wpf
-{
-    internal class WpfTopLevelImpl : FrameworkElement, ITopLevelImpl
-    {
-        private HwndSource? _currentHwndSource;
-        private IInputRoot? _inputRoot;
-        private readonly HwndSourceHook _hook;
-        private readonly ITopLevelImpl _ttl;
-        private readonly IEnumerable<object> _surfaces;
-        private readonly IMouseDevice _mouse;
-        private readonly IKeyboardDevice _keyboard;
-        private Size _finalSize;
-
-        public EmbeddableControlRoot ControlRoot { get; }
-        internal ImageSource? ImageSource { get; set; }
-
-        public class CustomControlRoot : EmbeddableControlRoot, IEmbeddedLayoutRoot
-        {
-            public CustomControlRoot(WpfTopLevelImpl impl) : base(impl)
-            {
-                EnforceClientSize = false;
-            }
-
-            protected override void OnMeasureInvalidated()
-            {
-                ((FrameworkElement?)PlatformImpl)?.InvalidateMeasure();
-            }
-
-            public Size AllocatedSize => ClientSize;
-        }
-
-        public WpfTopLevelImpl()
-        {
-            PresentationSource.AddSourceChangedHandler(this, OnSourceChanged);
-            _hook = WndProc;
-            _ttl = this;
-            _surfaces = new object[] {new WritableBitmapSurface(this), new Direct2DImageSurface(this)};
-            _mouse = new WpfMouseDevice(this);
-            _keyboard = AvaloniaLocator.Current.GetRequiredService<IKeyboardDevice>();
-
-            ControlRoot = new CustomControlRoot(this);
-            SnapsToDevicePixels = true;
-            Focusable = true;
-            DataContextChanged += delegate
-            {
-                ControlRoot.DataContext = DataContext;
-            };
-        }
-
-        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
-        {
-            if (msg == (int)UnmanagedMethods.WindowsMessage.WM_DPICHANGED)
-                _ttl.ScalingChanged?.Invoke(_ttl.RenderScaling);
-            return IntPtr.Zero;
-        }
-
-        private void OnSourceChanged(object sender, SourceChangedEventArgs e)
-        {
-            _currentHwndSource?.RemoveHook(_hook);
-            _currentHwndSource = e.NewSource as HwndSource;
-            _currentHwndSource?.AddHook(_hook);
-            _ttl.ScalingChanged?.Invoke(_ttl.RenderScaling);
-        }
-
-        
-        public IRenderer CreateRenderer(IRenderRoot root)
-        {
-            return new CompositingRenderer(root, Win32Platform.Compositor, () => _surfaces);
-        }
-
-        public void Dispose()
-        {
-            _ttl.Closed?.Invoke();
-            foreach(var d in _surfaces.OfType<IDisposable>())
-                d.Dispose();
-        }
-
-        Size ITopLevelImpl.ClientSize => _finalSize;
-        Size? ITopLevelImpl.FrameSize => null;
-
-        double ITopLevelImpl.RenderScaling => PresentationSource.FromVisual(this)?.CompositionTarget?.TransformToDevice.M11 ?? 1;
-
-        IEnumerable<object> ITopLevelImpl.Surfaces => _surfaces;
-
-        private Size _previousSize;
-        protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
-        {
-            _finalSize = finalSize.ToAvaloniaSize();
-            if (_finalSize == _previousSize)
-                return finalSize;
-            _previousSize = _finalSize;
-            _ttl.Resized?.Invoke(finalSize.ToAvaloniaSize(), WindowResizeReason.Unspecified);
-            return base.ArrangeOverride(finalSize);
-        }
-
-        protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
-        {
-            ControlRoot.Measure(availableSize.ToAvaloniaSize());
-            return ControlRoot.DesiredSize.ToWpfSize();
-        }
-
-        protected override void OnRender(DrawingContext drawingContext)
-        {
-            if(ActualHeight == 0 || ActualWidth == 0)
-                return;
-            _ttl.Paint?.Invoke(new Rect(0, 0, ActualWidth, ActualHeight));
-            if (ImageSource != null)
-                drawingContext.DrawImage(ImageSource, new System.Windows.Rect(0, 0, ActualWidth, ActualHeight));
-        }
-
-
-
-        void ITopLevelImpl.SetInputRoot(IInputRoot inputRoot) => _inputRoot = inputRoot;
-
-        Point ITopLevelImpl.PointToClient(PixelPoint point) => PointFromScreen(point.ToWpfPoint()).ToAvaloniaPoint();
-
-        PixelPoint ITopLevelImpl.PointToScreen(Point point) => PointToScreen(point.ToWpfPoint()).ToAvaloniaPixelPoint();
-
-        protected override void OnLostFocus(RoutedEventArgs e) => LostFocus?.Invoke();
-
-        private static RawInputModifiers GetModifiers(MouseEventArgs? e)
-        {
-            var state = Keyboard.Modifiers;
-            var rv = default(RawInputModifiers);
-            if (state.HasFlag(ModifierKeys.Windows))
-                rv |= RawInputModifiers.Meta;
-            if (state.HasFlag(ModifierKeys.Alt))
-                rv |= RawInputModifiers.Alt;
-            if (state.HasFlag(ModifierKeys.Control))
-                rv |= RawInputModifiers.Control;
-            if (state.HasFlag(ModifierKeys.Shift))
-                rv |= RawInputModifiers.Shift;
-            if (e != null)
-            {
-                if (e.LeftButton == MouseButtonState.Pressed)
-                    rv |= RawInputModifiers.LeftMouseButton;
-                if (e.RightButton == MouseButtonState.Pressed)
-                    rv |= RawInputModifiers.RightMouseButton;
-                if (e.MiddleButton == MouseButtonState.Pressed)
-                    rv |= RawInputModifiers.MiddleMouseButton;
-            }
-            return rv;
-        }
-
-        private void MouseEvent(RawPointerEventType type, MouseEventArgs e)
-            => _ttl.Input?.Invoke(new RawPointerEventArgs(_mouse, (uint)e.Timestamp, _inputRoot!, type,
-            e.GetPosition(this).ToAvaloniaPoint(), GetModifiers(e)));
-
-        protected override void OnMouseDown(MouseButtonEventArgs e)
-        {
-            RawPointerEventType type;
-            if(e.ChangedButton == MouseButton.Left)
-                type = RawPointerEventType.LeftButtonDown;
-            else if (e.ChangedButton == MouseButton.Middle)
-                type = RawPointerEventType.MiddleButtonDown;
-            else if (e.ChangedButton == MouseButton.Right)
-                type = RawPointerEventType.RightButtonDown;
-            else
-                return;
-            MouseEvent(type, e);
-            Focus();
-        }
-
-        protected override void OnMouseUp(MouseButtonEventArgs e)
-        {
-            RawPointerEventType type;
-            if (e.ChangedButton == MouseButton.Left)
-                type = RawPointerEventType.LeftButtonUp;
-            else if (e.ChangedButton == MouseButton.Middle)
-                type = RawPointerEventType.MiddleButtonUp;
-            else if (e.ChangedButton == MouseButton.Right)
-                type = RawPointerEventType.RightButtonUp;
-            else
-                return;
-            MouseEvent(type, e);
-            Focus();
-        }
-
-        protected override void OnMouseMove(MouseEventArgs e)
-        {
-            MouseEvent(RawPointerEventType.Move, e);
-        }
-
-        protected override void OnMouseWheel(MouseWheelEventArgs e) =>
-            _ttl.Input?.Invoke(new RawMouseWheelEventArgs(_mouse, (uint) e.Timestamp, _inputRoot!,
-                e.GetPosition(this).ToAvaloniaPoint(), new Vector(0, e.Delta), GetModifiers(e)));
-
-        protected override void OnMouseLeave(MouseEventArgs e) => MouseEvent(RawPointerEventType.LeaveWindow, e);
-
-        protected override void OnKeyDown(KeyEventArgs e)
-            => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint) e.Timestamp, _inputRoot!, RawKeyEventType.KeyDown,
-                (Key) e.Key,
-                GetModifiers(null)));
-
-        protected override void OnKeyUp(KeyEventArgs e)
-            => _ttl.Input?.Invoke(new RawKeyEventArgs(_keyboard, (uint)e.Timestamp, _inputRoot!, RawKeyEventType.KeyUp,
-                (Key)e.Key,
-                GetModifiers(null)));
-
-        protected override void OnTextInput(TextCompositionEventArgs e)
-            => _ttl.Input?.Invoke(new RawTextInputEventArgs(_keyboard, (uint) e.Timestamp, _inputRoot!, e.Text));
-
-        void ITopLevelImpl.SetCursor(ICursorImpl? cursor)
-        {
-            if (cursor == null)
-                Cursor = Cursors.Arrow;
-            else if (cursor is IPlatformHandle handle)
-                Cursor = CursorShim.FromHCursor(handle.Handle);
-        }
-
-        Action<RawInputEventArgs>? ITopLevelImpl.Input { get; set; } //TODO
-        Action<Rect>? ITopLevelImpl.Paint { get; set; }
-        Action<Size, WindowResizeReason>? ITopLevelImpl.Resized { get; set; }
-        Action<double>? ITopLevelImpl.ScalingChanged { get; set; }
-
-        Action<WindowTransparencyLevel>? ITopLevelImpl.TransparencyLevelChanged { get; set; }
-
-        Action? ITopLevelImpl.Closed { get; set; }
-        public new Action? LostFocus { get; set; }
-
-        internal Vector GetScaling()
-        {
-            var src = PresentationSource.FromVisual(this)?.CompositionTarget;
-            if (src == null)
-                return new Vector(1, 1);
-            return new Vector(src.TransformToDevice.M11, src.TransformToDevice.M22);
-        }
-
-        public IPopupImpl? CreatePopup() => null;
-
-        public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) { }
-
-        public WindowTransparencyLevel TransparencyLevel { get; private set; }
-
-        public void SetFrameThemeVariant(PlatformThemeVariant themeVariant) { }
-
-        public AcrylicPlatformCompensationLevels AcrylicCompensationLevels { get; } = new AcrylicPlatformCompensationLevels(1, 1, 1);
-        
-        public object? TryGetFeature(Type featureType) => null;
-    }
-}

+ 0 - 67
src/Windows/Avalonia.Win32.Interoperability/Wpf/WritableBitmapSurface.cs

@@ -1,67 +0,0 @@
-using System;
-using System.Windows;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using Avalonia.Controls.Platform.Surfaces;
-using Avalonia.Platform;
-using PixelFormat = Avalonia.Platform.PixelFormat;
-
-namespace Avalonia.Win32.Interoperability.Wpf
-{
-    internal class WritableBitmapSurface : IFramebufferPlatformSurface
-    {
-        private readonly WpfTopLevelImpl _impl;
-        private WriteableBitmap? _bitmap;
-        public WritableBitmapSurface(WpfTopLevelImpl impl)
-        {
-            _impl = impl;
-        }
-
-        public ILockedFramebuffer Lock()
-        {
-            var scale = _impl.GetScaling();
-            var size = new Size(_impl.ActualWidth * scale.X, _impl.ActualHeight * scale.Y);
-            var dpi = scale * 96;
-            if (_bitmap == null || _bitmap.PixelWidth != (int) size.Width || _bitmap.PixelHeight != (int) size.Height)
-            {
-                _bitmap = new WriteableBitmap((int) size.Width, (int) size.Height, dpi.X, dpi.Y,
-                    System.Windows.Media.PixelFormats.Bgra32, null);
-            }
-            return new LockedFramebuffer(_impl, _bitmap, dpi);
-        }
-
-        internal class LockedFramebuffer : ILockedFramebuffer
-        {
-            private readonly WpfTopLevelImpl _impl;
-            private readonly WriteableBitmap _bitmap;
-
-            public LockedFramebuffer(WpfTopLevelImpl impl, WriteableBitmap bitmap, Vector dpi)
-            {
-                _impl = impl;
-                _bitmap = bitmap;
-                Dpi = dpi;
-                _bitmap.Lock();
-            }
-
-            public void Dispose()
-            {
-                _bitmap.AddDirtyRect(new Int32Rect(0, 0, _bitmap.PixelWidth, _bitmap.PixelHeight));
-                _bitmap.Unlock();
-                /*
-                using (var fileStream = new FileStream("c:\\tools\\wat.png", FileMode.Create))
-                {
-                    BitmapEncoder encoder = new PngBitmapEncoder();
-                    encoder.Frames.Add(BitmapFrame.Create(_bitmap));
-                    encoder.Save(fileStream);
-                }*/
-                _impl.ImageSource = _bitmap;
-            }
-
-            public IntPtr Address => _bitmap.BackBuffer;
-            public PixelSize Size => new PixelSize(_bitmap.PixelWidth, _bitmap.PixelHeight);
-            public int RowBytes => _bitmap.BackBufferStride;
-            public Vector Dpi { get; }
-            public PixelFormat Format => PixelFormat.Bgra8888;
-        }
-    }
-}