• 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 constants;
7 mod defaults;
8 mod evdev;
9 mod event_source;
10 
11 use std::collections::BTreeMap;
12 use std::io::Read;
13 use std::io::Write;
14 
15 use anyhow::anyhow;
16 use anyhow::Context;
17 use base::error;
18 use base::warn;
19 use base::AsRawDescriptor;
20 use base::Event;
21 use base::EventToken;
22 use base::RawDescriptor;
23 use base::WaitContext;
24 use base::WorkerThread;
25 use data_model::Le16;
26 use data_model::Le32;
27 use linux_input_sys::virtio_input_event;
28 use linux_input_sys::InputEventDecoder;
29 use remain::sorted;
30 use thiserror::Error;
31 use vm_memory::GuestMemory;
32 use zerocopy::AsBytes;
33 use zerocopy::FromBytes;
34 
35 use self::constants::*;
36 use self::event_source::EvdevEventSource;
37 use self::event_source::EventSource;
38 use self::event_source::SocketEventSource;
39 use super::copy_config;
40 use super::virtio_device::Error as VirtioError;
41 use super::DescriptorChain;
42 use super::DescriptorError;
43 use super::DeviceType;
44 use super::Interrupt;
45 use super::Queue;
46 use super::Reader;
47 use super::SignalableInterrupt;
48 use super::VirtioDevice;
49 use super::VirtioDeviceSaved;
50 use super::Writer;
51 use crate::Suspendable;
52 
53 const EVENT_QUEUE_SIZE: u16 = 64;
54 const STATUS_QUEUE_SIZE: u16 = 64;
55 const QUEUE_SIZES: &[u16] = &[EVENT_QUEUE_SIZE, STATUS_QUEUE_SIZE];
56 
57 #[sorted]
58 #[derive(Error, Debug)]
59 pub enum InputError {
60     // Virtio descriptor error
61     #[error("virtio descriptor error: {0}")]
62     Descriptor(DescriptorError),
63     // Failed to get axis information of event device
64     #[error("failed to get axis information of event device: {0}")]
65     EvdevAbsInfoError(base::Error),
66     // Failed to get event types supported by device
67     #[error("failed to get event types supported by device: {0}")]
68     EvdevEventTypesError(base::Error),
69     // Failed to grab event device
70     #[error("failed to grab event device: {0}")]
71     EvdevGrabError(base::Error),
72     // Failed to get name of event device
73     #[error("failed to get id of event device: {0}")]
74     EvdevIdError(base::Error),
75     // Failed to get name of event device
76     #[error("failed to get name of event device: {0}")]
77     EvdevNameError(base::Error),
78     // Failed to get properties of event device
79     #[error("failed to get properties of event device: {0}")]
80     EvdevPropertiesError(base::Error),
81     // Failed to get serial name of event device
82     #[error("failed to get serial name of event device: {0}")]
83     EvdevSerialError(base::Error),
84     /// Failed to read events from the source
85     #[error("failed to read events from the source: {0}")]
86     EventsReadError(std::io::Error),
87     /// Failed to write events to the source
88     #[error("failed to write events to the source: {0}")]
89     EventsWriteError(std::io::Error),
90     // Detected error on guest side
91     #[error("detected error on guest side: {0}")]
92     GuestError(String),
93     // Error while reading from virtqueue
94     #[error("failed to read from virtqueue: {0}")]
95     ReadQueue(std::io::Error),
96     // Error while writing to virtqueue
97     #[error("failed to write to virtqueue: {0}")]
98     WriteQueue(std::io::Error),
99 }
100 
101 pub type Result<T> = std::result::Result<T, InputError>;
102 
103 #[derive(Copy, Clone, Default, Debug, AsBytes, FromBytes)]
104 #[repr(C)]
105 pub struct virtio_input_device_ids {
106     bustype: Le16,
107     vendor: Le16,
108     product: Le16,
109     version: Le16,
110 }
111 
112 impl virtio_input_device_ids {
new(bustype: u16, product: u16, vendor: u16, version: u16) -> virtio_input_device_ids113     fn new(bustype: u16, product: u16, vendor: u16, version: u16) -> virtio_input_device_ids {
114         virtio_input_device_ids {
115             bustype: Le16::from(bustype),
116             vendor: Le16::from(vendor),
117             product: Le16::from(product),
118             version: Le16::from(version),
119         }
120     }
121 }
122 
123 #[derive(Copy, Clone, Default, Debug, AsBytes, FromBytes)]
124 #[repr(C)]
125 pub struct virtio_input_absinfo {
126     min: Le32,
127     max: Le32,
128     fuzz: Le32,
129     flat: Le32,
130 }
131 
132 impl virtio_input_absinfo {
new(min: u32, max: u32, fuzz: u32, flat: u32) -> virtio_input_absinfo133     fn new(min: u32, max: u32, fuzz: u32, flat: u32) -> virtio_input_absinfo {
134         virtio_input_absinfo {
135             min: Le32::from(min),
136             max: Le32::from(max),
137             fuzz: Le32::from(fuzz),
138             flat: Le32::from(flat),
139         }
140     }
141 }
142 
143 #[derive(Copy, Clone, AsBytes, FromBytes)]
144 #[repr(C)]
145 struct virtio_input_config {
146     select: u8,
147     subsel: u8,
148     size: u8,
149     reserved: [u8; 5],
150     payload: [u8; 128],
151 }
152 
153 impl virtio_input_config {
new() -> virtio_input_config154     fn new() -> virtio_input_config {
155         virtio_input_config {
156             select: 0,
157             subsel: 0,
158             size: 0,
159             reserved: [0u8; 5],
160             payload: [0u8; 128],
161         }
162     }
163 
set_payload_slice(&mut self, slice: &[u8])164     fn set_payload_slice(&mut self, slice: &[u8]) {
165         let bytes_written = match (&mut self.payload[..]).write(slice) {
166             Ok(x) => x,
167             Err(_) => {
168                 // This won't happen because write is guaranteed to succeed with slices
169                 unreachable!();
170             }
171         };
172         self.size = bytes_written as u8;
173         if bytes_written < slice.len() {
174             // This shouldn't happen since everywhere this function is called the size is guaranteed
175             // to be at most 128 bytes (the size of the payload)
176             warn!("Slice is too long to fit in payload");
177         }
178     }
179 
set_payload_bitmap(&mut self, bitmap: &virtio_input_bitmap)180     fn set_payload_bitmap(&mut self, bitmap: &virtio_input_bitmap) {
181         self.size = bitmap.min_size();
182         self.payload.copy_from_slice(&bitmap.bitmap);
183     }
184 
set_absinfo(&mut self, absinfo: &virtio_input_absinfo)185     fn set_absinfo(&mut self, absinfo: &virtio_input_absinfo) {
186         self.set_payload_slice(absinfo.as_bytes());
187     }
188 
set_device_ids(&mut self, device_ids: &virtio_input_device_ids)189     fn set_device_ids(&mut self, device_ids: &virtio_input_device_ids) {
190         self.set_payload_slice(device_ids.as_bytes());
191     }
192 }
193 
194 #[derive(Copy, Clone)]
195 #[repr(C)]
196 pub struct virtio_input_bitmap {
197     bitmap: [u8; 128],
198 }
199 
200 impl virtio_input_bitmap {
new(bitmap: [u8; 128]) -> virtio_input_bitmap201     fn new(bitmap: [u8; 128]) -> virtio_input_bitmap {
202         virtio_input_bitmap { bitmap }
203     }
204 
len(&self) -> usize205     fn len(&self) -> usize {
206         self.bitmap.len()
207     }
208 
209     // Creates a bitmap from an array of bit indices
from_bits(set_indices: &[u16]) -> virtio_input_bitmap210     fn from_bits(set_indices: &[u16]) -> virtio_input_bitmap {
211         let mut ret = virtio_input_bitmap { bitmap: [0u8; 128] };
212         for idx in set_indices {
213             let byte_pos = (idx / 8) as usize;
214             let bit_byte = 1u8 << (idx % 8);
215             if byte_pos < ret.len() {
216                 ret.bitmap[byte_pos] |= bit_byte;
217             } else {
218                 // This would only happen if new event codes (or types, or ABS_*, etc) are defined to be
219                 // larger than or equal to 1024, in which case a new version of the virtio input
220                 // protocol needs to be defined.
221                 // There is nothing we can do about this error except log it.
222                 error!("Attempted to set an out of bounds bit: {}", idx);
223             }
224         }
225         ret
226     }
227 
228     // Returns the length of the minimum array that can hold all set bits in the map
min_size(&self) -> u8229     fn min_size(&self) -> u8 {
230         self.bitmap
231             .iter()
232             .rposition(|v| *v != 0)
233             .map_or(0, |i| i + 1) as u8
234     }
235 }
236 
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     guest_memory: GuestMemory,
351 }
352 
353 impl<T: EventSource> Worker<T> {
354     // 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>355     fn fill_event_virtqueue(
356         event_source: &mut T,
357         avail_desc: DescriptorChain,
358         mem: &GuestMemory,
359     ) -> Result<usize> {
360         let mut writer = Writer::new(mem.clone(), avail_desc).map_err(InputError::Descriptor)?;
361 
362         while writer.available_bytes() >= virtio_input_event::SIZE {
363             if let Some(evt) = event_source.pop_available_event() {
364                 writer.write_obj(evt).map_err(InputError::WriteQueue)?;
365             } else {
366                 break;
367             }
368         }
369 
370         Ok(writer.bytes_written())
371     }
372 
373     // Send events from the source to the guest
send_events(&mut self) -> bool374     fn send_events(&mut self) -> bool {
375         let mut needs_interrupt = false;
376 
377         // Only consume from the queue iterator if we know we have events to send
378         while self.event_source.available_events_count() > 0 {
379             match self.event_queue.pop(&self.guest_memory) {
380                 None => {
381                     break;
382                 }
383                 Some(avail_desc) => {
384                     let avail_desc_index = avail_desc.index;
385 
386                     let bytes_written = match Worker::fill_event_virtqueue(
387                         &mut self.event_source,
388                         avail_desc,
389                         &self.guest_memory,
390                     ) {
391                         Ok(count) => count,
392                         Err(e) => {
393                             error!("Input: failed to send events to guest: {}", e);
394                             break;
395                         }
396                     };
397 
398                     self.event_queue.add_used(
399                         &self.guest_memory,
400                         avail_desc_index,
401                         bytes_written as u32,
402                     );
403                     needs_interrupt = true;
404                 }
405             }
406         }
407 
408         needs_interrupt
409     }
410 
411     // 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>412     fn read_event_virtqueue(
413         avail_desc: DescriptorChain,
414         event_source: &mut T,
415         mem: &GuestMemory,
416     ) -> Result<usize> {
417         let mut reader = Reader::new(mem.clone(), avail_desc).map_err(InputError::Descriptor)?;
418         while reader.available_bytes() >= virtio_input_event::SIZE {
419             let evt: virtio_input_event = reader.read_obj().map_err(InputError::ReadQueue)?;
420             event_source.send_event(&evt)?;
421         }
422 
423         Ok(reader.bytes_read())
424     }
425 
process_status_queue(&mut self) -> Result<bool>426     fn process_status_queue(&mut self) -> Result<bool> {
427         let mut needs_interrupt = false;
428         while let Some(avail_desc) = self.status_queue.pop(&self.guest_memory) {
429             let avail_desc_index = avail_desc.index;
430 
431             let bytes_read = match Worker::read_event_virtqueue(
432                 avail_desc,
433                 &mut self.event_source,
434                 &self.guest_memory,
435             ) {
436                 Ok(count) => count,
437                 Err(e) => {
438                     error!("Input: failed to read events from virtqueue: {}", e);
439                     return Err(e);
440                 }
441             };
442 
443             self.status_queue
444                 .add_used(&self.guest_memory, avail_desc_index, bytes_read as u32);
445             needs_interrupt = true;
446         }
447 
448         Ok(needs_interrupt)
449     }
450 
451     // Allow error! and early return anywhere in function
452     #[allow(clippy::needless_return)]
run(&mut self, event_queue_evt: Event, status_queue_evt: Event, kill_evt: Event)453     fn run(&mut self, event_queue_evt: Event, status_queue_evt: Event, kill_evt: Event) {
454         if let Err(e) = self.event_source.init() {
455             error!("failed initializing event source: {}", e);
456             return;
457         }
458 
459         #[derive(EventToken)]
460         enum Token {
461             EventQAvailable,
462             StatusQAvailable,
463             InputEventsAvailable,
464             InterruptResample,
465             Kill,
466         }
467         let wait_ctx: WaitContext<Token> = match WaitContext::build_with(&[
468             (&event_queue_evt, Token::EventQAvailable),
469             (&status_queue_evt, Token::StatusQAvailable),
470             (&self.event_source, Token::InputEventsAvailable),
471             (&kill_evt, Token::Kill),
472         ]) {
473             Ok(wait_ctx) => wait_ctx,
474             Err(e) => {
475                 error!("failed creating WaitContext: {}", e);
476                 return;
477             }
478         };
479         if let Some(resample_evt) = self.interrupt.get_resample_evt() {
480             if wait_ctx
481                 .add(resample_evt, Token::InterruptResample)
482                 .is_err()
483             {
484                 error!("failed adding resample event to WaitContext.");
485                 return;
486             }
487         }
488 
489         'wait: loop {
490             let wait_events = match wait_ctx.wait() {
491                 Ok(wait_events) => wait_events,
492                 Err(e) => {
493                     error!("failed polling for events: {}", e);
494                     break;
495                 }
496             };
497 
498             let mut eventq_needs_interrupt = false;
499             let mut statusq_needs_interrupt = false;
500             for wait_event in wait_events.iter().filter(|e| e.is_readable) {
501                 match wait_event.token {
502                     Token::EventQAvailable => {
503                         if let Err(e) = event_queue_evt.wait() {
504                             error!("failed reading event queue Event: {}", e);
505                             break 'wait;
506                         }
507                         eventq_needs_interrupt |= self.send_events();
508                     }
509                     Token::StatusQAvailable => {
510                         if let Err(e) = status_queue_evt.wait() {
511                             error!("failed reading status queue Event: {}", e);
512                             break 'wait;
513                         }
514                         match self.process_status_queue() {
515                             Ok(b) => statusq_needs_interrupt |= b,
516                             Err(e) => error!("failed processing status events: {}", e),
517                         }
518                     }
519                     Token::InputEventsAvailable => match self.event_source.receive_events() {
520                         Err(e) => error!("error receiving events: {}", e),
521                         Ok(_cnt) => eventq_needs_interrupt |= self.send_events(),
522                     },
523                     Token::InterruptResample => {
524                         self.interrupt.interrupt_resample();
525                     }
526                     Token::Kill => {
527                         let _ = kill_evt.wait();
528                         break 'wait;
529                     }
530                 }
531             }
532             if eventq_needs_interrupt {
533                 self.event_queue
534                     .trigger_interrupt(&self.guest_memory, &self.interrupt);
535             }
536             if statusq_needs_interrupt {
537                 self.status_queue
538                     .trigger_interrupt(&self.guest_memory, &self.interrupt);
539             }
540         }
541 
542         if let Err(e) = self.event_source.finalize() {
543             error!("failed finalizing event source: {}", e);
544             return;
545         }
546     }
547 }
548 
549 /// Virtio input device
550 
551 pub struct Input<T: EventSource + Send + 'static> {
552     worker_thread: Option<WorkerThread<Worker<T>>>,
553     config: VirtioInputConfig,
554     source: Option<T>,
555     virtio_features: u64,
556 }
557 
558 impl<T> VirtioDevice for Input<T>
559 where
560     T: 'static + EventSource + Send,
561 {
keep_rds(&self) -> Vec<RawDescriptor>562     fn keep_rds(&self) -> Vec<RawDescriptor> {
563         if let Some(source) = &self.source {
564             return vec![source.as_raw_descriptor()];
565         }
566         Vec::new()
567     }
568 
device_type(&self) -> DeviceType569     fn device_type(&self) -> DeviceType {
570         DeviceType::Input
571     }
572 
queue_max_sizes(&self) -> &[u16]573     fn queue_max_sizes(&self) -> &[u16] {
574         QUEUE_SIZES
575     }
576 
read_config(&self, offset: u64, data: &mut [u8])577     fn read_config(&self, offset: u64, data: &mut [u8]) {
578         self.config.read(offset as usize, data);
579     }
580 
write_config(&mut self, offset: u64, data: &[u8])581     fn write_config(&mut self, offset: u64, data: &[u8]) {
582         self.config.write(offset as usize, data);
583     }
584 
features(&self) -> u64585     fn features(&self) -> u64 {
586         self.virtio_features
587     }
588 
activate( &mut self, mem: GuestMemory, interrupt: Interrupt, mut queues: Vec<(Queue, Event)>, ) -> anyhow::Result<()>589     fn activate(
590         &mut self,
591         mem: GuestMemory,
592         interrupt: Interrupt,
593         mut queues: Vec<(Queue, Event)>,
594     ) -> anyhow::Result<()> {
595         if queues.len() != 2 {
596             return Err(anyhow!("expected 2 queues, got {}", queues.len()));
597         }
598 
599         // Status is queue 1, event is queue 0
600         let (status_queue, status_queue_evt) = queues.remove(1);
601         let (event_queue, event_queue_evt) = queues.remove(0);
602 
603         let source = self
604             .source
605             .take()
606             .context("tried to activate device without a source for events")?;
607         self.worker_thread = Some(WorkerThread::start("v_input", move |kill_evt| {
608             let mut worker = Worker {
609                 interrupt,
610                 event_source: source,
611                 event_queue,
612                 status_queue,
613                 guest_memory: mem,
614             };
615             worker.run(event_queue_evt, status_queue_evt, kill_evt);
616             worker
617         }));
618 
619         Ok(())
620     }
621 
reset(&mut self) -> bool622     fn reset(&mut self) -> bool {
623         if let Some(worker_thread) = self.worker_thread.take() {
624             let worker = worker_thread.stop();
625             self.source = Some(worker.event_source);
626             return true;
627         }
628         false
629     }
630 
stop(&mut self) -> std::result::Result<Option<VirtioDeviceSaved>, VirtioError>631     fn stop(&mut self) -> std::result::Result<Option<VirtioDeviceSaved>, VirtioError> {
632         if let Some(worker_thread) = self.worker_thread.take() {
633             let worker = worker_thread.stop();
634             self.source = Some(worker.event_source);
635             let queues = vec![
636                 /* 0 */ worker.event_queue,
637                 /* 1 */ worker.status_queue,
638             ];
639             Ok(Some(VirtioDeviceSaved { queues }))
640         } else {
641             Ok(None)
642         }
643     }
644 }
645 
646 impl<T> Suspendable for Input<T> where T: 'static + EventSource + Send {}
647 
648 /// 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,649 pub fn new_evdev<T>(source: T, virtio_features: u64) -> Result<Input<EvdevEventSource<T>>>
650 where
651     T: Read + Write + AsRawDescriptor + Send + 'static,
652 {
653     Ok(Input {
654         worker_thread: None,
655         config: VirtioInputConfig::from_evdev(&source)?,
656         source: Some(EvdevEventSource::new(source)),
657         virtio_features,
658     })
659 }
660 
661 /// Creates a new virtio touch device which supports single touch only.
new_single_touch<T>( idx: u32, source: T, width: u32, height: u32, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,662 pub fn new_single_touch<T>(
663     idx: u32,
664     source: T,
665     width: u32,
666     height: u32,
667     virtio_features: u64,
668 ) -> Result<Input<SocketEventSource<T>>>
669 where
670     T: Read + Write + AsRawDescriptor + Send + 'static,
671 {
672     Ok(Input {
673         worker_thread: None,
674         config: defaults::new_single_touch_config(idx, width, height),
675         source: Some(SocketEventSource::new(source)),
676         virtio_features,
677     })
678 }
679 
680 /// Creates a new virtio touch device which supports multi touch.
new_multi_touch<T>( idx: u32, source: T, width: u32, height: u32, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,681 pub fn new_multi_touch<T>(
682     idx: u32,
683     source: T,
684     width: u32,
685     height: u32,
686     virtio_features: u64,
687 ) -> Result<Input<SocketEventSource<T>>>
688 where
689     T: Read + Write + AsRawDescriptor + Send + 'static,
690 {
691     Ok(Input {
692         worker_thread: None,
693         config: defaults::new_multi_touch_config(idx, width, height),
694         source: Some(SocketEventSource::new(source)),
695         virtio_features,
696     })
697 }
698 
699 /// Creates a new virtio trackpad device which supports (single) touch, primary and secondary
700 /// buttons as well as X and Y axis.
new_trackpad<T>( idx: u32, source: T, width: u32, height: u32, virtio_features: u64, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawDescriptor + Send + 'static,701 pub fn new_trackpad<T>(
702     idx: u32,
703     source: T,
704     width: u32,
705     height: u32,
706     virtio_features: u64,
707 ) -> Result<Input<SocketEventSource<T>>>
708 where
709     T: Read + Write + AsRawDescriptor + Send + 'static,
710 {
711     Ok(Input {
712         worker_thread: None,
713         config: defaults::new_trackpad_config(idx, width, height),
714         source: Some(SocketEventSource::new(source)),
715         virtio_features,
716     })
717 }
718 
719 /// 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,720 pub fn new_mouse<T>(
721     idx: u32,
722     source: T,
723     virtio_features: u64,
724 ) -> Result<Input<SocketEventSource<T>>>
725 where
726     T: Read + Write + AsRawDescriptor + Send + 'static,
727 {
728     Ok(Input {
729         worker_thread: None,
730         config: defaults::new_mouse_config(idx),
731         source: Some(SocketEventSource::new(source)),
732         virtio_features,
733     })
734 }
735 
736 /// 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,737 pub fn new_keyboard<T>(
738     idx: u32,
739     source: T,
740     virtio_features: u64,
741 ) -> Result<Input<SocketEventSource<T>>>
742 where
743     T: Read + Write + AsRawDescriptor + Send + 'static,
744 {
745     Ok(Input {
746         worker_thread: None,
747         config: defaults::new_keyboard_config(idx),
748         source: Some(SocketEventSource::new(source)),
749         virtio_features,
750     })
751 }
752 
753 /// 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,754 pub fn new_switches<T>(
755     idx: u32,
756     source: T,
757     virtio_features: u64,
758 ) -> Result<Input<SocketEventSource<T>>>
759 where
760     T: Read + Write + AsRawDescriptor + Send + 'static,
761 {
762     Ok(Input {
763         worker_thread: None,
764         config: defaults::new_switches_config(idx),
765         source: Some(SocketEventSource::new(source)),
766         virtio_features,
767     })
768 }
769