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