blob: 705c959d045fa9693ca45510712d28b797d1ea98 [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//! Common definitions of the Android Input Framework in rust.
18
19use bitflags::bitflags;
20use std::fmt;
21
22/// The InputDevice ID.
23#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
24pub struct DeviceId(pub i32);
25
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070026#[repr(u32)]
27pub enum SourceClass {
28 None = input_bindgen::AINPUT_SOURCE_CLASS_NONE,
29 Button = input_bindgen::AINPUT_SOURCE_CLASS_BUTTON,
30 Pointer = input_bindgen::AINPUT_SOURCE_CLASS_POINTER,
31 Navigation = input_bindgen::AINPUT_SOURCE_CLASS_NAVIGATION,
32 Position = input_bindgen::AINPUT_SOURCE_CLASS_POSITION,
33 Joystick = input_bindgen::AINPUT_SOURCE_CLASS_JOYSTICK,
34}
35
36bitflags! {
37 /// Source of the input device or input events.
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070038 #[derive(Debug, PartialEq)]
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070039 pub struct Source: u32 {
Siarhei Vishniakou88daa902023-10-03 14:04:18 -070040 // Constants from SourceClass, added here for compatibility reasons
41 /// SourceClass::Button
42 const SourceClassButton = SourceClass::Button as u32;
43 /// SourceClass::Pointer
44 const SourceClassPointer = SourceClass::Pointer as u32;
45 /// SourceClass::Navigation
46 const SourceClassNavigation = SourceClass::Navigation as u32;
47 /// SourceClass::Position
48 const SourceClassPosition = SourceClass::Position as u32;
49 /// SourceClass::Joystick
50 const SourceClassJoystick = SourceClass::Joystick as u32;
51
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -070052 /// SOURCE_UNKNOWN
53 const Unknown = input_bindgen::AINPUT_SOURCE_UNKNOWN;
54 /// SOURCE_KEYBOARD
55 const Keyboard = input_bindgen::AINPUT_SOURCE_KEYBOARD;
56 /// SOURCE_DPAD
57 const Dpad = input_bindgen::AINPUT_SOURCE_DPAD;
58 /// SOURCE_GAMEPAD
59 const Gamepad = input_bindgen::AINPUT_SOURCE_GAMEPAD;
60 /// SOURCE_TOUCHSCREEN
61 const Touchscreen = input_bindgen::AINPUT_SOURCE_TOUCHSCREEN;
62 /// SOURCE_MOUSE
63 const Mouse = input_bindgen::AINPUT_SOURCE_MOUSE;
64 /// SOURCE_STYLUS
65 const Stylus = input_bindgen::AINPUT_SOURCE_STYLUS;
66 /// SOURCE_BLUETOOTH_STYLUS
67 const BluetoothStylus = input_bindgen::AINPUT_SOURCE_BLUETOOTH_STYLUS;
68 /// SOURCE_TRACKBALL
69 const Trackball = input_bindgen::AINPUT_SOURCE_TRACKBALL;
70 /// SOURCE_MOUSE_RELATIVE
71 const MouseRelative = input_bindgen::AINPUT_SOURCE_MOUSE_RELATIVE;
72 /// SOURCE_TOUCHPAD
73 const Touchpad = input_bindgen::AINPUT_SOURCE_TOUCHPAD;
74 /// SOURCE_TOUCH_NAVIGATION
75 const TouchNavigation = input_bindgen::AINPUT_SOURCE_TOUCH_NAVIGATION;
76 /// SOURCE_JOYSTICK
77 const Joystick = input_bindgen::AINPUT_SOURCE_JOYSTICK;
78 /// SOURCE_HDMI
79 const HDMI = input_bindgen::AINPUT_SOURCE_HDMI;
80 /// SOURCE_SENSOR
81 const Sensor = input_bindgen::AINPUT_SOURCE_SENSOR;
82 /// SOURCE_ROTARY_ENCODER
83 const RotaryEncoder = input_bindgen::AINPUT_SOURCE_ROTARY_ENCODER;
84 }
85}
86
Prabir Pradhan0762b1f2023-06-22 23:08:18 +000087/// A rust enum representation of a MotionEvent action.
88#[repr(u32)]
89pub enum MotionAction {
90 /// ACTION_DOWN
91 Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN,
92 /// ACTION_UP
93 Up = input_bindgen::AMOTION_EVENT_ACTION_UP,
94 /// ACTION_MOVE
95 Move = input_bindgen::AMOTION_EVENT_ACTION_MOVE,
96 /// ACTION_CANCEL
97 Cancel = input_bindgen::AMOTION_EVENT_ACTION_CANCEL,
98 /// ACTION_OUTSIDE
99 Outside = input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE,
100 /// ACTION_POINTER_DOWN
101 PointerDown {
102 /// The index of the affected pointer.
103 action_index: usize,
104 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN,
105 /// ACTION_POINTER_UP
106 PointerUp {
107 /// The index of the affected pointer.
108 action_index: usize,
109 } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP,
110 /// ACTION_HOVER_ENTER
111 HoverEnter = input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER,
112 /// ACTION_HOVER_MOVE
113 HoverMove = input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE,
114 /// ACTION_HOVER_EXIT
115 HoverExit = input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT,
116 /// ACTION_SCROLL
117 Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL,
118 /// ACTION_BUTTON_PRESS
119 ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS,
120 /// ACTION_BUTTON_RELEASE
121 ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
122}
123
124impl fmt::Display for MotionAction {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 match self {
127 MotionAction::Down => write!(f, "DOWN"),
128 MotionAction::Up => write!(f, "UP"),
129 MotionAction::Move => write!(f, "MOVE"),
130 MotionAction::Cancel => write!(f, "CANCEL"),
131 MotionAction::Outside => write!(f, "OUTSIDE"),
132 MotionAction::PointerDown { action_index } => {
133 write!(f, "POINTER_DOWN({})", action_index)
134 }
135 MotionAction::PointerUp { action_index } => write!(f, "POINTER_UP({})", action_index),
136 MotionAction::HoverMove => write!(f, "HOVER_MOVE"),
137 MotionAction::Scroll => write!(f, "SCROLL"),
138 MotionAction::HoverEnter => write!(f, "HOVER_ENTER"),
139 MotionAction::HoverExit => write!(f, "HOVER_EXIT"),
140 MotionAction::ButtonPress => write!(f, "BUTTON_PRESS"),
141 MotionAction::ButtonRelease => write!(f, "BUTTON_RELEASE"),
142 }
143 }
144}
145
146impl From<u32> for MotionAction {
147 fn from(action: u32) -> Self {
148 let (action_masked, action_index) = MotionAction::breakdown_action(action);
149 match action_masked {
150 input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down,
151 input_bindgen::AMOTION_EVENT_ACTION_UP => MotionAction::Up,
152 input_bindgen::AMOTION_EVENT_ACTION_MOVE => MotionAction::Move,
153 input_bindgen::AMOTION_EVENT_ACTION_CANCEL => MotionAction::Cancel,
154 input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE => MotionAction::Outside,
155 input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN => {
156 MotionAction::PointerDown { action_index }
157 }
158 input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP => {
159 MotionAction::PointerUp { action_index }
160 }
161 input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER => MotionAction::HoverEnter,
162 input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE => MotionAction::HoverMove,
163 input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT => MotionAction::HoverExit,
164 input_bindgen::AMOTION_EVENT_ACTION_SCROLL => MotionAction::Scroll,
165 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => MotionAction::ButtonPress,
166 input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => MotionAction::ButtonRelease,
167 _ => panic!("Unknown action: {}", action),
168 }
169 }
170}
171
172impl MotionAction {
173 fn breakdown_action(action: u32) -> (u32, usize) {
174 let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK;
175 let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
176 >> input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
177 (action_masked, index.try_into().unwrap())
178 }
179}
180
181bitflags! {
182 /// MotionEvent flags.
Siarhei Vishniakou93992432023-10-09 15:47:48 -0700183 #[derive(Debug)]
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700184 pub struct MotionFlags: u32 {
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000185 /// FLAG_CANCELED
Siarhei Vishniakou227a7f82023-07-18 18:30:32 -0700186 const CANCELED = input_bindgen::AMOTION_EVENT_FLAG_CANCELED as u32;
187 /// FLAG_WINDOW_IS_OBSCURED
188 const WINDOW_IS_OBSCURED = input_bindgen::AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
189 /// FLAG_WINDOW_IS_PARTIALLY_OBSCURED
190 const WINDOW_IS_PARTIALLY_OBSCURED =
191 input_bindgen::AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
192 /// FLAG_IS_ACCESSIBILITY_EVENT
193 const IS_ACCESSIBILITY_EVENT =
194 input_bindgen::AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
195 /// FLAG_NO_FOCUS_CHANGE
196 const NO_FOCUS_CHANGE = input_bindgen::AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
Prabir Pradhan0762b1f2023-06-22 23:08:18 +0000197 }
198}
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700199
200impl Source {
201 /// Return true if this source is from the provided class
202 pub fn is_from_class(&self, source_class: SourceClass) -> bool {
203 let class_bits = source_class as u32;
204 self.bits() & class_bits == class_bits
205 }
206}
Siarhei Vishniakou88daa902023-10-03 14:04:18 -0700207
208#[cfg(test)]
209mod tests {
210 use crate::input::SourceClass;
211 use crate::Source;
212 #[test]
213 fn convert_source_class_pointer() {
214 let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
215 assert!(source.is_from_class(SourceClass::Pointer));
216 }
217}