diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs b/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs index 0589e30edb..723028c666 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs @@ -15,6 +15,8 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput private IInputRoot _inputRoot; private readonly Queue _inputThreadActions = new Queue(); private TouchDevice _touch = new TouchDevice(); + private MouseDevice _mouse = new MouseDevice(); + private Point _mousePosition; private readonly Queue _inputQueue = new Queue(); private Action _onInput; @@ -50,6 +52,10 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput if (type >= LibInputEventType.LIBINPUT_EVENT_TOUCH_DOWN && type <= LibInputEventType.LIBINPUT_EVENT_TOUCH_CANCEL) HandleTouch(ev, type); + + if (type >= LibInputEventType.LIBINPUT_EVENT_POINTER_MOTION + && type <= LibInputEventType.LIBINPUT_EVENT_POINTER_AXIS) + HandlePointer(ev, type); libinput_event_destroy(ev); libinput_dispatch(ctx); @@ -123,6 +129,45 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput } } + private void HandlePointer(IntPtr ev, LibInputEventType type) + { + //TODO: support input modifiers + var pev = libinput_event_get_pointer_event(ev); + var info = _screen.ScaledSize; + var ts = libinput_event_pointer_get_time_usec(pev) / 1000; + if (type == LibInputEventType.LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE) + { + _mousePosition = new Point(libinput_event_pointer_get_absolute_x_transformed(pev, (int)info.Width), + libinput_event_pointer_get_absolute_y_transformed(pev, (int)info.Height)); + ScheduleInput(new RawPointerEventArgs(_mouse, ts, _inputRoot, RawPointerEventType.Move, _mousePosition, + InputModifiers.None)); + } + else if (type == LibInputEventType.LIBINPUT_EVENT_POINTER_BUTTON) + { + var button = (EvKey)libinput_event_pointer_get_button(pev); + var buttonState = libinput_event_pointer_get_button_state(pev); + + + var evnt = button == EvKey.BTN_LEFT ? + (buttonState == 1 ? RawPointerEventType.LeftButtonDown : RawPointerEventType.LeftButtonUp) : + button == EvKey.BTN_MIDDLE ? + (buttonState == 1 ? RawPointerEventType.MiddleButtonDown : RawPointerEventType.MiddleButtonUp) : + button == EvKey.BTN_RIGHT ? + (buttonState == 1 ? + RawPointerEventType.RightButtonDown : + RawPointerEventType.RightButtonUp) : + (RawPointerEventType)(-1); + if (evnt == (RawPointerEventType)(-1)) + return; + + + ScheduleInput( + new RawPointerEventArgs(_mouse, ts, _inputRoot, evnt, _mousePosition, InputModifiers.None)); + } + + } + + public void Initialize(IScreenInfoProvider screen, Action onInput) { diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputNativeUnsafeMethods.cs b/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputNativeUnsafeMethods.cs index 6c82f53071..0492090461 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputNativeUnsafeMethods.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputNativeUnsafeMethods.cs @@ -116,7 +116,24 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput [DllImport(LibInput)] public extern static double libinput_event_touch_get_y_transformed(IntPtr ev, int height); - - + + [DllImport(LibInput)] + public extern static IntPtr libinput_event_get_pointer_event(IntPtr ev); + + + [DllImport(LibInput)] + public extern static ulong libinput_event_pointer_get_time_usec(IntPtr ev); + + [DllImport(LibInput)] + public extern static double libinput_event_pointer_get_absolute_x_transformed(IntPtr ev, int width); + + [DllImport(LibInput)] + public extern static double libinput_event_pointer_get_absolute_y_transformed(IntPtr ev, int height); + + [DllImport(LibInput)] + public extern static int libinput_event_pointer_get_button(IntPtr ev); + + [DllImport(LibInput)] + public extern static int libinput_event_pointer_get_button_state(IntPtr ev); } }