1use crate::enums::*;
2use libc::{c_char, c_uint};
3use log::warn;
4use std::ffi::{CStr, CString};
5use std::fmt;
6
7use evdev_sys as raw;
8
9pub(crate) unsafe fn ptr_to_str(ptr: *const c_char) -> Option<&'static str> {
10 let slice = CStr::from_ptr(ptr.as_ref()?);
11 let buf = slice.to_bytes();
12 std::str::from_utf8(buf).ok()
13}
14
15pub struct EventTypeIterator {
16 current: EventType,
17}
18
19pub struct EventCodeIterator {
20 current: EventCode,
21}
22
23pub struct InputPropIterator {
24 current: InputProp,
25}
26
27pub fn event_code_to_int(event_code: &EventCode) -> (c_uint, c_uint) {
28 match *event_code {
29 EventCode::EV_SYN(code) => (EventType::EV_SYN as c_uint, code as c_uint),
30 EventCode::EV_KEY(code) => (EventType::EV_KEY as c_uint, code as c_uint),
31 EventCode::EV_REL(code) => (EventType::EV_REL as c_uint, code as c_uint),
32 EventCode::EV_ABS(code) => (EventType::EV_ABS as c_uint, code as c_uint),
33 EventCode::EV_MSC(code) => (EventType::EV_MSC as c_uint, code as c_uint),
34 EventCode::EV_SW(code) => (EventType::EV_SW as c_uint, code as c_uint),
35 EventCode::EV_LED(code) => (EventType::EV_LED as c_uint, code as c_uint),
36 EventCode::EV_SND(code) => (EventType::EV_SND as c_uint, code as c_uint),
37 EventCode::EV_REP(code) => (EventType::EV_REP as c_uint, code as c_uint),
38 EventCode::EV_FF(code) => (EventType::EV_FF as c_uint, code as c_uint),
39 EventCode::EV_FF_STATUS(code) => {
40 (EventType::EV_FF_STATUS as c_uint, code as c_uint)
41 }
42 EventCode::EV_UNK {
43 event_type,
44 event_code,
45 } => (event_type as c_uint, event_code as c_uint),
46 _ => {
47 warn!("Event code not found");
48 (0, 0)
49 }
50 }
51}
52
53pub fn int_to_event_code(event_type: c_uint, event_code: c_uint) -> EventCode {
54 let ev_type: EventType = int_to_event_type(event_type as u32).unwrap();
55 let code = event_code as u32;
56
57 let ev_code = match ev_type {
58 EventType::EV_SYN => int_to_ev_syn(code).map(EventCode::EV_SYN),
59 EventType::EV_KEY => int_to_ev_key(code).map(EventCode::EV_KEY),
60 EventType::EV_ABS => int_to_ev_abs(code).map(EventCode::EV_ABS),
61 EventType::EV_REL => int_to_ev_rel(code).map(EventCode::EV_REL),
62 EventType::EV_MSC => int_to_ev_msc(code).map(EventCode::EV_MSC),
63 EventType::EV_SW => int_to_ev_sw(code).map(EventCode::EV_SW),
64 EventType::EV_LED => int_to_ev_led(code).map(EventCode::EV_LED),
65 EventType::EV_SND => int_to_ev_snd(code).map(EventCode::EV_SND),
66 EventType::EV_REP => int_to_ev_rep(code).map(EventCode::EV_REP),
67 EventType::EV_FF => int_to_ev_ff(code).map(EventCode::EV_FF),
68 EventType::EV_PWR => Some(EventCode::EV_PWR),
69 EventType::EV_FF_STATUS => int_to_ev_ff(code).map(EventCode::EV_FF_STATUS),
70 EventType::EV_UNK => None,
71 EventType::EV_MAX => Some(EventCode::EV_MAX),
72 };
73
74 ev_code.unwrap_or(EventCode::EV_UNK {
75 event_type,
76 event_code,
77 })
78}
79
80impl fmt::Display for EventType {
81 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 write!(
83 f,
84 "{}",
85 unsafe { ptr_to_str(raw::libevdev_event_type_get_name(*self as c_uint)) }
86 .unwrap_or("")
87 )
88 }
89}
90
91impl fmt::Display for EventCode {
92 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93 let (ev_type, ev_code) = event_code_to_int(self);
94 write!(
95 f,
96 "{}",
97 unsafe { ptr_to_str(raw::libevdev_event_code_get_name(ev_type, ev_code)) }
98 .unwrap_or("")
99 )
100 }
101}
102
103impl fmt::Display for InputProp {
104 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105 write!(
106 f,
107 "{}",
108 unsafe { ptr_to_str(raw::libevdev_property_get_name(*self as c_uint)) }
109 .unwrap_or("")
110 )
111 }
112}
113
114impl EventType {
115 pub fn iter(&self) -> EventTypeIterator {
116 EventTypeIterator { current: *self }
117 }
118
119 pub fn from_str(name: &str) -> Option<EventType> {
121 let name = CString::new(name).unwrap();
122 let result = unsafe { raw::libevdev_event_type_from_name(name.as_ptr()) };
123
124 match result {
125 -1 => None,
126 k => int_to_event_type(k as u32),
127 }
128 }
129
130 pub fn get_max(ev_type: &EventType) -> Option<i32> {
133 let result = unsafe { raw::libevdev_event_type_get_max(*ev_type as c_uint) };
134
135 match result {
136 -1 => None,
137 k => Some(k),
138 }
139 }
140}
141
142impl EventCode {
143 pub fn iter(&self) -> EventCodeIterator {
144 EventCodeIterator { current: *self }
145 }
146
147 pub fn from_str(ev_type: &EventType, name: &str) -> Option<EventCode> {
152 let name = CString::new(name).unwrap();
153 let result = unsafe {
154 raw::libevdev_event_code_from_name(*ev_type as c_uint, name.as_ptr())
155 };
156
157 match result {
158 -1 => None,
159 k => Some(int_to_event_code(*ev_type as u32, k as u32)),
160 }
161 }
162}
163
164impl InputProp {
165 pub fn iter(&self) -> InputPropIterator {
166 InputPropIterator { current: *self }
167 }
168
169 pub fn from_str(name: &str) -> Option<InputProp> {
174 let name = CString::new(name).unwrap();
175 let result = unsafe { raw::libevdev_property_from_name(name.as_ptr()) };
176
177 match result {
178 -1 => None,
179 k => int_to_input_prop(k as u32),
180 }
181 }
182}
183
184impl Iterator for EventTypeIterator {
186 type Item = EventType;
187
188 fn next(&mut self) -> Option<EventType> {
189 match self.current {
190 EventType::EV_MAX => None,
191 _ => {
192 let mut raw_code = (self.current as u32) + 1;
193 loop {
194 match int_to_event_type(raw_code) {
195 Some(EventType::EV_UNK) => raw_code += 1,
197 Some(x) => {
198 let code = self.current;
199 self.current = x;
200 return Some(code);
201 }
202 None => raw_code += 1,
203 }
204 }
205 }
206 }
207 }
208}
209
210impl Iterator for EventCodeIterator {
211 type Item = EventCode;
212
213 fn next(&mut self) -> Option<EventCode> {
214 match self.current {
215 EventCode::EV_SYN(code) => match code {
216 EV_SYN::SYN_MAX => {
217 let ev_code = self.current;
218 self.current = EventCode::EV_KEY(EV_KEY::KEY_RESERVED);
219 Some(ev_code)
220 }
221 _ => {
222 let mut raw_code = (code as u32) + 1;
223 loop {
224 match int_to_ev_syn(raw_code) {
225 Some(x) => {
226 let ev_code = self.current;
227 self.current = EventCode::EV_SYN(x);
228 return Some(ev_code);
229 }
230 None => raw_code += 1,
231 }
232 }
233 }
234 },
235 EventCode::EV_KEY(code) => match code {
236 EV_KEY::KEY_MAX => {
237 let ev_code = self.current;
238 self.current = EventCode::EV_REL(EV_REL::REL_X);
239 Some(ev_code)
240 }
241 _ => {
242 let mut raw_code = (code as u32) + 1;
243 loop {
244 match int_to_ev_key(raw_code) {
245 Some(x) => {
246 let ev_code = self.current;
247 self.current = EventCode::EV_KEY(x);
248 return Some(ev_code);
249 }
250 None => raw_code += 1,
251 }
252 }
253 }
254 },
255 EventCode::EV_REL(code) => match code {
256 EV_REL::REL_MAX => {
257 let ev_code = self.current;
258 self.current = EventCode::EV_ABS(EV_ABS::ABS_X);
259 Some(ev_code)
260 }
261 _ => {
262 let mut raw_code = (code as u32) + 1;
263 loop {
264 match int_to_ev_rel(raw_code) {
265 Some(x) => {
266 let ev_code = self.current;
267 self.current = EventCode::EV_REL(x);
268 return Some(ev_code);
269 }
270 None => raw_code += 1,
271 }
272 }
273 }
274 },
275 EventCode::EV_ABS(code) => match code {
276 EV_ABS::ABS_MAX => {
277 let ev_code = self.current;
278 self.current = EventCode::EV_MSC(EV_MSC::MSC_SERIAL);
279 Some(ev_code)
280 }
281 _ => {
282 let mut raw_code = (code as u32) + 1;
283 loop {
284 match int_to_ev_abs(raw_code) {
285 Some(x) => {
286 let ev_code = self.current;
287 self.current = EventCode::EV_ABS(x);
288 return Some(ev_code);
289 }
290 None => raw_code += 1,
291 }
292 }
293 }
294 },
295 EventCode::EV_MSC(code) => match code {
296 EV_MSC::MSC_MAX => {
297 let ev_code = self.current;
298 self.current = EventCode::EV_SW(EV_SW::SW_LID);
299 Some(ev_code)
300 }
301 _ => {
302 let mut raw_code = (code as u32) + 1;
303 loop {
304 match int_to_ev_msc(raw_code) {
305 Some(x) => {
306 let ev_code = self.current;
307 self.current = EventCode::EV_MSC(x);
308 return Some(ev_code);
309 }
310 None => raw_code += 1,
311 }
312 }
313 }
314 },
315 EventCode::EV_SW(code) => match code {
316 EV_SW::SW_MAX => {
317 let ev_code = self.current;
318 self.current = EventCode::EV_LED(EV_LED::LED_NUML);
319 Some(ev_code)
320 }
321 _ => {
322 let mut raw_code = (code as u32) + 1;
323 loop {
324 match int_to_ev_sw(raw_code) {
325 Some(x) => {
326 let ev_code = self.current;
327 self.current = EventCode::EV_SW(x);
328 return Some(ev_code);
329 }
330 None => raw_code += 1,
331 }
332 }
333 }
334 },
335 EventCode::EV_LED(code) => match code {
336 EV_LED::LED_MAX => {
337 let ev_code = self.current;
338 self.current = EventCode::EV_SND(EV_SND::SND_CLICK);
339 Some(ev_code)
340 }
341 _ => {
342 let mut raw_code = (code as u32) + 1;
343 loop {
344 match int_to_ev_led(raw_code) {
345 Some(x) => {
346 let ev_code = self.current;
347 self.current = EventCode::EV_LED(x);
348 return Some(ev_code);
349 }
350 None => raw_code += 1,
351 }
352 }
353 }
354 },
355 EventCode::EV_SND(code) => match code {
356 EV_SND::SND_MAX => {
357 let ev_code = self.current;
358 self.current = EventCode::EV_REP(EV_REP::REP_DELAY);
359 Some(ev_code)
360 }
361 _ => {
362 let mut raw_code = (code as u32) + 1;
363 loop {
364 match int_to_ev_snd(raw_code) {
365 Some(x) => {
366 let ev_code = self.current;
367 self.current = EventCode::EV_SND(x);
368 return Some(ev_code);
369 }
370 None => raw_code += 1,
371 }
372 }
373 }
374 },
375 EventCode::EV_REP(code) => match code {
376 EV_REP::REP_MAX => {
377 let ev_code = self.current;
378 self.current = EventCode::EV_FF(EV_FF::FF_STATUS_STOPPED);
379 Some(ev_code)
380 }
381 _ => {
382 let mut raw_code = (code as u32) + 1;
383 loop {
384 match int_to_ev_rep(raw_code) {
385 Some(x) => {
386 let ev_code = self.current;
387 self.current = EventCode::EV_REP(x);
388 return Some(ev_code);
389 }
390 None => raw_code += 1,
391 }
392 }
393 }
394 },
395 EventCode::EV_FF(code) => match code {
396 EV_FF::FF_MAX => None,
397 _ => {
398 let mut raw_code = (code as u32) + 1;
399 loop {
400 match int_to_ev_ff(raw_code) {
401 Some(x) => {
402 let ev_code = self.current;
403 self.current = EventCode::EV_FF(x);
404 return Some(ev_code);
405 }
406 None => raw_code += 1,
407 }
408 }
409 }
410 },
411 _ => None,
412 }
413 }
414}
415
416impl Iterator for InputPropIterator {
417 type Item = InputProp;
418
419 fn next(&mut self) -> Option<InputProp> {
420 match self.current {
421 InputProp::INPUT_PROP_MAX => None,
422 _ => {
423 let mut raw_enum = (self.current as u32) + 1;
424 loop {
425 match int_to_input_prop(raw_enum) {
426 Some(x) => {
427 let prop = self.current;
428 self.current = x;
429 return Some(prop);
430 }
431 None => raw_enum += 1,
432 }
433 }
434 }
435 }
436 }
437}