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