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
use core::convert::TryFrom;
use lock::Mutex;
use virtio_drivers::{InputConfigSelect, VirtIOHeader, VirtIOInput as InnerDriver};
use crate::prelude::{CapabilityType, InputCapability, InputEvent, InputEventType};
use crate::scheme::{impl_event_scheme, InputScheme, Scheme};
use crate::utils::EventListener;
use crate::DeviceResult;
pub struct VirtIoInput<'a> {
inner: Mutex<InnerDriver<'a>>,
listener: EventListener<InputEvent>,
}
impl<'a> VirtIoInput<'a> {
pub fn new(header: &'static mut VirtIOHeader) -> DeviceResult<Self> {
let inner = Mutex::new(InnerDriver::new(header)?);
Ok(Self {
inner,
listener: EventListener::new(),
})
}
}
impl_event_scheme!(VirtIoInput<'_>, InputEvent);
impl<'a> Scheme for VirtIoInput<'a> {
fn name(&self) -> &str {
"virtio-input"
}
fn handle_irq(&self, _irq_num: usize) {
let mut inner = self.inner.lock();
inner.ack_interrupt();
while let Some(e) = inner.pop_pending_event() {
if let Ok(event_type) = InputEventType::try_from(e.event_type) {
self.listener.trigger(InputEvent {
event_type,
code: e.code,
value: e.value as i32,
});
}
}
}
}
impl<'a> InputScheme for VirtIoInput<'a> {
fn capability(&self, cap_type: CapabilityType) -> InputCapability {
let mut inner = self.inner.lock();
let mut bitmap = [0u8; 128];
match cap_type {
CapabilityType::InputProp => {
let size = inner.query_config_select(InputConfigSelect::PropBits, 0, &mut bitmap);
InputCapability::from_bitmap(&bitmap[..size as usize])
}
CapabilityType::Event => {
let mut cap = InputCapability::empty();
for i in 0..crate::input::input_event_codes::ev::EV_CNT {
let size =
inner.query_config_select(InputConfigSelect::EvBits, i as u8, &mut bitmap);
if size > 0 {
cap.set(i);
}
}
cap
}
_ => {
let size = inner.query_config_select(
InputConfigSelect::EvBits,
cap_type as u8,
&mut bitmap,
);
InputCapability::from_bitmap(&bitmap[..size as usize])
}
}
}
}