summary refs log tree commit diff
path: root/linux_input_sys/src
diff options
context:
space:
mode:
authorNoah Gold <nkgold@google.com>2020-02-01 13:01:58 -0800
committerCommit Bot <commit-bot@chromium.org>2020-03-06 01:00:39 +0000
commitdc7f52bdb76a8f3b3cf6260bc0d861758956991e (patch)
treeabde34b5dc09609981c695f5de5772fe2661358a /linux_input_sys/src
parentd2a862b41f07d387926f0b984c56dc838003102c (diff)
downloadcrosvm-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.rs99
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 }),
         }
     }
 }