gpu_display/
event_device.rs

1// Copyright 2019 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::collections::VecDeque;
6use std::fmt;
7use std::io;
8use std::io::Read;
9use std::io::Write;
10use std::iter::ExactSizeIterator;
11
12use base::AsRawDescriptor;
13use base::RawDescriptor;
14use base::ReadNotifier;
15use base::StreamChannel;
16use linux_input_sys::virtio_input_event;
17use linux_input_sys::InputEventDecoder;
18use serde::Deserialize;
19use serde::Serialize;
20use zerocopy::FromZeros;
21use zerocopy::IntoBytes;
22
23const EVENT_SIZE: usize = virtio_input_event::SIZE;
24const EVENT_BUFFER_LEN_MAX: usize = 64 * EVENT_SIZE;
25
26#[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
27pub enum EventDeviceKind {
28    /// Produces relative mouse motions, wheel, and button clicks while the real mouse is captured.
29    Mouse,
30    /// Produces absolute motion and touch events from the display window's events.
31    Touchscreen,
32    /// Produces key events while the display window has focus.
33    Keyboard,
34}
35
36/// Encapsulates a virtual event device, such as a mouse or keyboard
37#[derive(Deserialize, Serialize)]
38pub struct EventDevice {
39    kind: EventDeviceKind,
40    event_buffer: VecDeque<u8>,
41    event_socket: StreamChannel,
42}
43
44impl EventDevice {
45    pub fn new(kind: EventDeviceKind, mut event_socket: StreamChannel) -> EventDevice {
46        let _ = event_socket.set_nonblocking(true);
47        EventDevice {
48            kind,
49            event_buffer: Default::default(),
50            event_socket,
51        }
52    }
53
54    #[inline]
55    pub fn mouse(event_socket: StreamChannel) -> EventDevice {
56        Self::new(EventDeviceKind::Mouse, event_socket)
57    }
58
59    #[inline]
60    pub fn touchscreen(event_socket: StreamChannel) -> EventDevice {
61        Self::new(EventDeviceKind::Touchscreen, event_socket)
62    }
63
64    #[inline]
65    pub fn keyboard(event_socket: StreamChannel) -> EventDevice {
66        Self::new(EventDeviceKind::Keyboard, event_socket)
67    }
68
69    #[inline]
70    pub fn kind(&self) -> EventDeviceKind {
71        self.kind
72    }
73
74    /// Flushes the buffered events that did not fit into the underlying transport, if any.
75    ///
76    /// Returns `Ok(true)` if, after this function returns, there all the buffer of events is
77    /// empty.
78    pub fn flush_buffered_events(&mut self) -> io::Result<bool> {
79        while !self.event_buffer.is_empty() {
80            let written = self.event_socket.write(self.event_buffer.as_slices().0)?;
81            if written == 0 {
82                return Ok(false);
83            }
84            self.event_buffer.drain(..written);
85        }
86        Ok(true)
87    }
88
89    pub fn is_buffered_events_empty(&self) -> bool {
90        self.event_buffer.is_empty()
91    }
92
93    /// Determines if there is space in the event buffer for the given number
94    /// of events. The buffer is capped at `EVENT_BUFFER_LEN_MAX`.
95    #[inline]
96    fn can_buffer_events(&self, num_events: usize) -> bool {
97        let event_bytes = match EVENT_SIZE.checked_mul(num_events) {
98            Some(bytes) => bytes,
99            None => return false,
100        };
101        let free_bytes = EVENT_BUFFER_LEN_MAX.saturating_sub(self.event_buffer.len());
102
103        free_bytes >= event_bytes
104    }
105
106    pub fn send_report<E: IntoIterator<Item = virtio_input_event>>(
107        &mut self,
108        events: E,
109    ) -> io::Result<bool>
110    where
111        E::IntoIter: ExactSizeIterator,
112    {
113        let it = events.into_iter();
114
115        if !self.can_buffer_events(it.len() + 1) {
116            return Ok(false);
117        }
118
119        for event in it {
120            let bytes = event.as_bytes();
121            self.event_buffer.extend(bytes.iter());
122        }
123
124        self.event_buffer
125            .extend(virtio_input_event::syn().as_bytes().iter());
126
127        self.flush_buffered_events()
128    }
129
130    /// Sends the given `event`, returning `Ok(true)` if, after this function returns, there are no
131    /// buffered events remaining.
132    pub fn send_event_encoded(&mut self, event: virtio_input_event) -> io::Result<bool> {
133        if !self.flush_buffered_events()? {
134            return Ok(false);
135        }
136
137        let bytes = event.as_bytes();
138        let written = self.event_socket.write(bytes)?;
139
140        if written == bytes.len() {
141            return Ok(true);
142        }
143
144        if self.can_buffer_events(1) {
145            self.event_buffer.extend(bytes[written..].iter());
146        }
147
148        Ok(false)
149    }
150
151    pub fn recv_event_encoded(&self) -> io::Result<virtio_input_event> {
152        let mut event = virtio_input_event::new_zeroed();
153        (&self.event_socket).read_exact(event.as_mut_bytes())?;
154        Ok(event)
155    }
156}
157
158impl AsRawDescriptor for EventDevice {
159    fn as_raw_descriptor(&self) -> RawDescriptor {
160        self.event_socket.as_raw_descriptor()
161    }
162}
163
164impl ReadNotifier for EventDevice {
165    fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
166        self.event_socket.get_read_notifier()
167    }
168}
169
170impl fmt::Debug for EventDevice {
171    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
172        write!(f, "Event device ({:?})", self.kind)
173    }
174}