1 // Copyright 2019 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 //! Linux input system bindings. 6 7 use std::mem::size_of; 8 9 use data_model::zerocopy_from_slice; 10 use data_model::Le16; 11 use data_model::SLe32; 12 use zerocopy::AsBytes; 13 use zerocopy::FromBytes; 14 15 pub const EV_SYN: u16 = 0x00; 16 pub const EV_KEY: u16 = 0x01; 17 pub const EV_REL: u16 = 0x02; 18 pub const EV_ABS: u16 = 0x03; 19 pub const SYN_REPORT: u16 = 0; 20 pub const REL_X: u16 = 0x00; 21 pub const REL_Y: u16 = 0x01; 22 pub const ABS_X: u16 = 0x00; 23 pub const ABS_Y: u16 = 0x01; 24 pub const ABS_PRESSURE: u16 = 0x18; 25 pub const ABS_TILT_X: u16 = 0x1a; 26 pub const ABS_TILT_Y: u16 = 0x1b; 27 pub const ABS_TOOL_WIDTH: u16 = 0x1c; 28 pub const BTN_TOUCH: u16 = 0x14a; 29 pub const BTN_TOOL_FINGER: u16 = 0x145; 30 pub const ABS_MT_SLOT: u16 = 0x2f; 31 pub const ABS_MT_TOUCH_MAJOR: u16 = 0x30; 32 pub const ABS_MT_TOUCH_MINOR: u16 = 0x31; 33 pub const ABS_MT_WIDTH_MAJOR: u16 = 0x32; 34 pub const ABS_MT_WIDTH_MINOR: u16 = 0x33; 35 pub const ABS_MT_ORIENTATION: u16 = 0x34; 36 pub const ABS_MT_POSITION_X: u16 = 0x35; 37 pub const ABS_MT_POSITION_Y: u16 = 0x36; 38 pub const ABS_MT_TOOL_TYPE: u16 = 0x37; 39 pub const ABS_MT_BLOB_ID: u16 = 0x38; 40 pub const ABS_MT_TRACKING_ID: u16 = 0x39; 41 pub const ABS_MT_PRESSURE: u16 = 0x3a; 42 pub const ABS_MT_DISTANCE: u16 = 0x3b; 43 pub const ABS_MT_TOOL_X: u16 = 0x3c; 44 pub const ABS_MT_TOOL_Y: u16 = 0x3d; 45 46 /// Allows a raw input event of the implementor's type to be decoded into 47 /// a virtio_input_event. 48 pub trait InputEventDecoder { 49 const SIZE: usize; decode(data: &[u8]) -> virtio_input_event50 fn decode(data: &[u8]) -> virtio_input_event; 51 } 52 53 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, FromBytes, AsBytes)] 54 #[repr(C)] 55 pub struct input_event { 56 pub timestamp_fields: [u64; 2], 57 pub type_: u16, 58 pub code: u16, 59 pub value: i32, 60 } 61 62 impl input_event { from_virtio_input_event(other: &virtio_input_event) -> input_event63 pub fn from_virtio_input_event(other: &virtio_input_event) -> input_event { 64 input_event { 65 timestamp_fields: [0, 0], 66 type_: other.type_.into(), 67 code: other.code.into(), 68 value: other.value.into(), 69 } 70 } 71 } 72 73 impl InputEventDecoder for input_event { 74 const SIZE: usize = size_of::<Self>(); 75 decode(data: &[u8]) -> virtio_input_event76 fn decode(data: &[u8]) -> virtio_input_event { 77 #[repr(align(8))] 78 #[derive(FromBytes)] 79 struct Aligner([u8; input_event::SIZE]); 80 let data_aligned = zerocopy_from_slice::<Aligner>(data).unwrap(); 81 let e: &input_event = zerocopy_from_slice(data_aligned.0.as_bytes()).unwrap(); 82 virtio_input_event { 83 type_: Le16::from(e.type_), 84 code: Le16::from(e.code), 85 value: SLe32::from(e.value), 86 } 87 } 88 } 89 90 #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, AsBytes, FromBytes)] 91 #[repr(C)] 92 pub struct virtio_input_event { 93 pub type_: Le16, 94 pub code: Le16, 95 pub value: SLe32, 96 } 97 98 impl InputEventDecoder for virtio_input_event { 99 const SIZE: usize = size_of::<Self>(); 100 decode(data: &[u8]) -> virtio_input_event101 fn decode(data: &[u8]) -> virtio_input_event { 102 #[repr(align(4))] 103 #[derive(FromBytes)] 104 struct Aligner([u8; virtio_input_event::SIZE]); 105 let data_aligned = zerocopy_from_slice::<Aligner>(data).unwrap(); 106 *zerocopy_from_slice(data_aligned.0.as_bytes()).unwrap() 107 } 108 } 109 110 impl virtio_input_event { 111 #[inline] syn() -> virtio_input_event112 pub fn syn() -> virtio_input_event { 113 virtio_input_event { 114 type_: Le16::from(EV_SYN), 115 code: Le16::from(SYN_REPORT), 116 value: SLe32::from(0), 117 } 118 } 119 120 #[inline] absolute(code: u16, value: i32) -> virtio_input_event121 pub fn absolute(code: u16, value: i32) -> virtio_input_event { 122 virtio_input_event { 123 type_: Le16::from(EV_ABS), 124 code: Le16::from(code), 125 value: SLe32::from(value), 126 } 127 } 128 129 #[inline] relative(code: u16, value: i32) -> virtio_input_event130 pub fn relative(code: u16, value: i32) -> virtio_input_event { 131 virtio_input_event { 132 type_: Le16::from(EV_REL), 133 code: Le16::from(code), 134 value: SLe32::from(value), 135 } 136 } 137 138 #[inline] multitouch_tracking_id(id: i32) -> virtio_input_event139 pub fn multitouch_tracking_id(id: i32) -> virtio_input_event { 140 Self::absolute(ABS_MT_TRACKING_ID, id) 141 } 142 143 #[inline] multitouch_slot(slot: i32) -> virtio_input_event144 pub fn multitouch_slot(slot: i32) -> virtio_input_event { 145 Self::absolute(ABS_MT_SLOT, slot) 146 } 147 148 #[inline] multitouch_absolute_x(x: i32) -> virtio_input_event149 pub fn multitouch_absolute_x(x: i32) -> virtio_input_event { 150 Self::absolute(ABS_MT_POSITION_X, x) 151 } 152 153 #[inline] multitouch_absolute_y(y: i32) -> virtio_input_event154 pub fn multitouch_absolute_y(y: i32) -> virtio_input_event { 155 Self::absolute(ABS_MT_POSITION_Y, y) 156 } 157 158 #[inline] absolute_x(x: i32) -> virtio_input_event159 pub fn absolute_x(x: i32) -> virtio_input_event { 160 Self::absolute(ABS_X, x) 161 } 162 163 #[inline] absolute_y(y: i32) -> virtio_input_event164 pub fn absolute_y(y: i32) -> virtio_input_event { 165 Self::absolute(ABS_Y, y) 166 } 167 168 #[inline] relative_x(x: i32) -> virtio_input_event169 pub fn relative_x(x: i32) -> virtio_input_event { 170 Self::relative(REL_X, x) 171 } 172 173 #[inline] relative_y(y: i32) -> virtio_input_event174 pub fn relative_y(y: i32) -> virtio_input_event { 175 Self::relative(REL_Y, y) 176 } 177 178 #[inline] touch(has_contact: bool) -> virtio_input_event179 pub fn touch(has_contact: bool) -> virtio_input_event { 180 Self::key(BTN_TOUCH, has_contact) 181 } 182 183 #[inline] finger_tool(active: bool) -> virtio_input_event184 pub fn finger_tool(active: bool) -> virtio_input_event { 185 Self::key(BTN_TOOL_FINGER, active) 186 } 187 188 #[inline] key(code: u16, pressed: bool) -> virtio_input_event189 pub fn key(code: u16, pressed: bool) -> virtio_input_event { 190 virtio_input_event { 191 type_: Le16::from(EV_KEY), 192 code: Le16::from(code), 193 value: SLe32::from(i32::from(pressed)), 194 } 195 } 196 } 197