1 // Copyright 2019 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use base::{ioctl_ior_nr, ioctl_iow_nr, ioctl_with_mut_ref, ioctl_with_ptr, ioctl_with_ref};
6 use data_model::Le32;
7
8 use super::constants::*;
9 use super::virtio_input_absinfo;
10 use super::virtio_input_bitmap;
11 use super::virtio_input_device_ids;
12 use super::InputError;
13 use super::Result;
14
15 use std::collections::BTreeMap;
16 use std::os::raw::c_uint;
17 use std::ptr::null;
18
19 use base::{AsRawDescriptor, Descriptor};
20
21 const EVDEV: c_uint = 69;
22
23 #[repr(C)]
24 #[derive(Copy, Clone)]
25 struct evdev_buffer {
26 buffer: [std::os::raw::c_uchar; 128],
27 }
28
29 impl evdev_buffer {
new() -> evdev_buffer30 fn new() -> evdev_buffer {
31 evdev_buffer { buffer: [0u8; 128] }
32 }
33
get(&self, bit: usize) -> bool34 fn get(&self, bit: usize) -> bool {
35 let idx = bit / 8;
36 let inner_bit = bit % 8;
37 self.buffer
38 .get(idx)
39 .map_or(false, |val| val & (1u8 << inner_bit) != 0)
40 }
41 }
42
43 #[repr(C)]
44 #[derive(Copy, Clone)]
45 struct evdev_id {
46 bustype: u16,
47 vendor: u16,
48 product: u16,
49 version: u16,
50 }
51
52 impl evdev_id {
new() -> evdev_id53 fn new() -> evdev_id {
54 evdev_id {
55 bustype: 0,
56 vendor: 0,
57 product: 0,
58 version: 0,
59 }
60 }
61 }
62
63 #[repr(C)]
64 #[derive(Copy, Clone)]
65 struct evdev_abs_info {
66 // These should technically by signed ints, but Le32 is only compatible with u32 and we only
67 // forward the bytes but don't care about its actual values.
68 value: u32,
69 minimum: u32,
70 maximum: u32,
71 fuzz: u32,
72 flat: u32,
73 resolution: u32,
74 }
75
76 impl evdev_abs_info {
new() -> evdev_abs_info77 fn new() -> evdev_abs_info {
78 evdev_abs_info {
79 value: 0,
80 minimum: 0,
81 maximum: 0,
82 fuzz: 0,
83 flat: 0,
84 resolution: 0,
85 }
86 }
87 }
88
89 impl From<evdev_abs_info> for virtio_input_absinfo {
from(other: evdev_abs_info) -> Self90 fn from(other: evdev_abs_info) -> Self {
91 virtio_input_absinfo {
92 min: Le32::from(other.minimum),
93 max: Le32::from(other.maximum),
94 fuzz: Le32::from(other.fuzz),
95 flat: Le32::from(other.flat),
96 }
97 }
98 }
99
100 ioctl_ior_nr!(EVIOCGID, EVDEV, 0x02, evdev_id);
101 ioctl_ior_nr!(EVIOCGNAME, EVDEV, 0x06, evdev_buffer);
102 ioctl_ior_nr!(EVIOCGUNIQ, EVDEV, 0x08, evdev_buffer);
103 ioctl_ior_nr!(EVIOCGPROP, EVDEV, 0x09, evdev_buffer);
104 ioctl_ior_nr!(EVIOCGBIT, EVDEV, 0x20 + evt, evdev_buffer, evt);
105 ioctl_ior_nr!(EVIOCGABS, EVDEV, 0x40 + abs, evdev_abs_info, abs);
106 ioctl_iow_nr!(EVIOCGRAB, EVDEV, 0x90, u32);
107
errno() -> base::Error108 fn errno() -> base::Error {
109 base::Error::last()
110 }
111
112 /// Gets id information from an event device (see EVIOCGID ioctl for details).
device_ids<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_device_ids>113 pub fn device_ids<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_device_ids> {
114 let mut dev_id = evdev_id::new();
115 let len = unsafe {
116 // Safe because the kernel won't write more than size of evdev_id and we check the return
117 // value
118 ioctl_with_mut_ref(
119 &Descriptor(descriptor.as_raw_descriptor()),
120 EVIOCGID(),
121 &mut dev_id,
122 )
123 };
124 if len < 0 {
125 return Err(InputError::EvdevIdError(errno()));
126 }
127 Ok(virtio_input_device_ids::new(
128 dev_id.bustype,
129 dev_id.vendor,
130 dev_id.product,
131 dev_id.version,
132 ))
133 }
134
135 /// Gets the name of an event device (see EVIOCGNAME ioctl for details).
name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>>136 pub fn name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>> {
137 let mut name = evdev_buffer::new();
138 let len = unsafe {
139 // Safe because the kernel won't write more than size of evdev_buffer and we check the
140 // return value
141 ioctl_with_mut_ref(
142 &Descriptor(descriptor.as_raw_descriptor()),
143 EVIOCGNAME(),
144 &mut name,
145 )
146 };
147 if len < 0 {
148 return Err(InputError::EvdevNameError(errno()));
149 }
150 Ok(name.buffer[0..len as usize].to_vec())
151 }
152
153 /// Gets the unique (serial) name of an event device (see EVIOCGUNIQ ioctl for details).
serial_name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>>154 pub fn serial_name<T: AsRawDescriptor>(descriptor: &T) -> Result<Vec<u8>> {
155 let mut uniq = evdev_buffer::new();
156 let len = unsafe {
157 // Safe because the kernel won't write more than size of evdev_buffer and we check the
158 // return value
159 ioctl_with_mut_ref(
160 &Descriptor(descriptor.as_raw_descriptor()),
161 EVIOCGUNIQ(),
162 &mut uniq,
163 )
164 };
165 if len < 0 {
166 return Err(InputError::EvdevSerialError(errno()));
167 }
168 Ok(uniq.buffer[0..len as usize].to_vec())
169 }
170
171 /// Gets the properties of an event device (see EVIOCGPROP ioctl for details).
properties<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_bitmap>172 pub fn properties<T: AsRawDescriptor>(descriptor: &T) -> Result<virtio_input_bitmap> {
173 let mut props = evdev_buffer::new();
174 let len = unsafe {
175 // Safe because the kernel won't write more than size of evdev_buffer and we check the
176 // return value
177 ioctl_with_mut_ref(
178 &Descriptor(descriptor.as_raw_descriptor()),
179 EVIOCGPROP(),
180 &mut props,
181 )
182 };
183 if len < 0 {
184 return Err(InputError::EvdevPropertiesError(errno()));
185 }
186 Ok(virtio_input_bitmap::new(props.buffer))
187 }
188
189 /// Gets the event types supported by an event device as well as the event codes supported for each
190 /// type (see EVIOCGBIT ioctl for details).
supported_events<T: AsRawDescriptor>( descriptor: &T, ) -> Result<BTreeMap<u16, virtio_input_bitmap>>191 pub fn supported_events<T: AsRawDescriptor>(
192 descriptor: &T,
193 ) -> Result<BTreeMap<u16, virtio_input_bitmap>> {
194 let mut evts: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new();
195
196 let mut evt_types = evdev_buffer::new();
197 let len = unsafe {
198 // Safe because the kernel won't write more than size of evdev_buffer and we check the
199 // return value
200 ioctl_with_mut_ref(
201 &Descriptor(descriptor.as_raw_descriptor()),
202 EVIOCGBIT(0),
203 &mut evt_types,
204 )
205 };
206 if len < 0 {
207 return Err(InputError::EvdevEventTypesError(errno()));
208 }
209
210 // no need to ask for zero (EV_SYN) since it's always supported and treated as a special case
211 for ev in 1..EV_MAX {
212 if ev == EV_REP || !evt_types.get(ev as usize) {
213 // Event type not supported, skip it.
214 continue;
215 }
216 // Create a new zero-filled buffer every time to avoid carry-overs.
217 let mut evt_codes = evdev_buffer::new();
218 let len = unsafe {
219 // Safe because the kernel won't write more than size of evdev_buffer and we check the
220 // return value
221 ioctl_with_mut_ref(
222 &Descriptor(descriptor.as_raw_descriptor()),
223 EVIOCGBIT(ev as c_uint),
224 &mut evt_codes,
225 )
226 };
227 if len < 0 {
228 return Err(InputError::EvdevEventTypesError(errno()));
229 }
230 evts.insert(ev, virtio_input_bitmap::new(evt_codes.buffer));
231 }
232 Ok(evts)
233 }
234
235 /// Gets the absolute axes of an event device (see EVIOCGABS ioctl for details).
abs_info<T: AsRawDescriptor>(descriptor: &T) -> BTreeMap<u16, virtio_input_absinfo>236 pub fn abs_info<T: AsRawDescriptor>(descriptor: &T) -> BTreeMap<u16, virtio_input_absinfo> {
237 let mut ret: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new();
238
239 for abs in 0..ABS_MAX {
240 // Create a new one, zero-ed out every time to avoid carry-overs.
241 let mut abs_info = evdev_abs_info::new();
242 let len = unsafe {
243 // Safe because the kernel won't write more than size of evdev_buffer and we check the
244 // return value
245 ioctl_with_mut_ref(
246 &Descriptor(descriptor.as_raw_descriptor()),
247 EVIOCGABS(abs as c_uint),
248 &mut abs_info,
249 )
250 };
251 if len > 0 {
252 ret.insert(abs, virtio_input_absinfo::from(abs_info));
253 }
254 }
255 ret
256 }
257
258 /// Grabs an event device (see EVIOCGGRAB ioctl for details). After this function succeeds the given
259 /// descriptor has exclusive access to the device, effectively making it unusable for any other process in
260 /// the host.
grab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()>261 pub fn grab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()> {
262 let val: u32 = 1;
263 let ret = unsafe {
264 // Safe because the kernel only read the value of the ptr and we check the return value
265 ioctl_with_ref(
266 &Descriptor(descriptor.as_raw_descriptor()),
267 EVIOCGRAB(),
268 &val,
269 )
270 };
271 if ret == 0 {
272 Ok(())
273 } else {
274 Err(InputError::EvdevGrabError(errno()))
275 }
276 }
277
ungrab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()>278 pub fn ungrab_evdev<T: AsRawDescriptor>(descriptor: &mut T) -> Result<()> {
279 let ret = unsafe {
280 // Safe because the kernel only reads the value of the ptr (doesn't dereference) and
281 // we check the return value
282 ioctl_with_ptr(
283 &Descriptor(descriptor.as_raw_descriptor()),
284 EVIOCGRAB(),
285 null::<u32>(),
286 )
287 };
288 if ret == 0 {
289 Ok(())
290 } else {
291 Err(InputError::EvdevGrabError(errno()))
292 }
293 }
294