A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

110 lines
5.4 KiB

using System;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Logging;
using static Avalonia.LinuxFramebuffer.Input.LibInput.LibInputNativeUnsafeMethods;
namespace Avalonia.LinuxFramebuffer.Input.LibInput;
public partial class LibInputBackend
{
private MouseDevice _mouse = new MouseDevice();
private Point _mousePosition;
private const string Pointer = LibInput + "/" + nameof(Pointer);
private void HandlePointer(IntPtr ev, LibInputEventType type)
{
var modifiers = RawInputModifiers.None; //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;
switch (type)
{
case 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,
modifiers));
break;
case LibInputEventType.LIBINPUT_EVENT_POINTER_BUTTON:
{
var button = (EvKey)libinput_event_pointer_get_button(pev);
var buttonState = libinput_event_pointer_get_button_state(pev);
RawPointerEventArgs? evnt = button switch
{
EvKey.BTN_LEFT when buttonState == 1
=> new(_mouse, ts, InputRoot, RawPointerEventType.LeftButtonDown, _mousePosition, modifiers),
EvKey.BTN_LEFT when buttonState == 0
=> new(_mouse, ts, InputRoot, RawPointerEventType.LeftButtonUp, _mousePosition, modifiers),
EvKey.BTN_RIGHT when buttonState == 1
=> new(_mouse, ts, InputRoot, RawPointerEventType.RightButtonUp, _mousePosition, modifiers),
EvKey.BTN_RIGHT when buttonState == 2
=> new(_mouse, ts, InputRoot, RawPointerEventType.RightButtonDown, _mousePosition, modifiers),
EvKey.BTN_MIDDLE when buttonState == 1
=> new(_mouse, ts, InputRoot, RawPointerEventType.MiddleButtonDown, _mousePosition, modifiers),
EvKey.BTN_MIDDLE when buttonState == 2
=> new(_mouse, ts, InputRoot, RawPointerEventType.MiddleButtonUp, _mousePosition, modifiers),
_ => default,
};
if (evnt is not null)
{
ScheduleInput(evnt);
}
else
{
Logger.TryGet(LogEventLevel.Warning, Pointer)
?.Log(this, $"The button {button} is not associated");
}
}
break;
// Backward compatibility with low-res wheel
case LibInputEventType.LIBINPUT_EVENT_POINTER_AXIS:
{
var sourceAxis = libinput_event_pointer_get_axis_source(pev);
switch (sourceAxis)
{
case LibInputPointerAxisSource.LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
{
var value = libinput_event_pointer_get_axis_value_discrete(pev,
LibInputPointerAxis.LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
ScheduleInput(new RawMouseWheelEventArgs(_mouse
, ts
, InputRoot
, _mousePosition
, new Vector(0, -value)
, modifiers));
}
break;
case LibInputPointerAxisSource.LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
case LibInputPointerAxisSource.LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
case LibInputPointerAxisSource.LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT:
default:
Logger.TryGet(LogEventLevel.Debug, Pointer)
?.Log(this, $"The pointer axis {sourceAxis} is not managed.");
break;
}
}
break;
// Hi-Res wheel
case LibInputEventType.LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
{
var value = new Vector(0,
-libinput_event_pointer_get_scroll_value_v120(pev,
LibInputPointerAxis.LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL) / 120);
ScheduleInput(new RawMouseWheelEventArgs(_mouse
, ts
, InputRoot
, _mousePosition
, value
, modifiers));
}
break;
default:
Logger.TryGet(LogEventLevel.Warning, Pointer)
?.Log(this, $"The pointer event {type} is not mapped.");
break;
}
}
}