blob: af8f889cb54f4673c1bc2dea01eab63fcef793b2 [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 Devmuraria8359fc2024-06-10 20:01:25 +000021mod keyboard_classification_config;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000022mod keyboard_classifier;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000023
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000024pub use input::{
25 DeviceClass, DeviceId, InputDevice, ModifierState, MotionAction, MotionFlags, Source,
26};
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000027pub use input_verifier::InputVerifier;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000028pub use keyboard_classifier::KeyboardClassifier;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000029
30#[cxx::bridge(namespace = "android::input")]
Andrew Walbran37994222023-08-03 12:16:28 +000031#[allow(unsafe_op_in_unsafe_fn)]
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000032mod ffi {
33 #[namespace = "android"]
34 unsafe extern "C++" {
35 include!("ffi/FromRustToCpp.h");
36 fn shouldLog(tag: &str) -> bool;
37 }
38
39 #[namespace = "android::input::verifier"]
40 extern "Rust" {
41 /// Used to validate the incoming motion stream.
42 /// This class is not thread-safe.
43 /// State is stored in the "InputVerifier" object
44 /// that can be created via the 'create' method.
45 /// Usage:
46 ///
47 /// ```ignore
48 /// Box<InputVerifier> verifier = create("inputChannel name");
49 /// result = process_movement(verifier, ...);
50 /// if (result) {
51 /// crash(result.error_message());
52 /// }
53 /// ```
54 type InputVerifier;
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000055 #[cxx_name = create]
56 fn create_input_verifier(name: String) -> Box<InputVerifier>;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000057 fn process_movement(
58 verifier: &mut InputVerifier,
59 device_id: i32,
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070060 source: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000061 action: u32,
62 pointer_properties: &[RustPointerProperties],
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -070063 flags: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000064 ) -> String;
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -070065 fn reset_device(verifier: &mut InputVerifier, device_id: i32);
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000066 }
67
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000068 #[namespace = "android::input::keyboardClassifier"]
69 extern "Rust" {
70 /// Used to classify a keyboard into alphabetic and non-alphabetic
71 type KeyboardClassifier;
72 #[cxx_name = create]
73 fn create_keyboard_classifier() -> Box<KeyboardClassifier>;
74 #[cxx_name = notifyKeyboardChanged]
75 fn notify_keyboard_changed(
76 classifier: &mut KeyboardClassifier,
77 device_id: i32,
78 identifier: RustInputDeviceIdentifier,
79 device_classes: u32,
80 );
81 #[cxx_name = getKeyboardType]
82 fn get_keyboard_type(classifier: &mut KeyboardClassifier, device_id: i32) -> u32;
83 #[cxx_name = isFinalized]
84 fn is_finalized(classifier: &mut KeyboardClassifier, device_id: i32) -> bool;
85 #[cxx_name = processKey]
86 fn process_key(
87 classifier: &mut KeyboardClassifier,
88 device_id: i32,
89 evdev_code: i32,
90 modifier_state: u32,
91 );
92 }
93
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000094 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
95 pub struct RustPointerProperties {
96 pub id: i32,
97 }
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +000098
99 #[derive(Debug)]
100 pub struct RustInputDeviceIdentifier {
101 pub name: String,
102 pub location: String,
103 pub unique_id: String,
104 pub bus: u16,
105 pub vendor: u16,
106 pub product: u16,
107 pub version: u16,
108 pub descriptor: String,
109 }
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000110}
111
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000112use crate::ffi::{RustInputDeviceIdentifier, RustPointerProperties};
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000113
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000114fn create_input_verifier(name: String) -> Box<InputVerifier> {
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -0700115 Box::new(InputVerifier::new(&name, ffi::shouldLog("InputVerifierLogEvents")))
116}
117
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000118fn process_movement(
119 verifier: &mut InputVerifier,
120 device_id: i32,
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700121 source: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000122 action: u32,
123 pointer_properties: &[RustPointerProperties],
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700124 flags: u32,
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000125) -> String {
Linnan Li13ccabe2024-04-19 17:14:43 +0000126 let motion_flags = MotionFlags::from_bits(flags);
127 if motion_flags.is_none() {
128 panic!(
129 "The conversion of flags 0x{:08x} failed, please check if some flags have not been \
130 added to MotionFlags.",
131 flags
132 );
133 }
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000134 let result = verifier.process_movement(
135 DeviceId(device_id),
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700136 Source::from_bits(source).unwrap(),
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000137 action,
138 pointer_properties,
Linnan Li13ccabe2024-04-19 17:14:43 +0000139 motion_flags.unwrap(),
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000140 );
141 match result {
142 Ok(()) => "".to_string(),
143 Err(e) => e,
144 }
145}
146
Siarhei Vishniakou1160ecd2023-06-28 15:57:47 -0700147fn reset_device(verifier: &mut InputVerifier, device_id: i32) {
148 verifier.reset_device(DeviceId(device_id));
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000149}
Vaibhav Devmurarie58ffb92024-05-22 17:38:25 +0000150
151fn create_keyboard_classifier() -> Box<KeyboardClassifier> {
152 Box::new(KeyboardClassifier::new())
153}
154
155fn notify_keyboard_changed(
156 classifier: &mut KeyboardClassifier,
157 device_id: i32,
158 identifier: RustInputDeviceIdentifier,
159 device_classes: u32,
160) {
161 let classes = DeviceClass::from_bits(device_classes);
162 if classes.is_none() {
163 panic!(
164 "The conversion of device class 0x{:08x} failed, please check if some device classes
165 have not been added to DeviceClass.",
166 device_classes
167 );
168 }
169 classifier.notify_keyboard_changed(InputDevice {
170 device_id: DeviceId(device_id),
171 identifier,
172 classes: classes.unwrap(),
173 });
174}
175
176fn get_keyboard_type(classifier: &mut KeyboardClassifier, device_id: i32) -> u32 {
177 classifier.get_keyboard_type(DeviceId(device_id)) as u32
178}
179
180fn is_finalized(classifier: &mut KeyboardClassifier, device_id: i32) -> bool {
181 classifier.is_finalized(DeviceId(device_id))
182}
183
184fn process_key(
185 classifier: &mut KeyboardClassifier,
186 device_id: i32,
187 evdev_code: i32,
188 meta_state: u32,
189) {
190 let modifier_state = ModifierState::from_bits(meta_state);
191 if modifier_state.is_none() {
192 panic!(
193 "The conversion of meta state 0x{:08x} failed, please check if some meta state
194 have not been added to ModifierState.",
195 meta_state
196 );
197 }
198 classifier.process_key(DeviceId(device_id), evdev_code, modifier_state.unwrap());
199}