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