ferroui_linuxframebuffer/input/lib_input/
lib_input_native_unsafe_methods.rs1#![allow(non_camel_case_types)]
12
13pub mod lib_input_event_type {
15 pub const LIBINPUT_EVENT_NONE: i32 = 0;
16 pub const LIBINPUT_EVENT_DEVICE_ADDED: i32 = 1;
17 pub const LIBINPUT_EVENT_DEVICE_REMOVED: i32 = 2;
18 pub const LIBINPUT_EVENT_KEYBOARD_KEY: i32 = 300;
19 pub const LIBINPUT_EVENT_POINTER_MOTION: i32 = 400;
20 pub const LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE: i32 = 401;
21 pub const LIBINPUT_EVENT_POINTER_BUTTON: i32 = 402;
22 pub const LIBINPUT_EVENT_POINTER_AXIS: i32 = 403;
23 pub const LIBINPUT_EVENT_POINTER_SCROLL_WHEEL: i32 = 404;
24 pub const LIBINPUT_EVENT_POINTER_SCROLL_FINGER: i32 = 405;
25 pub const LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS: i32 = 406;
26 pub const LIBINPUT_EVENT_TOUCH_DOWN: i32 = 500;
27 pub const LIBINPUT_EVENT_TOUCH_UP: i32 = 501;
28 pub const LIBINPUT_EVENT_TOUCH_MOTION: i32 = 502;
29 pub const LIBINPUT_EVENT_TOUCH_CANCEL: i32 = 503;
30 pub const LIBINPUT_EVENT_TOUCH_FRAME: i32 = 504;
31 pub const LIBINPUT_EVENT_TABLET_TOOL_AXIS: i32 = 600;
32 pub const LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY: i32 = 601;
33 pub const LIBINPUT_EVENT_TABLET_TOOL_TIP: i32 = 602;
34 pub const LIBINPUT_EVENT_TABLET_TOOL_BUTTON: i32 = 603;
35 pub const LIBINPUT_EVENT_TABLET_PAD_BUTTON: i32 = 700;
36 pub const LIBINPUT_EVENT_TABLET_PAD_RING: i32 = 701;
37 pub const LIBINPUT_EVENT_TABLET_PAD_STRIP: i32 = 702;
38 pub const LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN: i32 = 800;
39 pub const LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE: i32 = 801;
40 pub const LIBINPUT_EVENT_GESTURE_SWIPE_END: i32 = 802;
41 pub const LIBINPUT_EVENT_GESTURE_PINCH_BEGIN: i32 = 803;
42 pub const LIBINPUT_EVENT_GESTURE_PINCH_UPDATE: i32 = 804;
43 pub const LIBINPUT_EVENT_GESTURE_PINCH_END: i32 = 805;
44 pub const LIBINPUT_EVENT_SWITCH_TOGGLE: i32 = 900;
45}
46
47pub mod lib_input_pointer_axis_source {
49 pub const LIBINPUT_POINTER_AXIS_SOURCE_WHEEL: i32 = 1;
51 pub const LIBINPUT_POINTER_AXIS_SOURCE_FINGER: i32 = 2;
53 pub const LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS: i32 = 3;
55 pub const LIBINPUT_POINTER_AXIS_SOURCE_WHEEL_TILT: i32 = 4;
58}
59
60pub mod lib_input_pointer_axis {
62 pub const LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL: i32 = 0;
63 pub const LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL: i32 = 1;
64}
65
66#[cfg(target_os = "linux")]
67pub use imp::LibInput;
68
69#[cfg(target_os = "linux")]
70mod imp {
71 use std::ffi::{c_char, c_double, c_int, c_void, CString};
72
73 #[repr(C)]
76 pub(crate) struct libinput_interface {
77 open_restricted: unsafe extern "C" fn(path: *const c_char, flags: c_int, user_data: *mut c_void) -> c_int,
78 close_restricted: unsafe extern "C" fn(fd: c_int, user_data: *mut c_void),
79 }
80
81 unsafe extern "C" fn open_restricted(path: *const c_char, flags: c_int, _user_data: *mut c_void) -> c_int {
82 let fd = unsafe { libc::open(path, flags, 0) };
84 if fd == -1 {
85 return -std::io::Error::last_os_error().raw_os_error().unwrap_or(libc::EIO);
86 }
87 fd
88 }
89
90 unsafe extern "C" fn close_restricted(fd: c_int, _user_data: *mut c_void) {
91 unsafe {
93 libc::close(fd);
94 }
95 }
96
97 static INTERFACE: libinput_interface = libinput_interface { open_restricted, close_restricted };
98
99 ferroui_base::native_functions! {
100 pub struct LibInput(lib) {
102 lib::libinput_path_create_context: unsafe extern "C" fn(*const libinput_interface, *mut c_void) -> *mut c_void;
103 lib::libinput_path_add_device: unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void;
104 lib::libinput_path_remove_device: unsafe extern "C" fn(*mut c_void);
105 lib::libinput_device_config_calibration_set_matrix: unsafe extern "C" fn(*mut c_void, *const f32) -> c_int;
106 lib::libinput_get_fd: unsafe extern "C" fn(*mut c_void) -> c_int;
107 lib::libinput_dispatch: unsafe extern "C" fn(*mut c_void) -> c_int;
108 lib::libinput_get_event: unsafe extern "C" fn(*mut c_void) -> *mut c_void;
109 lib::libinput_event_get_type: unsafe extern "C" fn(*mut c_void) -> c_int;
110 lib::libinput_event_destroy: unsafe extern "C" fn(*mut c_void);
111 lib::libinput_event_get_touch_event: unsafe extern "C" fn(*mut c_void) -> *mut c_void;
112 lib::libinput_event_touch_get_slot: unsafe extern "C" fn(*mut c_void) -> c_int;
113 lib::libinput_event_touch_get_time_usec: unsafe extern "C" fn(*mut c_void) -> u64;
114 lib::libinput_event_touch_get_x_transformed: unsafe extern "C" fn(*mut c_void, u32) -> c_double;
115 lib::libinput_event_touch_get_y_transformed: unsafe extern "C" fn(*mut c_void, u32) -> c_double;
116 lib::libinput_event_get_pointer_event: unsafe extern "C" fn(*mut c_void) -> *mut c_void;
117 lib::libinput_event_pointer_get_time_usec: unsafe extern "C" fn(*mut c_void) -> u64;
118 lib::libinput_event_pointer_get_absolute_x_transformed: unsafe extern "C" fn(*mut c_void, u32) -> c_double;
119 lib::libinput_event_pointer_get_absolute_y_transformed: unsafe extern "C" fn(*mut c_void, u32) -> c_double;
120 lib::libinput_event_pointer_get_button: unsafe extern "C" fn(*mut c_void) -> u32;
121 lib::libinput_event_pointer_get_button_state: unsafe extern "C" fn(*mut c_void) -> c_int;
122 lib::libinput_event_pointer_get_axis_source: unsafe extern "C" fn(*mut c_void) -> c_int;
123 lib::libinput_event_pointer_get_axis_value_discrete: unsafe extern "C" fn(*mut c_void, c_int) -> c_double;
124 lib::libinput_event_pointer_get_scroll_value_v120: unsafe extern "C" fn(*mut c_void, c_int) -> c_double;
125 }
126 }
127
128 pub struct Context<'a> {
131 lib: &'a LibInput,
132 ctx: *mut c_void,
133 }
134
135 pub struct Event<'a> {
137 lib: &'a LibInput,
138 ev: *mut c_void,
139 }
140
141 impl LibInput {
142 pub fn path_create_context(&self) -> Option<Context<'_>> {
145 let ctx = unsafe { (self.libinput_path_create_context)(&INTERFACE, std::ptr::null_mut()) };
148 (!ctx.is_null()).then_some(Context { lib: self, ctx })
149 }
150 }
151
152 impl<'a> Context<'a> {
156 pub fn path_add_device(&self, path: &str, calibration: &[f32; 6]) -> bool {
160 let Ok(path) = CString::new(path) else {
161 return false;
162 };
163 let device = unsafe { (self.lib.libinput_path_add_device)(self.ctx, path.as_ptr()) };
165 if device.is_null() {
166 return false;
167 }
168 unsafe {
171 (self.lib.libinput_device_config_calibration_set_matrix)(device, calibration.as_ptr());
172 }
173 true
174 }
175
176 pub fn get_fd(&self) -> i32 {
177 unsafe { (self.lib.libinput_get_fd)(self.ctx) }
179 }
180
181 pub fn dispatch(&self) {
182 unsafe {
184 (self.lib.libinput_dispatch)(self.ctx);
185 }
186 }
187
188 pub fn get_event(&self) -> Option<Event<'a>> {
189 let ev = unsafe { (self.lib.libinput_get_event)(self.ctx) };
191 (!ev.is_null()).then_some(Event { lib: self.lib, ev })
192 }
193 }
194
195 impl Event<'_> {
196 pub fn get_type(&self) -> i32 {
197 unsafe { (self.lib.libinput_event_get_type)(self.ev) }
199 }
200
201 pub fn touch(&self, with_position: bool, range: u32) -> Option<(i32, u64, f64, f64)> {
205 unsafe {
208 let tev = (self.lib.libinput_event_get_touch_event)(self.ev);
209 if tev.is_null() {
210 return None;
211 }
212 let slot = (self.lib.libinput_event_touch_get_slot)(tev);
213 let time = (self.lib.libinput_event_touch_get_time_usec)(tev);
214 let (x, y) = if with_position {
215 (
216 (self.lib.libinput_event_touch_get_x_transformed)(tev, range),
217 (self.lib.libinput_event_touch_get_y_transformed)(tev, range),
218 )
219 } else {
220 (0.0, 0.0)
221 };
222 Some((slot, time, x, y))
223 }
224 }
225
226 fn pointer(&self) -> *mut c_void {
227 unsafe { (self.lib.libinput_event_get_pointer_event)(self.ev) }
229 }
230
231 pub fn pointer_time_usec(&self) -> u64 {
232 unsafe { (self.lib.libinput_event_pointer_get_time_usec)(self.pointer()) }
234 }
235
236 pub fn pointer_absolute(&self, range: u32) -> (f64, f64) {
238 unsafe {
240 let pev = self.pointer();
241 (
242 (self.lib.libinput_event_pointer_get_absolute_x_transformed)(pev, range),
243 (self.lib.libinput_event_pointer_get_absolute_y_transformed)(pev, range),
244 )
245 }
246 }
247
248 pub fn pointer_button(&self) -> (u32, i32) {
250 unsafe {
252 let pev = self.pointer();
253 (
254 (self.lib.libinput_event_pointer_get_button)(pev),
255 (self.lib.libinput_event_pointer_get_button_state)(pev),
256 )
257 }
258 }
259
260 pub fn pointer_axis(&self) -> (i32, f64) {
263 unsafe {
266 let pev = self.pointer();
267 let source = (self.lib.libinput_event_pointer_get_axis_source)(pev);
268 let value = if source == super::lib_input_pointer_axis_source::LIBINPUT_POINTER_AXIS_SOURCE_WHEEL {
269 (self.lib.libinput_event_pointer_get_axis_value_discrete)(
270 pev,
271 super::lib_input_pointer_axis::LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
272 )
273 } else {
274 0.0
275 };
276 (source, value)
277 }
278 }
279
280 pub fn pointer_scroll_value_v120(&self) -> f64 {
282 unsafe {
284 (self.lib.libinput_event_pointer_get_scroll_value_v120)(
285 self.pointer(),
286 super::lib_input_pointer_axis::LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
287 )
288 }
289 }
290 }
291
292 impl Drop for Event<'_> {
293 fn drop(&mut self) {
294 unsafe {
296 (self.lib.libinput_event_destroy)(self.ev);
297 }
298 }
299 }
300}