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
5 #[allow(dead_code)]
6 mod defaults;
7 mod evdev;
8 mod event_source;
9
10 use std::collections::BTreeMap;
11 use std::io::Read;
12 use std::io::Write;
13
14 use anyhow::anyhow;
15 use anyhow::bail;
16 use anyhow::Context;
17 use base::custom_serde::deserialize_seq_to_arr;
18 use base::custom_serde::serialize_arr;
19 use base::error;
20 use base::warn;
21 use base::AsRawDescriptor;
22 use base::Event;
23 use base::EventToken;
24 use base::RawDescriptor;
25 use base::WaitContext;
26 use base::WorkerThread;
27 use data_model::Le16;
28 use data_model::Le32;
29 use linux_input_sys::constants::*;
30 use linux_input_sys::virtio_input_event;
31 use linux_input_sys::InputEventDecoder;
32 use remain::sorted;
33 use serde::Deserialize;
34 use serde::Serialize;
35 use thiserror::Error;
36 use vm_memory::GuestMemory;
37 use zerocopy::AsBytes;
38 use zerocopy::FromBytes;
39 use zerocopy::FromZeroes;
40
41 use self::event_source::EvdevEventSource;
42 use self::event_source::EventSource;
43 use self::event_source::SocketEventSource;
44 use super::copy_config;
45 use super::DescriptorChain;
46 use super::DeviceType;
47 use super::Interrupt;
48 use super::Queue;
49 use super::VirtioDevice;
50
51 const EVENT_QUEUE_SIZE: u16 = 64;
52 const STATUS_QUEUE_SIZE: u16 = 64;
53 const QUEUE_SIZES: &[u16] = &[EVENT_QUEUE_SIZE, STATUS_QUEUE_SIZE];
54
55 #[sorted]
56 #[derive(Error, Debug)]
57 pub enum InputError {
58 // Failed to get axis information of event device
59 #[error("failed to get axis information of event device: {0}")]
60 EvdevAbsInfoError(base::Error),
61 // Failed to get event types supported by device
62 #[error("failed to get event types supported by device: {0}")]
63 EvdevEventTypesError(base::Error),
64 // Failed to grab event device
65 #[error("failed to grab event device: {0}")]
66 EvdevGrabError(base::Error),
67 // Failed to get name of event device
68 #[error("failed to get id of event device: {0}")]
69 EvdevIdError(base::Error),
70 // Failed to get name of event device
71 #[error("failed to get name of event device: {0}")]
72 EvdevNameError(base::Error),
73 // Failed to get properties of event device
74 #[error("failed to get properties of event device: {0}")]
75 EvdevPropertiesError(base::Error),
76 // Failed to get serial name of event device
77 #[error("failed to get serial name of event device: {0}")]
78 EvdevSerialError(base::Error),
79 /// Failed to read events from the source
80 #[error("failed to read events from the source: {0}")]
81 EventsReadError(std::io::Error),
82 /// Failed to write events to the source
83 #[error("failed to write events to the source: {0}")]
84 EventsWriteError(std::io::Error),
85 // Detected error on guest side
86 #[error("detected error on guest side: {0}")]
87 GuestError(String),
88 // Error while reading from virtqueue
89 #[error("failed to read from virtqueue: {0}")]
90 ReadQueue(std::io::Error),
91 // Error while writing to virtqueue
92 #[error("failed to write to virtqueue: {0}")]
93 WriteQueue(std::io::Error),
94 }
95
96 pub type Result<T> = std::result::Result<T, InputError>;
97
98 #[derive(Copy, Clone, Default, Debug, AsBytes, FromZeroes, FromBytes, Serialize, Deserialize)]
99 #[repr(C)]
100 pub struct virtio_input_device_ids {
101 bustype: Le16,
102 vendor: Le16,
103 product: Le16,
104 version: Le16,
105 }
106
107 impl virtio_input_device_ids {
new(bustype: u16, product: u16, vendor: u16, version: u16) -> virtio_input_device_ids108 fn new(bustype: u16, product: u16, vendor: u16, version: u16) -> virtio_input_device_ids {
109 virtio_input_device_ids {
110 bustype: Le16::from(bustype),
111 vendor: Le16::from(vendor),
112 product: Le16::from(product),
113 version: Le16::from(version),
114 }
115 }
116 }
117
118 #[derive(Copy, Clone, Default, Debug, AsBytes, FromZeroes, FromBytes, Serialize, Deserialize)]
119 #[repr(C)]
120 pub struct virtio_input_absinfo {
121 min: Le32,
122 max: Le32,
123 fuzz: Le32,
124 flat: Le32,
125 }
126
127 impl virtio_input_absinfo {
new(min: u32, max: u32, fuzz: u32, flat: u32) -> virtio_input_absinfo128 fn new(min: u32, max: u32, fuzz: u32, flat: u32) -> virtio_input_absinfo {
129 virtio_input_absinfo {
130 min: Le32::from(min),
131 max: Le32::from(max),
132 fuzz: Le32::from(fuzz),
133 flat: Le32::from(flat),
134 }
135 }
136 }
137
138 #[derive(Copy, Clone, AsBytes, FromZeroes, FromBytes)]
139 #[repr(C)]
140 struct virtio_input_config {
141 select: u8,
142 subsel: u8,
143 size: u8,
144 reserved: [u8; 5],
145 payload: [u8; 128],
146 }
147
148 impl virtio_input_config {
new() -> virtio_input_config149 fn new() -> virtio_input_config {
150 virtio_input_config {
151 select: 0,
152 subsel: 0,
153 size: 0,
154 reserved: [0u8; 5],
155 payload: [0u8; 128],
156 }
157 }
158
set_payload_slice(&mut self, slice: &[u8])159 fn set_payload_slice(&mut self, slice: &[u8]) {
160 let bytes_written = match (&mut self.payload[..]).write(slice) {
161 Ok(x) => x,
162 Err(_) => {
163 // This won't happen because write is guaranteed to succeed with slices
164 unreachable!();
165 }
166 };
167 self.size = bytes_written as u8;
168 if bytes_written < slice.len() {
169 // This shouldn't happen since everywhere this function is called the size is guaranteed
170 // to be at most 128 bytes (the size of the payload)
171 warn!("Slice is too long to fit in payload");
172 }
173 }
174
set_payload_bitmap(&mut self, bitmap: &virtio_input_bitmap)175 fn set_payload_bitmap(&mut self, bitmap: &virtio_input_bitmap) {
176 self.size = bitmap.min_size();
177 self.payload.copy_from_slice(&bitmap.bitmap);
178 }
179
set_absinfo(&mut self, absinfo: &virtio_input_absinfo)180 fn set_absinfo(&mut self, absinfo: &virtio_input_absinfo) {
181 self.set_payload_slice(absinfo.as_bytes());
182 }
183
set_device_ids(&mut self, device_ids: &virtio_input_device_ids)184 fn set_device_ids(&mut self, device_ids: &virtio_input_device_ids) {
185 self.set_payload_slice(device_ids.as_bytes());
186 }
187 }
188
189 #[derive(Copy, Clone, Debug, Deserialize, Serialize)]
190 #[repr(C)]
191 pub struct virtio_input_bitmap {
192 #[serde(
193 serialize_with = "serialize_arr",
194 deserialize_with = "deserialize_seq_to_arr"
195 )]
196 bitmap: [u8; 128],
197 }
198
199 impl virtio_input_bitmap {
new(bitmap: [u8; 128]) -> virtio_input_bitmap200 fn new(bitmap: [u8; 128]) -> virtio_input_bitmap {
201 virtio_input_bitmap { bitmap }
202 }
203
len(&self) -> usize204 fn len(&self) -> usize {
205 self.bitmap.len()
206 }
207
208 // Creates a bitmap from an array of bit indices
from_bits(set_indices: &[u16]) -> virtio_input_bitmap209 fn from_bits(set_indices: &[u16]) -> virtio_input_bitmap {
210 let mut ret = virtio_input_bitmap { bitmap: [0u8; 128] };
211 for idx in set_indices {
212 let byte_pos = (idx / 8) as usize;
213 let bit_byte = 1u8 << (idx % 8);
214 if byte_pos < ret.len() {
215 ret.bitmap[byte_pos] |= bit_byte;
216 } else {
217 // This would only happen if new event codes (or types, or ABS_*, etc) are defined
218 // to be larger than or equal to 1024, in which case a new version
219 // of the virtio input protocol needs to be defined.
220 // There is nothing we can do about this error except log it.
221 error!("Attempted to set an out of bounds bit: {}", idx);
222 }
223 }
224 ret
225 }
226
227 // Returns the length of the minimum array that can hold all set bits in the map
min_size(&self) -> u8228 fn min_size(&self) -> u8 {
229 self.bitmap
230 .iter()
231 .rposition(|v| *v != 0)
232 .map_or(0, |i| i + 1) as u8
233 }
234 }
235
236 #[derive(Debug, Serialize, Deserialize, Clone)]
237 pub struct VirtioInputConfig {
238 select: u8,
239 subsel: u8,
240 device_ids: virtio_input_device_ids,
241 name: Vec<u8>,
242 serial_name: Vec<u8>,
243 properties: virtio_input_bitmap,
244 supported_events: BTreeMap<u16, virtio_input_bitmap>,
245 axis_info: BTreeMap<u16, virtio_input_absinfo>,
246 }
247
248 impl VirtioInputConfig {
new( device_ids: virtio_input_device_ids, name: Vec<u8>, serial_name: Vec<u8>, properties: virtio_input_bitmap, supported_events: BTreeMap<u16, virtio_input_bitmap>, axis_info: BTreeMap<u16, virtio_input_absinfo>, ) -> VirtioInputConfig249 fn new(
250 device_ids: virtio_input_device_ids,
251 name: Vec<u8>,
252 serial_name: Vec<u8>,
253 properties: virtio_input_bitmap,
254 supported_events: BTreeMap<u16, virtio_input_bitmap>,
255 axis_info: BTreeMap<u16, virtio_input_absinfo>,
256 ) -> VirtioInputConfig {
257 VirtioInputConfig {
258 select: 0,
259 subsel: 0,
260 device_ids,
261 name,
262 serial_name,
263 properties,
264 supported_events,
265 axis_info,
266 }
267 }
268
from_evdev<T: AsRawDescriptor>(source: &T) -> Result<VirtioInputConfig>269 fn from_evdev<T: AsRawDescriptor>(source: &T) -> Result<VirtioInputConfig> {
270 Ok(VirtioInputConfig::new(
271 evdev::device_ids(source)?,
272 evdev::name(source)?,
273 evdev::serial_name(source)?,
274 evdev::properties(source)?,
275 evdev::supported_events(source)?,
276 evdev::abs_info(source),
277 ))
278 }
279
build_config_memory(&self) -> virtio_input_config280 fn build_config_memory(&self) -> virtio_input_config {
281 let mut cfg = virtio_input_config::new();
282 cfg.select = self.select;
283 cfg.subsel = self.subsel;
284 match self.select {
285 VIRTIO_INPUT_CFG_ID_NAME => {
286 cfg.set_payload_slice(&self.name);
287 }
288 VIRTIO_INPUT_CFG_ID_SERIAL => {
289 cfg.set_payload_slice(&self.serial_name);
290 }
291 VIRTIO_INPUT_CFG_PROP_BITS => {
292 cfg.set_payload_bitmap(&self.properties);
293 }
294 VIRTIO_INPUT_CFG_EV_BITS => {
295 let ev_type = self.subsel as u16;
296 // zero is a special case: return all supported event types (just like EVIOCGBIT)
297 if ev_type == 0 {
298 let events_bm = virtio_input_bitmap::from_bits(
299 &self.supported_events.keys().cloned().collect::<Vec<u16>>(),
300 );
301 cfg.set_payload_bitmap(&events_bm);
302 } else if let Some(supported_codes) = self.supported_events.get(&ev_type) {
303 cfg.set_payload_bitmap(supported_codes);
304 }
305 }
306 VIRTIO_INPUT_CFG_ABS_INFO => {
307 let abs_axis = self.subsel as u16;
308 if let Some(absinfo) = self.axis_info.get(&abs_axis) {
309 cfg.set_absinfo(absinfo);
310 } // else all zeroes in the payload
311 }
312 VIRTIO_INPUT_CFG_ID_DEVIDS => {
313 cfg.set_device_ids(&self.device_ids);
314 }
315 VIRTIO_INPUT_CFG_UNSET => {
316 // Per the virtio spec at https://docs.oasis-open.org/virtio/virtio/v1.1/cs01/virtio-v1.1-cs01.html#x1-3390008,
317 // there is no action required of us when this is set. It's unclear whether we
318 // should be zeroing the virtio_input_config, but empirically we know that the
319 // existing behavior of doing nothing works with the Linux virtio-input frontend.
320 }
321 _ => {
322 warn!("Unsuported virtio input config selection: {}", self.select);
323 }
324 }
325 cfg
326 }
327
read(&self, offset: usize, data: &mut [u8])328 fn read(&self, offset: usize, data: &mut [u8]) {
329 copy_config(
330 data,
331 0,
332 self.build_config_memory().as_bytes(),
333 offset as u64,
334 );
335 }
336
write(&mut self, offset: usize, data: &[u8])337 fn write(&mut self, offset: usize, data: &[u8]) {
338 let mut config = self.build_config_memory();
339 copy_config(config.as_bytes_mut(), offset as u64, data, 0);
340 self.select = config.select;
341 self.subsel = config.subsel;
342 }
343 }
344
345 struct Worker<T: EventSource> {
346 interrupt: Interrupt,
347 event_source: T,
348 event_queue: Queue,
349 status_queue: Queue,
350 }
351
352 impl<T: EventSource> Worker<T> {
353 // Fills a virtqueue with events from the source. Returns the number of bytes written.
fill_event_virtqueue( event_source: &mut T, avail_desc: &mut DescriptorChain, ) -> Result<usize>354 fn fill_event_virtqueue(
355 event_source: &mut T,
356 avail_desc: &mut DescriptorChain,
357 ) -> Result<usize> {
358 let writer = &mut avail_desc.writer;
359
360 while writer.available_bytes() >= virtio_input_event::SIZE {
361 if let Some(evt) = event_source.pop_available_event() {
362 writer.write_obj(evt).map_err(InputError::WriteQueue)?;
363 } else {
364 break;
365 }
366 }
367
368 Ok(writer.bytes_written())
369 }
370
371 // Send events from the source to the guest
send_events(&mut self) -> bool372 fn send_events(&mut self) -> bool {
373 let mut needs_interrupt = false;
374
375 // Only consume from the queue iterator if we know we have events to send
376 while self.event_source.available_events_count() > 0 {
377 match self.event_queue.pop() {
378 None => {
379 break;
380 }
381 Some(mut avail_desc) => {
382 let bytes_written =
383 match Worker::fill_event_virtqueue(&mut self.event_source, &mut avail_desc)
384 {
385 Ok(count) => count,
386 Err(e) => {
387 error!("Input: failed to send events to guest: {}", e);
388 break;
389 }
390 };
391
392 self.event_queue.add_used(avail_desc, bytes_written as u32);
393 needs_interrupt = true;
394 }
395 }
396 }
397
398 needs_interrupt
399 }
400
401 // Sends events from the guest to the source. Returns the number of bytes read.
read_event_virtqueue( avail_desc: &mut DescriptorChain, event_source: &mut T, ) -> Result<usize>402 fn read_event_virtqueue(
403 avail_desc: &mut DescriptorChain,
404 event_source: &mut T,
405 ) -> Result<usize> {
406 let reader = &mut avail_desc.reader;
407 while reader.available_bytes() >= virtio_input_event::SIZE {
408 let evt: virtio_input_event = reader.read_obj().map_err(InputError::ReadQueue)?;
409 event_source.send_event(&evt)?;
410 }
411
412 Ok(reader.bytes_read())
413 }
414
process_status_queue(&mut self) -> Result<bool>415 fn process_status_queue(&mut self) -> Result<bool> {
416 let mut needs_interrupt = false;
417 while let Some(mut avail_desc) = self.status_queue.pop() {
418 let bytes_read =
419 match Worker::read_event_virtqueue(&mut avail_desc, &mut self.event_source) {
420 Ok(count) => count,
421 Err(e) => {
422 error!("Input: failed to read events from virtqueue: {}", e);
423 return Err(e);
424 }
425 };
426
427 self.status_queue.add_used(avail_desc, bytes_read as u32);
428 needs_interrupt = true;
429 }
430
431 Ok(needs_interrupt)
432 }
433
434 // Allow error! and early return anywhere in function
435 #[allow(clippy::needless_return)]
run(&mut self, kill_evt: Event)436 fn run(&mut self, kill_evt: Event) {
437 if let Err(e) = self.event_source.init() {
438 error!("failed initializing event source: {}", e);
439 return;
440 }
441
442 #[derive(EventToken)]
443 enum Token {
444 EventQAvailable,
445 StatusQAvailable,
446 InputEventsAvailable,
447 InterruptResample,
448 Kill,
449 }
450 let wait_ctx: WaitContext<Token> = match WaitContext::build_with(&[
451 (self.event_queue.event(), Token::EventQAvailable),
452 (self.status_queue.event(), Token::StatusQAvailable),
453 (&self.event_source, Token::InputEventsAvailable),
454 (&kill_evt, Token::Kill),
455 ]) {
456 Ok(wait_ctx) => wait_ctx,
457 Err(e) => {
458 error!("failed creating WaitContext: {}", e);
459 return;
460 }
461 };
462 if let Some(resample_evt) = self.interrupt.get_resample_evt() {
463 if wait_ctx
464 .add(resample_evt, Token::InterruptResample)
465 .is_err()
466 {
467 error!("failed adding resample event to WaitContext.");
468 return;
469 }
470 }
471
472 'wait: loop {
473 let wait_events = match wait_ctx.wait() {
474 Ok(wait_events) => wait_events,
475 Err(e) => {
476 error!("failed polling for events: {}", e);
477 break;
478 }
479 };
480
481 let mut eventq_needs_interrupt = false;
482 let mut statusq_needs_interrupt = false;
483 for wait_event in wait_events.iter().filter(|e| e.is_readable) {
484 match wait_event.token {
485 Token::EventQAvailable => {
486 if let Err(e) = self.event_queue.event().wait() {
487 error!("failed reading event queue Event: {}", e);
488 break 'wait;
489 }
490 eventq_needs_interrupt |= self.send_events();
491 }
492 Token::StatusQAvailable => {
493 if let Err(e) = self.status_queue.event().wait() {
494 error!("failed reading status queue Event: {}", e);
495 break 'wait;
496 }
497 match self.process_status_queue() {
498 Ok(b) => statusq_needs_interrupt |= b,
499 Err(e) => error!("failed processing status events: {}", e),
500 }
501 }
502 Token::InputEventsAvailable => match self.event_source.receive_events() {
503 Err(e) => error!("error receiving events: {}", e),
504 Ok(_cnt) => eventq_needs_interrupt |= self.send_events(),
505 },
506 Token::InterruptResample => {
507 self.interrupt.interrupt_resample();
508 }
509 Token::Kill => {
510 let _ = kill_evt.wait();
511 break 'wait;
512 }
513 }
514 }
515 if eventq_needs_interrupt {
516 self.event_queue.trigger_interrupt(&self.interrupt);
517 }
518 if statusq_needs_interrupt {
519 self.status_queue.trigger_interrupt(&self.interrupt);
520 }
521 }
522
523 if let Err(e) = self.event_source.finalize() {
524 error!("failed finalizing event source: {}", e);
525 return;
526 }
527 }
528 }
529
530 /// Virtio input device
531
532 pub struct Input<T: EventSource + Send + 'static> {
533 worker_thread: Option<WorkerThread<Worker<T>>>,
534 config: VirtioInputConfig,
535 source: Option<T>,
536 virtio_features: u64,
537 }
538
539 /// Snapshot of [Input]'s state.
540 #[derive(Serialize, Deserialize)]
541 struct InputSnapshot {
542 config: VirtioInputConfig,
543 virtio_features: u64,
544 }
545
546 impl<T> VirtioDevice for Input<T>
547 where
548 T: 'static + EventSource + Send,
549 {
keep_rds(&self) -> Vec<RawDescriptor>550 fn keep_rds(&self) -> Vec<RawDescriptor> {
551 if let Some(source) = &self.source {
552 return vec![source.as_raw_descriptor()];
553 }
554 Vec::new()
555 }
556
device_type(&self) -> DeviceType557 fn device_type(&self) -> DeviceType {
558 DeviceType::Input
559 }
560
queue_max_sizes(&self) -> &[u16]561 fn queue_max_sizes(&self) -> &[u16] {
562 QUEUE_SIZES
563 }
564
read_config(&self, offset: u64, data: &mut [u8])565 fn read_config(&self, offset: u64, data: &mut [u8]) {
566 self.config.read(offset as usize, data);
567 }
568
write_config(&mut self, offset: u64, data: &[u8])569 fn write_config(&mut self, offset: u64, data: &[u8]) {
570 self.config.write(offset as usize, data);
571 }
572
features(&self) -> u64573 fn features(&self) -> u64 {
574 self.virtio_features
575 }
576
activate( &mut self, _mem: GuestMemory, interrupt: Interrupt, mut queues: BTreeMap<usize, Queue>, ) -> anyhow::Result<()>577 fn activate(
578 &mut self,
579 _mem: GuestMemory,
580 interrupt: Interrupt,
581 mut queues: BTreeMap<usize, Queue>,
582 ) -> anyhow::Result<()> {
583 if queues.len() != 2 {
584 return Err(anyhow!("expected 2 queues, got {}", queues.len()));
585 }
586 let event_queue = queues.remove(&0).unwrap();
587 let status_queue = queues.remove(&1).unwrap();
588
589 let source = self
590 .source
591 .take()
592 .context("tried to activate device without a source for events")?;
593 self.worker_thread = Some(WorkerThread::start("v_input", move |kill_evt| {
594 let mut worker = Worker {
595 interrupt,
596 event_source: source,
597 event_queue,
598 status_queue,
599 };
600 worker.run(kill_evt);
601 worker
602 }));
603
604 Ok(())
605 }
606
reset(&mut self) -> anyhow::Result<()>607 fn reset(&mut self) -> anyhow::Result<()> {
608 if let Some(worker_thread) = self.worker_thread.take() {
609 let worker = worker_thread.stop();
610 self.source = Some(worker.event_source);
611 }
612 Ok(())
613 }
614
virtio_sleep(&mut self) -> anyhow::Result<Option<BTreeMap<usize, Queue>>>615 fn virtio_sleep(&mut self) -> anyhow::Result<Option<BTreeMap<usize, Queue>>> {
616 if let Some(worker_thread) = self.worker_thread.take() {
617 let worker = worker_thread.stop();
618 self.source = Some(worker.event_source);
619 let queues = BTreeMap::from([(0, worker.event_queue), (1, worker.status_queue)]);
620 Ok(Some(queues))
621 } else {
622 Ok(None)
623 }
624 }
625
virtio_wake( &mut self, queues_state: Option<(GuestMemory, Interrupt, BTreeMap<usize, Queue>)>, ) -> anyhow::Result<()>626 fn virtio_wake(
627 &mut self,
628 queues_state: Option<(GuestMemory, Interrupt, BTreeMap<usize, Queue>)>,
629 ) -> anyhow::Result<()> {
630 if let Some((mem, interrupt, queues)) = queues_state {
631 self.activate(mem, interrupt, queues)?;
632 }
633 Ok(())
634 }
635
virtio_snapshot(&mut self) -> anyhow::Result<serde_json::Value>636 fn virtio_snapshot(&mut self) -> anyhow::Result<serde_json::Value> {
637 serde_json::to_value(InputSnapshot {
638 virtio_features: self.virtio_features,
639 config: self.config.clone(),
640 })
641 .context("failed to serialize InputSnapshot")
642 }
643
virtio_restore(&mut self, data: serde_json::Value) -> anyhow::Result<()>644 fn virtio_restore(&mut self, data: serde_json::Value) -> anyhow::Result<()> {
645 let snap: InputSnapshot = serde_json::from_value(data).context("error deserializing")?;
646 if snap.virtio_features != self.virtio_features {
647 bail!(
648 "expected virtio_features to match, but they did not. Live: {:?}, snapshot {:?}",
649 self.virtio_features,
650 snap.virtio_features,
651 );
652 }
653 self.config = snap.config;
654 Ok(())
655 }
656 }
657
658 /// Creates a new virtio input device from an event device node
new_evdev<T>(source: T, virtio_features: u64) -> Result<Input<EvdevEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,659 pub fn new_evdev<T>(source: T, virtio_features: u64) -> Result<Input<EvdevEventSource<T>>>
660 where
661 T: Read + Write + AsRawDescriptor + Send + 'static,
662 {
663 Ok(Input {
664 worker_thread: None,
665 config: VirtioInputConfig::from_evdev(&source)?,
666 source: Some(EvdevEventSource::new(source)),
667 virtio_features,
668 })
669 }
670
671 /// Creates a new virtio touch device which supports single touch only.
new_single_touch<T>( idx: u32, source: T, width: u32, height: u32, name: Option<&str>, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,672 pub fn new_single_touch<T>(
673 idx: u32,
674 source: T,
675 width: u32,
676 height: u32,
677 name: Option<&str>,
678 virtio_features: u64,
679 ) -> Result<Input<SocketEventSource<T>>>
680 where
681 T: Read + Write + AsRawDescriptor + Send + 'static,
682 {
683 Ok(Input {
684 worker_thread: None,
685 config: defaults::new_single_touch_config(idx, width, height, name),
686 source: Some(SocketEventSource::new(source)),
687 virtio_features,
688 })
689 }
690
691 /// Creates a new virtio touch device which supports multi touch.
new_multi_touch<T>( idx: u32, source: T, width: u32, height: u32, name: Option<&str>, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,692 pub fn new_multi_touch<T>(
693 idx: u32,
694 source: T,
695 width: u32,
696 height: u32,
697 name: Option<&str>,
698 virtio_features: u64,
699 ) -> Result<Input<SocketEventSource<T>>>
700 where
701 T: Read + Write + AsRawDescriptor + Send + 'static,
702 {
703 Ok(Input {
704 worker_thread: None,
705 config: defaults::new_multi_touch_config(idx, width, height, name),
706 source: Some(SocketEventSource::new(source)),
707 virtio_features,
708 })
709 }
710
711 /// Creates a new virtio trackpad device which supports (single) touch, primary and secondary
712 /// buttons as well as X and Y axis.
new_trackpad<T>( idx: u32, source: T, width: u32, height: u32, name: Option<&str>, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,713 pub fn new_trackpad<T>(
714 idx: u32,
715 source: T,
716 width: u32,
717 height: u32,
718 name: Option<&str>,
719 virtio_features: u64,
720 ) -> Result<Input<SocketEventSource<T>>>
721 where
722 T: Read + Write + AsRawDescriptor + Send + 'static,
723 {
724 Ok(Input {
725 worker_thread: None,
726 config: defaults::new_trackpad_config(idx, width, height, name),
727 source: Some(SocketEventSource::new(source)),
728 virtio_features,
729 })
730 }
731
732 /// Creates a new virtio mouse which supports primary, secondary, wheel and REL events.
new_mouse<T>( idx: u32, source: T, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,733 pub fn new_mouse<T>(
734 idx: u32,
735 source: T,
736 virtio_features: u64,
737 ) -> Result<Input<SocketEventSource<T>>>
738 where
739 T: Read + Write + AsRawDescriptor + Send + 'static,
740 {
741 Ok(Input {
742 worker_thread: None,
743 config: defaults::new_mouse_config(idx),
744 source: Some(SocketEventSource::new(source)),
745 virtio_features,
746 })
747 }
748
749 /// Creates a new virtio keyboard, which supports the same events as an en-us physical keyboard.
new_keyboard<T>( idx: u32, source: T, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,750 pub fn new_keyboard<T>(
751 idx: u32,
752 source: T,
753 virtio_features: u64,
754 ) -> Result<Input<SocketEventSource<T>>>
755 where
756 T: Read + Write + AsRawDescriptor + Send + 'static,
757 {
758 Ok(Input {
759 worker_thread: None,
760 config: defaults::new_keyboard_config(idx),
761 source: Some(SocketEventSource::new(source)),
762 virtio_features,
763 })
764 }
765
766 /// Creates a new virtio device for switches.
new_switches<T>( idx: u32, source: T, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,767 pub fn new_switches<T>(
768 idx: u32,
769 source: T,
770 virtio_features: u64,
771 ) -> Result<Input<SocketEventSource<T>>>
772 where
773 T: Read + Write + AsRawDescriptor + Send + 'static,
774 {
775 Ok(Input {
776 worker_thread: None,
777 config: defaults::new_switches_config(idx),
778 source: Some(SocketEventSource::new(source)),
779 virtio_features,
780 })
781 }
782
783 /// Creates a new virtio device for rotary.
new_rotary<T>( idx: u32, source: T, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,784 pub fn new_rotary<T>(
785 idx: u32,
786 source: T,
787 virtio_features: u64,
788 ) -> Result<Input<SocketEventSource<T>>>
789 where
790 T: Read + Write + AsRawDescriptor + Send + 'static,
791 {
792 Ok(Input {
793 worker_thread: None,
794 config: defaults::new_rotary_config(idx),
795 source: Some(SocketEventSource::new(source)),
796 virtio_features,
797 })
798 }
799