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 std::os::unix::io::{AsRawFd, RawFd};
14
15 use data_model::{DataInit, Le16, Le32};
16 use sys_util::{error, warn, EventFd, GuestMemory, PollContext, PollToken};
17
18 use self::event_source::{input_event, EvdevEventSource, EventSource, SocketEventSource};
19 use super::{Queue, VirtioDevice, INTERRUPT_STATUS_USED_RING, TYPE_INPUT};
20 use std::cmp::min;
21 use std::collections::BTreeMap;
22 use std::fmt::{self, Display};
23 use std::io::Read;
24 use std::io::Write;
25 use std::mem::size_of;
26 use std::sync::atomic::{AtomicUsize, Ordering};
27 use std::sync::Arc;
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 #[derive(Debug)]
35 pub enum InputError {
36 /// Failed to write events to the source
37 EventsWriteError(sys_util::GuestMemoryError),
38 /// Failed to read events from the source
39 EventsReadError(std::io::Error),
40 // Failed to get name of event device
41 EvdevIdError(sys_util::Error),
42 // Failed to get name of event device
43 EvdevNameError(sys_util::Error),
44 // Failed to get serial name of event device
45 EvdevSerialError(sys_util::Error),
46 // Failed to get properties of event device
47 EvdevPropertiesError(sys_util::Error),
48 // Failed to get event types supported by device
49 EvdevEventTypesError(sys_util::Error),
50 // Failed to get axis information of event device
51 EvdevAbsInfoError(sys_util::Error),
52 // Failed to grab event device
53 EvdevGrabError(sys_util::Error),
54 }
55 pub type Result<T> = std::result::Result<T, InputError>;
56
57 impl Display for InputError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59 use self::InputError::*;
60
61 match self {
62 EventsWriteError(e) => write!(f, "failed to write events to the source: {}", e),
63 EventsReadError(e) => write!(f, "failed to read events from the source: {}", e),
64 EvdevIdError(e) => write!(f, "failed to get id of event device: {}", e),
65 EvdevNameError(e) => write!(f, "failed to get name of event device: {}", e),
66 EvdevSerialError(e) => write!(f, "failed to get serial name of event device: {}", e),
67 EvdevPropertiesError(e) => write!(f, "failed to get properties of event device: {}", e),
68 EvdevEventTypesError(e) => {
69 write!(f, "failed to get event types supported by device: {}", e)
70 }
71 EvdevAbsInfoError(e) => {
72 write!(f, "failed to get axis information of event device: {}", e)
73 }
74 EvdevGrabError(e) => write!(f, "failed to grab event device: {}", e),
75 }
76 }
77 }
78
79 #[derive(Copy, Clone, Default, Debug)]
80 #[repr(C)]
81 pub struct virtio_input_device_ids {
82 bustype: Le16,
83 vendor: Le16,
84 product: Le16,
85 version: Le16,
86 }
87
88 // Safe because it only has data and has no implicit padding.
89 unsafe impl DataInit for virtio_input_device_ids {}
90
91 impl virtio_input_device_ids {
new(bustype: u16, product: u16, vendor: u16, version: u16) -> virtio_input_device_ids92 fn new(bustype: u16, product: u16, vendor: u16, version: u16) -> virtio_input_device_ids {
93 virtio_input_device_ids {
94 bustype: Le16::from(bustype),
95 vendor: Le16::from(vendor),
96 product: Le16::from(product),
97 version: Le16::from(version),
98 }
99 }
100 }
101
102 #[derive(Copy, Clone, Default, Debug)]
103 #[repr(C)]
104 pub struct virtio_input_absinfo {
105 min: Le32,
106 max: Le32,
107 fuzz: Le32,
108 flat: Le32,
109 }
110
111 // Safe because it only has data and has no implicit padding.
112 unsafe impl DataInit for virtio_input_absinfo {}
113
114 impl virtio_input_absinfo {
new(min: u32, max: u32, fuzz: u32, flat: u32) -> virtio_input_absinfo115 fn new(min: u32, max: u32, fuzz: u32, flat: u32) -> virtio_input_absinfo {
116 virtio_input_absinfo {
117 min: Le32::from(min),
118 max: Le32::from(max),
119 fuzz: Le32::from(fuzz),
120 flat: Le32::from(flat),
121 }
122 }
123 }
124
125 #[derive(Copy, Clone)]
126 #[repr(C)]
127 struct virtio_input_config {
128 select: u8,
129 subsel: u8,
130 size: u8,
131 reserved: [u8; 5],
132 payload: [u8; 128],
133 }
134
135 // Safe because it only has data and has no implicit padding.
136 unsafe impl DataInit for virtio_input_config {}
137
138 impl virtio_input_config {
new() -> virtio_input_config139 fn new() -> virtio_input_config {
140 virtio_input_config {
141 select: 0,
142 subsel: 0,
143 size: 0,
144 reserved: [0u8; 5],
145 payload: [0u8; 128],
146 }
147 }
148
set_payload_slice(&mut self, slice: &[u8])149 fn set_payload_slice(&mut self, slice: &[u8]) {
150 let bytes_written = match (&mut self.payload[..]).write(slice) {
151 Ok(x) => x,
152 Err(_) => {
153 // This won't happen because write is guaranteed to succeed with slices
154 unreachable!();
155 }
156 };
157 self.size = bytes_written as u8;
158 if bytes_written < slice.len() {
159 // This shouldn't happen since everywhere this function is called the size is guaranteed
160 // to be at most 128 bytes (the size of the payload)
161 warn!("Slice is too long to fit in payload");
162 }
163 }
164
set_payload_bitmap(&mut self, bitmap: &virtio_input_bitmap)165 fn set_payload_bitmap(&mut self, bitmap: &virtio_input_bitmap) {
166 self.size = bitmap.min_size();
167 self.payload.copy_from_slice(&bitmap.bitmap);
168 }
169
set_absinfo(&mut self, absinfo: &virtio_input_absinfo)170 fn set_absinfo(&mut self, absinfo: &virtio_input_absinfo) {
171 self.set_payload_slice(absinfo.as_slice());
172 }
173
set_device_ids(&mut self, device_ids: &virtio_input_device_ids)174 fn set_device_ids(&mut self, device_ids: &virtio_input_device_ids) {
175 self.set_payload_slice(device_ids.as_slice());
176 }
177 }
178
179 #[derive(Copy, Clone)]
180 #[repr(C)]
181 pub struct virtio_input_bitmap {
182 bitmap: [u8; 128],
183 }
184
185 impl virtio_input_bitmap {
new(bitmap: [u8; 128]) -> virtio_input_bitmap186 fn new(bitmap: [u8; 128]) -> virtio_input_bitmap {
187 virtio_input_bitmap { bitmap }
188 }
189
len(&self) -> usize190 fn len(&self) -> usize {
191 self.bitmap.len()
192 }
193
194 // Creates a bitmap from an array of bit indices
from_bits(set_indices: &[u16]) -> virtio_input_bitmap195 fn from_bits(set_indices: &[u16]) -> virtio_input_bitmap {
196 let mut ret = virtio_input_bitmap { bitmap: [0u8; 128] };
197 for idx in set_indices {
198 let byte_pos = (idx / 8) as usize;
199 let bit_byte = 1u8 << (idx % 8);
200 if byte_pos < ret.len() {
201 ret.bitmap[byte_pos] |= bit_byte;
202 } else {
203 // This would only happen if new event codes (or types, or ABS_*, etc) are defined to be
204 // larger than or equal to 1024, in which case a new version of the virtio input
205 // protocol needs to be defined.
206 // There is nothing we can do about this error except log it.
207 error!("Attempted to set an out of bounds bit: {}", idx);
208 }
209 }
210 ret
211 }
212
213 // Returns the length of the minimum array that can hold all set bits in the map
min_size(&self) -> u8214 fn min_size(&self) -> u8 {
215 self.bitmap
216 .iter()
217 .rposition(|v| *v != 0)
218 .map_or(0, |i| i + 1) as u8
219 }
220 }
221
222 pub struct VirtioInputConfig {
223 select: u8,
224 subsel: u8,
225 device_ids: virtio_input_device_ids,
226 name: Vec<u8>,
227 serial_name: Vec<u8>,
228 properties: virtio_input_bitmap,
229 supported_events: BTreeMap<u16, virtio_input_bitmap>,
230 axis_info: BTreeMap<u16, virtio_input_absinfo>,
231 }
232
233 impl VirtioInputConfig {
234 const CONFIG_MEM_SIZE: usize = size_of::<virtio_input_config>();
235
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>, ) -> VirtioInputConfig236 fn new(
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 ) -> VirtioInputConfig {
244 VirtioInputConfig {
245 select: 0,
246 subsel: 0,
247 device_ids,
248 name,
249 serial_name,
250 properties,
251 supported_events,
252 axis_info,
253 }
254 }
255
from_evdev<T: AsRawFd>(source: &T) -> Result<VirtioInputConfig>256 fn from_evdev<T: AsRawFd>(source: &T) -> Result<VirtioInputConfig> {
257 Ok(VirtioInputConfig::new(
258 evdev::device_ids(source)?,
259 evdev::name(source)?,
260 evdev::serial_name(source)?,
261 evdev::properties(source)?,
262 evdev::supported_events(source)?,
263 evdev::abs_info(source),
264 ))
265 }
266
validate_read_offsets(&self, offset: usize, len: usize) -> bool267 fn validate_read_offsets(&self, offset: usize, len: usize) -> bool {
268 if offset + len > VirtioInputConfig::CONFIG_MEM_SIZE {
269 error!(
270 "Attempt to read from invalid config range: [{}..{}], valid ranges in [0..{}]",
271 offset,
272 offset + len,
273 VirtioInputConfig::CONFIG_MEM_SIZE
274 );
275 return false;
276 }
277 true
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 _ => {
316 warn!("Unsuported virtio input config selection: {}", self.select);
317 }
318 }
319 cfg
320 }
321
read(&self, offset: usize, data: &mut [u8])322 fn read(&self, offset: usize, data: &mut [u8]) {
323 let data_len = data.len();
324 if self.validate_read_offsets(offset, data_len) {
325 let config = self.build_config_memory();
326 data.clone_from_slice(&config.as_slice()[offset..offset + data_len]);
327 }
328 }
329
validate_write_offsets(&self, offset: usize, len: usize) -> bool330 fn validate_write_offsets(&self, offset: usize, len: usize) -> bool {
331 const MAX_WRITABLE_BYTES: usize = 2;
332 if offset + len > MAX_WRITABLE_BYTES {
333 error!(
334 "Attempt to write to invalid config range: [{}..{}], valid ranges in [0..{}]",
335 offset,
336 offset + len,
337 MAX_WRITABLE_BYTES
338 );
339 return false;
340 }
341 true
342 }
343
write(&mut self, offset: usize, data: &[u8])344 fn write(&mut self, offset: usize, data: &[u8]) {
345 let len = data.len();
346 if self.validate_write_offsets(offset, len) {
347 let mut selectors: [u8; 2] = [self.select, self.subsel];
348 selectors[offset..offset + len].clone_from_slice(&data);
349 self.select = selectors[0];
350 self.subsel = selectors[1];
351 }
352 }
353 }
354
355 #[derive(Copy, Clone, Debug, Default)]
356 #[repr(C)]
357 struct virtio_input_event {
358 type_: Le16,
359 code: Le16,
360 value: Le32,
361 }
362
363 // Safe because it only has data and has no implicit padding.
364 unsafe impl DataInit for virtio_input_event {}
365
366 impl virtio_input_event {
367 const EVENT_SIZE: usize = size_of::<virtio_input_event>();
new(type_: u16, code: u16, value: u32) -> virtio_input_event368 fn new(type_: u16, code: u16, value: u32) -> virtio_input_event {
369 virtio_input_event {
370 type_: Le16::from(type_),
371 code: Le16::from(code),
372 value: Le32::from(value),
373 }
374 }
375
from_input_event(other: &input_event) -> virtio_input_event376 fn from_input_event(other: &input_event) -> virtio_input_event {
377 virtio_input_event {
378 type_: Le16::from(other.type_),
379 code: Le16::from(other.code),
380 value: Le32::from(other.value),
381 }
382 }
383 }
384
385 struct Worker<T: EventSource> {
386 event_source: T,
387 event_queue: Queue,
388 status_queue: Queue,
389 guest_memory: GuestMemory,
390 interrupt_status: Arc<AtomicUsize>,
391 interrupt_evt: EventFd,
392 interrupt_resample_evt: EventFd,
393 }
394
395 impl<T: EventSource> Worker<T> {
signal_used_queue(&self)396 fn signal_used_queue(&self) {
397 self.interrupt_status
398 .fetch_or(INTERRUPT_STATUS_USED_RING as usize, Ordering::SeqCst);
399 self.interrupt_evt.write(1).unwrap();
400 }
401
402 // Send events from the source to the guest
send_events(&mut self) -> bool403 fn send_events(&mut self) -> bool {
404 let queue = &mut self.event_queue;
405 let mut needs_interrupt = false;
406
407 // Only consume from the queue iterator if we know we have events to send
408 while self.event_source.available_events_count() > 0 {
409 match queue.pop(&self.guest_memory) {
410 None => {
411 break;
412 }
413 Some(avail_desc) => {
414 if !avail_desc.is_write_only() {
415 panic!("Received a read only descriptor on event queue");
416 }
417 let avail_events_size =
418 self.event_source.available_events_count() * virtio_input_event::EVENT_SIZE;
419 let len = min(avail_desc.len as usize, avail_events_size);
420 if let Err(e) =
421 self.guest_memory
422 .read_to_memory(avail_desc.addr, &self.event_source, len)
423 {
424 // Read is guaranteed to succeed here, so the only possible failure would be
425 // writing outside the guest memory region, which would mean the address and
426 // length given in the queue descriptor are wrong.
427 panic!("failed reading events into guest memory: {}", e);
428 }
429
430 queue.add_used(&self.guest_memory, avail_desc.index, len as u32);
431 needs_interrupt = true;
432 }
433 }
434 }
435
436 needs_interrupt
437 }
438
process_status_queue(&mut self) -> Result<bool>439 fn process_status_queue(&mut self) -> Result<bool> {
440 let queue = &mut self.status_queue;
441
442 let mut needs_interrupt = false;
443 while let Some(avail_desc) = queue.pop(&self.guest_memory) {
444 if !avail_desc.is_read_only() {
445 panic!("Received a writable descriptor on status queue");
446 }
447 let len = avail_desc.len as usize;
448 if len % virtio_input_event::EVENT_SIZE != 0 {
449 warn!(
450 "Ignoring buffer of unexpected size on status queue: {:0}",
451 len
452 );
453 } else {
454 self.guest_memory
455 .write_from_memory(avail_desc.addr, &self.event_source, len)
456 .map_err(InputError::EventsWriteError)?;
457 }
458
459 queue.add_used(&self.guest_memory, avail_desc.index, len as u32);
460 needs_interrupt = true;
461 }
462
463 Ok(needs_interrupt)
464 }
465
run( &mut self, event_queue_evt_fd: EventFd, status_queue_evt_fd: EventFd, kill_evt: EventFd, )466 fn run(
467 &mut self,
468 event_queue_evt_fd: EventFd,
469 status_queue_evt_fd: EventFd,
470 kill_evt: EventFd,
471 ) {
472 if let Err(e) = self.event_source.init() {
473 error!("failed initializing event source: {}", e);
474 return;
475 }
476
477 #[derive(PollToken)]
478 enum Token {
479 EventQAvailable,
480 StatusQAvailable,
481 InputEventsAvailable,
482 InterruptResample,
483 Kill,
484 }
485 let poll_ctx: PollContext<Token> = match PollContext::new()
486 .and_then(|pc| {
487 pc.add(&event_queue_evt_fd, Token::EventQAvailable)
488 .and(Ok(pc))
489 })
490 .and_then(|pc| {
491 pc.add(&status_queue_evt_fd, Token::StatusQAvailable)
492 .and(Ok(pc))
493 })
494 .and_then(|pc| {
495 pc.add(&self.event_source, Token::InputEventsAvailable)
496 .and(Ok(pc))
497 })
498 .and_then(|pc| {
499 pc.add(&self.interrupt_resample_evt, Token::InterruptResample)
500 .and(Ok(pc))
501 })
502 .and_then(|pc| pc.add(&kill_evt, Token::Kill).and(Ok(pc)))
503 {
504 Ok(poll_ctx) => poll_ctx,
505 Err(e) => {
506 error!("failed creating PollContext: {}", e);
507 return;
508 }
509 };
510
511 'poll: loop {
512 let poll_events = match poll_ctx.wait() {
513 Ok(poll_events) => poll_events,
514 Err(e) => {
515 error!("failed polling for events: {}", e);
516 break;
517 }
518 };
519
520 let mut needs_interrupt = false;
521 for poll_event in poll_events.iter_readable() {
522 match poll_event.token() {
523 Token::EventQAvailable => {
524 if let Err(e) = event_queue_evt_fd.read() {
525 error!("failed reading event queue EventFd: {}", e);
526 break 'poll;
527 }
528 needs_interrupt |= self.send_events();
529 }
530 Token::StatusQAvailable => {
531 if let Err(e) = status_queue_evt_fd.read() {
532 error!("failed reading status queue EventFd: {}", e);
533 break 'poll;
534 }
535 match self.process_status_queue() {
536 Ok(b) => needs_interrupt |= b,
537 Err(e) => error!("failed processing status events: {}", e),
538 }
539 }
540 Token::InputEventsAvailable => match self.event_source.receive_events() {
541 Err(e) => error!("error receiving events: {}", e),
542 Ok(_cnt) => needs_interrupt |= self.send_events(),
543 },
544 Token::InterruptResample => {
545 let _ = self.interrupt_resample_evt.read();
546 if self.interrupt_status.load(Ordering::SeqCst) != 0 {
547 self.interrupt_evt.write(1).unwrap();
548 }
549 }
550 Token::Kill => {
551 let _ = kill_evt.read();
552 break 'poll;
553 }
554 }
555 }
556 if needs_interrupt {
557 self.signal_used_queue();
558 }
559 }
560
561 if let Err(e) = self.event_source.finalize() {
562 error!("failed finalizing event source: {}", e);
563 return;
564 }
565 }
566 }
567
568 /// Virtio input device
569
570 pub struct Input<T: EventSource> {
571 kill_evt: Option<EventFd>,
572 config: VirtioInputConfig,
573 source: Option<T>,
574 }
575
576 impl<T: EventSource> Drop for Input<T> {
drop(&mut self)577 fn drop(&mut self) {
578 if let Some(kill_evt) = self.kill_evt.take() {
579 // Ignore the result because there is nothing we can do about it.
580 let _ = kill_evt.write(1);
581 }
582 }
583 }
584
585 impl<T> VirtioDevice for Input<T>
586 where
587 T: 'static + EventSource + Send,
588 {
keep_fds(&self) -> Vec<RawFd>589 fn keep_fds(&self) -> Vec<RawFd> {
590 if let Some(source) = &self.source {
591 return vec![source.as_raw_fd()];
592 }
593 Vec::new()
594 }
595
device_type(&self) -> u32596 fn device_type(&self) -> u32 {
597 TYPE_INPUT
598 }
599
queue_max_sizes(&self) -> &[u16]600 fn queue_max_sizes(&self) -> &[u16] {
601 QUEUE_SIZES
602 }
603
read_config(&self, offset: u64, data: &mut [u8])604 fn read_config(&self, offset: u64, data: &mut [u8]) {
605 self.config.read(offset as usize, data);
606 }
607
write_config(&mut self, offset: u64, data: &[u8])608 fn write_config(&mut self, offset: u64, data: &[u8]) {
609 self.config.write(offset as usize, data);
610 }
611
activate( &mut self, mem: GuestMemory, interrupt_evt: EventFd, interrupt_resample_evt: EventFd, status: Arc<AtomicUsize>, mut queues: Vec<Queue>, mut queue_evts: Vec<EventFd>, )612 fn activate(
613 &mut self,
614 mem: GuestMemory,
615 interrupt_evt: EventFd,
616 interrupt_resample_evt: EventFd,
617 status: Arc<AtomicUsize>,
618 mut queues: Vec<Queue>,
619 mut queue_evts: Vec<EventFd>,
620 ) {
621 if queues.len() != 2 || queue_evts.len() != 2 {
622 return;
623 }
624
625 let (self_kill_evt, kill_evt) = match EventFd::new().and_then(|e| Ok((e.try_clone()?, e))) {
626 Ok(v) => v,
627 Err(e) => {
628 error!("failed to create kill EventFd pair: {}", e);
629 return;
630 }
631 };
632 self.kill_evt = Some(self_kill_evt);
633
634 // Status is queue 1, event is queue 0
635 let status_queue = queues.remove(1);
636 let status_queue_evt_fd = queue_evts.remove(1);
637
638 let event_queue = queues.remove(0);
639 let event_queue_evt_fd = queue_evts.remove(0);
640
641 if let Some(source) = self.source.take() {
642 let worker_result = thread::Builder::new()
643 .name(String::from("virtio_input"))
644 .spawn(move || {
645 let mut worker = Worker {
646 event_source: source,
647 event_queue,
648 status_queue,
649 guest_memory: mem,
650 interrupt_status: status,
651 interrupt_evt,
652 interrupt_resample_evt,
653 };
654 worker.run(event_queue_evt_fd, status_queue_evt_fd, kill_evt);
655 });
656
657 if let Err(e) = worker_result {
658 error!("failed to spawn virtio_input worker: {}", e);
659 return;
660 }
661 } else {
662 error!("tried to activate device without a source for events");
663 return;
664 }
665 }
666 }
667
668 /// Creates a new virtio input device from an event device node
new_evdev<T>(source: T) -> Result<Input<EvdevEventSource<T>>> where T: Read + Write + AsRawFd,669 pub fn new_evdev<T>(source: T) -> Result<Input<EvdevEventSource<T>>>
670 where
671 T: Read + Write + AsRawFd,
672 {
673 Ok(Input {
674 kill_evt: None,
675 config: VirtioInputConfig::from_evdev(&source)?,
676 source: Some(EvdevEventSource::new(source)),
677 })
678 }
679
680 /// Creates a new virtio touch device which supports single touch only.
new_single_touch<T>( source: T, width: u32, height: u32, ) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawFd,681 pub fn new_single_touch<T>(
682 source: T,
683 width: u32,
684 height: u32,
685 ) -> Result<Input<SocketEventSource<T>>>
686 where
687 T: Read + Write + AsRawFd,
688 {
689 Ok(Input {
690 kill_evt: None,
691 config: defaults::new_single_touch_config(width, height),
692 source: Some(SocketEventSource::new(source)),
693 })
694 }
695
696 /// Creates a new virtio trackpad device which supports (single) touch, primary and secondary
697 /// buttons as well as X and Y axis.
new_trackpad<T>(source: T, width: u32, height: u32) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawFd,698 pub fn new_trackpad<T>(source: T, width: u32, height: u32) -> Result<Input<SocketEventSource<T>>>
699 where
700 T: Read + Write + AsRawFd,
701 {
702 Ok(Input {
703 kill_evt: None,
704 config: defaults::new_trackpad_config(width, height),
705 source: Some(SocketEventSource::new(source)),
706 })
707 }
708
709 /// Creates a new virtio mouse which supports primary, secondary, wheel and REL events.
new_mouse<T>(source: T) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawFd,710 pub fn new_mouse<T>(source: T) -> Result<Input<SocketEventSource<T>>>
711 where
712 T: Read + Write + AsRawFd,
713 {
714 Ok(Input {
715 kill_evt: None,
716 config: defaults::new_mouse_config(),
717 source: Some(SocketEventSource::new(source)),
718 })
719 }
720
721 /// Creates a new virtio keyboard, which supports the same events as an en-us physical keyboard.
new_keyboard<T>(source: T) -> Result<Input<SocketEventSource<T>>> where T: Read + Write + AsRawFd,722 pub fn new_keyboard<T>(source: T) -> Result<Input<SocketEventSource<T>>>
723 where
724 T: Read + Write + AsRawFd,
725 {
726 Ok(Input {
727 kill_evt: None,
728 config: defaults::new_keyboard_config(),
729 source: Some(SocketEventSource::new(source)),
730 })
731 }
732