Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/linux_input_sys/src/lib.rs
5394 views
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
pub mod constants;
8
9
use std::mem::size_of;
10
11
use constants::*;
12
use data_model::Le16;
13
use data_model::SLe32;
14
use zerocopy::FromBytes;
15
use zerocopy::Immutable;
16
use zerocopy::IntoBytes;
17
use zerocopy::KnownLayout;
18
19
/// Allows a raw input event of the implementor's type to be decoded into
20
/// a virtio_input_event.
21
pub trait InputEventDecoder {
22
const SIZE: usize;
23
fn decode(data: &[u8]) -> virtio_input_event;
24
}
25
26
#[derive(
27
Copy, Clone, Debug, Default, Eq, PartialEq, FromBytes, Immutable, IntoBytes, KnownLayout,
28
)]
29
#[repr(C)]
30
pub struct input_event {
31
pub timestamp_fields: [u64; 2],
32
pub type_: u16,
33
pub code: u16,
34
pub value: i32,
35
}
36
37
impl input_event {
38
pub fn from_virtio_input_event(other: &virtio_input_event) -> input_event {
39
input_event {
40
timestamp_fields: [0, 0],
41
type_: other.type_.into(),
42
code: other.code.into(),
43
value: other.value.into(),
44
}
45
}
46
}
47
48
impl InputEventDecoder for input_event {
49
const SIZE: usize = size_of::<Self>();
50
51
fn decode(data: &[u8]) -> virtio_input_event {
52
let e = input_event::read_from_bytes(data).unwrap();
53
virtio_input_event {
54
type_: Le16::from(e.type_),
55
code: Le16::from(e.code),
56
value: SLe32::from(e.value),
57
}
58
}
59
}
60
61
#[derive(
62
Copy, Clone, Debug, Default, Eq, PartialEq, FromBytes, Immutable, IntoBytes, KnownLayout,
63
)]
64
#[repr(C)]
65
pub struct virtio_input_event {
66
pub type_: Le16,
67
pub code: Le16,
68
pub value: SLe32,
69
}
70
71
impl InputEventDecoder for virtio_input_event {
72
const SIZE: usize = size_of::<Self>();
73
74
fn decode(data: &[u8]) -> virtio_input_event {
75
virtio_input_event::read_from_bytes(data).unwrap()
76
}
77
}
78
79
impl virtio_input_event {
80
#[inline]
81
pub fn syn() -> virtio_input_event {
82
virtio_input_event {
83
type_: Le16::from(EV_SYN),
84
code: Le16::from(SYN_REPORT),
85
value: SLe32::from(0),
86
}
87
}
88
89
#[inline]
90
pub fn absolute(code: u16, value: i32) -> virtio_input_event {
91
virtio_input_event {
92
type_: Le16::from(EV_ABS),
93
code: Le16::from(code),
94
value: SLe32::from(value),
95
}
96
}
97
98
#[inline]
99
pub fn relative(code: u16, value: i32) -> virtio_input_event {
100
virtio_input_event {
101
type_: Le16::from(EV_REL),
102
code: Le16::from(code),
103
value: SLe32::from(value),
104
}
105
}
106
107
#[inline]
108
pub fn multitouch_tracking_id(id: i32) -> virtio_input_event {
109
Self::absolute(ABS_MT_TRACKING_ID, id)
110
}
111
112
#[inline]
113
pub fn multitouch_slot(slot: i32) -> virtio_input_event {
114
Self::absolute(ABS_MT_SLOT, slot)
115
}
116
117
#[inline]
118
pub fn multitouch_absolute_x(x: i32) -> virtio_input_event {
119
Self::absolute(ABS_MT_POSITION_X, x)
120
}
121
122
#[inline]
123
pub fn multitouch_absolute_y(y: i32) -> virtio_input_event {
124
Self::absolute(ABS_MT_POSITION_Y, y)
125
}
126
127
#[inline]
128
pub fn absolute_x(x: i32) -> virtio_input_event {
129
Self::absolute(ABS_X, x)
130
}
131
132
#[inline]
133
pub fn absolute_y(y: i32) -> virtio_input_event {
134
Self::absolute(ABS_Y, y)
135
}
136
137
#[inline]
138
pub fn relative_x(x: i32) -> virtio_input_event {
139
Self::relative(REL_X, x)
140
}
141
142
#[inline]
143
pub fn relative_y(y: i32) -> virtio_input_event {
144
Self::relative(REL_Y, y)
145
}
146
147
#[inline]
148
pub fn touch(has_contact: bool) -> virtio_input_event {
149
Self::key(BTN_TOUCH, has_contact, false)
150
}
151
152
#[inline]
153
pub fn left_click(has_contact: bool) -> virtio_input_event {
154
Self::key(BTN_LEFT, has_contact, false)
155
}
156
157
#[inline]
158
pub fn wheel(delta: i32) -> virtio_input_event {
159
Self::relative(REL_WHEEL, delta)
160
}
161
162
#[inline]
163
pub fn right_click(has_contact: bool) -> virtio_input_event {
164
Self::key(BTN_RIGHT, has_contact, false)
165
}
166
167
#[inline]
168
pub fn middle_click(has_contact: bool) -> virtio_input_event {
169
Self::key(BTN_MIDDLE, has_contact, false)
170
}
171
172
#[inline]
173
pub fn forward_click(has_contact: bool) -> virtio_input_event {
174
Self::key(BTN_FORWARD, has_contact, false)
175
}
176
177
#[inline]
178
pub fn back_click(has_contact: bool) -> virtio_input_event {
179
Self::key(BTN_BACK, has_contact, false)
180
}
181
182
#[inline]
183
pub fn finger_tool(active: bool) -> virtio_input_event {
184
Self::key(BTN_TOOL_FINGER, active, false)
185
}
186
187
/// Repeated keys must set the `repeat` option if the key was already down, or repeated keys
188
/// will not be seen correctly by the guest.
189
#[inline]
190
pub fn key(code: u16, down: bool, repeat: bool) -> virtio_input_event {
191
virtio_input_event {
192
type_: Le16::from(EV_KEY),
193
code: Le16::from(code),
194
value: SLe32::from(match (down, repeat) {
195
(true, true) => 2,
196
(true, false) => 1,
197
// repeat is not meaningful for key up events.
198
_ => 0,
199
}),
200
}
201
}
202
203
/// If the event is EV_LED for the given LED code, return if it is on.
204
pub fn get_led_state(&self, led_code: u16) -> Option<bool> {
205
if self.type_ == EV_LED && self.code == led_code {
206
return match self.value.to_native() {
207
0 => Some(false),
208
1 => Some(true),
209
_ => None,
210
};
211
}
212
None
213
}
214
}
215
216