1pub mod constants;
8
9use std::mem::size_of;
10
11use constants::*;
12use data_model::Le16;
13use data_model::SLe32;
14use zerocopy::FromBytes;
15use zerocopy::Immutable;
16use zerocopy::IntoBytes;
17use zerocopy::KnownLayout;
18
19pub trait InputEventDecoder {
22 const SIZE: usize;
23 fn decode(data: &[u8]) -> virtio_input_event;
24}
25
26#[derive(
27 Copy, Clone, Debug, Default, Eq, PartialEq, FromBytes, Immutable, IntoBytes, KnownLayout,
28)]
29#[repr(C)]
30pub struct input_event {
31 pub timestamp_fields: [u64; 2],
32 pub type_: u16,
33 pub code: u16,
34 pub value: i32,
35}
36
37impl input_event {
38 pub fn from_virtio_input_event(other: &virtio_input_event) -> input_event {
39 input_event {
40 timestamp_fields: [0, 0],
41 type_: other.type_.into(),
42 code: other.code.into(),
43 value: other.value.into(),
44 }
45 }
46}
47
48impl InputEventDecoder for input_event {
49 const SIZE: usize = size_of::<Self>();
50
51 fn decode(data: &[u8]) -> virtio_input_event {
52 let e = input_event::read_from_bytes(data).unwrap();
53 virtio_input_event {
54 type_: Le16::from(e.type_),
55 code: Le16::from(e.code),
56 value: SLe32::from(e.value),
57 }
58 }
59}
60
61#[derive(
62 Copy, Clone, Debug, Default, Eq, PartialEq, FromBytes, Immutable, IntoBytes, KnownLayout,
63)]
64#[repr(C)]
65pub struct virtio_input_event {
66 pub type_: Le16,
67 pub code: Le16,
68 pub value: SLe32,
69}
70
71impl InputEventDecoder for virtio_input_event {
72 const SIZE: usize = size_of::<Self>();
73
74 fn decode(data: &[u8]) -> virtio_input_event {
75 virtio_input_event::read_from_bytes(data).unwrap()
76 }
77}
78
79impl virtio_input_event {
80 #[inline]
81 pub fn syn() -> virtio_input_event {
82 virtio_input_event {
83 type_: Le16::from(EV_SYN),
84 code: Le16::from(SYN_REPORT),
85 value: SLe32::from(0),
86 }
87 }
88
89 #[inline]
90 pub fn absolute(code: u16, value: i32) -> virtio_input_event {
91 virtio_input_event {
92 type_: Le16::from(EV_ABS),
93 code: Le16::from(code),
94 value: SLe32::from(value),
95 }
96 }
97
98 #[inline]
99 pub fn relative(code: u16, value: i32) -> virtio_input_event {
100 virtio_input_event {
101 type_: Le16::from(EV_REL),
102 code: Le16::from(code),
103 value: SLe32::from(value),
104 }
105 }
106
107 #[inline]
108 pub fn multitouch_tracking_id(id: i32) -> virtio_input_event {
109 Self::absolute(ABS_MT_TRACKING_ID, id)
110 }
111
112 #[inline]
113 pub fn multitouch_slot(slot: i32) -> virtio_input_event {
114 Self::absolute(ABS_MT_SLOT, slot)
115 }
116
117 #[inline]
118 pub fn multitouch_absolute_x(x: i32) -> virtio_input_event {
119 Self::absolute(ABS_MT_POSITION_X, x)
120 }
121
122 #[inline]
123 pub fn multitouch_absolute_y(y: i32) -> virtio_input_event {
124 Self::absolute(ABS_MT_POSITION_Y, y)
125 }
126
127 #[inline]
128 pub fn absolute_x(x: i32) -> virtio_input_event {
129 Self::absolute(ABS_X, x)
130 }
131
132 #[inline]
133 pub fn absolute_y(y: i32) -> virtio_input_event {
134 Self::absolute(ABS_Y, y)
135 }
136
137 #[inline]
138 pub fn relative_x(x: i32) -> virtio_input_event {
139 Self::relative(REL_X, x)
140 }
141
142 #[inline]
143 pub fn relative_y(y: i32) -> virtio_input_event {
144 Self::relative(REL_Y, y)
145 }
146
147 #[inline]
148 pub fn touch(has_contact: bool) -> virtio_input_event {
149 Self::key(BTN_TOUCH, has_contact, false)
150 }
151
152 #[inline]
153 pub fn left_click(has_contact: bool) -> virtio_input_event {
154 Self::key(BTN_LEFT, has_contact, false)
155 }
156
157 #[inline]
158 pub fn wheel(delta: i32) -> virtio_input_event {
159 Self::relative(REL_WHEEL, delta)
160 }
161
162 #[inline]
163 pub fn right_click(has_contact: bool) -> virtio_input_event {
164 Self::key(BTN_RIGHT, has_contact, false)
165 }
166
167 #[inline]
168 pub fn middle_click(has_contact: bool) -> virtio_input_event {
169 Self::key(BTN_MIDDLE, has_contact, false)
170 }
171
172 #[inline]
173 pub fn forward_click(has_contact: bool) -> virtio_input_event {
174 Self::key(BTN_FORWARD, has_contact, false)
175 }
176
177 #[inline]
178 pub fn back_click(has_contact: bool) -> virtio_input_event {
179 Self::key(BTN_BACK, has_contact, false)
180 }
181
182 #[inline]
183 pub fn finger_tool(active: bool) -> virtio_input_event {
184 Self::key(BTN_TOOL_FINGER, active, false)
185 }
186
187 #[inline]
190 pub fn key(code: u16, down: bool, repeat: bool) -> virtio_input_event {
191 virtio_input_event {
192 type_: Le16::from(EV_KEY),
193 code: Le16::from(code),
194 value: SLe32::from(match (down, repeat) {
195 (true, true) => 2,
196 (true, false) => 1,
197 _ => 0,
199 }),
200 }
201 }
202
203 pub fn get_led_state(&self, led_code: u16) -> Option<bool> {
205 if self.type_ == EV_LED && self.code == led_code {
206 return match self.value.to_native() {
207 0 => Some(false),
208 1 => Some(true),
209 _ => None,
210 };
211 }
212 None
213 }
214}