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