• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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