|
|
@@ -4,11 +4,15 @@ using System.Runtime.InteropServices;
|
|
|
using Avalonia.Controls.Embedding.Offscreen;
|
|
|
using Avalonia.Controls.Platform.Surfaces;
|
|
|
using Avalonia.Input;
|
|
|
+using Avalonia.Input.Raw;
|
|
|
using Avalonia.Layout;
|
|
|
using Avalonia.Platform;
|
|
|
using Avalonia.Remote.Protocol;
|
|
|
+using Avalonia.Remote.Protocol.Input;
|
|
|
using Avalonia.Remote.Protocol.Viewport;
|
|
|
using Avalonia.Threading;
|
|
|
+using InputModifiers = Avalonia.Input.InputModifiers;
|
|
|
+using Key = Avalonia.Input.Key;
|
|
|
using PixelFormat = Avalonia.Platform.PixelFormat;
|
|
|
using ProtocolPixelFormat = Avalonia.Remote.Protocol.Viewport.PixelFormat;
|
|
|
|
|
|
@@ -33,6 +37,65 @@ namespace Avalonia.Controls.Remote.Server
|
|
|
_transport.OnMessage += OnMessage;
|
|
|
}
|
|
|
|
|
|
+ private static RawMouseEventType GetAvaloniaEventType (Avalonia.Remote.Protocol.Input.MouseButton button, bool pressed)
|
|
|
+ {
|
|
|
+ switch (button)
|
|
|
+ {
|
|
|
+ case Avalonia.Remote.Protocol.Input.MouseButton.Left:
|
|
|
+ return pressed ? RawMouseEventType.LeftButtonDown : RawMouseEventType.LeftButtonUp;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.MouseButton.Middle:
|
|
|
+ return pressed ? RawMouseEventType.MiddleButtonDown : RawMouseEventType.MiddleButtonUp;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.MouseButton.Right:
|
|
|
+ return pressed ? RawMouseEventType.RightButtonDown : RawMouseEventType.RightButtonUp;
|
|
|
+
|
|
|
+ default:
|
|
|
+ return RawMouseEventType.Move;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static InputModifiers GetAvaloniaInputModifiers (Avalonia.Remote.Protocol.Input.InputModifiers[] modifiers)
|
|
|
+ {
|
|
|
+ var result = InputModifiers.None;
|
|
|
+
|
|
|
+ foreach(var modifier in modifiers)
|
|
|
+ {
|
|
|
+ switch (modifier)
|
|
|
+ {
|
|
|
+ case Avalonia.Remote.Protocol.Input.InputModifiers.Control:
|
|
|
+ result |= InputModifiers.Control;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.InputModifiers.Alt:
|
|
|
+ result |= InputModifiers.Alt;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.InputModifiers.Shift:
|
|
|
+ result |= InputModifiers.Shift;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.InputModifiers.Windows:
|
|
|
+ result |= InputModifiers.Windows;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.InputModifiers.LeftMouseButton:
|
|
|
+ result |= InputModifiers.LeftMouseButton;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.InputModifiers.MiddleMouseButton:
|
|
|
+ result |= InputModifiers.MiddleMouseButton;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case Avalonia.Remote.Protocol.Input.InputModifiers.RightMouseButton:
|
|
|
+ result |= InputModifiers.RightMouseButton;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
protected virtual void OnMessage(IAvaloniaRemoteTransportConnection transport, object obj)
|
|
|
{
|
|
|
lock (_lock)
|
|
|
@@ -51,8 +114,9 @@ namespace Avalonia.Controls.Remote.Server
|
|
|
{
|
|
|
_dpi = new Vector(renderInfo.DpiX, renderInfo.DpiY);
|
|
|
_invalidated = true;
|
|
|
- RenderIfNeeded();
|
|
|
}
|
|
|
+
|
|
|
+ Dispatcher.UIThread.Post(RenderIfNeeded);
|
|
|
}
|
|
|
if (obj is ClientSupportedPixelFormatsMessage supportedFormats)
|
|
|
{
|
|
|
@@ -91,6 +155,80 @@ namespace Avalonia.Controls.Remote.Server
|
|
|
_pendingAllocation = allocated;
|
|
|
}
|
|
|
}
|
|
|
+ if(obj is PointerMovedEventMessage pointer)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.Post(() =>
|
|
|
+ {
|
|
|
+ Input?.Invoke(new RawMouseEventArgs(
|
|
|
+ MouseDevice,
|
|
|
+ 0,
|
|
|
+ InputRoot,
|
|
|
+ RawMouseEventType.Move,
|
|
|
+ new Point(pointer.X, pointer.Y),
|
|
|
+ GetAvaloniaInputModifiers(pointer.Modifiers)));
|
|
|
+ }, DispatcherPriority.Input);
|
|
|
+ }
|
|
|
+ if(obj is PointerPressedEventMessage pressed)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.Post(() =>
|
|
|
+ {
|
|
|
+ Input?.Invoke(new RawMouseEventArgs(
|
|
|
+ MouseDevice,
|
|
|
+ 0,
|
|
|
+ InputRoot,
|
|
|
+ GetAvaloniaEventType(pressed.Button, true),
|
|
|
+ new Point(pressed.X, pressed.Y),
|
|
|
+ GetAvaloniaInputModifiers(pressed.Modifiers)));
|
|
|
+ }, DispatcherPriority.Input);
|
|
|
+ }
|
|
|
+ if (obj is PointerPressedEventMessage released)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.Post(() =>
|
|
|
+ {
|
|
|
+ Input?.Invoke(new RawMouseEventArgs(
|
|
|
+ MouseDevice,
|
|
|
+ 0,
|
|
|
+ InputRoot,
|
|
|
+ GetAvaloniaEventType(released.Button, false),
|
|
|
+ new Point(released.X, released.Y),
|
|
|
+ GetAvaloniaInputModifiers(released.Modifiers)));
|
|
|
+ }, DispatcherPriority.Input);
|
|
|
+ }
|
|
|
+ if(obj is ScrollEventMessage scroll)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.Post(() =>
|
|
|
+ {
|
|
|
+ Input?.Invoke(new RawMouseWheelEventArgs(
|
|
|
+ MouseDevice,
|
|
|
+ 0,
|
|
|
+ InputRoot,
|
|
|
+ new Point(scroll.X, scroll.Y),
|
|
|
+ new Vector(scroll.DeltaX, scroll.DeltaY),
|
|
|
+ GetAvaloniaInputModifiers(scroll.Modifiers)));
|
|
|
+ }, DispatcherPriority.Input);
|
|
|
+ }
|
|
|
+ if(obj is KeyEventMessage key)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.Post(() =>
|
|
|
+ {
|
|
|
+ Input?.Invoke(new RawKeyEventArgs(
|
|
|
+ KeyboardDevice,
|
|
|
+ 0,
|
|
|
+ key.IsDown ? RawKeyEventType.KeyDown : RawKeyEventType.KeyUp,
|
|
|
+ (Key)key.Key,
|
|
|
+ GetAvaloniaInputModifiers(key.Modifiers)));
|
|
|
+ }, DispatcherPriority.Input);
|
|
|
+ }
|
|
|
+ if(obj is TextInputEventMessage text)
|
|
|
+ {
|
|
|
+ Dispatcher.UIThread.Post(() =>
|
|
|
+ {
|
|
|
+ Input?.Invoke(new RawTextInputEventArgs(
|
|
|
+ KeyboardDevice,
|
|
|
+ 0,
|
|
|
+ text.Text));
|
|
|
+ }, DispatcherPriority.Input);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -184,5 +322,7 @@ namespace Avalonia.Controls.Remote.Server
|
|
|
}
|
|
|
|
|
|
public override IMouseDevice MouseDevice { get; } = new MouseDevice();
|
|
|
+
|
|
|
+ public IKeyboardDevice KeyboardDevice { get; } = new KeyboardDevice();
|
|
|
}
|
|
|
}
|