blob: 5010475334a07845155c5950cb1a5fcc47bbf468 [file] [log] [blame]
Prabir Pradhan0762b1f2023-06-22 23:08:18 +00001/*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! The rust component of libinput.
18
19mod input;
20mod input_verifier;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000021mod keyboard_classifier;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000022
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000023pub use input::{
24 DeviceClass, DeviceId, InputDevice, ModifierState, MotionAction, MotionFlags, Source,
25};
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000026pub use input_verifier::InputVerifier;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000027pub use keyboard_classifier::KeyboardClassifier;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000028
29#[cxx::bridge(namespace = "android::input")]
Andrew Walbran37994222023-08-03 12:16:28 +000030#[allow(unsafe_op_in_unsafe_fn)]
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000031mod ffi {
32 #[namespace = "android"]
33 unsafe extern "C++" {
34 include!("ffi/FromRustToCpp.h");
35 fn shouldLog(tag: &str) -> bool;
36 }
37
38 #[namespace = "android::input::verifier"]
39 extern "Rust" {
40 /// Used to validate the incoming motion stream.
41 /// This class is not thread-safe.
42 /// State is stored in the "InputVerifier" object
43 /// that can be created via the 'create' method.
44 /// Usage:
45 ///
46 /// ```ignore
47 /// Box<InputVerifier> verifier = create("inputChannel name");
48 /// result = process_movement(verifier, ...);
49 /// if (result) {
50 /// crash(result.error_message());
51 /// }
52 /// ```
53 type InputVerifier;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000054 #[cxx_name = create]
55 fn create_input_verifier(name: String) -> Box<InputVerifier>;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000056 fn process_movement(
57 verifier: &mut InputVerifier,
58 device_id: i32,
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070059 source: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000060 action: u32,
61 pointer_properties: &[RustPointerProperties],
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -070062 flags: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000063 ) -> String;
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -070064 fn reset_device(verifier: &mut InputVerifier, device_id: i32);
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000065 }
66
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000067 #[namespace = "android::input::keyboardClassifier"]
68 extern "Rust" {
69 /// Used to classify a keyboard into alphabetic and non-alphabetic
70 type KeyboardClassifier;
71 #[cxx_name = create]
72 fn create_keyboard_classifier() -> Box<KeyboardClassifier>;
73 #[cxx_name = notifyKeyboardChanged]
74 fn notify_keyboard_changed(
75 classifier: &mut KeyboardClassifier,
76 device_id: i32,
77 identifier: RustInputDeviceIdentifier,
78 device_classes: u32,
79 );
80 #[cxx_name = getKeyboardType]
81 fn get_keyboard_type(classifier: &mut KeyboardClassifier, device_id: i32) -> u32;
82 #[cxx_name = isFinalized]
83 fn is_finalized(classifier: &mut KeyboardClassifier, device_id: i32) -> bool;
84 #[cxx_name = processKey]
85 fn process_key(
86 classifier: &mut KeyboardClassifier,
87 device_id: i32,
88 evdev_code: i32,
89 modifier_state: u32,
90 );
91 }
92
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000093 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
94 pub struct RustPointerProperties {
95 pub id: i32,
96 }
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000097
98 #[derive(Debug)]
99 pub struct RustInputDeviceIdentifier {
100 pub name: String,
101 pub location: String,
102 pub unique_id: String,
103 pub bus: u16,
104 pub vendor: u16,
105 pub product: u16,
106 pub version: u16,
107 pub descriptor: String,
108 }
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000109}
110
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000111use crate::ffi::{RustInputDeviceIdentifier, RustPointerProperties};
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000112
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000113fn create_input_verifier(name: String) -> Box<InputVerifier> {
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -0700114 Box::new(InputVerifier::new(&name, ffi::shouldLog("InputVerifierLogEvents")))
115}
116
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000117fn process_movement(
118 verifier: &mut InputVerifier,
119 device_id: i32,
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700120 source: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000121 action: u32,
122 pointer_properties: &[RustPointerProperties],
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700123 flags: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000124) -> String {
Linnan Li13ccabe2024-04-19 17:14:43 +0000125 let motion_flags = MotionFlags::from_bits(flags);
126 if motion_flags.is_none() {
127 panic!(
128 "The conversion of flags 0x{:08x} failed, please check if some flags have not been \
129 added to MotionFlags.",
130 flags
131 );
132 }
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000133 let result = verifier.process_movement(
134 DeviceId(device_id),
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700135 Source::from_bits(source).unwrap(),
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000136 action,
137 pointer_properties,
Linnan Li13ccabe2024-04-19 17:14:43 +0000138 motion_flags.unwrap(),
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000139 );
140 match result {
141 Ok(()) => "".to_string(),
142 Err(e) => e,
143 }
144}
145
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -0700146fn reset_device(verifier: &mut InputVerifier, device_id: i32) {
147 verifier.reset_device(DeviceId(device_id));
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000148}
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000149
150fn create_keyboard_classifier() -> Box<KeyboardClassifier> {
151 Box::new(KeyboardClassifier::new())
152}
153
154fn notify_keyboard_changed(
155 classifier: &mut KeyboardClassifier,
156 device_id: i32,
157 identifier: RustInputDeviceIdentifier,
158 device_classes: u32,
159) {
160 let classes = DeviceClass::from_bits(device_classes);
161 if classes.is_none() {
162 panic!(
163 "The conversion of device class 0x{:08x} failed, please check if some device classes
164 have not been added to DeviceClass.",
165 device_classes
166 );
167 }
168 classifier.notify_keyboard_changed(InputDevice {
169 device_id: DeviceId(device_id),
170 identifier,
171 classes: classes.unwrap(),
172 });
173}
174
175fn get_keyboard_type(classifier: &mut KeyboardClassifier, device_id: i32) -> u32 {
176 classifier.get_keyboard_type(DeviceId(device_id)) as u32
177}
178
179fn is_finalized(classifier: &mut KeyboardClassifier, device_id: i32) -> bool {
180 classifier.is_finalized(DeviceId(device_id))
181}
182
183fn process_key(
184 classifier: &mut KeyboardClassifier,
185 device_id: i32,
186 evdev_code: i32,
187 meta_state: u32,
188) {
189 let modifier_state = ModifierState::from_bits(meta_state);
190 if modifier_state.is_none() {
191 panic!(
192 "The conversion of meta state 0x{:08x} failed, please check if some meta state
193 have not been added to ModifierState.",
194 meta_state
195 );
196 }
197 classifier.process_key(DeviceId(device_id), evdev_code, modifier_state.unwrap());
198}