|  | /* | 
|  | * Copyright 2023 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | //! Common definitions of the Android Input Framework in rust. | 
|  |  | 
|  | use bitflags::bitflags; | 
|  | use std::fmt; | 
|  |  | 
|  | /// The InputDevice ID. | 
|  | #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] | 
|  | pub struct DeviceId(pub i32); | 
|  |  | 
|  | #[repr(u32)] | 
|  | pub enum SourceClass { | 
|  | None = input_bindgen::AINPUT_SOURCE_CLASS_NONE, | 
|  | Button = input_bindgen::AINPUT_SOURCE_CLASS_BUTTON, | 
|  | Pointer = input_bindgen::AINPUT_SOURCE_CLASS_POINTER, | 
|  | Navigation = input_bindgen::AINPUT_SOURCE_CLASS_NAVIGATION, | 
|  | Position = input_bindgen::AINPUT_SOURCE_CLASS_POSITION, | 
|  | Joystick = input_bindgen::AINPUT_SOURCE_CLASS_JOYSTICK, | 
|  | } | 
|  |  | 
|  | bitflags! { | 
|  | /// Source of the input device or input events. | 
|  | pub struct Source: u32 { | 
|  | /// SOURCE_UNKNOWN | 
|  | const Unknown = input_bindgen::AINPUT_SOURCE_UNKNOWN; | 
|  | /// SOURCE_KEYBOARD | 
|  | const Keyboard = input_bindgen::AINPUT_SOURCE_KEYBOARD; | 
|  | /// SOURCE_DPAD | 
|  | const Dpad = input_bindgen::AINPUT_SOURCE_DPAD; | 
|  | /// SOURCE_GAMEPAD | 
|  | const Gamepad = input_bindgen::AINPUT_SOURCE_GAMEPAD; | 
|  | /// SOURCE_TOUCHSCREEN | 
|  | const Touchscreen = input_bindgen::AINPUT_SOURCE_TOUCHSCREEN; | 
|  | /// SOURCE_MOUSE | 
|  | const Mouse = input_bindgen::AINPUT_SOURCE_MOUSE; | 
|  | /// SOURCE_STYLUS | 
|  | const Stylus = input_bindgen::AINPUT_SOURCE_STYLUS; | 
|  | /// SOURCE_BLUETOOTH_STYLUS | 
|  | const BluetoothStylus = input_bindgen::AINPUT_SOURCE_BLUETOOTH_STYLUS; | 
|  | /// SOURCE_TRACKBALL | 
|  | const Trackball = input_bindgen::AINPUT_SOURCE_TRACKBALL; | 
|  | /// SOURCE_MOUSE_RELATIVE | 
|  | const MouseRelative = input_bindgen::AINPUT_SOURCE_MOUSE_RELATIVE; | 
|  | /// SOURCE_TOUCHPAD | 
|  | const Touchpad = input_bindgen::AINPUT_SOURCE_TOUCHPAD; | 
|  | /// SOURCE_TOUCH_NAVIGATION | 
|  | const TouchNavigation = input_bindgen::AINPUT_SOURCE_TOUCH_NAVIGATION; | 
|  | /// SOURCE_JOYSTICK | 
|  | const Joystick = input_bindgen::AINPUT_SOURCE_JOYSTICK; | 
|  | /// SOURCE_HDMI | 
|  | const HDMI = input_bindgen::AINPUT_SOURCE_HDMI; | 
|  | /// SOURCE_SENSOR | 
|  | const Sensor = input_bindgen::AINPUT_SOURCE_SENSOR; | 
|  | /// SOURCE_ROTARY_ENCODER | 
|  | const RotaryEncoder = input_bindgen::AINPUT_SOURCE_ROTARY_ENCODER; | 
|  | } | 
|  | } | 
|  |  | 
|  | /// A rust enum representation of a MotionEvent action. | 
|  | #[repr(u32)] | 
|  | pub enum MotionAction { | 
|  | /// ACTION_DOWN | 
|  | Down = input_bindgen::AMOTION_EVENT_ACTION_DOWN, | 
|  | /// ACTION_UP | 
|  | Up = input_bindgen::AMOTION_EVENT_ACTION_UP, | 
|  | /// ACTION_MOVE | 
|  | Move = input_bindgen::AMOTION_EVENT_ACTION_MOVE, | 
|  | /// ACTION_CANCEL | 
|  | Cancel = input_bindgen::AMOTION_EVENT_ACTION_CANCEL, | 
|  | /// ACTION_OUTSIDE | 
|  | Outside = input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE, | 
|  | /// ACTION_POINTER_DOWN | 
|  | PointerDown { | 
|  | /// The index of the affected pointer. | 
|  | action_index: usize, | 
|  | } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN, | 
|  | /// ACTION_POINTER_UP | 
|  | PointerUp { | 
|  | /// The index of the affected pointer. | 
|  | action_index: usize, | 
|  | } = input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP, | 
|  | /// ACTION_HOVER_ENTER | 
|  | HoverEnter = input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER, | 
|  | /// ACTION_HOVER_MOVE | 
|  | HoverMove = input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE, | 
|  | /// ACTION_HOVER_EXIT | 
|  | HoverExit = input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT, | 
|  | /// ACTION_SCROLL | 
|  | Scroll = input_bindgen::AMOTION_EVENT_ACTION_SCROLL, | 
|  | /// ACTION_BUTTON_PRESS | 
|  | ButtonPress = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS, | 
|  | /// ACTION_BUTTON_RELEASE | 
|  | ButtonRelease = input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE, | 
|  | } | 
|  |  | 
|  | impl fmt::Display for MotionAction { | 
|  | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
|  | match self { | 
|  | MotionAction::Down => write!(f, "DOWN"), | 
|  | MotionAction::Up => write!(f, "UP"), | 
|  | MotionAction::Move => write!(f, "MOVE"), | 
|  | MotionAction::Cancel => write!(f, "CANCEL"), | 
|  | MotionAction::Outside => write!(f, "OUTSIDE"), | 
|  | MotionAction::PointerDown { action_index } => { | 
|  | write!(f, "POINTER_DOWN({})", action_index) | 
|  | } | 
|  | MotionAction::PointerUp { action_index } => write!(f, "POINTER_UP({})", action_index), | 
|  | MotionAction::HoverMove => write!(f, "HOVER_MOVE"), | 
|  | MotionAction::Scroll => write!(f, "SCROLL"), | 
|  | MotionAction::HoverEnter => write!(f, "HOVER_ENTER"), | 
|  | MotionAction::HoverExit => write!(f, "HOVER_EXIT"), | 
|  | MotionAction::ButtonPress => write!(f, "BUTTON_PRESS"), | 
|  | MotionAction::ButtonRelease => write!(f, "BUTTON_RELEASE"), | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | impl From<u32> for MotionAction { | 
|  | fn from(action: u32) -> Self { | 
|  | let (action_masked, action_index) = MotionAction::breakdown_action(action); | 
|  | match action_masked { | 
|  | input_bindgen::AMOTION_EVENT_ACTION_DOWN => MotionAction::Down, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_UP => MotionAction::Up, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_MOVE => MotionAction::Move, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_CANCEL => MotionAction::Cancel, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_OUTSIDE => MotionAction::Outside, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_POINTER_DOWN => { | 
|  | MotionAction::PointerDown { action_index } | 
|  | } | 
|  | input_bindgen::AMOTION_EVENT_ACTION_POINTER_UP => { | 
|  | MotionAction::PointerUp { action_index } | 
|  | } | 
|  | input_bindgen::AMOTION_EVENT_ACTION_HOVER_ENTER => MotionAction::HoverEnter, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_HOVER_MOVE => MotionAction::HoverMove, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_HOVER_EXIT => MotionAction::HoverExit, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_SCROLL => MotionAction::Scroll, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_BUTTON_PRESS => MotionAction::ButtonPress, | 
|  | input_bindgen::AMOTION_EVENT_ACTION_BUTTON_RELEASE => MotionAction::ButtonRelease, | 
|  | _ => panic!("Unknown action: {}", action), | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | impl MotionAction { | 
|  | fn breakdown_action(action: u32) -> (u32, usize) { | 
|  | let action_masked = action & input_bindgen::AMOTION_EVENT_ACTION_MASK; | 
|  | let index = (action & input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) | 
|  | >> input_bindgen::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; | 
|  | (action_masked, index.try_into().unwrap()) | 
|  | } | 
|  | } | 
|  |  | 
|  | bitflags! { | 
|  | /// MotionEvent flags. | 
|  | pub struct MotionFlags: u32 { | 
|  | /// FLAG_CANCELED | 
|  | const CANCELED = input_bindgen::AMOTION_EVENT_FLAG_CANCELED as u32; | 
|  | /// FLAG_WINDOW_IS_OBSCURED | 
|  | const WINDOW_IS_OBSCURED = input_bindgen::AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; | 
|  | /// FLAG_WINDOW_IS_PARTIALLY_OBSCURED | 
|  | const WINDOW_IS_PARTIALLY_OBSCURED = | 
|  | input_bindgen::AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; | 
|  | /// FLAG_IS_ACCESSIBILITY_EVENT | 
|  | const IS_ACCESSIBILITY_EVENT = | 
|  | input_bindgen::AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT; | 
|  | /// FLAG_NO_FOCUS_CHANGE | 
|  | const NO_FOCUS_CHANGE = input_bindgen::AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE; | 
|  | } | 
|  | } | 
|  |  | 
|  | impl Source { | 
|  | /// Return true if this source is from the provided class | 
|  | pub fn is_from_class(&self, source_class: SourceClass) -> bool { | 
|  | let class_bits = source_class as u32; | 
|  | self.bits() & class_bits == class_bits | 
|  | } | 
|  | } |