forked from AvaloniaUI/Avalonia
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEvDevDevice.cs
More file actions
88 lines (76 loc) · 2.81 KB
/
EvDevDevice.cs
File metadata and controls
88 lines (76 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace Avalonia.LinuxFramebuffer
{
unsafe class EvDevDevice
{
private static readonly Lazy<List<EvDevDevice>> AllMouseDevices = new Lazy<List<EvDevDevice>>(()
=> OpenMouseDevices());
private static List<EvDevDevice> OpenMouseDevices()
{
var rv = new List<EvDevDevice>();
foreach (var dev in Directory.GetFiles("/dev/input", "event*").Select(Open))
{
if (!dev.IsMouse)
NativeUnsafeMethods.close(dev.Fd);
else
rv.Add(dev);
}
return rv;
}
public static IReadOnlyList<EvDevDevice> MouseDevices => AllMouseDevices.Value;
public int Fd { get; }
private IntPtr _dev;
public string Name { get; }
public List<EvType> EventTypes { get; private set; } = new List<EvType>();
public input_absinfo? AbsX { get; }
public input_absinfo? AbsY { get; }
public EvDevDevice(int fd, IntPtr dev)
{
Fd = fd;
_dev = dev;
Name = Marshal.PtrToStringAnsi(NativeUnsafeMethods.libevdev_get_name(_dev));
foreach (EvType type in Enum.GetValues(typeof(EvType)))
{
if (NativeUnsafeMethods.libevdev_has_event_type(dev, type) != 0)
EventTypes.Add(type);
}
var ptr = NativeUnsafeMethods.libevdev_get_abs_info(dev, (int) AbsAxis.ABS_X);
if (ptr != null)
AbsX = *ptr;
ptr = NativeUnsafeMethods.libevdev_get_abs_info(dev, (int)AbsAxis.ABS_Y);
if (ptr != null)
AbsY = *ptr;
}
public input_event? NextEvent()
{
input_event ev;
if (NativeUnsafeMethods.libevdev_next_event(_dev, 2, out ev) == 0)
return ev;
return null;
}
public bool IsMouse => EventTypes.Contains(EvType.EV_REL);
public static EvDevDevice Open(string device)
{
var fd = NativeUnsafeMethods.open(device, 2048, 0);
if (fd <= 0)
throw new Exception($"Unable to open {device} code {Marshal.GetLastWin32Error()}");
IntPtr dev;
var rc = NativeUnsafeMethods.libevdev_new_from_fd(fd, out dev);
if (rc < 0)
{
NativeUnsafeMethods.close(fd);
throw new Exception($"Unable to initialize evdev for {device} code {Marshal.GetLastWin32Error()}");
}
return new EvDevDevice(fd, dev);
}
}
public class EvDevAxisInfo
{
public int Minimum { get; set; }
public int Maximum { get; set; }
}
}