|
@@ -1,5 +1,5 @@
|
|
|
+#nullable enable
|
|
|
using System;
|
|
|
-using System.Collections.Generic;
|
|
|
using System.IO;
|
|
|
using System.Threading;
|
|
|
using Avalonia.Input;
|
|
@@ -9,27 +9,27 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput
|
|
|
{
|
|
|
public partial class LibInputBackend : IInputBackend
|
|
|
{
|
|
|
- private IScreenInfoProvider _screen;
|
|
|
- private IInputRoot _inputRoot;
|
|
|
- private TouchDevice _touch = new TouchDevice();
|
|
|
- private const string LibInput = nameof(Avalonia.LinuxFramebuffer) + "/" + nameof(Avalonia.LinuxFramebuffer.Input) + "/" + nameof(LibInput);
|
|
|
- private Action<RawInputEventArgs> _onInput;
|
|
|
- private Dictionary<int, Point> _pointers = new Dictionary<int, Point>();
|
|
|
+ private IScreenInfoProvider? _screen;
|
|
|
+ private IInputRoot? _inputRoot;
|
|
|
+ private const string LibInput = nameof(LinuxFramebuffer) + "/" + nameof(Input) + "/" + nameof(LibInput);
|
|
|
+ private Action<RawInputEventArgs>? _onInput;
|
|
|
+ private readonly LibInputBackendOptions? _options;
|
|
|
|
|
|
public LibInputBackend()
|
|
|
{
|
|
|
- var ctx = libinput_path_create_context();
|
|
|
- new Thread(() => InputThread(ctx))
|
|
|
- {
|
|
|
- IsBackground = true
|
|
|
- }.Start();
|
|
|
+ _options = default;
|
|
|
+ }
|
|
|
+
|
|
|
+ public LibInputBackend(LibInputBackendOptions options)
|
|
|
+ {
|
|
|
+ _options = options;
|
|
|
}
|
|
|
|
|
|
- private unsafe void InputThread(IntPtr ctx)
|
|
|
+ private unsafe void InputThread(IntPtr ctx, LibInputBackendOptions options)
|
|
|
{
|
|
|
var fd = libinput_get_fd(ctx);
|
|
|
|
|
|
- foreach (var f in Directory.GetFiles("/dev/input", "event*"))
|
|
|
+ foreach (var f in options.Events!)
|
|
|
libinput_path_add_device(ctx, f);
|
|
|
while (true)
|
|
|
{
|
|
@@ -37,8 +37,8 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput
|
|
|
libinput_dispatch(ctx);
|
|
|
while ((ev = libinput_get_event(ctx)) != IntPtr.Zero)
|
|
|
{
|
|
|
-
|
|
|
var type = libinput_event_get_type(ev);
|
|
|
+
|
|
|
if (type >= LibInputEventType.LIBINPUT_EVENT_TOUCH_DOWN &&
|
|
|
type <= LibInputEventType.LIBINPUT_EVENT_TOUCH_CANCEL)
|
|
|
HandleTouch(ev, type);
|
|
@@ -56,50 +56,24 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void ScheduleInput(RawInputEventArgs ev) => _onInput.Invoke(ev);
|
|
|
-
|
|
|
- private void HandleTouch(IntPtr ev, LibInputEventType type)
|
|
|
- {
|
|
|
- var tev = libinput_event_get_touch_event(ev);
|
|
|
- if (tev == IntPtr.Zero)
|
|
|
- return;
|
|
|
- if (type < LibInputEventType.LIBINPUT_EVENT_TOUCH_FRAME)
|
|
|
- {
|
|
|
- var info = _screen.ScaledSize;
|
|
|
- var slot = libinput_event_touch_get_slot(tev);
|
|
|
- Point pt;
|
|
|
-
|
|
|
- if (type == LibInputEventType.LIBINPUT_EVENT_TOUCH_DOWN
|
|
|
- || type == LibInputEventType.LIBINPUT_EVENT_TOUCH_MOTION)
|
|
|
- {
|
|
|
- var x = libinput_event_touch_get_x_transformed(tev, (int)info.Width);
|
|
|
- var y = libinput_event_touch_get_y_transformed(tev, (int)info.Height);
|
|
|
- pt = new Point(x, y);
|
|
|
- _pointers[slot] = pt;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- _pointers.TryGetValue(slot, out pt);
|
|
|
- _pointers.Remove(slot);
|
|
|
- }
|
|
|
-
|
|
|
- var ts = libinput_event_touch_get_time_usec(tev) / 1000;
|
|
|
- if (_inputRoot == null)
|
|
|
- return;
|
|
|
- ScheduleInput(new RawTouchEventArgs(_touch, ts,
|
|
|
- _inputRoot,
|
|
|
- type == LibInputEventType.LIBINPUT_EVENT_TOUCH_DOWN ? RawPointerEventType.TouchBegin
|
|
|
- : type == LibInputEventType.LIBINPUT_EVENT_TOUCH_UP ? RawPointerEventType.TouchEnd
|
|
|
- : type == LibInputEventType.LIBINPUT_EVENT_TOUCH_MOTION ? RawPointerEventType.TouchUpdate
|
|
|
- : RawPointerEventType.TouchCancel,
|
|
|
- pt, RawInputModifiers.None, slot));
|
|
|
- }
|
|
|
- }
|
|
|
+ private void ScheduleInput(RawInputEventArgs ev) => _onInput?.Invoke(ev);
|
|
|
|
|
|
public void Initialize(IScreenInfoProvider screen, Action<RawInputEventArgs> onInput)
|
|
|
{
|
|
|
_screen = screen;
|
|
|
_onInput = onInput;
|
|
|
+ var ctx = libinput_path_create_context();
|
|
|
+ var options = new LibInputBackendOptions()
|
|
|
+ {
|
|
|
+ Events = _options?.Events is null
|
|
|
+ ? Directory.GetFiles("/dev/input", "event*")
|
|
|
+ : _options.Events,
|
|
|
+ };
|
|
|
+ new Thread(() => InputThread(ctx, options))
|
|
|
+ {
|
|
|
+ Name = "Input Manager Worker",
|
|
|
+ IsBackground = true
|
|
|
+ }.Start();
|
|
|
}
|
|
|
|
|
|
public void SetInputRoot(IInputRoot root)
|