diff options
author | Noah Gold <nkgold@google.com> | 2020-02-01 13:01:58 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-03-06 01:00:39 +0000 |
commit | dc7f52bdb76a8f3b3cf6260bc0d861758956991e (patch) | |
tree | abde34b5dc09609981c695f5de5772fe2661358a /linux_input_sys/src | |
parent | d2a862b41f07d387926f0b984c56dc838003102c (diff) | |
download | crosvm-dc7f52bdb76a8f3b3cf6260bc0d861758956991e.tar crosvm-dc7f52bdb76a8f3b3cf6260bc0d861758956991e.tar.gz crosvm-dc7f52bdb76a8f3b3cf6260bc0d861758956991e.tar.bz2 crosvm-dc7f52bdb76a8f3b3cf6260bc0d861758956991e.tar.lz crosvm-dc7f52bdb76a8f3b3cf6260bc0d861758956991e.tar.xz crosvm-dc7f52bdb76a8f3b3cf6260bc0d861758956991e.tar.zst crosvm-dc7f52bdb76a8f3b3cf6260bc0d861758956991e.zip |
Use simple virtio_input_events where possible.
Previously, all input events in CrosVM were required to be linux input_events, which have a timestamp field that is actually unused by when we send/receive from the guest which are of type virtio_input_event. This CL allows CrosVM to understand both types of input events in a first class manner. It is a follow up on https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1930405. This CL also addresses some bugs with window driven input: 1. attach_event_device was being called before the surface was created, so the devices were never attached. 2. The default touchpad size was not being set to the display window size. Additionally, it removes the unused event "filter" feature on event sources. Breaking change: from this point forward, CrosVM will treat input events sent via a socket (e.g. SocketEventSource) to be virtio_input_events. BUG=None TEST=builds + manual Change-Id: I7fec07c582e5a071a6f116975ba70d6e621bb483 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2034046 Reviewed-by: Zach Reizner <zachr@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Noah Gold <nkgold@google.com>
Diffstat (limited to 'linux_input_sys/src')
-rw-r--r-- | linux_input_sys/src/lib.rs | 99 |
1 files changed, 75 insertions, 24 deletions
diff --git a/linux_input_sys/src/lib.rs b/linux_input_sys/src/lib.rs index 3880be2..f70dcc9 100644 --- a/linux_input_sys/src/lib.rs +++ b/linux_input_sys/src/lib.rs @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use data_model::DataInit; +use data_model::{DataInit, Le16, Le32}; use std::mem::size_of; const EV_SYN: u16 = 0x00; @@ -20,6 +20,13 @@ const ABS_Y: u16 = 0x01; const BTN_TOUCH: u16 = 0x14a; const BTN_TOOL_FINGER: u16 = 0x145; +/// Allows a raw input event of the implementor's type to be decoded into +/// a virtio_input_event. +pub trait InputEventDecoder { + const SIZE: usize; + fn decode(data: &[u8]) -> virtio_input_event; +} + #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] #[repr(C)] pub struct input_event { @@ -32,55 +39,99 @@ pub struct input_event { unsafe impl DataInit for input_event {} impl input_event { - pub const EVENT_SIZE: usize = size_of::<input_event>(); - - #[inline] - pub fn syn() -> input_event { + pub fn from_virtio_input_event(other: &virtio_input_event) -> input_event { input_event { timestamp_fields: [0, 0], - type_: EV_SYN, - code: SYN_REPORT, - value: 0, + type_: other.type_.into(), + code: other.code.into(), + value: other.value.into(), + } + } +} + +impl InputEventDecoder for input_event { + const SIZE: usize = size_of::<Self>(); + + fn decode(data: &[u8]) -> virtio_input_event { + #[repr(align(8))] + struct Aligner([u8; input_event::SIZE]); + let data_aligned = Aligner(*<[u8; input_event::SIZE]>::from_slice(data).unwrap()); + let e = Self::from_slice(&data_aligned.0).unwrap(); + virtio_input_event { + type_: Le16::from(e.type_), + code: Le16::from(e.code), + value: Le32::from(e.value), + } + } +} + +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] +#[repr(C)] +pub struct virtio_input_event { + pub type_: Le16, + pub code: Le16, + pub value: Le32, +} + +// Safe because it only has data and has no implicit padding. +unsafe impl DataInit for virtio_input_event {} + +impl InputEventDecoder for virtio_input_event { + const SIZE: usize = size_of::<Self>(); + + fn decode(data: &[u8]) -> virtio_input_event { + #[repr(align(4))] + struct Aligner([u8; virtio_input_event::SIZE]); + let data_aligned = Aligner(*<[u8; virtio_input_event::SIZE]>::from_slice(data).unwrap()); + *Self::from_slice(&data_aligned.0).unwrap() + } +} + +impl virtio_input_event { + #[inline] + pub fn syn() -> virtio_input_event { + virtio_input_event { + type_: Le16::from(EV_SYN), + code: Le16::from(SYN_REPORT), + value: Le32::from(0), } } #[inline] - pub fn absolute(code: u16, value: u32) -> input_event { - input_event { - timestamp_fields: [0, 0], - type_: EV_ABS, - code, - value, + pub fn absolute(code: u16, value: u32) -> virtio_input_event { + virtio_input_event { + type_: Le16::from(EV_ABS), + code: Le16::from(code), + value: Le32::from(value), } } #[inline] - pub fn absolute_x(x: u32) -> input_event { + pub fn absolute_x(x: u32) -> virtio_input_event { Self::absolute(ABS_X, x) } #[inline] - pub fn absolute_y(y: u32) -> input_event { + pub fn absolute_y(y: u32) -> virtio_input_event { Self::absolute(ABS_Y, y) } #[inline] - pub fn touch(has_contact: bool) -> input_event { + pub fn touch(has_contact: bool) -> virtio_input_event { Self::key(BTN_TOUCH, has_contact) } #[inline] - pub fn finger_tool(active: bool) -> input_event { + pub fn finger_tool(active: bool) -> virtio_input_event { Self::key(BTN_TOOL_FINGER, active) } #[inline] - pub fn key(code: u16, pressed: bool) -> input_event { - input_event { - timestamp_fields: [0, 0], - type_: EV_KEY, - code, - value: if pressed { 1 } else { 0 }, + pub fn key(code: u16, pressed: bool) -> virtio_input_event { + virtio_input_event { + type_: Le16::from(EV_KEY), + code: Le16::from(code), + value: Le32::from(if pressed { 1 } else { 0 }), } } } |