linux_input_sys/
lib.rs

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
7pub mod constants;
8
9use std::mem::size_of;
10
11use constants::*;
12use data_model::Le16;
13use data_model::SLe32;
14use zerocopy::FromBytes;
15use zerocopy::Immutable;
16use zerocopy::IntoBytes;
17use zerocopy::KnownLayout;
18
19/// Allows a raw input event of the implementor's type to be decoded into
20/// a virtio_input_event.
21pub 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)]
30pub struct input_event {
31    pub timestamp_fields: [u64; 2],
32    pub type_: u16,
33    pub code: u16,
34    pub value: i32,
35}
36
37impl 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
48impl 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)]
65pub struct virtio_input_event {
66    pub type_: Le16,
67    pub code: Le16,
68    pub value: SLe32,
69}
70
71impl 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
79impl 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}