diff options
author | Jorge E. Moreira <jemoreira@google.com> | 2019-03-07 10:59:54 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-03-09 01:18:59 -0800 |
commit | 99d3f08dc5d4ad63d8596c349f9d207144e2c949 (patch) | |
tree | c3f2b3a7236d51b2ae1de66a8bcfbd37c028c0e4 | |
parent | e5828e7ecdb1b92645161e0b0b66e7645da92447 (diff) | |
download | crosvm-99d3f08dc5d4ad63d8596c349f9d207144e2c949.tar crosvm-99d3f08dc5d4ad63d8596c349f9d207144e2c949.tar.gz crosvm-99d3f08dc5d4ad63d8596c349f9d207144e2c949.tar.bz2 crosvm-99d3f08dc5d4ad63d8596c349f9d207144e2c949.tar.lz crosvm-99d3f08dc5d4ad63d8596c349f9d207144e2c949.tar.xz crosvm-99d3f08dc5d4ad63d8596c349f9d207144e2c949.tar.zst crosvm-99d3f08dc5d4ad63d8596c349f9d207144e2c949.zip |
Add a (single touch only) touch screen input device
Very similar to the trackpad device, it has the INPUT_PROP_DIRECT property and does not support any buttons, just touch events. Change-Id: I2c963013e402ff2aa1b4b529c6c494dd57f4add9 Reviewed-on: https://chromium-review.googlesource.com/1509697 Commit-Ready: Jorge Moreira Broche <jemoreira@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Dylan Reid <dgreid@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
-rw-r--r-- | devices/src/virtio/input/defaults.rs | 27 | ||||
-rw-r--r-- | devices/src/virtio/input/mod.rs | 16 | ||||
-rw-r--r-- | src/linux.rs | 22 | ||||
-rw-r--r-- | src/main.rs | 42 |
4 files changed, 95 insertions, 12 deletions
diff --git a/devices/src/virtio/input/defaults.rs b/devices/src/virtio/input/defaults.rs index f5343f7..a7a01d9 100644 --- a/devices/src/virtio/input/defaults.rs +++ b/devices/src/virtio/input/defaults.rs @@ -48,6 +48,33 @@ pub fn new_keyboard_config() -> VirtioInputConfig { ) } +/// Instantiates a VirtioInputConfig object with the default configuration for a touchscreen (no +/// multitouch support). +pub fn new_single_touch_config(width: u32, height: u32) -> VirtioInputConfig { + VirtioInputConfig::new( + virtio_input_device_ids::new(0, 0, 0, 0), + "Crosvm Virtio Touchscreen".as_bytes().to_vec(), + "virtio-touchscreen".as_bytes().to_vec(), + virtio_input_bitmap::from_bits(&[INPUT_PROP_DIRECT]), + default_touchscreen_events(), + default_touchscreen_absinfo(width, height), + ) +} + +fn default_touchscreen_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo> { + let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new(); + absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0)); + absinfo.insert(ABS_Y, virtio_input_absinfo::new(0, height, 0, 0)); + absinfo +} + +fn default_touchscreen_events() -> BTreeMap<u16, virtio_input_bitmap> { + let mut supported_events: BTreeMap<u16, virtio_input_bitmap> = BTreeMap::new(); + supported_events.insert(EV_KEY, virtio_input_bitmap::from_bits(&[BTN_TOUCH])); + supported_events.insert(EV_ABS, virtio_input_bitmap::from_bits(&[ABS_X, ABS_Y])); + supported_events +} + fn default_trackpad_absinfo(width: u32, height: u32) -> BTreeMap<u16, virtio_input_absinfo> { let mut absinfo: BTreeMap<u16, virtio_input_absinfo> = BTreeMap::new(); absinfo.insert(ABS_X, virtio_input_absinfo::new(0, width, 0, 0)); diff --git a/devices/src/virtio/input/mod.rs b/devices/src/virtio/input/mod.rs index 22ef168..98dac60 100644 --- a/devices/src/virtio/input/mod.rs +++ b/devices/src/virtio/input/mod.rs @@ -687,6 +687,22 @@ where }) } +/// Creates a new virtio touch device which supports single touch only. +pub fn new_single_touch<T>( + source: T, + width: u32, + height: u32, +) -> Result<Input<SocketEventSource<T>>> +where + T: Read + Write + AsRawFd, +{ + Ok(Input { + kill_evt: None, + config: defaults::new_single_touch_config(width, height), + source: Some(SocketEventSource::new(source)), + }) +} + /// Creates a new virtio trackpad device which supports (single) touch, primary and secondary /// buttons as well as X and Y axis. pub fn new_trackpad<T>(source: T, width: u32, height: u32) -> Result<Input<SocketEventSource<T>>> diff --git a/src/linux.rs b/src/linux.rs index 6398270..acea1de 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -44,7 +44,7 @@ use sys_util::{ use vhost; use vm_control::{VmRequest, VmResponse, VmRunMode}; -use crate::{Config, DiskOption, TrackpadOption}; +use crate::{Config, DiskOption, TouchDeviceOption}; use arch::{self, LinuxArch, RunnableLinuxVm, VirtioDeviceStub, VmComponents}; @@ -358,7 +358,21 @@ fn create_tpm_device(cfg: &Config) -> DeviceResult { }) } -fn create_trackpad_device(cfg: &Config, trackpad_spec: &TrackpadOption) -> DeviceResult { +fn create_single_touch_device(cfg: &Config, single_touch_spec: &TouchDeviceOption) -> DeviceResult { + let socket = create_input_socket(&single_touch_spec.path).map_err(|e| { + error!("failed configuring virtio single touch: {:?}", e); + e + })?; + + let dev = virtio::new_single_touch(socket, single_touch_spec.width, single_touch_spec.height) + .map_err(Error::InputDeviceNew)?; + Ok(VirtioDeviceStub { + dev: Box::new(dev), + jail: simple_jail(&cfg, "input_device.policy")?, + }) +} + +fn create_trackpad_device(cfg: &Config, trackpad_spec: &TouchDeviceOption) -> DeviceResult { let socket = create_input_socket(&trackpad_spec.path).map_err(|e| { error!("failed configuring virtio trackpad: {}", e); e @@ -651,6 +665,10 @@ fn create_virtio_devices( } } + if let Some(single_touch_spec) = &cfg.virtio_single_touch { + devs.push(create_single_touch_device(cfg, single_touch_spec)?); + } + if let Some(trackpad_spec) = &cfg.virtio_trackpad { devs.push(create_trackpad_device(cfg, trackpad_spec)?); } diff --git a/src/main.rs b/src/main.rs index c2e294f..c4228be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,21 +79,21 @@ struct GidMap { count: u32, } -const DEFAULT_TRACKPAD_WIDTH: u32 = 800; -const DEFAULT_TRACKPAD_HEIGHT: u32 = 1280; +const DEFAULT_TOUCH_DEVICE_WIDTH: u32 = 800; +const DEFAULT_TOUCH_DEVICE_HEIGHT: u32 = 1280; -struct TrackpadOption { +struct TouchDeviceOption { path: PathBuf, width: u32, height: u32, } -impl TrackpadOption { - fn new(path: PathBuf) -> TrackpadOption { - TrackpadOption { +impl TouchDeviceOption { + fn new(path: PathBuf) -> TouchDeviceOption { + TouchDeviceOption { path, - width: DEFAULT_TRACKPAD_WIDTH, - height: DEFAULT_TRACKPAD_HEIGHT, + width: DEFAULT_TOUCH_DEVICE_WIDTH, + height: DEFAULT_TOUCH_DEVICE_HEIGHT, } } } @@ -126,7 +126,8 @@ pub struct Config { software_tpm: bool, cras_audio: bool, null_audio: bool, - virtio_trackpad: Option<TrackpadOption>, + virtio_single_touch: Option<TouchDeviceOption>, + virtio_trackpad: Option<TouchDeviceOption>, virtio_mouse: Option<PathBuf>, virtio_keyboard: Option<PathBuf>, virtio_input_evdevs: Vec<PathBuf>, @@ -163,6 +164,7 @@ impl Default for Config { seccomp_policy_dir: PathBuf::from(SECCOMP_POLICY_DIR), cras_audio: false, null_audio: false, + virtio_single_touch: None, virtio_trackpad: None, virtio_mouse: None, virtio_keyboard: None, @@ -570,6 +572,25 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument:: "software-tpm" => { cfg.software_tpm = true; } + "single-touch" => { + if cfg.virtio_single_touch.is_some() { + return Err(argument::Error::TooManyArguments( + "`single-touch` already given".to_owned(), + )); + } + let mut it = value.unwrap().split(":"); + + let mut single_touch_spec = + TouchDeviceOption::new(PathBuf::from(it.next().unwrap().to_owned())); + if let Some(width) = it.next() { + single_touch_spec.width = width.trim().parse().unwrap(); + } + if let Some(height) = it.next() { + single_touch_spec.height = height.trim().parse().unwrap(); + } + + cfg.virtio_single_touch = Some(single_touch_spec); + } "trackpad" => { if cfg.virtio_trackpad.is_some() { return Err(argument::Error::TooManyArguments( @@ -579,7 +600,7 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument:: let mut it = value.unwrap().split(":"); let mut trackpad_spec = - TrackpadOption::new(PathBuf::from(it.next().unwrap().to_owned())); + TouchDeviceOption::new(PathBuf::from(it.next().unwrap().to_owned())); if let Some(width) = it.next() { trackpad_spec.width = width.trim().parse().unwrap(); } @@ -686,6 +707,7 @@ fn run_vm(args: std::env::Args) -> std::result::Result<(), ()> { #[cfg(feature = "tpm")] Argument::flag("software-tpm", "enable a software emulated trusted platform module device"), Argument::value("evdev", "PATH", "Path to an event device node. The device will be grabbed (unusable from the host) and made available to the guest with the same configuration it shows on the host"), + Argument::value("single-touch", "PATH:WIDTH:HEIGHT", "Path to a socket from where to read single touch input events (such as those from a touchscreen) and write status updates to, optionally followed by width and height (defaults to 800x1280)."), Argument::value("trackpad", "PATH:WIDTH:HEIGHT", "Path to a socket from where to read trackpad input events and write status updates to, optionally followed by screen width and height (defaults to 800x1280)."), Argument::value("mouse", "PATH", "Path to a socket from where to read mouse input events and write status updates to."), Argument::value("keyboard", "PATH", "Path to a socket from where to read keyboard input events and write status updates to."), |