Skip to content

Commit 2040166

Browse files
committed
feat: add evdev.device
1 parent 6d3217e commit 2040166

File tree

1 file changed

+270
-0
lines changed

1 file changed

+270
-0
lines changed

evdev/device.lua

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
local ffi = require("ffi")
2+
3+
local Event = require("evdev.event")
4+
local evdev = require("evdev.libevdev")
5+
local util = require("evdev.util")
6+
7+
local libevdev_grab_mode = evdev.enum.libevdev_grab_mode
8+
local libevdev_read_flag = evdev.enum.libevdev_read_flag
9+
local open_flag = util.enum.open_flag
10+
11+
---@class Device
12+
---@field fd number
13+
---@field pathname string
14+
---@field dev ffi.cdata*
15+
local Device = {}
16+
17+
---@param pathname string
18+
---@param flags number[] `open_flag[]`
19+
---@return Device
20+
local function init(class, pathname, flags)
21+
---@type Device
22+
local self = setmetatable({}, { __index = class })
23+
24+
self.pathname = pathname
25+
26+
local fd = util.open_file(pathname, flags or { open_flag.RDONLY, open_flag.NONBLOCK })
27+
if fd < 0 then
28+
return nil, string.format("Error: %s", util.err_string(ffi.errno()))
29+
end
30+
31+
self.fd = fd
32+
33+
local dev_ptr = ffi.new("struct libevdev *[1]")
34+
35+
local rc = evdev.libevdev_new_from_fd(fd, dev_ptr)
36+
if rc < 0 then
37+
return nil, string.format("Error: %s", util.err_string(-rc))
38+
end
39+
40+
self.dev = dev_ptr[0]
41+
42+
ffi.gc(dev_ptr, evdev.libevdev_free)
43+
44+
return self
45+
end
46+
47+
---@param pathname string
48+
---@param flags number[] `open_flag[]`
49+
---@return Device
50+
function Device:new(pathname, flags)
51+
return init(self, pathname, flags)
52+
end
53+
54+
---@param mode boolean|number `libevdev_grab_mode`
55+
---@return number
56+
function Device:grab(mode)
57+
if mode == true then
58+
mode = libevdev_grab_mode.GRAB
59+
elseif mode == false then
60+
mode = libevdev_grab_mode.UNGRAB
61+
end
62+
63+
return evdev.libevdev_grab(self.dev, mode)
64+
end
65+
66+
---@param flags? number|number[] `libevdev_read_flag` or `libevdev_read_flag[]` (default: `NORMAL`)
67+
---@param event? Event
68+
---@return number rc, Event event
69+
function Device:next_event(flags, event)
70+
local flag = util.bit_or(flags or libevdev_read_flag.NORMAL)
71+
event = event or Event:new()
72+
local rc = evdev.libevdev_next_event(self.dev, flag, event.ev)
73+
return rc, event
74+
end
75+
76+
---@return boolean
77+
function Device:has_event_pending()
78+
return evdev.libevdev_has_event_pending(self.dev) == 1
79+
end
80+
81+
---@return string
82+
function Device:name()
83+
return util.to_string(evdev.libevdev_get_name(self.dev))
84+
end
85+
86+
---@return string
87+
function Device:phys()
88+
return util.to_string(evdev.libevdev_get_phys(self.dev))
89+
end
90+
91+
---@return string
92+
function Device:uniq()
93+
return util.to_string(evdev.libevdev_get_uniq(self.dev))
94+
end
95+
96+
---@return number
97+
function Device:id_product()
98+
return evdev.libevdev_get_id_product(self.dev)
99+
end
100+
101+
---@return number
102+
function Device:id_vendor()
103+
return evdev.libevdev_get_id_vendor(self.dev)
104+
end
105+
106+
---@return number
107+
function Device:id_bustype()
108+
return evdev.libevdev_get_id_bustype(self.dev)
109+
end
110+
111+
---@return number
112+
function Device:id_version()
113+
return evdev.libevdev_get_id_version(self.dev)
114+
end
115+
116+
---@return number
117+
function Device:driver_version()
118+
return evdev.libevdev_get_driver_version(self.dev)
119+
end
120+
121+
---@param prop number
122+
---@return boolean
123+
function Device:has_property(prop)
124+
return evdev.libevdev_has_property(self.dev, prop) == 1
125+
end
126+
127+
---@param prop number
128+
---@return number
129+
function Device:enable_property(prop)
130+
return evdev.libevdev_enable_property(self.dev, prop)
131+
end
132+
133+
---@param prop number
134+
---@return number
135+
function Device:disable_property(prop)
136+
return evdev.libevdev_disable_property(self.dev, prop)
137+
end
138+
139+
---@param ev_type number
140+
---@return boolean
141+
function Device:has_event_type(ev_type)
142+
return evdev.libevdev_has_event_type(self.dev, ev_type) == 1
143+
end
144+
145+
---@param ev_type number
146+
---@param ev_code number
147+
---@return boolean
148+
function Device:has_event_code(ev_type, ev_code)
149+
return evdev.libevdev_has_event_code(self.dev, ev_type, ev_code) == 1
150+
end
151+
152+
---@param code number
153+
---@return number
154+
function Device:abs_minimum(code)
155+
return evdev.libevdev_get_abs_minimum(self.dev, code)
156+
end
157+
158+
---@param code number
159+
---@return number
160+
function Device:abs_maximum(code)
161+
return evdev.libevdev_get_abs_maximum(self.dev, code)
162+
end
163+
164+
---@param code number
165+
---@return number
166+
function Device:abs_fuzz(code)
167+
return evdev.libevdev_get_abs_fuzz(self.dev, code)
168+
end
169+
170+
---@param code number
171+
---@return number
172+
function Device:abs_flat(code)
173+
return evdev.libevdev_get_abs_flat(self.dev, code)
174+
end
175+
176+
---@param code number
177+
---@return number
178+
function Device:abs_resolution(code)
179+
return evdev.libevdev_get_abs_resolution(self.dev, code)
180+
end
181+
182+
---@param code number
183+
---@return ffi.cdata*|evdev_input_absinfo
184+
function Device:abs_info(code)
185+
return evdev.libevdev_get_abs_info(self.dev, code)
186+
end
187+
188+
---@param ev_type number
189+
---@param code number
190+
---@return number
191+
function Device:event_value(ev_type, code)
192+
return evdev.libevdev_get_event_value(self.dev, ev_type, code)
193+
end
194+
195+
---@param ev_type number
196+
---@param code number
197+
---@param value_ptr? ffi.cdata*
198+
---@return number|nil
199+
function Device:fetch_event_value(ev_type, code, value_ptr)
200+
value_ptr = value_ptr or ffi.new("int[1]")
201+
local rc = evdev.libevdev_fetch_event_value(self.dev, ev_type, code, value_ptr)
202+
if rc ~= 0 then
203+
return value_ptr[0]
204+
end
205+
end
206+
207+
---@param slot number
208+
---@param code number
209+
---@return number
210+
function Device:slot_value(slot, code)
211+
return evdev.libevdev_get_slot_value(self.dev, slot, code)
212+
end
213+
214+
---@param slot number
215+
---@param code number
216+
---@param value_ptr? ffi.cdata*
217+
---@return number|nil
218+
function Device:fetch_slot_value(slot, code, value_ptr)
219+
value_ptr = value_ptr or ffi.new("int[1]")
220+
local rc = evdev.libevdev_fetch_slot_value(self.dev, slot, code, value_ptr)
221+
if rc ~= 0 then
222+
return value_ptr[0]
223+
end
224+
end
225+
226+
---@return number
227+
function Device:num_slots()
228+
return evdev.libevdev_get_num_slots(self.dev)
229+
end
230+
231+
---@return number
232+
function Device:current_slot()
233+
return evdev.libevdev_get_current_slot(self.dev)
234+
end
235+
236+
---@param ev_type number
237+
---@return number
238+
function Device:enable_event_type(ev_type)
239+
return evdev.libevdev_enable_event_type(self.dev, ev_type)
240+
end
241+
242+
---@param ev_type number
243+
---@return number
244+
function Device:disable_event_type(ev_type)
245+
return evdev.libevdev_disable_event_type(self.dev, ev_type)
246+
end
247+
248+
---@param ev_type number
249+
---@param code number
250+
---@param data? nil|ffi.cdata*|evdev_input_absinfo|number
251+
---@return number
252+
function Device:enable_event_code(ev_type, code, data)
253+
local data_type = type(data)
254+
if data_type == "number" then
255+
data = ffi.new("int", data)
256+
elseif data_type == "table" then
257+
data = ffi.new("struct input_absinfo", data)
258+
end
259+
260+
return evdev.libevdev_enable_event_code(self.dev, ev_type, code, data)
261+
end
262+
263+
---@param ev_type number
264+
---@param code number
265+
---@return number
266+
function Device:disable_event_code(ev_type, code)
267+
return evdev.libevdev_disable_event_code(self.dev, ev_type, code)
268+
end
269+
270+
return Device

0 commit comments

Comments
 (0)