• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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