mirror of
https://github.com/rust-mobile/android-activity.git
synced 2026-07-17 03:58:54 +00:00
6fb438de82
This is based on the 2022.0.0 agdk-libraries release
1459 lines
47 KiB
Rust
Executable File
1459 lines
47 KiB
Rust
Executable File
// GameActivity handles input events by double buffering MotionEvent and KeyEvent structs which
|
|
// essentially just mirror state from the corresponding Java objects.
|
|
//
|
|
// See also the javadocs for
|
|
// [`android.view.InputEvent`](https://developer.android.com/reference/android/view/InputEvent.html),
|
|
// [`android.view.MotionEvent`](https://developer.android.com/reference/android/view/MotionEvent.html),
|
|
// and [`android.view.KeyEvent`](https://developer.android.com/reference/android/view/KeyEvent).
|
|
//
|
|
// This code is mostly based on https://github.com/rust-windowing/android-ndk-rs/blob/master/ndk/src/event.rs
|
|
//
|
|
// The `Source` enum was defined based on the Java docs since there are a couple of source types that
|
|
// aren't exposed via the AInputQueue API
|
|
// The `Class` was also bound differently to `android-ndk-rs` considering how the class is defined
|
|
// by masking bits from the `Source`.
|
|
|
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
|
use std::{convert::TryInto, ops::Deref};
|
|
use crate::ffi::{GameActivityMotionEvent, GameActivityKeyEvent};
|
|
|
|
use bitflags::bitflags;
|
|
|
|
// Note: try to keep this wrapper API similar to the AInputEvent API if possible
|
|
|
|
|
|
/// An enum representing the source of an [`MotionEvent`] or [`KeyEvent`]
|
|
///
|
|
/// See [the InputDevice docs](https://developer.android.com/reference/android/view/InputDevice#SOURCE_ANY)
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(i32)]
|
|
pub enum Source {
|
|
BluetoothStylus = 0x0000c002,
|
|
Dpad = 0x00000201,
|
|
/// Either a gamepad or a joystick
|
|
Gamepad = 0x00000401,
|
|
Hdmi = 0x02000001,
|
|
/// Either a gamepad or a joystick
|
|
Joystick = 0x01000010,
|
|
/// Pretty much any device with buttons. Query the keyboard type to determine
|
|
/// if it has alphabetic keys and can be used for text entry.
|
|
Keyboard = 0x00000101,
|
|
/// A pointing device, such as a mouse or trackpad
|
|
Mouse = 0x00002002,
|
|
/// A pointing device, such as a mouse or trackpad whose relative motions should be treated as navigation events
|
|
MouseRelative = 0x00020004,
|
|
/// An input device akin to a scroll wheel
|
|
RotaryEncoder = 0x00400000,
|
|
Sensor = 0x04000000,
|
|
Stylus = 0x00004002,
|
|
Touchpad = 0x00100008,
|
|
Touchscreen = 0x00001002,
|
|
TouchNavigation = 0x00200000,
|
|
Trackball = 0x00010004,
|
|
|
|
Unknown = 0,
|
|
}
|
|
|
|
bitflags! {
|
|
struct SourceFlags: u32 {
|
|
const CLASS_MASK = 0x000000ff;
|
|
|
|
const BUTTON = 0x00000001;
|
|
const POINTER = 0x00000002;
|
|
const TRACKBALL = 0x00000004;
|
|
const POSITION = 0x00000008;
|
|
const JOYSTICK = 0x00000010;
|
|
const NONE = 0;
|
|
}
|
|
}
|
|
|
|
/// An enum representing the class of a [`MotionEvent`] or [`KeyEvent`] source
|
|
///
|
|
/// See [the InputDevice docs](https://developer.android.com/reference/android/view/InputDevice#SOURCE_CLASS_MASK)
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum Class {
|
|
None,
|
|
Button,
|
|
Pointer,
|
|
Trackball,
|
|
Position,
|
|
Joystick
|
|
}
|
|
|
|
impl From<i32> for Class {
|
|
fn from(source: i32) -> Self {
|
|
let class = SourceFlags::from_bits_truncate(source as u32);
|
|
match class {
|
|
SourceFlags::BUTTON => Class::Button,
|
|
SourceFlags::POINTER => Class::Pointer,
|
|
SourceFlags::TRACKBALL => Class::Trackball,
|
|
SourceFlags::POSITION => Class::Position,
|
|
SourceFlags::JOYSTICK => Class::Joystick,
|
|
_ => Class::None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A bitfield representing the state of modifier keys during an event.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-25)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub struct MetaState(pub u32);
|
|
|
|
impl MetaState {
|
|
#[inline]
|
|
pub fn alt_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_ALT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn alt_left_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_ALT_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn alt_right_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_ALT_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn shift_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_SHIFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn shift_left_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_SHIFT_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn shift_right_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_SHIFT_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn sym_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_SYM_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn function_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_FUNCTION_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn ctrl_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_CTRL_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn ctrl_left_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_CTRL_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn ctrl_right_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_CTRL_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn meta_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_META_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn meta_left_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_META_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn meta_right_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_META_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn caps_lock_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_CAPS_LOCK_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn num_lock_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_NUM_LOCK_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn scroll_lock_on(self) -> bool {
|
|
self.0 & ndk_sys::AMETA_SCROLL_LOCK_ON != 0
|
|
}
|
|
}
|
|
|
|
/// A motion event.
|
|
///
|
|
/// For general discussion of motion events in Android, see [the relevant
|
|
/// javadoc](https://developer.android.com/reference/android/view/MotionEvent).
|
|
#[derive(Clone, Debug)]
|
|
pub struct MotionEvent {
|
|
ga_event: GameActivityMotionEvent
|
|
}
|
|
|
|
impl Deref for MotionEvent {
|
|
type Target = GameActivityMotionEvent;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.ga_event
|
|
}
|
|
}
|
|
|
|
/// A motion action.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-29)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(u32)]
|
|
pub enum MotionAction {
|
|
Down = ndk_sys::AMOTION_EVENT_ACTION_DOWN,
|
|
Up = ndk_sys::AMOTION_EVENT_ACTION_UP,
|
|
Move = ndk_sys::AMOTION_EVENT_ACTION_MOVE,
|
|
Cancel = ndk_sys::AMOTION_EVENT_ACTION_CANCEL,
|
|
Outside = ndk_sys::AMOTION_EVENT_ACTION_OUTSIDE,
|
|
PointerDown = ndk_sys::AMOTION_EVENT_ACTION_POINTER_DOWN,
|
|
PointerUp = ndk_sys::AMOTION_EVENT_ACTION_POINTER_UP,
|
|
HoverMove = ndk_sys::AMOTION_EVENT_ACTION_HOVER_MOVE,
|
|
Scroll = ndk_sys::AMOTION_EVENT_ACTION_SCROLL,
|
|
HoverEnter = ndk_sys::AMOTION_EVENT_ACTION_HOVER_ENTER,
|
|
HoverExit = ndk_sys::AMOTION_EVENT_ACTION_HOVER_EXIT,
|
|
ButtonPress = ndk_sys::AMOTION_EVENT_ACTION_BUTTON_PRESS,
|
|
ButtonRelease = ndk_sys::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
|
|
}
|
|
|
|
/// An axis of a motion event.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-32)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(u32)]
|
|
pub enum Axis {
|
|
X = ndk_sys::AMOTION_EVENT_AXIS_X,
|
|
Y = ndk_sys::AMOTION_EVENT_AXIS_Y,
|
|
Pressure = ndk_sys::AMOTION_EVENT_AXIS_PRESSURE,
|
|
Size = ndk_sys::AMOTION_EVENT_AXIS_SIZE,
|
|
TouchMajor = ndk_sys::AMOTION_EVENT_AXIS_TOUCH_MAJOR,
|
|
TouchMinor = ndk_sys::AMOTION_EVENT_AXIS_TOUCH_MINOR,
|
|
ToolMajor = ndk_sys::AMOTION_EVENT_AXIS_TOOL_MAJOR,
|
|
ToolMinor = ndk_sys::AMOTION_EVENT_AXIS_TOOL_MINOR,
|
|
Orientation = ndk_sys::AMOTION_EVENT_AXIS_ORIENTATION,
|
|
Vscroll = ndk_sys::AMOTION_EVENT_AXIS_VSCROLL,
|
|
Hscroll = ndk_sys::AMOTION_EVENT_AXIS_HSCROLL,
|
|
Z = ndk_sys::AMOTION_EVENT_AXIS_Z,
|
|
Rx = ndk_sys::AMOTION_EVENT_AXIS_RX,
|
|
Ry = ndk_sys::AMOTION_EVENT_AXIS_RY,
|
|
Rz = ndk_sys::AMOTION_EVENT_AXIS_RZ,
|
|
HatX = ndk_sys::AMOTION_EVENT_AXIS_HAT_X,
|
|
HatY = ndk_sys::AMOTION_EVENT_AXIS_HAT_Y,
|
|
Ltrigger = ndk_sys::AMOTION_EVENT_AXIS_LTRIGGER,
|
|
Rtrigger = ndk_sys::AMOTION_EVENT_AXIS_RTRIGGER,
|
|
Throttle = ndk_sys::AMOTION_EVENT_AXIS_THROTTLE,
|
|
Rudder = ndk_sys::AMOTION_EVENT_AXIS_RUDDER,
|
|
Wheel = ndk_sys::AMOTION_EVENT_AXIS_WHEEL,
|
|
Gas = ndk_sys::AMOTION_EVENT_AXIS_GAS,
|
|
Brake = ndk_sys::AMOTION_EVENT_AXIS_BRAKE,
|
|
Distance = ndk_sys::AMOTION_EVENT_AXIS_DISTANCE,
|
|
Tilt = ndk_sys::AMOTION_EVENT_AXIS_TILT,
|
|
Scroll = ndk_sys::AMOTION_EVENT_AXIS_SCROLL,
|
|
RelativeX = ndk_sys::AMOTION_EVENT_AXIS_RELATIVE_X,
|
|
RelativeY = ndk_sys::AMOTION_EVENT_AXIS_RELATIVE_Y,
|
|
Generic1 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_1,
|
|
Generic2 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_2,
|
|
Generic3 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_3,
|
|
Generic4 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_4,
|
|
Generic5 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_5,
|
|
Generic6 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_6,
|
|
Generic7 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_7,
|
|
Generic8 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_8,
|
|
Generic9 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_9,
|
|
Generic10 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_10,
|
|
Generic11 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_11,
|
|
Generic12 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_12,
|
|
Generic13 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_13,
|
|
Generic14 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_14,
|
|
Generic15 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_15,
|
|
Generic16 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_16,
|
|
}
|
|
|
|
/// A bitfield representing the state of buttons during a motion event.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-33)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub struct ButtonState(pub u32);
|
|
|
|
impl ButtonState {
|
|
#[inline]
|
|
pub fn primary(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_PRIMARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn secondary(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_SECONDARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn teriary(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_TERTIARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn back(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_BACK != 0
|
|
}
|
|
#[inline]
|
|
pub fn forward(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_FORWARD != 0
|
|
}
|
|
#[inline]
|
|
pub fn stylus_primary(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn stylus_secondary(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_SECONDARY != 0
|
|
}
|
|
}
|
|
|
|
/// A bitfield representing which edges were touched by a motion event.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-31)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub struct EdgeFlags(pub u32);
|
|
|
|
impl EdgeFlags {
|
|
#[inline]
|
|
pub fn top(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_TOP != 0
|
|
}
|
|
#[inline]
|
|
pub fn bottom(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_BOTTOM != 0
|
|
}
|
|
#[inline]
|
|
pub fn left(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_LEFT != 0
|
|
}
|
|
#[inline]
|
|
pub fn right(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_RIGHT != 0
|
|
}
|
|
}
|
|
|
|
/// Flags associated with this [`MotionEvent`].
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-30)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub struct MotionEventFlags(pub u32);
|
|
|
|
impl MotionEventFlags {
|
|
#[inline]
|
|
pub fn window_is_obscured(self) -> bool {
|
|
self.0 & ndk_sys::AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED != 0
|
|
}
|
|
}
|
|
|
|
impl MotionEvent {
|
|
pub(crate) fn new(ga_event: GameActivityMotionEvent) -> Self {
|
|
Self { ga_event }
|
|
}
|
|
|
|
/// Get the source of the event.
|
|
///
|
|
#[inline]
|
|
pub fn source(&self) -> Source {
|
|
self.source.try_into().unwrap_or(Source::Unknown)
|
|
}
|
|
|
|
/// Get the class of the event source.
|
|
///
|
|
#[inline]
|
|
pub fn class(&self) -> Class {
|
|
Class::from(self.source)
|
|
}
|
|
|
|
/// Get the device id associated with the event.
|
|
///
|
|
#[inline]
|
|
pub fn device_id(&self) -> i32 {
|
|
self.deviceId
|
|
}
|
|
|
|
/// Returns the motion action associated with the event.
|
|
///
|
|
/// See [the MotionEvent docs](https://developer.android.com/reference/android/view/MotionEvent#getActionMasked())
|
|
#[inline]
|
|
pub fn action(&self) -> MotionAction {
|
|
let action = self.action as u32 & ndk_sys::AMOTION_EVENT_ACTION_MASK;
|
|
action.try_into().unwrap()
|
|
}
|
|
|
|
/// Returns the pointer index of an `Up` or `Down` event.
|
|
///
|
|
/// Pointer indices can change per motion event. For an identifier that stays the same, see
|
|
/// [`Pointer::pointer_id()`].
|
|
///
|
|
/// This only has a meaning when the [action](Self::action) is one of [`Up`](MotionAction::Up),
|
|
/// [`Down`](MotionAction::Down), [`PointerUp`](MotionAction::PointerUp),
|
|
/// or [`PointerDown`](MotionAction::PointerDown).
|
|
#[inline]
|
|
pub fn pointer_index(&self) -> usize {
|
|
let action = self.action as u32 & ndk_sys::AMOTION_EVENT_ACTION_MASK;
|
|
let index = (action & ndk_sys::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
|
|
>> ndk_sys::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
|
index as usize
|
|
}
|
|
|
|
/*
|
|
/// Returns the pointer id associated with the given pointer index.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getpointerid)
|
|
// TODO: look at output with out-of-range pointer index
|
|
// Probably -1 though
|
|
pub fn pointer_id_for(&self, pointer_index: usize) -> i32 {
|
|
unsafe { ndk_sys::AMotionEvent_getPointerId(self.ptr.as_ptr(), pointer_index) }
|
|
}
|
|
*/
|
|
|
|
/// Returns the number of pointers in this event
|
|
///
|
|
/// See [the MotionEvent docs](https://developer.android.com/reference/android/view/MotionEvent#getPointerCount())
|
|
#[inline]
|
|
pub fn pointer_count(&self) -> usize {
|
|
self.pointerCount as usize
|
|
}
|
|
|
|
/// An iterator over the pointers in this motion event
|
|
#[inline]
|
|
pub fn pointers(&self) -> PointersIter<'_> {
|
|
PointersIter {
|
|
event: self,
|
|
next_index: 0,
|
|
count: self.pointer_count(),
|
|
}
|
|
}
|
|
|
|
/// The pointer at a given pointer index. Panics if the pointer index is out of bounds.
|
|
///
|
|
/// If you need to loop over all the pointers, prefer the [`pointers()`](Self::pointers) method.
|
|
#[inline]
|
|
pub fn pointer_at_index(&self, index: usize) -> Pointer<'_> {
|
|
if index >= self.pointer_count() {
|
|
panic!("Pointer index {} is out of bounds", index);
|
|
}
|
|
Pointer {
|
|
event: self,
|
|
index,
|
|
}
|
|
}
|
|
|
|
/*
|
|
/// Returns the size of the history contained in this event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_gethistorysize)
|
|
#[inline]
|
|
pub fn history_size(&self) -> usize {
|
|
unsafe { ndk_sys::AMotionEvent_getHistorySize(self.ptr.as_ptr()) as usize }
|
|
}
|
|
|
|
/// An iterator over the historical events contained in this event.
|
|
#[inline]
|
|
pub fn history(&self) -> HistoricalMotionEventsIter<'_> {
|
|
HistoricalMotionEventsIter {
|
|
event: self.ptr,
|
|
next_history_index: 0,
|
|
history_size: self.history_size(),
|
|
_marker: std::marker::PhantomData,
|
|
}
|
|
}
|
|
*/
|
|
|
|
/// Returns the state of any modifier keys that were pressed during the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getmetastate)
|
|
#[inline]
|
|
pub fn meta_state(&self) -> MetaState {
|
|
MetaState(self.metaState as u32)
|
|
}
|
|
|
|
/// Returns the button state during this event, as a bitfield.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getbuttonstate)
|
|
#[inline]
|
|
pub fn button_state(&self) -> ButtonState {
|
|
ButtonState(self.buttonState as u32)
|
|
}
|
|
|
|
/// Returns the time of the start of this gesture, in the `java.lang.System.nanoTime()` time
|
|
/// base
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getdowntime)
|
|
#[inline]
|
|
pub fn down_time(&self) -> i64 {
|
|
self.downTime
|
|
}
|
|
|
|
/// Returns a bitfield indicating which edges were touched by this event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getedgeflags)
|
|
#[inline]
|
|
pub fn edge_flags(&self) -> EdgeFlags {
|
|
EdgeFlags(self.edgeFlags as u32)
|
|
}
|
|
|
|
/// Returns the time of this event, in the `java.lang.System.nanoTime()` time base
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_geteventtime)
|
|
#[inline]
|
|
pub fn event_time(&self) -> i64 {
|
|
self.eventTime
|
|
}
|
|
|
|
/// The flags associated with a motion event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getflags)
|
|
#[inline]
|
|
pub fn flags(&self) -> MotionEventFlags {
|
|
MotionEventFlags(self.flags as u32)
|
|
}
|
|
|
|
/* Missing from GameActivity currently...
|
|
/// Returns the offset in the x direction between the coordinates and the raw coordinates
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getxoffset)
|
|
#[inline]
|
|
pub fn x_offset(&self) -> f32 {
|
|
self.x_offset
|
|
}
|
|
|
|
/// Returns the offset in the y direction between the coordinates and the raw coordinates
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getyoffset)
|
|
#[inline]
|
|
pub fn y_offset(&self) -> f32 {
|
|
self.y_offset
|
|
}
|
|
*/
|
|
|
|
/// Returns the precision of the x value of the coordinates
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getxprecision)
|
|
#[inline]
|
|
pub fn x_precision(&self) -> f32 {
|
|
self.precisionX
|
|
}
|
|
|
|
/// Returns the precision of the y value of the coordinates
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getyprecision)
|
|
#[inline]
|
|
pub fn y_precision(&self) -> f32 {
|
|
self.precisionY
|
|
}
|
|
}
|
|
|
|
/// A view into the data of a specific pointer in a motion event.
|
|
#[derive(Debug)]
|
|
pub struct Pointer<'a> {
|
|
event: &'a MotionEvent,
|
|
index: usize,
|
|
}
|
|
|
|
impl<'a> Pointer<'a> {
|
|
#[inline]
|
|
pub fn pointer_index(&self) -> usize {
|
|
self.index
|
|
}
|
|
|
|
#[inline]
|
|
pub fn pointer_id(&self) -> i32 {
|
|
let pointer = &self.event.pointers[self.index];
|
|
pointer.id
|
|
}
|
|
|
|
#[inline]
|
|
pub fn axis_value(&self, axis: Axis) -> f32 {
|
|
let pointer = &self.event.pointers[self.index];
|
|
pointer.axisValues[axis as u32 as usize]
|
|
}
|
|
|
|
#[inline]
|
|
pub fn orientation(&self) -> f32 {
|
|
self.axis_value(Axis::Orientation)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn pressure(&self) -> f32 {
|
|
self.axis_value(Axis::Pressure)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_x(&self) -> f32 {
|
|
let pointer = &self.event.pointers[self.index];
|
|
pointer.rawX
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_y(&self) -> f32 {
|
|
let pointer = &self.event.pointers[self.index];
|
|
pointer.rawY
|
|
}
|
|
|
|
#[inline]
|
|
pub fn x(&self) -> f32 {
|
|
self.axis_value(Axis::X)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn y(&self) -> f32 {
|
|
self.axis_value(Axis::Y)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn size(&self) -> f32 {
|
|
self.axis_value(Axis::Size)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_major(&self) -> f32 {
|
|
self.axis_value(Axis::ToolMajor)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_minor(&self) -> f32 {
|
|
self.axis_value(Axis::ToolMinor)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_major(&self) -> f32 {
|
|
self.axis_value(Axis::TouchMajor)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_minor(&self) -> f32 {
|
|
self.axis_value(Axis::TouchMinor)
|
|
}
|
|
}
|
|
|
|
/// An iterator over the pointers in a [`MotionEvent`].
|
|
#[derive(Debug)]
|
|
pub struct PointersIter<'a> {
|
|
event: &'a MotionEvent,
|
|
next_index: usize,
|
|
count: usize,
|
|
}
|
|
|
|
impl<'a> Iterator for PointersIter<'a> {
|
|
type Item = Pointer<'a>;
|
|
fn next(&mut self) -> Option<Pointer<'a>> {
|
|
if self.next_index < self.count {
|
|
let ptr = Pointer {
|
|
event: self.event,
|
|
index: self.next_index,
|
|
};
|
|
self.next_index += 1;
|
|
Some(ptr)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
let size = self.count - self.next_index;
|
|
(size, Some(size))
|
|
}
|
|
}
|
|
|
|
impl<'a> ExactSizeIterator for PointersIter<'a> {
|
|
fn len(&self) -> usize {
|
|
self.count - self.next_index
|
|
}
|
|
}
|
|
|
|
/*
|
|
/// Represents a view into a past moment of a motion event
|
|
#[derive(Debug)]
|
|
pub struct HistoricalMotionEvent<'a> {
|
|
event: NonNull<ndk_sys::AInputEvent>,
|
|
history_index: usize,
|
|
_marker: std::marker::PhantomData<&'a MotionEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
impl<'a> HistoricalMotionEvent<'a> {
|
|
/// Returns the "history index" associated with this historical event. Older events have smaller indices.
|
|
#[inline]
|
|
pub fn history_index(&self) -> usize {
|
|
self.history_index
|
|
}
|
|
|
|
/// Returns the time of the historical event, in the `java.lang.System.nanoTime()` time base
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_gethistoricaleventtime)
|
|
#[inline]
|
|
pub fn event_time(&self) -> i64 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalEventTime(
|
|
self.event.as_ptr(),
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
/// An iterator over the pointers of this historical motion event
|
|
#[inline]
|
|
pub fn pointers(&self) -> HistoricalPointersIter<'a> {
|
|
HistoricalPointersIter {
|
|
event: self.event,
|
|
history_index: self.history_index,
|
|
next_pointer_index: 0,
|
|
pointer_count: unsafe {
|
|
ndk_sys::AMotionEvent_getPointerCount(self.event.as_ptr()) as usize
|
|
},
|
|
_marker: std::marker::PhantomData,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// An iterator over all the historical moments in a [`MotionEvent`].
|
|
///
|
|
/// It iterates from oldest to newest.
|
|
#[derive(Debug)]
|
|
pub struct HistoricalMotionEventsIter<'a> {
|
|
event: NonNull<ndk_sys::AInputEvent>,
|
|
next_history_index: usize,
|
|
history_size: usize,
|
|
_marker: std::marker::PhantomData<&'a MotionEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
impl<'a> Iterator for HistoricalMotionEventsIter<'a> {
|
|
type Item = HistoricalMotionEvent<'a>;
|
|
|
|
fn next(&mut self) -> Option<HistoricalMotionEvent<'a>> {
|
|
if self.next_history_index < self.history_size {
|
|
let res = HistoricalMotionEvent {
|
|
event: self.event,
|
|
history_index: self.next_history_index,
|
|
_marker: std::marker::PhantomData,
|
|
};
|
|
self.next_history_index += 1;
|
|
Some(res)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
let size = self.history_size - self.next_history_index;
|
|
(size, Some(size))
|
|
}
|
|
}
|
|
impl ExactSizeIterator for HistoricalMotionEventsIter<'_> {
|
|
fn len(&self) -> usize {
|
|
self.history_size - self.next_history_index
|
|
}
|
|
}
|
|
impl<'a> DoubleEndedIterator for HistoricalMotionEventsIter<'a> {
|
|
fn next_back(&mut self) -> Option<HistoricalMotionEvent<'a>> {
|
|
if self.next_history_index < self.history_size {
|
|
self.history_size -= 1;
|
|
Some(HistoricalMotionEvent {
|
|
event: self.event,
|
|
history_index: self.history_size,
|
|
_marker: std::marker::PhantomData,
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A view into a pointer at a historical moment
|
|
#[derive(Debug)]
|
|
pub struct HistoricalPointer<'a> {
|
|
event: NonNull<ndk_sys::AInputEvent>,
|
|
pointer_index: usize,
|
|
history_index: usize,
|
|
_marker: std::marker::PhantomData<&'a MotionEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
impl<'a> HistoricalPointer<'a> {
|
|
#[inline]
|
|
pub fn pointer_index(&self) -> usize {
|
|
self.pointer_index
|
|
}
|
|
|
|
#[inline]
|
|
pub fn pointer_id(&self) -> i32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getPointerId(self.event.as_ptr(), self.pointer_index as ndk_sys::size_t)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn history_index(&self) -> usize {
|
|
self.history_index
|
|
}
|
|
|
|
#[inline]
|
|
pub fn axis_value(&self, axis: Axis) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalAxisValue(
|
|
self.event.as_ptr(),
|
|
axis as i32,
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn orientation(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalOrientation(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn pressure(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalPressure(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_x(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalRawX(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_y(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalRawY(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn x(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalX(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn y(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalY(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn size(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalSize(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_major(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalToolMajor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_minor(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalToolMinor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_major(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalTouchMajor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_minor(&self) -> f32 {
|
|
unsafe {
|
|
ndk_sys::AMotionEvent_getHistoricalTouchMinor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index as ndk_sys::size_t,
|
|
self.history_index as ndk_sys::size_t,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// An iterator over the pointers in a historical motion event
|
|
#[derive(Debug)]
|
|
pub struct HistoricalPointersIter<'a> {
|
|
event: NonNull<ndk_sys::AInputEvent>,
|
|
history_index: usize,
|
|
next_pointer_index: usize,
|
|
pointer_count: usize,
|
|
_marker: std::marker::PhantomData<&'a MotionEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
impl<'a> Iterator for HistoricalPointersIter<'a> {
|
|
type Item = HistoricalPointer<'a>;
|
|
|
|
fn next(&mut self) -> Option<HistoricalPointer<'a>> {
|
|
if self.next_pointer_index < self.pointer_count {
|
|
let ptr = HistoricalPointer {
|
|
event: self.event,
|
|
history_index: self.history_index,
|
|
pointer_index: self.next_pointer_index,
|
|
_marker: std::marker::PhantomData,
|
|
};
|
|
self.next_pointer_index += 1;
|
|
Some(ptr)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
let size = self.pointer_count - self.next_pointer_index;
|
|
(size, Some(size))
|
|
}
|
|
}
|
|
impl ExactSizeIterator for HistoricalPointersIter<'_> {
|
|
fn len(&self) -> usize {
|
|
self.pointer_count - self.next_pointer_index
|
|
}
|
|
}
|
|
|
|
*/
|
|
|
|
/// A key event.
|
|
///
|
|
/// For general discussion of key events in Android, see [the relevant
|
|
/// javadoc](https://developer.android.com/reference/android/view/KeyEvent).
|
|
#[derive(Debug)]
|
|
pub struct KeyEvent {
|
|
ga_event: GameActivityKeyEvent
|
|
}
|
|
|
|
impl Deref for KeyEvent {
|
|
type Target = GameActivityKeyEvent;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.ga_event
|
|
}
|
|
}
|
|
|
|
/// Key actions.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-27)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(u32)]
|
|
pub enum KeyAction {
|
|
Down = ndk_sys::AKEY_EVENT_ACTION_DOWN,
|
|
Up = ndk_sys::AKEY_EVENT_ACTION_UP,
|
|
Multiple = ndk_sys::AKEY_EVENT_ACTION_MULTIPLE,
|
|
}
|
|
|
|
/// Key codes.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-39)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(u32)]
|
|
pub enum Keycode {
|
|
Unknown = ndk_sys::AKEYCODE_UNKNOWN,
|
|
SoftLeft = ndk_sys::AKEYCODE_SOFT_LEFT,
|
|
SoftRight = ndk_sys::AKEYCODE_SOFT_RIGHT,
|
|
Home = ndk_sys::AKEYCODE_HOME,
|
|
Back = ndk_sys::AKEYCODE_BACK,
|
|
Call = ndk_sys::AKEYCODE_CALL,
|
|
Endcall = ndk_sys::AKEYCODE_ENDCALL,
|
|
Keycode0 = ndk_sys::AKEYCODE_0,
|
|
Keycode1 = ndk_sys::AKEYCODE_1,
|
|
Keycode2 = ndk_sys::AKEYCODE_2,
|
|
Keycode3 = ndk_sys::AKEYCODE_3,
|
|
Keycode4 = ndk_sys::AKEYCODE_4,
|
|
Keycode5 = ndk_sys::AKEYCODE_5,
|
|
Keycode6 = ndk_sys::AKEYCODE_6,
|
|
Keycode7 = ndk_sys::AKEYCODE_7,
|
|
Keycode8 = ndk_sys::AKEYCODE_8,
|
|
Keycode9 = ndk_sys::AKEYCODE_9,
|
|
Star = ndk_sys::AKEYCODE_STAR,
|
|
Pound = ndk_sys::AKEYCODE_POUND,
|
|
DpadUp = ndk_sys::AKEYCODE_DPAD_UP,
|
|
DpadDown = ndk_sys::AKEYCODE_DPAD_DOWN,
|
|
DpadLeft = ndk_sys::AKEYCODE_DPAD_LEFT,
|
|
DpadRight = ndk_sys::AKEYCODE_DPAD_RIGHT,
|
|
DpadCenter = ndk_sys::AKEYCODE_DPAD_CENTER,
|
|
VolumeUp = ndk_sys::AKEYCODE_VOLUME_UP,
|
|
VolumeDown = ndk_sys::AKEYCODE_VOLUME_DOWN,
|
|
Power = ndk_sys::AKEYCODE_POWER,
|
|
Camera = ndk_sys::AKEYCODE_CAMERA,
|
|
Clear = ndk_sys::AKEYCODE_CLEAR,
|
|
A = ndk_sys::AKEYCODE_A,
|
|
B = ndk_sys::AKEYCODE_B,
|
|
C = ndk_sys::AKEYCODE_C,
|
|
D = ndk_sys::AKEYCODE_D,
|
|
E = ndk_sys::AKEYCODE_E,
|
|
F = ndk_sys::AKEYCODE_F,
|
|
G = ndk_sys::AKEYCODE_G,
|
|
H = ndk_sys::AKEYCODE_H,
|
|
I = ndk_sys::AKEYCODE_I,
|
|
J = ndk_sys::AKEYCODE_J,
|
|
K = ndk_sys::AKEYCODE_K,
|
|
L = ndk_sys::AKEYCODE_L,
|
|
M = ndk_sys::AKEYCODE_M,
|
|
N = ndk_sys::AKEYCODE_N,
|
|
O = ndk_sys::AKEYCODE_O,
|
|
P = ndk_sys::AKEYCODE_P,
|
|
Q = ndk_sys::AKEYCODE_Q,
|
|
R = ndk_sys::AKEYCODE_R,
|
|
S = ndk_sys::AKEYCODE_S,
|
|
T = ndk_sys::AKEYCODE_T,
|
|
U = ndk_sys::AKEYCODE_U,
|
|
V = ndk_sys::AKEYCODE_V,
|
|
W = ndk_sys::AKEYCODE_W,
|
|
X = ndk_sys::AKEYCODE_X,
|
|
Y = ndk_sys::AKEYCODE_Y,
|
|
Z = ndk_sys::AKEYCODE_Z,
|
|
Comma = ndk_sys::AKEYCODE_COMMA,
|
|
Period = ndk_sys::AKEYCODE_PERIOD,
|
|
AltLeft = ndk_sys::AKEYCODE_ALT_LEFT,
|
|
AltRight = ndk_sys::AKEYCODE_ALT_RIGHT,
|
|
ShiftLeft = ndk_sys::AKEYCODE_SHIFT_LEFT,
|
|
ShiftRight = ndk_sys::AKEYCODE_SHIFT_RIGHT,
|
|
Tab = ndk_sys::AKEYCODE_TAB,
|
|
Space = ndk_sys::AKEYCODE_SPACE,
|
|
Sym = ndk_sys::AKEYCODE_SYM,
|
|
Explorer = ndk_sys::AKEYCODE_EXPLORER,
|
|
Envelope = ndk_sys::AKEYCODE_ENVELOPE,
|
|
Enter = ndk_sys::AKEYCODE_ENTER,
|
|
Del = ndk_sys::AKEYCODE_DEL,
|
|
Grave = ndk_sys::AKEYCODE_GRAVE,
|
|
Minus = ndk_sys::AKEYCODE_MINUS,
|
|
Equals = ndk_sys::AKEYCODE_EQUALS,
|
|
LeftBracket = ndk_sys::AKEYCODE_LEFT_BRACKET,
|
|
RightBracket = ndk_sys::AKEYCODE_RIGHT_BRACKET,
|
|
Backslash = ndk_sys::AKEYCODE_BACKSLASH,
|
|
Semicolon = ndk_sys::AKEYCODE_SEMICOLON,
|
|
Apostrophe = ndk_sys::AKEYCODE_APOSTROPHE,
|
|
Slash = ndk_sys::AKEYCODE_SLASH,
|
|
At = ndk_sys::AKEYCODE_AT,
|
|
Num = ndk_sys::AKEYCODE_NUM,
|
|
Headsethook = ndk_sys::AKEYCODE_HEADSETHOOK,
|
|
Focus = ndk_sys::AKEYCODE_FOCUS,
|
|
Plus = ndk_sys::AKEYCODE_PLUS,
|
|
Menu = ndk_sys::AKEYCODE_MENU,
|
|
Notification = ndk_sys::AKEYCODE_NOTIFICATION,
|
|
Search = ndk_sys::AKEYCODE_SEARCH,
|
|
MediaPlayPause = ndk_sys::AKEYCODE_MEDIA_PLAY_PAUSE,
|
|
MediaStop = ndk_sys::AKEYCODE_MEDIA_STOP,
|
|
MediaNext = ndk_sys::AKEYCODE_MEDIA_NEXT,
|
|
MediaPrevious = ndk_sys::AKEYCODE_MEDIA_PREVIOUS,
|
|
MediaRewind = ndk_sys::AKEYCODE_MEDIA_REWIND,
|
|
MediaFastForward = ndk_sys::AKEYCODE_MEDIA_FAST_FORWARD,
|
|
Mute = ndk_sys::AKEYCODE_MUTE,
|
|
PageUp = ndk_sys::AKEYCODE_PAGE_UP,
|
|
PageDown = ndk_sys::AKEYCODE_PAGE_DOWN,
|
|
Pictsymbols = ndk_sys::AKEYCODE_PICTSYMBOLS,
|
|
SwitchCharset = ndk_sys::AKEYCODE_SWITCH_CHARSET,
|
|
ButtonA = ndk_sys::AKEYCODE_BUTTON_A,
|
|
ButtonB = ndk_sys::AKEYCODE_BUTTON_B,
|
|
ButtonC = ndk_sys::AKEYCODE_BUTTON_C,
|
|
ButtonX = ndk_sys::AKEYCODE_BUTTON_X,
|
|
ButtonY = ndk_sys::AKEYCODE_BUTTON_Y,
|
|
ButtonZ = ndk_sys::AKEYCODE_BUTTON_Z,
|
|
ButtonL1 = ndk_sys::AKEYCODE_BUTTON_L1,
|
|
ButtonR1 = ndk_sys::AKEYCODE_BUTTON_R1,
|
|
ButtonL2 = ndk_sys::AKEYCODE_BUTTON_L2,
|
|
ButtonR2 = ndk_sys::AKEYCODE_BUTTON_R2,
|
|
ButtonThumbl = ndk_sys::AKEYCODE_BUTTON_THUMBL,
|
|
ButtonThumbr = ndk_sys::AKEYCODE_BUTTON_THUMBR,
|
|
ButtonStart = ndk_sys::AKEYCODE_BUTTON_START,
|
|
ButtonSelect = ndk_sys::AKEYCODE_BUTTON_SELECT,
|
|
ButtonMode = ndk_sys::AKEYCODE_BUTTON_MODE,
|
|
Escape = ndk_sys::AKEYCODE_ESCAPE,
|
|
ForwardDel = ndk_sys::AKEYCODE_FORWARD_DEL,
|
|
CtrlLeft = ndk_sys::AKEYCODE_CTRL_LEFT,
|
|
CtrlRight = ndk_sys::AKEYCODE_CTRL_RIGHT,
|
|
CapsLock = ndk_sys::AKEYCODE_CAPS_LOCK,
|
|
ScrollLock = ndk_sys::AKEYCODE_SCROLL_LOCK,
|
|
MetaLeft = ndk_sys::AKEYCODE_META_LEFT,
|
|
MetaRight = ndk_sys::AKEYCODE_META_RIGHT,
|
|
Function = ndk_sys::AKEYCODE_FUNCTION,
|
|
Sysrq = ndk_sys::AKEYCODE_SYSRQ,
|
|
Break = ndk_sys::AKEYCODE_BREAK,
|
|
MoveHome = ndk_sys::AKEYCODE_MOVE_HOME,
|
|
MoveEnd = ndk_sys::AKEYCODE_MOVE_END,
|
|
Insert = ndk_sys::AKEYCODE_INSERT,
|
|
Forward = ndk_sys::AKEYCODE_FORWARD,
|
|
MediaPlay = ndk_sys::AKEYCODE_MEDIA_PLAY,
|
|
MediaPause = ndk_sys::AKEYCODE_MEDIA_PAUSE,
|
|
MediaClose = ndk_sys::AKEYCODE_MEDIA_CLOSE,
|
|
MediaEject = ndk_sys::AKEYCODE_MEDIA_EJECT,
|
|
MediaRecord = ndk_sys::AKEYCODE_MEDIA_RECORD,
|
|
F1 = ndk_sys::AKEYCODE_F1,
|
|
F2 = ndk_sys::AKEYCODE_F2,
|
|
F3 = ndk_sys::AKEYCODE_F3,
|
|
F4 = ndk_sys::AKEYCODE_F4,
|
|
F5 = ndk_sys::AKEYCODE_F5,
|
|
F6 = ndk_sys::AKEYCODE_F6,
|
|
F7 = ndk_sys::AKEYCODE_F7,
|
|
F8 = ndk_sys::AKEYCODE_F8,
|
|
F9 = ndk_sys::AKEYCODE_F9,
|
|
F10 = ndk_sys::AKEYCODE_F10,
|
|
F11 = ndk_sys::AKEYCODE_F11,
|
|
F12 = ndk_sys::AKEYCODE_F12,
|
|
NumLock = ndk_sys::AKEYCODE_NUM_LOCK,
|
|
Numpad0 = ndk_sys::AKEYCODE_NUMPAD_0,
|
|
Numpad1 = ndk_sys::AKEYCODE_NUMPAD_1,
|
|
Numpad2 = ndk_sys::AKEYCODE_NUMPAD_2,
|
|
Numpad3 = ndk_sys::AKEYCODE_NUMPAD_3,
|
|
Numpad4 = ndk_sys::AKEYCODE_NUMPAD_4,
|
|
Numpad5 = ndk_sys::AKEYCODE_NUMPAD_5,
|
|
Numpad6 = ndk_sys::AKEYCODE_NUMPAD_6,
|
|
Numpad7 = ndk_sys::AKEYCODE_NUMPAD_7,
|
|
Numpad8 = ndk_sys::AKEYCODE_NUMPAD_8,
|
|
Numpad9 = ndk_sys::AKEYCODE_NUMPAD_9,
|
|
NumpadDivide = ndk_sys::AKEYCODE_NUMPAD_DIVIDE,
|
|
NumpadMultiply = ndk_sys::AKEYCODE_NUMPAD_MULTIPLY,
|
|
NumpadSubtract = ndk_sys::AKEYCODE_NUMPAD_SUBTRACT,
|
|
NumpadAdd = ndk_sys::AKEYCODE_NUMPAD_ADD,
|
|
NumpadDot = ndk_sys::AKEYCODE_NUMPAD_DOT,
|
|
NumpadComma = ndk_sys::AKEYCODE_NUMPAD_COMMA,
|
|
NumpadEnter = ndk_sys::AKEYCODE_NUMPAD_ENTER,
|
|
NumpadEquals = ndk_sys::AKEYCODE_NUMPAD_EQUALS,
|
|
NumpadLeftParen = ndk_sys::AKEYCODE_NUMPAD_LEFT_PAREN,
|
|
NumpadRightParen = ndk_sys::AKEYCODE_NUMPAD_RIGHT_PAREN,
|
|
VolumeMute = ndk_sys::AKEYCODE_VOLUME_MUTE,
|
|
Info = ndk_sys::AKEYCODE_INFO,
|
|
ChannelUp = ndk_sys::AKEYCODE_CHANNEL_UP,
|
|
ChannelDown = ndk_sys::AKEYCODE_CHANNEL_DOWN,
|
|
ZoomIn = ndk_sys::AKEYCODE_ZOOM_IN,
|
|
ZoomOut = ndk_sys::AKEYCODE_ZOOM_OUT,
|
|
Tv = ndk_sys::AKEYCODE_TV,
|
|
Window = ndk_sys::AKEYCODE_WINDOW,
|
|
Guide = ndk_sys::AKEYCODE_GUIDE,
|
|
Dvr = ndk_sys::AKEYCODE_DVR,
|
|
Bookmark = ndk_sys::AKEYCODE_BOOKMARK,
|
|
Captions = ndk_sys::AKEYCODE_CAPTIONS,
|
|
Settings = ndk_sys::AKEYCODE_SETTINGS,
|
|
TvPower = ndk_sys::AKEYCODE_TV_POWER,
|
|
TvInput = ndk_sys::AKEYCODE_TV_INPUT,
|
|
StbPower = ndk_sys::AKEYCODE_STB_POWER,
|
|
StbInput = ndk_sys::AKEYCODE_STB_INPUT,
|
|
AvrPower = ndk_sys::AKEYCODE_AVR_POWER,
|
|
AvrInput = ndk_sys::AKEYCODE_AVR_INPUT,
|
|
ProgRed = ndk_sys::AKEYCODE_PROG_RED,
|
|
ProgGreen = ndk_sys::AKEYCODE_PROG_GREEN,
|
|
ProgYellow = ndk_sys::AKEYCODE_PROG_YELLOW,
|
|
ProgBlue = ndk_sys::AKEYCODE_PROG_BLUE,
|
|
AppSwitch = ndk_sys::AKEYCODE_APP_SWITCH,
|
|
Button1 = ndk_sys::AKEYCODE_BUTTON_1,
|
|
Button2 = ndk_sys::AKEYCODE_BUTTON_2,
|
|
Button3 = ndk_sys::AKEYCODE_BUTTON_3,
|
|
Button4 = ndk_sys::AKEYCODE_BUTTON_4,
|
|
Button5 = ndk_sys::AKEYCODE_BUTTON_5,
|
|
Button6 = ndk_sys::AKEYCODE_BUTTON_6,
|
|
Button7 = ndk_sys::AKEYCODE_BUTTON_7,
|
|
Button8 = ndk_sys::AKEYCODE_BUTTON_8,
|
|
Button9 = ndk_sys::AKEYCODE_BUTTON_9,
|
|
Button10 = ndk_sys::AKEYCODE_BUTTON_10,
|
|
Button11 = ndk_sys::AKEYCODE_BUTTON_11,
|
|
Button12 = ndk_sys::AKEYCODE_BUTTON_12,
|
|
Button13 = ndk_sys::AKEYCODE_BUTTON_13,
|
|
Button14 = ndk_sys::AKEYCODE_BUTTON_14,
|
|
Button15 = ndk_sys::AKEYCODE_BUTTON_15,
|
|
Button16 = ndk_sys::AKEYCODE_BUTTON_16,
|
|
LanguageSwitch = ndk_sys::AKEYCODE_LANGUAGE_SWITCH,
|
|
MannerMode = ndk_sys::AKEYCODE_MANNER_MODE,
|
|
Keycode3dMode = ndk_sys::AKEYCODE_3D_MODE,
|
|
Contacts = ndk_sys::AKEYCODE_CONTACTS,
|
|
Calendar = ndk_sys::AKEYCODE_CALENDAR,
|
|
Music = ndk_sys::AKEYCODE_MUSIC,
|
|
Calculator = ndk_sys::AKEYCODE_CALCULATOR,
|
|
ZenkakuHankaku = ndk_sys::AKEYCODE_ZENKAKU_HANKAKU,
|
|
Eisu = ndk_sys::AKEYCODE_EISU,
|
|
Muhenkan = ndk_sys::AKEYCODE_MUHENKAN,
|
|
Henkan = ndk_sys::AKEYCODE_HENKAN,
|
|
KatakanaHiragana = ndk_sys::AKEYCODE_KATAKANA_HIRAGANA,
|
|
Yen = ndk_sys::AKEYCODE_YEN,
|
|
Ro = ndk_sys::AKEYCODE_RO,
|
|
Kana = ndk_sys::AKEYCODE_KANA,
|
|
Assist = ndk_sys::AKEYCODE_ASSIST,
|
|
BrightnessDown = ndk_sys::AKEYCODE_BRIGHTNESS_DOWN,
|
|
BrightnessUp = ndk_sys::AKEYCODE_BRIGHTNESS_UP,
|
|
MediaAudioTrack = ndk_sys::AKEYCODE_MEDIA_AUDIO_TRACK,
|
|
Sleep = ndk_sys::AKEYCODE_SLEEP,
|
|
Wakeup = ndk_sys::AKEYCODE_WAKEUP,
|
|
Pairing = ndk_sys::AKEYCODE_PAIRING,
|
|
MediaTopMenu = ndk_sys::AKEYCODE_MEDIA_TOP_MENU,
|
|
Keycode11 = ndk_sys::AKEYCODE_11,
|
|
Keycode12 = ndk_sys::AKEYCODE_12,
|
|
LastChannel = ndk_sys::AKEYCODE_LAST_CHANNEL,
|
|
TvDataService = ndk_sys::AKEYCODE_TV_DATA_SERVICE,
|
|
VoiceAssist = ndk_sys::AKEYCODE_VOICE_ASSIST,
|
|
TvRadioService = ndk_sys::AKEYCODE_TV_RADIO_SERVICE,
|
|
TvTeletext = ndk_sys::AKEYCODE_TV_TELETEXT,
|
|
TvNumberEntry = ndk_sys::AKEYCODE_TV_NUMBER_ENTRY,
|
|
TvTerrestrialAnalog = ndk_sys::AKEYCODE_TV_TERRESTRIAL_ANALOG,
|
|
TvTerrestrialDigital = ndk_sys::AKEYCODE_TV_TERRESTRIAL_DIGITAL,
|
|
TvSatellite = ndk_sys::AKEYCODE_TV_SATELLITE,
|
|
TvSatelliteBs = ndk_sys::AKEYCODE_TV_SATELLITE_BS,
|
|
TvSatelliteCs = ndk_sys::AKEYCODE_TV_SATELLITE_CS,
|
|
TvSatelliteService = ndk_sys::AKEYCODE_TV_SATELLITE_SERVICE,
|
|
TvNetwork = ndk_sys::AKEYCODE_TV_NETWORK,
|
|
TvAntennaCable = ndk_sys::AKEYCODE_TV_ANTENNA_CABLE,
|
|
TvInputHdmi1 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_1,
|
|
TvInputHdmi2 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_2,
|
|
TvInputHdmi3 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_3,
|
|
TvInputHdmi4 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_4,
|
|
TvInputComposite1 = ndk_sys::AKEYCODE_TV_INPUT_COMPOSITE_1,
|
|
TvInputComposite2 = ndk_sys::AKEYCODE_TV_INPUT_COMPOSITE_2,
|
|
TvInputComponent1 = ndk_sys::AKEYCODE_TV_INPUT_COMPONENT_1,
|
|
TvInputComponent2 = ndk_sys::AKEYCODE_TV_INPUT_COMPONENT_2,
|
|
TvInputVga1 = ndk_sys::AKEYCODE_TV_INPUT_VGA_1,
|
|
TvAudioDescription = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION,
|
|
TvAudioDescriptionMixUp = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP,
|
|
TvAudioDescriptionMixDown = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN,
|
|
TvZoomMode = ndk_sys::AKEYCODE_TV_ZOOM_MODE,
|
|
TvContentsMenu = ndk_sys::AKEYCODE_TV_CONTENTS_MENU,
|
|
TvMediaContextMenu = ndk_sys::AKEYCODE_TV_MEDIA_CONTEXT_MENU,
|
|
TvTimerProgramming = ndk_sys::AKEYCODE_TV_TIMER_PROGRAMMING,
|
|
Help = ndk_sys::AKEYCODE_HELP,
|
|
NavigatePrevious = ndk_sys::AKEYCODE_NAVIGATE_PREVIOUS,
|
|
NavigateNext = ndk_sys::AKEYCODE_NAVIGATE_NEXT,
|
|
NavigateIn = ndk_sys::AKEYCODE_NAVIGATE_IN,
|
|
NavigateOut = ndk_sys::AKEYCODE_NAVIGATE_OUT,
|
|
StemPrimary = ndk_sys::AKEYCODE_STEM_PRIMARY,
|
|
Stem1 = ndk_sys::AKEYCODE_STEM_1,
|
|
Stem2 = ndk_sys::AKEYCODE_STEM_2,
|
|
Stem3 = ndk_sys::AKEYCODE_STEM_3,
|
|
DpadUpLeft = ndk_sys::AKEYCODE_DPAD_UP_LEFT,
|
|
DpadDownLeft = ndk_sys::AKEYCODE_DPAD_DOWN_LEFT,
|
|
DpadUpRight = ndk_sys::AKEYCODE_DPAD_UP_RIGHT,
|
|
DpadDownRight = ndk_sys::AKEYCODE_DPAD_DOWN_RIGHT,
|
|
MediaSkipForward = ndk_sys::AKEYCODE_MEDIA_SKIP_FORWARD,
|
|
MediaSkipBackward = ndk_sys::AKEYCODE_MEDIA_SKIP_BACKWARD,
|
|
MediaStepForward = ndk_sys::AKEYCODE_MEDIA_STEP_FORWARD,
|
|
MediaStepBackward = ndk_sys::AKEYCODE_MEDIA_STEP_BACKWARD,
|
|
SoftSleep = ndk_sys::AKEYCODE_SOFT_SLEEP,
|
|
Cut = ndk_sys::AKEYCODE_CUT,
|
|
Copy = ndk_sys::AKEYCODE_COPY,
|
|
Paste = ndk_sys::AKEYCODE_PASTE,
|
|
SystemNavigationUp = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_UP,
|
|
SystemNavigationDown = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_DOWN,
|
|
SystemNavigationLeft = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_LEFT,
|
|
SystemNavigationRight = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
|
|
AllApps = ndk_sys::AKEYCODE_ALL_APPS,
|
|
Refresh = ndk_sys::AKEYCODE_REFRESH,
|
|
ThumbsUp = ndk_sys::AKEYCODE_THUMBS_UP,
|
|
ThumbsDown = ndk_sys::AKEYCODE_THUMBS_DOWN,
|
|
ProfileSwitch = ndk_sys::AKEYCODE_PROFILE_SWITCH,
|
|
}
|
|
|
|
impl KeyEvent {
|
|
|
|
pub(crate) fn new(ga_event: GameActivityKeyEvent) -> Self {
|
|
Self { ga_event }
|
|
}
|
|
|
|
/// Get the source of the event.
|
|
///
|
|
#[inline]
|
|
pub fn source(&self) -> Source {
|
|
self.source.try_into().unwrap_or(Source::Unknown)
|
|
}
|
|
|
|
/// Get the class of the event source.
|
|
///
|
|
#[inline]
|
|
pub fn class(&self) -> Class {
|
|
Class::from(self.source)
|
|
}
|
|
|
|
/// Get the device id associated with the event.
|
|
///
|
|
#[inline]
|
|
pub fn device_id(&self) -> i32 {
|
|
self.deviceId
|
|
}
|
|
|
|
/// Returns the key action associated with the event.
|
|
///
|
|
/// See [the KeyEvent docs](https://developer.android.com/reference/android/view/KeyEvent#getAction())
|
|
#[inline]
|
|
pub fn action(&self) -> KeyAction {
|
|
let action = self.action as u32;
|
|
action.try_into().unwrap()
|
|
}
|
|
|
|
/// Returns the last time the key was pressed. This is on the scale of
|
|
/// `java.lang.System.nanoTime()`, which has nanosecond precision, but no defined start time.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getdowntime)
|
|
#[inline]
|
|
pub fn down_time(&self) -> i64 {
|
|
self.downTime
|
|
}
|
|
|
|
/// Returns the time this event occured. This is on the scale of
|
|
/// `java.lang.System.nanoTime()`, which has nanosecond precision, but no defined start time.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_geteventtime)
|
|
#[inline]
|
|
pub fn event_time(&self) -> i64 {
|
|
self.eventTime
|
|
}
|
|
|
|
/// Returns the keycode associated with this key event
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getkeycode)
|
|
#[inline]
|
|
pub fn key_code(&self) -> Keycode {
|
|
let keycode = self.keyCode as u32;
|
|
keycode.try_into().unwrap_or(Keycode::Unknown)
|
|
}
|
|
|
|
/// Returns the number of repeats of a key.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getrepeatcount)
|
|
#[inline]
|
|
pub fn repeat_count(&self) -> i32 {
|
|
self.repeatCount
|
|
}
|
|
|
|
/// Returns the hardware keycode of a key. This varies from device to device.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getscancode)
|
|
#[inline]
|
|
pub fn scan_code(&self) -> i32 {
|
|
self.scanCode
|
|
}
|
|
}
|
|
|
|
/// Flags associated with [`KeyEvent`].
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-28)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub struct KeyEventFlags(pub u32);
|
|
|
|
impl KeyEventFlags {
|
|
#[inline]
|
|
pub fn cancelled(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_CANCELED != 0
|
|
}
|
|
#[inline]
|
|
pub fn cancelled_long_press(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_CANCELED_LONG_PRESS != 0
|
|
}
|
|
#[inline]
|
|
pub fn editor_action(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_EDITOR_ACTION != 0
|
|
}
|
|
#[inline]
|
|
pub fn fallback(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_FALLBACK != 0
|
|
}
|
|
#[inline]
|
|
pub fn from_system(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_FROM_SYSTEM != 0
|
|
}
|
|
#[inline]
|
|
pub fn keep_touch_mode(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_KEEP_TOUCH_MODE != 0
|
|
}
|
|
#[inline]
|
|
pub fn long_press(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_LONG_PRESS != 0
|
|
}
|
|
#[inline]
|
|
pub fn soft_keyboard(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_SOFT_KEYBOARD != 0
|
|
}
|
|
#[inline]
|
|
pub fn tracking(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_TRACKING != 0
|
|
}
|
|
#[inline]
|
|
pub fn virtual_hard_key(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY != 0
|
|
}
|
|
#[inline]
|
|
pub fn woke_here(&self) -> bool {
|
|
self.0 & ndk_sys::AKEY_EVENT_FLAG_WOKE_HERE != 0
|
|
}
|
|
}
|
|
|
|
impl KeyEvent {
|
|
|
|
/// Flags associated with this [`KeyEvent`].
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getflags)
|
|
#[inline]
|
|
pub fn flags(&self) -> KeyEventFlags {
|
|
KeyEventFlags(self.flags as u32)
|
|
}
|
|
|
|
/// Returns the state of the modifiers during this key event, represented by a bitmask.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getmetastate)
|
|
#[inline]
|
|
pub fn meta_state(&self) -> MetaState {
|
|
MetaState(self.metaState as u32)
|
|
}
|
|
} |