mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-23 11:35:39 +00:00
[Linux] Implemented libinput IMouseDriver2
This commit is contained in:
parent
340d34b07b
commit
bef4901659
|
@ -30,7 +30,7 @@
|
|||
using System;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
// Bindings for linux/input.h
|
||||
class Evdev
|
||||
|
@ -330,6 +330,123 @@ namespace OpenTK
|
|||
};
|
||||
|
||||
#endregion
|
||||
|
||||
public static MouseButton GetMouseButton(EvdevButton button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case EvdevButton.LEFT:
|
||||
return MouseButton.Left;
|
||||
case EvdevButton.RIGHT:
|
||||
return MouseButton.Right;
|
||||
case EvdevButton.MIDDLE:
|
||||
return MouseButton.Middle;
|
||||
case EvdevButton.BTN0:
|
||||
return MouseButton.Button1;
|
||||
case EvdevButton.BTN1:
|
||||
return MouseButton.Button2;
|
||||
case EvdevButton.BTN2:
|
||||
return MouseButton.Button3;
|
||||
case EvdevButton.BTN3:
|
||||
return MouseButton.Button4;
|
||||
case EvdevButton.BTN4:
|
||||
return MouseButton.Button5;
|
||||
case EvdevButton.BTN5:
|
||||
return MouseButton.Button6;
|
||||
case EvdevButton.BTN6:
|
||||
return MouseButton.Button7;
|
||||
case EvdevButton.BTN7:
|
||||
return MouseButton.Button8;
|
||||
case EvdevButton.BTN8:
|
||||
return MouseButton.Button9;
|
||||
case EvdevButton.BTN9:
|
||||
return MouseButton.LastButton;
|
||||
default:
|
||||
return MouseButton.LastButton;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum EvdevButton : uint
|
||||
{
|
||||
MISC = 0x100,
|
||||
BTN0 = 0x100,
|
||||
BTN1 = 0x101,
|
||||
BTN2 = 0x102,
|
||||
BTN3 = 0x103,
|
||||
BTN4 = 0x104,
|
||||
BTN5 = 0x105,
|
||||
BTN6 = 0x106,
|
||||
BTN7 = 0x107,
|
||||
BTN8 = 0x108,
|
||||
BTN9 = 0x109,
|
||||
|
||||
MOUSE = 0x110,
|
||||
LEFT = 0x110,
|
||||
RIGHT = 0x111,
|
||||
MIDDLE = 0x112,
|
||||
SIDE = 0x113,
|
||||
EXTRA = 0x114,
|
||||
FORWARD = 0x115,
|
||||
BACK = 0x116,
|
||||
TASK = 0x117,
|
||||
|
||||
JOYSTICK = 0x120,
|
||||
TRIGGER = 0x120,
|
||||
THUMB = 0x121,
|
||||
THUMB2 = 0x122,
|
||||
TOP = 0x123,
|
||||
TOP2 = 0x124,
|
||||
PINKIE = 0x125,
|
||||
BASE = 0x126,
|
||||
BASE2 = 0x127,
|
||||
BASE3 = 0x128,
|
||||
BASE4 = 0x129,
|
||||
BASE5 = 0x12a,
|
||||
BASE6 = 0x12b,
|
||||
DEAD = 0x12f,
|
||||
|
||||
GAMEPAD = 0x130,
|
||||
SOUTH = 0x130,
|
||||
A = SOUTH,
|
||||
EAST = 0x131,
|
||||
B = EAST,
|
||||
C = 0x132,
|
||||
NORTH = 0x133,
|
||||
X = NORTH,
|
||||
WEST = 0x134,
|
||||
Y = WEST,
|
||||
Z = 0x135,
|
||||
TL = 0x136,
|
||||
TR = 0x137,
|
||||
TL2 = 0x138,
|
||||
TR2 = 0x139,
|
||||
SELECT = 0x13a,
|
||||
START = 0x13b,
|
||||
MODE = 0x13c,
|
||||
THUMBL = 0x13d,
|
||||
THUMBR = 0x13e,
|
||||
|
||||
DIGI = 0x140,
|
||||
TOOL_PEN = 0x140,
|
||||
TOOL_RUBBER = 0x141,
|
||||
TOOL_BRUSH = 0x142,
|
||||
TOOL_PENCIL = 0x143,
|
||||
TOOL_AIRBRUSH = 0x144,
|
||||
TOOL_FINGER = 0x145,
|
||||
TOOL_MOUSE = 0x146,
|
||||
TOOL_LENS = 0x147,
|
||||
TOOL_QUINTTAP = 0x148, // Five fingers on trackpad
|
||||
TOUCH = 0x14a,
|
||||
STYLUS = 0x14b,
|
||||
STYLUS2 = 0x14c,
|
||||
TOOL_DOUBLETAP = 0x14d,
|
||||
TOOL_TRIPLETAP = 0x14e,
|
||||
TOOL_QUADTAP = 0x14f, // Four fingers on trackpad
|
||||
|
||||
WHEEL = 0x150,
|
||||
GEAR_DOWN = 0x150,
|
||||
GEAR_UP = 0x151,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,9 @@ namespace OpenTK.Platform.Linux
|
|||
[DllImport(lib, EntryPoint = "libinput_event_get_keyboard_event", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern KeyboardEvent GetKeyboardEvent(IntPtr @event);
|
||||
|
||||
[DllImport(lib, EntryPoint = "libinput_event_get_pointer_event", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern PointerEvent GetPointerEvent(IntPtr @event);
|
||||
|
||||
[DllImport(lib, EntryPoint = "libinput_event_get_type", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern InputEventType GetEventType(IntPtr @event);
|
||||
|
||||
|
@ -148,17 +151,54 @@ namespace OpenTK.Platform.Linux
|
|||
TouchFrame
|
||||
}
|
||||
|
||||
enum ButtonState
|
||||
{
|
||||
Released = 0,
|
||||
Pressed = 1
|
||||
}
|
||||
|
||||
enum KeyState
|
||||
{
|
||||
Released = 0,
|
||||
Pressed = 1
|
||||
}
|
||||
|
||||
enum PointerAxis
|
||||
{
|
||||
VerticalScroll = 0,
|
||||
HorizontalScroll = 1
|
||||
}
|
||||
|
||||
struct Fixed24
|
||||
{
|
||||
internal readonly int Value;
|
||||
|
||||
public static implicit operator double(Fixed24 n)
|
||||
{
|
||||
long l = ((1023L + 44L) << 52) + (1L << 51) + n.Value;
|
||||
unsafe
|
||||
{
|
||||
double d = *(double*)&l;
|
||||
return d - (3L << 43);
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator float(Fixed24 n)
|
||||
{
|
||||
return (float)(double)n;
|
||||
}
|
||||
|
||||
public static explicit operator int(Fixed24 n)
|
||||
{
|
||||
return n.Value >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
class InputInterface
|
||||
{
|
||||
IntPtr open;
|
||||
IntPtr close;
|
||||
internal readonly IntPtr open;
|
||||
internal readonly IntPtr close;
|
||||
|
||||
public InputInterface(
|
||||
OpenRestrictedCallback open_restricted,
|
||||
|
@ -179,25 +219,90 @@ namespace OpenTK.Platform.Linux
|
|||
|
||||
public IntPtr BaseEvent { get { return GetBaseEvent(@event); } }
|
||||
public IntPtr Event { get { return @event; } }
|
||||
public uint Time { get { return GetTime(@event); } }
|
||||
public uint Key { get { return GetKey(@event); } }
|
||||
public uint KeyCount { get { return GetSeatKeyCount(@event); } }
|
||||
public KeyState KeyState { get { return GetKeyState(@event); } }
|
||||
public uint Time { get { return GetTime(@event); } }
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_time", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetTime(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetKey(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key_state", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern KeyState GetKeyState(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_base_event", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern IntPtr GetBaseEvent(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_seat_key_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetSeatKeyCount(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetKey(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_keyboard_get_key_state", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern KeyState GetKeyState(IntPtr @event);
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct PointerEvent
|
||||
{
|
||||
IntPtr @event;
|
||||
|
||||
public IntPtr BaseEvent { get { return GetBaseEvent(@event); } }
|
||||
public IntPtr Event { get { return @event; } }
|
||||
public uint Time { get { return GetTime(@event); } }
|
||||
public EvdevButton Button { get { return (EvdevButton)GetButton(@event); } }
|
||||
public uint ButtonCount { get { return GetButtonCount(@event); } }
|
||||
public ButtonState ButtonState { get { return GetButtonState(@event); } }
|
||||
public PointerAxis Axis { get { return GetAxis(@event); } }
|
||||
public Fixed24 AxisValue { get { return GetAxisValue(@event); } }
|
||||
public Fixed24 DeltaX { get { return GetDX(@event); } }
|
||||
public Fixed24 DeltaY { get { return GetDY(@event); } }
|
||||
public Fixed24 X { get { return GetAbsX(@event); } }
|
||||
public Fixed24 Y { get { return GetAbsY(@event); } }
|
||||
// Are the following useful?
|
||||
//public Fixed24 TransformedX(int width) { return GetAbsXTransformed(@event, width); }
|
||||
//public Fixed24 TransformedY(int height) { return GetAbsXTransformed(@event, height); }
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_time", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetTime(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_base_event", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern IntPtr GetBaseEvent(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_seat_key_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetSeatKeyCount(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_button", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetButton(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_seat_button_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern uint GetButtonCount(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_button_state", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern ButtonState GetButtonState(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_axis", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern PointerAxis GetAxis(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_axis_value", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern Fixed24 GetAxisValue(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_dx", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern Fixed24 GetDX(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_dy", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern Fixed24 GetDY(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_x", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern Fixed24 GetAbsX(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_y", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern Fixed24 GetAbsY(IntPtr @event);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_x_transformed", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern Fixed24 GetAbsXTransformed(IntPtr @event, int width);
|
||||
|
||||
[DllImport(LibInput.lib, EntryPoint = "libinput_event_pointer_get_absolute_y_transformed", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern Fixed24 GetAbsYTransformed(IntPtr @event, int height);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,13 @@ namespace OpenTK.Platform.Linux
|
|||
public static extern bool isatty(int fd);
|
||||
}
|
||||
|
||||
enum ErrorNumber
|
||||
{
|
||||
Interrupted = 4,
|
||||
Again = 11,
|
||||
InvalidValue = 22,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum OpenFlags
|
||||
{
|
||||
|
|
|
@ -47,8 +47,7 @@ namespace OpenTK.Platform.Linux
|
|||
IntPtr egl_display;
|
||||
|
||||
IJoystickDriver2 JoystickDriver;
|
||||
IKeyboardDriver2 KeyboardDriver;
|
||||
IMouseDriver2 MouseDriver;
|
||||
LinuxInput MouseKeyboardDriver;
|
||||
|
||||
const string gpu_path = "/dev/dri"; // card0, card1, ...
|
||||
|
||||
|
@ -217,14 +216,18 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
lock (this)
|
||||
{
|
||||
KeyboardDriver = KeyboardDriver ?? new LinuxInput();
|
||||
return KeyboardDriver;
|
||||
MouseKeyboardDriver = MouseKeyboardDriver ?? new LinuxInput();
|
||||
return MouseKeyboardDriver;
|
||||
}
|
||||
}
|
||||
|
||||
public override IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
lock (this)
|
||||
{
|
||||
MouseKeyboardDriver = MouseKeyboardDriver ?? new LinuxInput();
|
||||
return MouseKeyboardDriver;
|
||||
}
|
||||
}
|
||||
|
||||
public override IJoystickDriver2 CreateJoystickDriver()
|
||||
|
|
|
@ -37,17 +37,16 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
class LinuxInput : IKeyboardDriver2, IMouseDriver2, IDisposable
|
||||
{
|
||||
class KeyboardDevice
|
||||
class DeviceBase
|
||||
{
|
||||
readonly IntPtr Device;
|
||||
string name;
|
||||
string output;
|
||||
|
||||
public KeyboardDevice(IntPtr device, int id)
|
||||
public DeviceBase(IntPtr device, int id)
|
||||
{
|
||||
Device = device;
|
||||
Id = id;
|
||||
State.SetIsConnected(true);
|
||||
}
|
||||
|
||||
public int Id
|
||||
|
@ -79,15 +78,28 @@ namespace OpenTK.Platform.Linux
|
|||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
public KeyboardState State;
|
||||
}
|
||||
|
||||
class MouseDevice
|
||||
class KeyboardDevice : DeviceBase
|
||||
{
|
||||
public KeyboardState State;
|
||||
|
||||
public KeyboardDevice(IntPtr device, int id)
|
||||
: base(device, id)
|
||||
{
|
||||
State.SetIsConnected(true);
|
||||
}
|
||||
}
|
||||
|
||||
class MouseDevice : DeviceBase
|
||||
{
|
||||
public int FD;
|
||||
public string Name;
|
||||
public MouseState State;
|
||||
|
||||
public MouseDevice(IntPtr device, int id)
|
||||
: base(device, id)
|
||||
{
|
||||
State.SetIsConnected(true);
|
||||
}
|
||||
}
|
||||
|
||||
static readonly object Sync = new object();
|
||||
|
@ -96,6 +108,11 @@ namespace OpenTK.Platform.Linux
|
|||
DeviceCollection<KeyboardDevice> Keyboards = new DeviceCollection<KeyboardDevice>();
|
||||
DeviceCollection<MouseDevice> Mice = new DeviceCollection<MouseDevice>();
|
||||
|
||||
// Global mouse cursor state
|
||||
Vector2 CursorPosition = Vector2.Zero;
|
||||
// Global mouse cursor offset (used for emulating SetPosition)
|
||||
Vector2 CursorOffset = Vector2.Zero;
|
||||
|
||||
IntPtr udev;
|
||||
IntPtr input_context;
|
||||
InputInterface input_interface = new InputInterface(
|
||||
|
@ -188,15 +205,20 @@ namespace OpenTK.Platform.Linux
|
|||
while (Interlocked.Read(ref exit) == 0)
|
||||
{
|
||||
int ret = Libc.poll(ref poll_fd, 1, -1);
|
||||
ErrorNumber error = (ErrorNumber)Marshal.GetLastWin32Error();
|
||||
bool is_error =
|
||||
ret < 0 && !(error == ErrorNumber.Again || error == ErrorNumber.Interrupted) ||
|
||||
(poll_fd.revents & (PollFlags.Hup | PollFlags.Error | PollFlags.Invalid)) != 0;
|
||||
|
||||
if (ret > 0 && (poll_fd.revents & (PollFlags.In | PollFlags.Pri)) != 0)
|
||||
{
|
||||
ProcessEvents(input_context);
|
||||
}
|
||||
|
||||
if (ret < 0 || (poll_fd.revents & (PollFlags.Hup | PollFlags.Error | PollFlags.Invalid)) != 0)
|
||||
if (is_error)
|
||||
{
|
||||
Debug.Print("[Input] Exiting input loop {0} due to poll error [ret:{1} events:{2}]. Error: {3}.",
|
||||
input_thread.ManagedThreadId, ret, poll_fd.revents, Marshal.GetLastWin32Error());
|
||||
input_thread.ManagedThreadId, ret, poll_fd.revents, error);
|
||||
Interlocked.Increment(ref exit);
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +303,23 @@ namespace OpenTK.Platform.Linux
|
|||
break;
|
||||
|
||||
case InputEventType.KeyboardKey:
|
||||
HandleKeyboard(input_context, device, LibInput.GetKeyboardEvent(pevent));
|
||||
HandleKeyboard(GetKeyboard(device), LibInput.GetKeyboardEvent(pevent));
|
||||
break;
|
||||
|
||||
case InputEventType.PointerAxis:
|
||||
HandlePointerAxis(GetMouse(device), LibInput.GetPointerEvent(pevent));
|
||||
break;
|
||||
|
||||
case InputEventType.PointerButton:
|
||||
HandlePointerButton(GetMouse(device), LibInput.GetPointerEvent(pevent));
|
||||
break;
|
||||
|
||||
case InputEventType.PointerMotion:
|
||||
HandlePointerMotion(GetMouse(device), LibInput.GetPointerEvent(pevent));
|
||||
break;
|
||||
|
||||
case InputEventType.PointerMotionAbsolute:
|
||||
HandlePointerMotionAbsolute(GetMouse(device), LibInput.GetPointerEvent(pevent));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -296,17 +334,19 @@ namespace OpenTK.Platform.Linux
|
|||
{
|
||||
KeyboardDevice keyboard = new KeyboardDevice(device, Keyboards.Count);
|
||||
Keyboards.Add(keyboard.Id, keyboard);
|
||||
Debug.Print("[Linux] libinput: added keyboard device {0}", keyboard.Id);
|
||||
Debug.Print("[Input] Added keyboard device {0}", keyboard.Id);
|
||||
}
|
||||
|
||||
if (LibInput.DeviceHasCapability(device, DeviceCapability.Mouse))
|
||||
{
|
||||
Debug.Print("[Linux] Todo: libinput mouse device.");
|
||||
MouseDevice mouse = new MouseDevice(device, Mice.Count);
|
||||
Mice.Add(mouse.Id, mouse);
|
||||
Debug.Print("[Input] Added mouse device {0}", mouse.Id);
|
||||
}
|
||||
|
||||
if (LibInput.DeviceHasCapability(device, DeviceCapability.Touch))
|
||||
{
|
||||
Debug.Print("[Linux] Todo: libinput touch device.");
|
||||
Debug.Print("[Input] Todo: touch device.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,13 +357,17 @@ namespace OpenTK.Platform.Linux
|
|||
int id = GetId(device);
|
||||
Keyboards.Remove(id);
|
||||
}
|
||||
|
||||
if (LibInput.DeviceHasCapability(device, DeviceCapability.Mouse))
|
||||
{
|
||||
int id = GetId(device);
|
||||
Mice.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleKeyboard(IntPtr context, IntPtr device, KeyboardEvent e)
|
||||
void HandleKeyboard(KeyboardDevice device, KeyboardEvent e)
|
||||
{
|
||||
int id = GetId(device);
|
||||
KeyboardDevice keyboard = Keyboards.FromHardwareId(id);
|
||||
if (keyboard != null)
|
||||
if (device != null)
|
||||
{
|
||||
Key key = Key.Unknown;
|
||||
uint raw = e.Key;
|
||||
|
@ -337,19 +381,89 @@ namespace OpenTK.Platform.Linux
|
|||
Debug.Print("[Linux] Unknown key with code '{0}'", raw);
|
||||
}
|
||||
|
||||
keyboard.State.SetKeyState(key, e.KeyState == KeyState.Pressed);
|
||||
device.State.SetKeyState(key, e.KeyState == KeyState.Pressed);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
void HandlePointerAxis(MouseDevice mouse, PointerEvent e)
|
||||
{
|
||||
if (mouse != null)
|
||||
{
|
||||
Debug.Print("[Linux] libinput ignoring invalid device id {0}", id);
|
||||
double value = e.AxisValue;
|
||||
PointerAxis axis = e.Axis;
|
||||
switch (axis)
|
||||
{
|
||||
case PointerAxis.HorizontalScroll:
|
||||
mouse.State.SetScrollRelative((float)value, 0);
|
||||
break;
|
||||
|
||||
case PointerAxis.VerticalScroll:
|
||||
mouse.State.SetScrollRelative(0, (float)value);
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Print("[Input] Unknown scroll axis {0}.", axis);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePointerButton(MouseDevice mouse, PointerEvent e)
|
||||
{
|
||||
if (mouse != null)
|
||||
{
|
||||
MouseButton button = Evdev.GetMouseButton(e.Button);
|
||||
ButtonState state = e.ButtonState;
|
||||
mouse.State[(MouseButton)button] = state == ButtonState.Pressed;
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePointerMotion(MouseDevice mouse, PointerEvent e)
|
||||
{
|
||||
Vector2 delta = new Vector2((float)e.X, (float)e.Y);
|
||||
if (mouse != null)
|
||||
{
|
||||
mouse.State.Position += delta;
|
||||
}
|
||||
}
|
||||
|
||||
void HandlePointerMotionAbsolute(MouseDevice mouse, PointerEvent e)
|
||||
{
|
||||
Vector2 position = new Vector2(e.X, e.Y);
|
||||
if (mouse != null)
|
||||
{
|
||||
mouse.State.Position = position;
|
||||
}
|
||||
CursorPosition = position; // update global cursor position
|
||||
}
|
||||
|
||||
static int GetId(IntPtr device)
|
||||
{
|
||||
return LibInput.DeviceGetData(device).ToInt32();
|
||||
}
|
||||
|
||||
KeyboardDevice GetKeyboard(IntPtr device)
|
||||
{
|
||||
int id = GetId(device);
|
||||
KeyboardDevice keyboard = Keyboards.FromHardwareId(id);
|
||||
if (keyboard == null)
|
||||
{
|
||||
Debug.Print("[Input] Keyboard {0} does not exist in device list.", id);
|
||||
}
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
MouseDevice GetMouse(IntPtr device)
|
||||
{
|
||||
int id = GetId(device);
|
||||
MouseDevice mouse = Mice.FromHardwareId(id);
|
||||
if (mouse == null)
|
||||
{
|
||||
Debug.Print("[Input] Mouse {0} does not exist in device list.", id);
|
||||
}
|
||||
return mouse;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IKeyboardDriver2 implementation
|
||||
|
@ -405,22 +519,45 @@ namespace OpenTK.Platform.Linux
|
|||
|
||||
MouseState IMouseDriver2.GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
lock (Sync)
|
||||
{
|
||||
MouseState state = new MouseState();
|
||||
foreach (MouseDevice mouse in Mice)
|
||||
{
|
||||
state.MergeBits(mouse.State);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
MouseState IMouseDriver2.GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
lock (Sync)
|
||||
{
|
||||
MouseDevice device = Mice.FromIndex(index);
|
||||
if (device != null)
|
||||
{
|
||||
return device.State;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new MouseState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IMouseDriver2.SetPosition(double x, double y)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// Todo: this does not appear to be supported in libinput.
|
||||
// We will have to emulate this in the KMS mouse rendering code.
|
||||
CursorOffset = new Vector2((float)x, (float)y);
|
||||
}
|
||||
|
||||
MouseState IMouseDriver2.GetCursorState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
MouseState state = (this as IMouseDriver2).GetState();
|
||||
state.Position = CursorPosition + CursorOffset;
|
||||
return state;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
Loading…
Reference in a new issue