1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2019 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker //! Linux input system bindings. 6*bb4ee6a4SAndroid Build Coastguard Worker 7*bb4ee6a4SAndroid Build Coastguard Worker pub mod constants; 8*bb4ee6a4SAndroid Build Coastguard Worker 9*bb4ee6a4SAndroid Build Coastguard Worker use std::mem::size_of; 10*bb4ee6a4SAndroid Build Coastguard Worker 11*bb4ee6a4SAndroid Build Coastguard Worker use constants::*; 12*bb4ee6a4SAndroid Build Coastguard Worker use data_model::Le16; 13*bb4ee6a4SAndroid Build Coastguard Worker use data_model::SLe32; 14*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::AsBytes; 15*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::FromBytes; 16*bb4ee6a4SAndroid Build Coastguard Worker use zerocopy::FromZeroes; 17*bb4ee6a4SAndroid Build Coastguard Worker 18*bb4ee6a4SAndroid Build Coastguard Worker /// Allows a raw input event of the implementor's type to be decoded into 19*bb4ee6a4SAndroid Build Coastguard Worker /// a virtio_input_event. 20*bb4ee6a4SAndroid Build Coastguard Worker pub trait InputEventDecoder { 21*bb4ee6a4SAndroid Build Coastguard Worker const SIZE: usize; decode(data: &[u8]) -> virtio_input_event22*bb4ee6a4SAndroid Build Coastguard Worker fn decode(data: &[u8]) -> virtio_input_event; 23*bb4ee6a4SAndroid Build Coastguard Worker } 24*bb4ee6a4SAndroid Build Coastguard Worker 25*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, FromZeroes, FromBytes, AsBytes)] 26*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)] 27*bb4ee6a4SAndroid Build Coastguard Worker pub struct input_event { 28*bb4ee6a4SAndroid Build Coastguard Worker pub timestamp_fields: [u64; 2], 29*bb4ee6a4SAndroid Build Coastguard Worker pub type_: u16, 30*bb4ee6a4SAndroid Build Coastguard Worker pub code: u16, 31*bb4ee6a4SAndroid Build Coastguard Worker pub value: i32, 32*bb4ee6a4SAndroid Build Coastguard Worker } 33*bb4ee6a4SAndroid Build Coastguard Worker 34*bb4ee6a4SAndroid Build Coastguard Worker impl input_event { from_virtio_input_event(other: &virtio_input_event) -> input_event35*bb4ee6a4SAndroid Build Coastguard Worker pub fn from_virtio_input_event(other: &virtio_input_event) -> input_event { 36*bb4ee6a4SAndroid Build Coastguard Worker input_event { 37*bb4ee6a4SAndroid Build Coastguard Worker timestamp_fields: [0, 0], 38*bb4ee6a4SAndroid Build Coastguard Worker type_: other.type_.into(), 39*bb4ee6a4SAndroid Build Coastguard Worker code: other.code.into(), 40*bb4ee6a4SAndroid Build Coastguard Worker value: other.value.into(), 41*bb4ee6a4SAndroid Build Coastguard Worker } 42*bb4ee6a4SAndroid Build Coastguard Worker } 43*bb4ee6a4SAndroid Build Coastguard Worker } 44*bb4ee6a4SAndroid Build Coastguard Worker 45*bb4ee6a4SAndroid Build Coastguard Worker impl InputEventDecoder for input_event { 46*bb4ee6a4SAndroid Build Coastguard Worker const SIZE: usize = size_of::<Self>(); 47*bb4ee6a4SAndroid Build Coastguard Worker decode(data: &[u8]) -> virtio_input_event48*bb4ee6a4SAndroid Build Coastguard Worker fn decode(data: &[u8]) -> virtio_input_event { 49*bb4ee6a4SAndroid Build Coastguard Worker let e = input_event::read_from(data).unwrap(); 50*bb4ee6a4SAndroid Build Coastguard Worker virtio_input_event { 51*bb4ee6a4SAndroid Build Coastguard Worker type_: Le16::from(e.type_), 52*bb4ee6a4SAndroid Build Coastguard Worker code: Le16::from(e.code), 53*bb4ee6a4SAndroid Build Coastguard Worker value: SLe32::from(e.value), 54*bb4ee6a4SAndroid Build Coastguard Worker } 55*bb4ee6a4SAndroid Build Coastguard Worker } 56*bb4ee6a4SAndroid Build Coastguard Worker } 57*bb4ee6a4SAndroid Build Coastguard Worker 58*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, AsBytes, FromZeroes, FromBytes)] 59*bb4ee6a4SAndroid Build Coastguard Worker #[repr(C)] 60*bb4ee6a4SAndroid Build Coastguard Worker pub struct virtio_input_event { 61*bb4ee6a4SAndroid Build Coastguard Worker pub type_: Le16, 62*bb4ee6a4SAndroid Build Coastguard Worker pub code: Le16, 63*bb4ee6a4SAndroid Build Coastguard Worker pub value: SLe32, 64*bb4ee6a4SAndroid Build Coastguard Worker } 65*bb4ee6a4SAndroid Build Coastguard Worker 66*bb4ee6a4SAndroid Build Coastguard Worker impl InputEventDecoder for virtio_input_event { 67*bb4ee6a4SAndroid Build Coastguard Worker const SIZE: usize = size_of::<Self>(); 68*bb4ee6a4SAndroid Build Coastguard Worker decode(data: &[u8]) -> virtio_input_event69*bb4ee6a4SAndroid Build Coastguard Worker fn decode(data: &[u8]) -> virtio_input_event { 70*bb4ee6a4SAndroid Build Coastguard Worker virtio_input_event::read_from(data).unwrap() 71*bb4ee6a4SAndroid Build Coastguard Worker } 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker 74*bb4ee6a4SAndroid Build Coastguard Worker impl virtio_input_event { 75*bb4ee6a4SAndroid Build Coastguard Worker #[inline] syn() -> virtio_input_event76*bb4ee6a4SAndroid Build Coastguard Worker pub fn syn() -> virtio_input_event { 77*bb4ee6a4SAndroid Build Coastguard Worker virtio_input_event { 78*bb4ee6a4SAndroid Build Coastguard Worker type_: Le16::from(EV_SYN), 79*bb4ee6a4SAndroid Build Coastguard Worker code: Le16::from(SYN_REPORT), 80*bb4ee6a4SAndroid Build Coastguard Worker value: SLe32::from(0), 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker } 83*bb4ee6a4SAndroid Build Coastguard Worker 84*bb4ee6a4SAndroid Build Coastguard Worker #[inline] absolute(code: u16, value: i32) -> virtio_input_event85*bb4ee6a4SAndroid Build Coastguard Worker pub fn absolute(code: u16, value: i32) -> virtio_input_event { 86*bb4ee6a4SAndroid Build Coastguard Worker virtio_input_event { 87*bb4ee6a4SAndroid Build Coastguard Worker type_: Le16::from(EV_ABS), 88*bb4ee6a4SAndroid Build Coastguard Worker code: Le16::from(code), 89*bb4ee6a4SAndroid Build Coastguard Worker value: SLe32::from(value), 90*bb4ee6a4SAndroid Build Coastguard Worker } 91*bb4ee6a4SAndroid Build Coastguard Worker } 92*bb4ee6a4SAndroid Build Coastguard Worker 93*bb4ee6a4SAndroid Build Coastguard Worker #[inline] relative(code: u16, value: i32) -> virtio_input_event94*bb4ee6a4SAndroid Build Coastguard Worker pub fn relative(code: u16, value: i32) -> virtio_input_event { 95*bb4ee6a4SAndroid Build Coastguard Worker virtio_input_event { 96*bb4ee6a4SAndroid Build Coastguard Worker type_: Le16::from(EV_REL), 97*bb4ee6a4SAndroid Build Coastguard Worker code: Le16::from(code), 98*bb4ee6a4SAndroid Build Coastguard Worker value: SLe32::from(value), 99*bb4ee6a4SAndroid Build Coastguard Worker } 100*bb4ee6a4SAndroid Build Coastguard Worker } 101*bb4ee6a4SAndroid Build Coastguard Worker 102*bb4ee6a4SAndroid Build Coastguard Worker #[inline] multitouch_tracking_id(id: i32) -> virtio_input_event103*bb4ee6a4SAndroid Build Coastguard Worker pub fn multitouch_tracking_id(id: i32) -> virtio_input_event { 104*bb4ee6a4SAndroid Build Coastguard Worker Self::absolute(ABS_MT_TRACKING_ID, id) 105*bb4ee6a4SAndroid Build Coastguard Worker } 106*bb4ee6a4SAndroid Build Coastguard Worker 107*bb4ee6a4SAndroid Build Coastguard Worker #[inline] multitouch_slot(slot: i32) -> virtio_input_event108*bb4ee6a4SAndroid Build Coastguard Worker pub fn multitouch_slot(slot: i32) -> virtio_input_event { 109*bb4ee6a4SAndroid Build Coastguard Worker Self::absolute(ABS_MT_SLOT, slot) 110*bb4ee6a4SAndroid Build Coastguard Worker } 111*bb4ee6a4SAndroid Build Coastguard Worker 112*bb4ee6a4SAndroid Build Coastguard Worker #[inline] multitouch_absolute_x(x: i32) -> virtio_input_event113*bb4ee6a4SAndroid Build Coastguard Worker pub fn multitouch_absolute_x(x: i32) -> virtio_input_event { 114*bb4ee6a4SAndroid Build Coastguard Worker Self::absolute(ABS_MT_POSITION_X, x) 115*bb4ee6a4SAndroid Build Coastguard Worker } 116*bb4ee6a4SAndroid Build Coastguard Worker 117*bb4ee6a4SAndroid Build Coastguard Worker #[inline] multitouch_absolute_y(y: i32) -> virtio_input_event118*bb4ee6a4SAndroid Build Coastguard Worker pub fn multitouch_absolute_y(y: i32) -> virtio_input_event { 119*bb4ee6a4SAndroid Build Coastguard Worker Self::absolute(ABS_MT_POSITION_Y, y) 120*bb4ee6a4SAndroid Build Coastguard Worker } 121*bb4ee6a4SAndroid Build Coastguard Worker 122*bb4ee6a4SAndroid Build Coastguard Worker #[inline] absolute_x(x: i32) -> virtio_input_event123*bb4ee6a4SAndroid Build Coastguard Worker pub fn absolute_x(x: i32) -> virtio_input_event { 124*bb4ee6a4SAndroid Build Coastguard Worker Self::absolute(ABS_X, x) 125*bb4ee6a4SAndroid Build Coastguard Worker } 126*bb4ee6a4SAndroid Build Coastguard Worker 127*bb4ee6a4SAndroid Build Coastguard Worker #[inline] absolute_y(y: i32) -> virtio_input_event128*bb4ee6a4SAndroid Build Coastguard Worker pub fn absolute_y(y: i32) -> virtio_input_event { 129*bb4ee6a4SAndroid Build Coastguard Worker Self::absolute(ABS_Y, y) 130*bb4ee6a4SAndroid Build Coastguard Worker } 131*bb4ee6a4SAndroid Build Coastguard Worker 132*bb4ee6a4SAndroid Build Coastguard Worker #[inline] relative_x(x: i32) -> virtio_input_event133*bb4ee6a4SAndroid Build Coastguard Worker pub fn relative_x(x: i32) -> virtio_input_event { 134*bb4ee6a4SAndroid Build Coastguard Worker Self::relative(REL_X, x) 135*bb4ee6a4SAndroid Build Coastguard Worker } 136*bb4ee6a4SAndroid Build Coastguard Worker 137*bb4ee6a4SAndroid Build Coastguard Worker #[inline] relative_y(y: i32) -> virtio_input_event138*bb4ee6a4SAndroid Build Coastguard Worker pub fn relative_y(y: i32) -> virtio_input_event { 139*bb4ee6a4SAndroid Build Coastguard Worker Self::relative(REL_Y, y) 140*bb4ee6a4SAndroid Build Coastguard Worker } 141*bb4ee6a4SAndroid Build Coastguard Worker 142*bb4ee6a4SAndroid Build Coastguard Worker #[inline] touch(has_contact: bool) -> virtio_input_event143*bb4ee6a4SAndroid Build Coastguard Worker pub fn touch(has_contact: bool) -> virtio_input_event { 144*bb4ee6a4SAndroid Build Coastguard Worker Self::key(BTN_TOUCH, has_contact, false) 145*bb4ee6a4SAndroid Build Coastguard Worker } 146*bb4ee6a4SAndroid Build Coastguard Worker 147*bb4ee6a4SAndroid Build Coastguard Worker #[inline] left_click(has_contact: bool) -> virtio_input_event148*bb4ee6a4SAndroid Build Coastguard Worker pub fn left_click(has_contact: bool) -> virtio_input_event { 149*bb4ee6a4SAndroid Build Coastguard Worker Self::key(BTN_LEFT, has_contact, false) 150*bb4ee6a4SAndroid Build Coastguard Worker } 151*bb4ee6a4SAndroid Build Coastguard Worker 152*bb4ee6a4SAndroid Build Coastguard Worker #[inline] wheel(delta: i32) -> virtio_input_event153*bb4ee6a4SAndroid Build Coastguard Worker pub fn wheel(delta: i32) -> virtio_input_event { 154*bb4ee6a4SAndroid Build Coastguard Worker Self::relative(REL_WHEEL, delta) 155*bb4ee6a4SAndroid Build Coastguard Worker } 156*bb4ee6a4SAndroid Build Coastguard Worker 157*bb4ee6a4SAndroid Build Coastguard Worker #[inline] right_click(has_contact: bool) -> virtio_input_event158*bb4ee6a4SAndroid Build Coastguard Worker pub fn right_click(has_contact: bool) -> virtio_input_event { 159*bb4ee6a4SAndroid Build Coastguard Worker Self::key(BTN_RIGHT, has_contact, false) 160*bb4ee6a4SAndroid Build Coastguard Worker } 161*bb4ee6a4SAndroid Build Coastguard Worker 162*bb4ee6a4SAndroid Build Coastguard Worker #[inline] middle_click(has_contact: bool) -> virtio_input_event163*bb4ee6a4SAndroid Build Coastguard Worker pub fn middle_click(has_contact: bool) -> virtio_input_event { 164*bb4ee6a4SAndroid Build Coastguard Worker Self::key(BTN_MIDDLE, has_contact, false) 165*bb4ee6a4SAndroid Build Coastguard Worker } 166*bb4ee6a4SAndroid Build Coastguard Worker 167*bb4ee6a4SAndroid Build Coastguard Worker #[inline] forward_click(has_contact: bool) -> virtio_input_event168*bb4ee6a4SAndroid Build Coastguard Worker pub fn forward_click(has_contact: bool) -> virtio_input_event { 169*bb4ee6a4SAndroid Build Coastguard Worker Self::key(BTN_FORWARD, has_contact, false) 170*bb4ee6a4SAndroid Build Coastguard Worker } 171*bb4ee6a4SAndroid Build Coastguard Worker 172*bb4ee6a4SAndroid Build Coastguard Worker #[inline] back_click(has_contact: bool) -> virtio_input_event173*bb4ee6a4SAndroid Build Coastguard Worker pub fn back_click(has_contact: bool) -> virtio_input_event { 174*bb4ee6a4SAndroid Build Coastguard Worker Self::key(BTN_BACK, has_contact, false) 175*bb4ee6a4SAndroid Build Coastguard Worker } 176*bb4ee6a4SAndroid Build Coastguard Worker 177*bb4ee6a4SAndroid Build Coastguard Worker #[inline] finger_tool(active: bool) -> virtio_input_event178*bb4ee6a4SAndroid Build Coastguard Worker pub fn finger_tool(active: bool) -> virtio_input_event { 179*bb4ee6a4SAndroid Build Coastguard Worker Self::key(BTN_TOOL_FINGER, active, false) 180*bb4ee6a4SAndroid Build Coastguard Worker } 181*bb4ee6a4SAndroid Build Coastguard Worker 182*bb4ee6a4SAndroid Build Coastguard Worker /// Repeated keys must set the `repeat` option if the key was already down, or repeated keys 183*bb4ee6a4SAndroid Build Coastguard Worker /// will not be seen correctly by the guest. 184*bb4ee6a4SAndroid Build Coastguard Worker #[inline] key(code: u16, down: bool, repeat: bool) -> virtio_input_event185*bb4ee6a4SAndroid Build Coastguard Worker pub fn key(code: u16, down: bool, repeat: bool) -> virtio_input_event { 186*bb4ee6a4SAndroid Build Coastguard Worker virtio_input_event { 187*bb4ee6a4SAndroid Build Coastguard Worker type_: Le16::from(EV_KEY), 188*bb4ee6a4SAndroid Build Coastguard Worker code: Le16::from(code), 189*bb4ee6a4SAndroid Build Coastguard Worker value: SLe32::from(match (down, repeat) { 190*bb4ee6a4SAndroid Build Coastguard Worker (true, true) => 2, 191*bb4ee6a4SAndroid Build Coastguard Worker (true, false) => 1, 192*bb4ee6a4SAndroid Build Coastguard Worker // repeat is not meaningful for key up events. 193*bb4ee6a4SAndroid Build Coastguard Worker _ => 0, 194*bb4ee6a4SAndroid Build Coastguard Worker }), 195*bb4ee6a4SAndroid Build Coastguard Worker } 196*bb4ee6a4SAndroid Build Coastguard Worker } 197*bb4ee6a4SAndroid Build Coastguard Worker 198*bb4ee6a4SAndroid Build Coastguard Worker /// If the event is EV_LED for the given LED code, return if it is on. get_led_state(&self, led_code: u16) -> Option<bool>199*bb4ee6a4SAndroid Build Coastguard Worker pub fn get_led_state(&self, led_code: u16) -> Option<bool> { 200*bb4ee6a4SAndroid Build Coastguard Worker if self.type_ == EV_LED && self.code == led_code { 201*bb4ee6a4SAndroid Build Coastguard Worker return match self.value.to_native() { 202*bb4ee6a4SAndroid Build Coastguard Worker 0 => Some(false), 203*bb4ee6a4SAndroid Build Coastguard Worker 1 => Some(true), 204*bb4ee6a4SAndroid Build Coastguard Worker _ => None, 205*bb4ee6a4SAndroid Build Coastguard Worker }; 206*bb4ee6a4SAndroid Build Coastguard Worker } 207*bb4ee6a4SAndroid Build Coastguard Worker None 208*bb4ee6a4SAndroid Build Coastguard Worker } 209*bb4ee6a4SAndroid Build Coastguard Worker } 210