1500 lines
49 KiB
Rust
1500 lines
49 KiB
Rust
//! Bindings for [`AInputEvent`, `AKeyEvent` and `AMotionEvent`]
|
|
//!
|
|
//! Most of these operations directly wrap functions in the NDK.
|
|
//!
|
|
//! See also the Java docs for [`android.view.InputEvent`], [`android.view.MotionEvent`], and
|
|
//! [`android.view.KeyEvent`].
|
|
//!
|
|
//! [`AInputEvent`, `AKeyEvent` and `AMotionEvent`]: https://developer.android.com/ndk/reference/group/input
|
|
//! [`android.view.InputEvent`]: https://developer.android.com/reference/android/view/InputEvent.html
|
|
//! [`android.view.MotionEvent`]: https://developer.android.com/reference/android/view/MotionEvent.html
|
|
//! [`android.view.KeyEvent`]: https://developer.android.com/reference/android/view/KeyEvent
|
|
|
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
|
use std::ptr::NonNull;
|
|
|
|
/// A native [`AInputEvent *`]
|
|
///
|
|
/// [`AInputEvent *`]: https://developer.android.com/ndk/reference/group/input#ainputevent
|
|
#[derive(Debug)]
|
|
pub enum InputEvent {
|
|
MotionEvent(MotionEvent),
|
|
KeyEvent(KeyEvent),
|
|
}
|
|
|
|
/// An enum representing the source of an [`InputEvent`].
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-36)
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(u32)]
|
|
pub enum Source {
|
|
Unknown = ffi::AINPUT_SOURCE_UNKNOWN,
|
|
Keyboard = ffi::AINPUT_SOURCE_KEYBOARD,
|
|
Dpad = ffi::AINPUT_SOURCE_DPAD,
|
|
Gamepad = ffi::AINPUT_SOURCE_GAMEPAD,
|
|
Touchscreen = ffi::AINPUT_SOURCE_TOUCHSCREEN,
|
|
Mouse = ffi::AINPUT_SOURCE_MOUSE,
|
|
Stylus = ffi::AINPUT_SOURCE_STYLUS,
|
|
BluetoothStylus = ffi::AINPUT_SOURCE_BLUETOOTH_STYLUS,
|
|
Trackball = ffi::AINPUT_SOURCE_TRACKBALL,
|
|
MouseRelative = ffi::AINPUT_SOURCE_MOUSE_RELATIVE,
|
|
Touchpad = ffi::AINPUT_SOURCE_TOUCHPAD,
|
|
TouchNavigation = ffi::AINPUT_SOURCE_TOUCH_NAVIGATION,
|
|
Joystick = ffi::AINPUT_SOURCE_JOYSTICK,
|
|
Hdmi = ffi::AINPUT_SOURCE_HDMI,
|
|
Sensor = ffi::AINPUT_SOURCE_SENSOR,
|
|
RotaryEncoder = ffi::AINPUT_SOURCE_ROTARY_ENCODER,
|
|
Any = ffi::AINPUT_SOURCE_ANY,
|
|
}
|
|
|
|
/// An enum representing the class of an [`InputEvent`] source.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-35)
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(u32)]
|
|
enum Class {
|
|
None = ffi::AINPUT_SOURCE_CLASS_NONE,
|
|
Button = ffi::AINPUT_SOURCE_CLASS_BUTTON,
|
|
Pointer = ffi::AINPUT_SOURCE_CLASS_POINTER,
|
|
Navigation = ffi::AINPUT_SOURCE_CLASS_NAVIGATION,
|
|
Position = ffi::AINPUT_SOURCE_CLASS_POSITION,
|
|
Joystick = ffi::AINPUT_SOURCE_CLASS_JOYSTICK,
|
|
}
|
|
|
|
impl InputEvent {
|
|
/// Initialize an [`InputEvent`] from a pointer
|
|
///
|
|
/// # Safety
|
|
/// By calling this function, you assert that the pointer is a valid pointer to a
|
|
/// native [`ffi::AInputEvent`].
|
|
#[inline]
|
|
pub unsafe fn from_ptr(ptr: NonNull<ffi::AInputEvent>) -> Self {
|
|
match ffi::AInputEvent_getType(ptr.as_ptr()) as u32 {
|
|
ffi::AINPUT_EVENT_TYPE_KEY => InputEvent::KeyEvent(KeyEvent::from_ptr(ptr)),
|
|
ffi::AINPUT_EVENT_TYPE_MOTION => InputEvent::MotionEvent(MotionEvent::from_ptr(ptr)),
|
|
x => panic!("Bad event type received: {}", x),
|
|
}
|
|
}
|
|
|
|
/// Returns a pointer to the native [`ffi::AInputEvent`].
|
|
#[inline]
|
|
pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
|
|
match self {
|
|
InputEvent::MotionEvent(MotionEvent { ptr }) => *ptr,
|
|
InputEvent::KeyEvent(KeyEvent { ptr }) => *ptr,
|
|
}
|
|
}
|
|
|
|
/// Get the source of the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#ainputevent_getsource)
|
|
#[inline]
|
|
pub fn source(&self) -> Source {
|
|
let source = unsafe { ffi::AInputEvent_getSource(self.ptr().as_ptr()) as u32 };
|
|
source.try_into().unwrap_or(Source::Unknown)
|
|
}
|
|
|
|
/// Get the device id associated with the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#ainputevent_getdeviceid)
|
|
#[inline]
|
|
pub fn device_id(&self) -> i32 {
|
|
unsafe { ffi::AInputEvent_getDeviceId(self.ptr().as_ptr()) }
|
|
}
|
|
}
|
|
|
|
/// 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 & ffi::AMETA_ALT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn alt_left_on(self) -> bool {
|
|
self.0 & ffi::AMETA_ALT_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn alt_right_on(self) -> bool {
|
|
self.0 & ffi::AMETA_ALT_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn shift_on(self) -> bool {
|
|
self.0 & ffi::AMETA_SHIFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn shift_left_on(self) -> bool {
|
|
self.0 & ffi::AMETA_SHIFT_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn shift_right_on(self) -> bool {
|
|
self.0 & ffi::AMETA_SHIFT_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn sym_on(self) -> bool {
|
|
self.0 & ffi::AMETA_SYM_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn function_on(self) -> bool {
|
|
self.0 & ffi::AMETA_FUNCTION_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn ctrl_on(self) -> bool {
|
|
self.0 & ffi::AMETA_CTRL_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn ctrl_left_on(self) -> bool {
|
|
self.0 & ffi::AMETA_CTRL_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn ctrl_right_on(self) -> bool {
|
|
self.0 & ffi::AMETA_CTRL_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn meta_on(self) -> bool {
|
|
self.0 & ffi::AMETA_META_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn meta_left_on(self) -> bool {
|
|
self.0 & ffi::AMETA_META_LEFT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn meta_right_on(self) -> bool {
|
|
self.0 & ffi::AMETA_META_RIGHT_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn caps_lock_on(self) -> bool {
|
|
self.0 & ffi::AMETA_CAPS_LOCK_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn num_lock_on(self) -> bool {
|
|
self.0 & ffi::AMETA_NUM_LOCK_ON != 0
|
|
}
|
|
#[inline]
|
|
pub fn scroll_lock_on(self) -> bool {
|
|
self.0 & ffi::AMETA_SCROLL_LOCK_ON != 0
|
|
}
|
|
}
|
|
|
|
/// A motion event
|
|
///
|
|
/// Wraps an [`AInputEvent *`] of the [`ffi::AINPUT_EVENT_TYPE_MOTION`] type.
|
|
///
|
|
/// For general discussion of motion events in Android, see [the relevant
|
|
/// javadoc](https://developer.android.com/reference/android/view/MotionEvent).
|
|
///
|
|
/// [`AInputEvent *`]: https://developer.android.com/ndk/reference/group/input#ainputevent
|
|
#[derive(Clone, Debug)]
|
|
pub struct MotionEvent {
|
|
ptr: NonNull<ffi::AInputEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
/// 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 = ffi::AMOTION_EVENT_ACTION_DOWN,
|
|
Up = ffi::AMOTION_EVENT_ACTION_UP,
|
|
Move = ffi::AMOTION_EVENT_ACTION_MOVE,
|
|
Cancel = ffi::AMOTION_EVENT_ACTION_CANCEL,
|
|
Outside = ffi::AMOTION_EVENT_ACTION_OUTSIDE,
|
|
PointerDown = ffi::AMOTION_EVENT_ACTION_POINTER_DOWN,
|
|
PointerUp = ffi::AMOTION_EVENT_ACTION_POINTER_UP,
|
|
HoverMove = ffi::AMOTION_EVENT_ACTION_HOVER_MOVE,
|
|
Scroll = ffi::AMOTION_EVENT_ACTION_SCROLL,
|
|
HoverEnter = ffi::AMOTION_EVENT_ACTION_HOVER_ENTER,
|
|
HoverExit = ffi::AMOTION_EVENT_ACTION_HOVER_EXIT,
|
|
ButtonPress = ffi::AMOTION_EVENT_ACTION_BUTTON_PRESS,
|
|
ButtonRelease = ffi::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 = ffi::AMOTION_EVENT_AXIS_X,
|
|
Y = ffi::AMOTION_EVENT_AXIS_Y,
|
|
Pressure = ffi::AMOTION_EVENT_AXIS_PRESSURE,
|
|
Size = ffi::AMOTION_EVENT_AXIS_SIZE,
|
|
TouchMajor = ffi::AMOTION_EVENT_AXIS_TOUCH_MAJOR,
|
|
TouchMinor = ffi::AMOTION_EVENT_AXIS_TOUCH_MINOR,
|
|
ToolMajor = ffi::AMOTION_EVENT_AXIS_TOOL_MAJOR,
|
|
ToolMinor = ffi::AMOTION_EVENT_AXIS_TOOL_MINOR,
|
|
Orientation = ffi::AMOTION_EVENT_AXIS_ORIENTATION,
|
|
Vscroll = ffi::AMOTION_EVENT_AXIS_VSCROLL,
|
|
Hscroll = ffi::AMOTION_EVENT_AXIS_HSCROLL,
|
|
Z = ffi::AMOTION_EVENT_AXIS_Z,
|
|
Rx = ffi::AMOTION_EVENT_AXIS_RX,
|
|
Ry = ffi::AMOTION_EVENT_AXIS_RY,
|
|
Rz = ffi::AMOTION_EVENT_AXIS_RZ,
|
|
HatX = ffi::AMOTION_EVENT_AXIS_HAT_X,
|
|
HatY = ffi::AMOTION_EVENT_AXIS_HAT_Y,
|
|
Ltrigger = ffi::AMOTION_EVENT_AXIS_LTRIGGER,
|
|
Rtrigger = ffi::AMOTION_EVENT_AXIS_RTRIGGER,
|
|
Throttle = ffi::AMOTION_EVENT_AXIS_THROTTLE,
|
|
Rudder = ffi::AMOTION_EVENT_AXIS_RUDDER,
|
|
Wheel = ffi::AMOTION_EVENT_AXIS_WHEEL,
|
|
Gas = ffi::AMOTION_EVENT_AXIS_GAS,
|
|
Brake = ffi::AMOTION_EVENT_AXIS_BRAKE,
|
|
Distance = ffi::AMOTION_EVENT_AXIS_DISTANCE,
|
|
Tilt = ffi::AMOTION_EVENT_AXIS_TILT,
|
|
Scroll = ffi::AMOTION_EVENT_AXIS_SCROLL,
|
|
RelativeX = ffi::AMOTION_EVENT_AXIS_RELATIVE_X,
|
|
RelativeY = ffi::AMOTION_EVENT_AXIS_RELATIVE_Y,
|
|
Generic1 = ffi::AMOTION_EVENT_AXIS_GENERIC_1,
|
|
Generic2 = ffi::AMOTION_EVENT_AXIS_GENERIC_2,
|
|
Generic3 = ffi::AMOTION_EVENT_AXIS_GENERIC_3,
|
|
Generic4 = ffi::AMOTION_EVENT_AXIS_GENERIC_4,
|
|
Generic5 = ffi::AMOTION_EVENT_AXIS_GENERIC_5,
|
|
Generic6 = ffi::AMOTION_EVENT_AXIS_GENERIC_6,
|
|
Generic7 = ffi::AMOTION_EVENT_AXIS_GENERIC_7,
|
|
Generic8 = ffi::AMOTION_EVENT_AXIS_GENERIC_8,
|
|
Generic9 = ffi::AMOTION_EVENT_AXIS_GENERIC_9,
|
|
Generic10 = ffi::AMOTION_EVENT_AXIS_GENERIC_10,
|
|
Generic11 = ffi::AMOTION_EVENT_AXIS_GENERIC_11,
|
|
Generic12 = ffi::AMOTION_EVENT_AXIS_GENERIC_12,
|
|
Generic13 = ffi::AMOTION_EVENT_AXIS_GENERIC_13,
|
|
Generic14 = ffi::AMOTION_EVENT_AXIS_GENERIC_14,
|
|
Generic15 = ffi::AMOTION_EVENT_AXIS_GENERIC_15,
|
|
Generic16 = ffi::AMOTION_EVENT_AXIS_GENERIC_16,
|
|
}
|
|
|
|
/// The tool type of a pointer.
|
|
///
|
|
/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-48)
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)]
|
|
#[repr(u32)]
|
|
pub enum ToolType {
|
|
Unknown = ffi::AMOTION_EVENT_TOOL_TYPE_UNKNOWN,
|
|
Finger = ffi::AMOTION_EVENT_TOOL_TYPE_FINGER,
|
|
Stylus = ffi::AMOTION_EVENT_TOOL_TYPE_STYLUS,
|
|
Mouse = ffi::AMOTION_EVENT_TOOL_TYPE_MOUSE,
|
|
Eraser = ffi::AMOTION_EVENT_TOOL_TYPE_ERASER,
|
|
Palm = ffi::AMOTION_EVENT_TOOL_TYPE_PALM,
|
|
}
|
|
|
|
/// 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 & ffi::AMOTION_EVENT_BUTTON_PRIMARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn secondary(self) -> bool {
|
|
self.0 & ffi::AMOTION_EVENT_BUTTON_SECONDARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn teriary(self) -> bool {
|
|
self.0 & ffi::AMOTION_EVENT_BUTTON_TERTIARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn back(self) -> bool {
|
|
self.0 & ffi::AMOTION_EVENT_BUTTON_BACK != 0
|
|
}
|
|
#[inline]
|
|
pub fn forward(self) -> bool {
|
|
self.0 & ffi::AMOTION_EVENT_BUTTON_FORWARD != 0
|
|
}
|
|
#[inline]
|
|
pub fn stylus_primary(self) -> bool {
|
|
self.0 & ffi::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY != 0
|
|
}
|
|
#[inline]
|
|
pub fn stylus_secondary(self) -> bool {
|
|
self.0 & ffi::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 & ffi::AMOTION_EVENT_EDGE_FLAG_TOP != 0
|
|
}
|
|
#[inline]
|
|
pub fn bottom(self) -> bool {
|
|
self.0 & ffi::AMOTION_EVENT_EDGE_FLAG_BOTTOM != 0
|
|
}
|
|
#[inline]
|
|
pub fn left(self) -> bool {
|
|
self.0 & ffi::AMOTION_EVENT_EDGE_FLAG_LEFT != 0
|
|
}
|
|
#[inline]
|
|
pub fn right(self) -> bool {
|
|
self.0 & ffi::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 & ffi::AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED != 0
|
|
}
|
|
}
|
|
|
|
impl MotionEvent {
|
|
/// Constructs a MotionEvent from a pointer to a native [`ffi::AInputEvent`]
|
|
///
|
|
/// # Safety
|
|
/// By calling this method, you assert that the pointer is a valid, non-null pointer to a
|
|
/// native [`ffi::AInputEvent`] and that [`ffi::AInputEvent`]
|
|
/// is an `AMotionEvent`.
|
|
#[inline]
|
|
pub unsafe fn from_ptr(ptr: NonNull<ffi::AInputEvent>) -> Self {
|
|
Self { ptr }
|
|
}
|
|
|
|
/// Returns a pointer to the native [`ffi::AInputEvent`]
|
|
#[inline]
|
|
pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
|
|
self.ptr
|
|
}
|
|
|
|
/// Get the source of the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#ainputevent_getsource)
|
|
#[inline]
|
|
pub fn source(&self) -> Source {
|
|
let source = unsafe { ffi::AInputEvent_getSource(self.ptr.as_ptr()) as u32 };
|
|
source.try_into().unwrap_or(Source::Unknown)
|
|
}
|
|
|
|
/// Get the device id associated with the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#ainputevent_getdeviceid)
|
|
#[inline]
|
|
pub fn device_id(&self) -> i32 {
|
|
unsafe { ffi::AInputEvent_getDeviceId(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// Returns the motion action associated with the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getaction)
|
|
#[inline]
|
|
pub fn action(&self) -> MotionAction {
|
|
let action = unsafe {
|
|
ffi::AMotionEvent_getAction(self.ptr.as_ptr()) as u32 & ffi::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 = unsafe { ffi::AMotionEvent_getAction(self.ptr.as_ptr()) as u32 };
|
|
let index = (action & ffi::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
|
|
>> ffi::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 { ffi::AMotionEvent_getPointerId(self.ptr.as_ptr(), pointer_index) }
|
|
}
|
|
*/
|
|
|
|
/// Returns the number of pointers in this event
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#amotionevent_getpointercount)
|
|
#[inline]
|
|
pub fn pointer_count(&self) -> usize {
|
|
unsafe { ffi::AMotionEvent_getPointerCount(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// An iterator over the pointers in this motion event
|
|
#[inline]
|
|
pub fn pointers(&self) -> PointersIter<'_> {
|
|
PointersIter {
|
|
event: self.ptr,
|
|
next_index: 0,
|
|
count: self.pointer_count(),
|
|
_marker: std::marker::PhantomData,
|
|
}
|
|
}
|
|
|
|
/// 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.ptr,
|
|
index,
|
|
_marker: std::marker::PhantomData,
|
|
}
|
|
}
|
|
|
|
/// 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 { ffi::AMotionEvent_getHistorySize(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { MetaState(ffi::AMotionEvent_getMetaState(self.ptr.as_ptr()) 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 {
|
|
unsafe { ButtonState(ffi::AMotionEvent_getButtonState(self.ptr.as_ptr()) 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 {
|
|
unsafe { ffi::AMotionEvent_getDownTime(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { EdgeFlags(ffi::AMotionEvent_getEdgeFlags(self.ptr.as_ptr()) 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 {
|
|
unsafe { ffi::AMotionEvent_getEventTime(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { MotionEventFlags(ffi::AMotionEvent_getFlags(self.ptr.as_ptr()) as u32) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { ffi::AMotionEvent_getXOffset(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { ffi::AMotionEvent_getYOffset(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { ffi::AMotionEvent_getXPrecision(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { ffi::AMotionEvent_getYPrecision(self.ptr.as_ptr()) }
|
|
}
|
|
}
|
|
|
|
/// A view into the data of a specific pointer in a motion event.
|
|
#[derive(Debug)]
|
|
pub struct Pointer<'a> {
|
|
event: NonNull<ffi::AInputEvent>,
|
|
index: usize,
|
|
_marker: std::marker::PhantomData<&'a MotionEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
impl<'a> Pointer<'a> {
|
|
#[inline]
|
|
pub fn pointer_index(&self) -> usize {
|
|
self.index
|
|
}
|
|
|
|
#[inline]
|
|
pub fn pointer_id(&self) -> i32 {
|
|
unsafe { ffi::AMotionEvent_getPointerId(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn axis_value(&self, axis: Axis) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getAxisValue(self.event.as_ptr(), axis as i32, self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn orientation(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getOrientation(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn pressure(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getPressure(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_x(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getRawX(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_y(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getRawY(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn x(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getX(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn y(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getY(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn size(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getSize(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_major(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getToolMajor(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_minor(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getToolMinor(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_major(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getTouchMajor(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_minor(&self) -> f32 {
|
|
unsafe { ffi::AMotionEvent_getTouchMinor(self.event.as_ptr(), self.index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_type(&self) -> ToolType {
|
|
let tool_type =
|
|
unsafe { ffi::AMotionEvent_getToolType(self.event.as_ptr(), self.index) as u32 };
|
|
tool_type.try_into().unwrap()
|
|
}
|
|
}
|
|
|
|
/// An iterator over the pointers in a [`MotionEvent`].
|
|
#[derive(Debug)]
|
|
pub struct PointersIter<'a> {
|
|
event: NonNull<ffi::AInputEvent>,
|
|
next_index: usize,
|
|
count: usize,
|
|
_marker: std::marker::PhantomData<&'a MotionEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
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,
|
|
_marker: std::marker::PhantomData,
|
|
};
|
|
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<ffi::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 { ffi::AMotionEvent_getHistoricalEventTime(self.event.as_ptr(), self.history_index) }
|
|
}
|
|
|
|
/// 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 { ffi::AMotionEvent_getPointerCount(self.event.as_ptr()) },
|
|
_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<ffi::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<ffi::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 { ffi::AMotionEvent_getPointerId(self.event.as_ptr(), self.pointer_index) }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn history_index(&self) -> usize {
|
|
self.history_index
|
|
}
|
|
|
|
#[inline]
|
|
pub fn axis_value(&self, axis: Axis) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalAxisValue(
|
|
self.event.as_ptr(),
|
|
axis as i32,
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn orientation(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalOrientation(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn pressure(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalPressure(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_x(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalRawX(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn raw_y(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalRawY(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn x(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalX(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn y(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalY(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn size(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalSize(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_major(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalToolMajor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn tool_minor(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalToolMinor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_major(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalTouchMajor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn touch_minor(&self) -> f32 {
|
|
unsafe {
|
|
ffi::AMotionEvent_getHistoricalTouchMinor(
|
|
self.event.as_ptr(),
|
|
self.pointer_index,
|
|
self.history_index,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// An iterator over the pointers in a historical motion event
|
|
#[derive(Debug)]
|
|
pub struct HistoricalPointersIter<'a> {
|
|
event: NonNull<ffi::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
|
|
///
|
|
/// Wraps an [`AInputEvent *`] of the [`ffi::AINPUT_EVENT_TYPE_KEY`] type.
|
|
///
|
|
/// For general discussion of key events in Android, see [the relevant
|
|
/// javadoc](https://developer.android.com/reference/android/view/KeyEvent).
|
|
///
|
|
/// [`AInputEvent *`]: https://developer.android.com/ndk/reference/group/input#ainputevent
|
|
#[derive(Debug)]
|
|
pub struct KeyEvent {
|
|
ptr: NonNull<ffi::AInputEvent>,
|
|
}
|
|
|
|
// TODO: thread safety?
|
|
|
|
/// 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 = ffi::AKEY_EVENT_ACTION_DOWN,
|
|
Up = ffi::AKEY_EVENT_ACTION_UP,
|
|
Multiple = ffi::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 = ffi::AKEYCODE_UNKNOWN,
|
|
SoftLeft = ffi::AKEYCODE_SOFT_LEFT,
|
|
SoftRight = ffi::AKEYCODE_SOFT_RIGHT,
|
|
Home = ffi::AKEYCODE_HOME,
|
|
Back = ffi::AKEYCODE_BACK,
|
|
Call = ffi::AKEYCODE_CALL,
|
|
Endcall = ffi::AKEYCODE_ENDCALL,
|
|
Keycode0 = ffi::AKEYCODE_0,
|
|
Keycode1 = ffi::AKEYCODE_1,
|
|
Keycode2 = ffi::AKEYCODE_2,
|
|
Keycode3 = ffi::AKEYCODE_3,
|
|
Keycode4 = ffi::AKEYCODE_4,
|
|
Keycode5 = ffi::AKEYCODE_5,
|
|
Keycode6 = ffi::AKEYCODE_6,
|
|
Keycode7 = ffi::AKEYCODE_7,
|
|
Keycode8 = ffi::AKEYCODE_8,
|
|
Keycode9 = ffi::AKEYCODE_9,
|
|
Star = ffi::AKEYCODE_STAR,
|
|
Pound = ffi::AKEYCODE_POUND,
|
|
DpadUp = ffi::AKEYCODE_DPAD_UP,
|
|
DpadDown = ffi::AKEYCODE_DPAD_DOWN,
|
|
DpadLeft = ffi::AKEYCODE_DPAD_LEFT,
|
|
DpadRight = ffi::AKEYCODE_DPAD_RIGHT,
|
|
DpadCenter = ffi::AKEYCODE_DPAD_CENTER,
|
|
VolumeUp = ffi::AKEYCODE_VOLUME_UP,
|
|
VolumeDown = ffi::AKEYCODE_VOLUME_DOWN,
|
|
Power = ffi::AKEYCODE_POWER,
|
|
Camera = ffi::AKEYCODE_CAMERA,
|
|
Clear = ffi::AKEYCODE_CLEAR,
|
|
A = ffi::AKEYCODE_A,
|
|
B = ffi::AKEYCODE_B,
|
|
C = ffi::AKEYCODE_C,
|
|
D = ffi::AKEYCODE_D,
|
|
E = ffi::AKEYCODE_E,
|
|
F = ffi::AKEYCODE_F,
|
|
G = ffi::AKEYCODE_G,
|
|
H = ffi::AKEYCODE_H,
|
|
I = ffi::AKEYCODE_I,
|
|
J = ffi::AKEYCODE_J,
|
|
K = ffi::AKEYCODE_K,
|
|
L = ffi::AKEYCODE_L,
|
|
M = ffi::AKEYCODE_M,
|
|
N = ffi::AKEYCODE_N,
|
|
O = ffi::AKEYCODE_O,
|
|
P = ffi::AKEYCODE_P,
|
|
Q = ffi::AKEYCODE_Q,
|
|
R = ffi::AKEYCODE_R,
|
|
S = ffi::AKEYCODE_S,
|
|
T = ffi::AKEYCODE_T,
|
|
U = ffi::AKEYCODE_U,
|
|
V = ffi::AKEYCODE_V,
|
|
W = ffi::AKEYCODE_W,
|
|
X = ffi::AKEYCODE_X,
|
|
Y = ffi::AKEYCODE_Y,
|
|
Z = ffi::AKEYCODE_Z,
|
|
Comma = ffi::AKEYCODE_COMMA,
|
|
Period = ffi::AKEYCODE_PERIOD,
|
|
AltLeft = ffi::AKEYCODE_ALT_LEFT,
|
|
AltRight = ffi::AKEYCODE_ALT_RIGHT,
|
|
ShiftLeft = ffi::AKEYCODE_SHIFT_LEFT,
|
|
ShiftRight = ffi::AKEYCODE_SHIFT_RIGHT,
|
|
Tab = ffi::AKEYCODE_TAB,
|
|
Space = ffi::AKEYCODE_SPACE,
|
|
Sym = ffi::AKEYCODE_SYM,
|
|
Explorer = ffi::AKEYCODE_EXPLORER,
|
|
Envelope = ffi::AKEYCODE_ENVELOPE,
|
|
Enter = ffi::AKEYCODE_ENTER,
|
|
Del = ffi::AKEYCODE_DEL,
|
|
Grave = ffi::AKEYCODE_GRAVE,
|
|
Minus = ffi::AKEYCODE_MINUS,
|
|
Equals = ffi::AKEYCODE_EQUALS,
|
|
LeftBracket = ffi::AKEYCODE_LEFT_BRACKET,
|
|
RightBracket = ffi::AKEYCODE_RIGHT_BRACKET,
|
|
Backslash = ffi::AKEYCODE_BACKSLASH,
|
|
Semicolon = ffi::AKEYCODE_SEMICOLON,
|
|
Apostrophe = ffi::AKEYCODE_APOSTROPHE,
|
|
Slash = ffi::AKEYCODE_SLASH,
|
|
At = ffi::AKEYCODE_AT,
|
|
Num = ffi::AKEYCODE_NUM,
|
|
Headsethook = ffi::AKEYCODE_HEADSETHOOK,
|
|
Focus = ffi::AKEYCODE_FOCUS,
|
|
Plus = ffi::AKEYCODE_PLUS,
|
|
Menu = ffi::AKEYCODE_MENU,
|
|
Notification = ffi::AKEYCODE_NOTIFICATION,
|
|
Search = ffi::AKEYCODE_SEARCH,
|
|
MediaPlayPause = ffi::AKEYCODE_MEDIA_PLAY_PAUSE,
|
|
MediaStop = ffi::AKEYCODE_MEDIA_STOP,
|
|
MediaNext = ffi::AKEYCODE_MEDIA_NEXT,
|
|
MediaPrevious = ffi::AKEYCODE_MEDIA_PREVIOUS,
|
|
MediaRewind = ffi::AKEYCODE_MEDIA_REWIND,
|
|
MediaFastForward = ffi::AKEYCODE_MEDIA_FAST_FORWARD,
|
|
Mute = ffi::AKEYCODE_MUTE,
|
|
PageUp = ffi::AKEYCODE_PAGE_UP,
|
|
PageDown = ffi::AKEYCODE_PAGE_DOWN,
|
|
Pictsymbols = ffi::AKEYCODE_PICTSYMBOLS,
|
|
SwitchCharset = ffi::AKEYCODE_SWITCH_CHARSET,
|
|
ButtonA = ffi::AKEYCODE_BUTTON_A,
|
|
ButtonB = ffi::AKEYCODE_BUTTON_B,
|
|
ButtonC = ffi::AKEYCODE_BUTTON_C,
|
|
ButtonX = ffi::AKEYCODE_BUTTON_X,
|
|
ButtonY = ffi::AKEYCODE_BUTTON_Y,
|
|
ButtonZ = ffi::AKEYCODE_BUTTON_Z,
|
|
ButtonL1 = ffi::AKEYCODE_BUTTON_L1,
|
|
ButtonR1 = ffi::AKEYCODE_BUTTON_R1,
|
|
ButtonL2 = ffi::AKEYCODE_BUTTON_L2,
|
|
ButtonR2 = ffi::AKEYCODE_BUTTON_R2,
|
|
ButtonThumbl = ffi::AKEYCODE_BUTTON_THUMBL,
|
|
ButtonThumbr = ffi::AKEYCODE_BUTTON_THUMBR,
|
|
ButtonStart = ffi::AKEYCODE_BUTTON_START,
|
|
ButtonSelect = ffi::AKEYCODE_BUTTON_SELECT,
|
|
ButtonMode = ffi::AKEYCODE_BUTTON_MODE,
|
|
Escape = ffi::AKEYCODE_ESCAPE,
|
|
ForwardDel = ffi::AKEYCODE_FORWARD_DEL,
|
|
CtrlLeft = ffi::AKEYCODE_CTRL_LEFT,
|
|
CtrlRight = ffi::AKEYCODE_CTRL_RIGHT,
|
|
CapsLock = ffi::AKEYCODE_CAPS_LOCK,
|
|
ScrollLock = ffi::AKEYCODE_SCROLL_LOCK,
|
|
MetaLeft = ffi::AKEYCODE_META_LEFT,
|
|
MetaRight = ffi::AKEYCODE_META_RIGHT,
|
|
Function = ffi::AKEYCODE_FUNCTION,
|
|
Sysrq = ffi::AKEYCODE_SYSRQ,
|
|
Break = ffi::AKEYCODE_BREAK,
|
|
MoveHome = ffi::AKEYCODE_MOVE_HOME,
|
|
MoveEnd = ffi::AKEYCODE_MOVE_END,
|
|
Insert = ffi::AKEYCODE_INSERT,
|
|
Forward = ffi::AKEYCODE_FORWARD,
|
|
MediaPlay = ffi::AKEYCODE_MEDIA_PLAY,
|
|
MediaPause = ffi::AKEYCODE_MEDIA_PAUSE,
|
|
MediaClose = ffi::AKEYCODE_MEDIA_CLOSE,
|
|
MediaEject = ffi::AKEYCODE_MEDIA_EJECT,
|
|
MediaRecord = ffi::AKEYCODE_MEDIA_RECORD,
|
|
F1 = ffi::AKEYCODE_F1,
|
|
F2 = ffi::AKEYCODE_F2,
|
|
F3 = ffi::AKEYCODE_F3,
|
|
F4 = ffi::AKEYCODE_F4,
|
|
F5 = ffi::AKEYCODE_F5,
|
|
F6 = ffi::AKEYCODE_F6,
|
|
F7 = ffi::AKEYCODE_F7,
|
|
F8 = ffi::AKEYCODE_F8,
|
|
F9 = ffi::AKEYCODE_F9,
|
|
F10 = ffi::AKEYCODE_F10,
|
|
F11 = ffi::AKEYCODE_F11,
|
|
F12 = ffi::AKEYCODE_F12,
|
|
NumLock = ffi::AKEYCODE_NUM_LOCK,
|
|
Numpad0 = ffi::AKEYCODE_NUMPAD_0,
|
|
Numpad1 = ffi::AKEYCODE_NUMPAD_1,
|
|
Numpad2 = ffi::AKEYCODE_NUMPAD_2,
|
|
Numpad3 = ffi::AKEYCODE_NUMPAD_3,
|
|
Numpad4 = ffi::AKEYCODE_NUMPAD_4,
|
|
Numpad5 = ffi::AKEYCODE_NUMPAD_5,
|
|
Numpad6 = ffi::AKEYCODE_NUMPAD_6,
|
|
Numpad7 = ffi::AKEYCODE_NUMPAD_7,
|
|
Numpad8 = ffi::AKEYCODE_NUMPAD_8,
|
|
Numpad9 = ffi::AKEYCODE_NUMPAD_9,
|
|
NumpadDivide = ffi::AKEYCODE_NUMPAD_DIVIDE,
|
|
NumpadMultiply = ffi::AKEYCODE_NUMPAD_MULTIPLY,
|
|
NumpadSubtract = ffi::AKEYCODE_NUMPAD_SUBTRACT,
|
|
NumpadAdd = ffi::AKEYCODE_NUMPAD_ADD,
|
|
NumpadDot = ffi::AKEYCODE_NUMPAD_DOT,
|
|
NumpadComma = ffi::AKEYCODE_NUMPAD_COMMA,
|
|
NumpadEnter = ffi::AKEYCODE_NUMPAD_ENTER,
|
|
NumpadEquals = ffi::AKEYCODE_NUMPAD_EQUALS,
|
|
NumpadLeftParen = ffi::AKEYCODE_NUMPAD_LEFT_PAREN,
|
|
NumpadRightParen = ffi::AKEYCODE_NUMPAD_RIGHT_PAREN,
|
|
VolumeMute = ffi::AKEYCODE_VOLUME_MUTE,
|
|
Info = ffi::AKEYCODE_INFO,
|
|
ChannelUp = ffi::AKEYCODE_CHANNEL_UP,
|
|
ChannelDown = ffi::AKEYCODE_CHANNEL_DOWN,
|
|
ZoomIn = ffi::AKEYCODE_ZOOM_IN,
|
|
ZoomOut = ffi::AKEYCODE_ZOOM_OUT,
|
|
Tv = ffi::AKEYCODE_TV,
|
|
Window = ffi::AKEYCODE_WINDOW,
|
|
Guide = ffi::AKEYCODE_GUIDE,
|
|
Dvr = ffi::AKEYCODE_DVR,
|
|
Bookmark = ffi::AKEYCODE_BOOKMARK,
|
|
Captions = ffi::AKEYCODE_CAPTIONS,
|
|
Settings = ffi::AKEYCODE_SETTINGS,
|
|
TvPower = ffi::AKEYCODE_TV_POWER,
|
|
TvInput = ffi::AKEYCODE_TV_INPUT,
|
|
StbPower = ffi::AKEYCODE_STB_POWER,
|
|
StbInput = ffi::AKEYCODE_STB_INPUT,
|
|
AvrPower = ffi::AKEYCODE_AVR_POWER,
|
|
AvrInput = ffi::AKEYCODE_AVR_INPUT,
|
|
ProgRed = ffi::AKEYCODE_PROG_RED,
|
|
ProgGreen = ffi::AKEYCODE_PROG_GREEN,
|
|
ProgYellow = ffi::AKEYCODE_PROG_YELLOW,
|
|
ProgBlue = ffi::AKEYCODE_PROG_BLUE,
|
|
AppSwitch = ffi::AKEYCODE_APP_SWITCH,
|
|
Button1 = ffi::AKEYCODE_BUTTON_1,
|
|
Button2 = ffi::AKEYCODE_BUTTON_2,
|
|
Button3 = ffi::AKEYCODE_BUTTON_3,
|
|
Button4 = ffi::AKEYCODE_BUTTON_4,
|
|
Button5 = ffi::AKEYCODE_BUTTON_5,
|
|
Button6 = ffi::AKEYCODE_BUTTON_6,
|
|
Button7 = ffi::AKEYCODE_BUTTON_7,
|
|
Button8 = ffi::AKEYCODE_BUTTON_8,
|
|
Button9 = ffi::AKEYCODE_BUTTON_9,
|
|
Button10 = ffi::AKEYCODE_BUTTON_10,
|
|
Button11 = ffi::AKEYCODE_BUTTON_11,
|
|
Button12 = ffi::AKEYCODE_BUTTON_12,
|
|
Button13 = ffi::AKEYCODE_BUTTON_13,
|
|
Button14 = ffi::AKEYCODE_BUTTON_14,
|
|
Button15 = ffi::AKEYCODE_BUTTON_15,
|
|
Button16 = ffi::AKEYCODE_BUTTON_16,
|
|
LanguageSwitch = ffi::AKEYCODE_LANGUAGE_SWITCH,
|
|
MannerMode = ffi::AKEYCODE_MANNER_MODE,
|
|
Keycode3dMode = ffi::AKEYCODE_3D_MODE,
|
|
Contacts = ffi::AKEYCODE_CONTACTS,
|
|
Calendar = ffi::AKEYCODE_CALENDAR,
|
|
Music = ffi::AKEYCODE_MUSIC,
|
|
Calculator = ffi::AKEYCODE_CALCULATOR,
|
|
ZenkakuHankaku = ffi::AKEYCODE_ZENKAKU_HANKAKU,
|
|
Eisu = ffi::AKEYCODE_EISU,
|
|
Muhenkan = ffi::AKEYCODE_MUHENKAN,
|
|
Henkan = ffi::AKEYCODE_HENKAN,
|
|
KatakanaHiragana = ffi::AKEYCODE_KATAKANA_HIRAGANA,
|
|
Yen = ffi::AKEYCODE_YEN,
|
|
Ro = ffi::AKEYCODE_RO,
|
|
Kana = ffi::AKEYCODE_KANA,
|
|
Assist = ffi::AKEYCODE_ASSIST,
|
|
BrightnessDown = ffi::AKEYCODE_BRIGHTNESS_DOWN,
|
|
BrightnessUp = ffi::AKEYCODE_BRIGHTNESS_UP,
|
|
MediaAudioTrack = ffi::AKEYCODE_MEDIA_AUDIO_TRACK,
|
|
Sleep = ffi::AKEYCODE_SLEEP,
|
|
Wakeup = ffi::AKEYCODE_WAKEUP,
|
|
Pairing = ffi::AKEYCODE_PAIRING,
|
|
MediaTopMenu = ffi::AKEYCODE_MEDIA_TOP_MENU,
|
|
Keycode11 = ffi::AKEYCODE_11,
|
|
Keycode12 = ffi::AKEYCODE_12,
|
|
LastChannel = ffi::AKEYCODE_LAST_CHANNEL,
|
|
TvDataService = ffi::AKEYCODE_TV_DATA_SERVICE,
|
|
VoiceAssist = ffi::AKEYCODE_VOICE_ASSIST,
|
|
TvRadioService = ffi::AKEYCODE_TV_RADIO_SERVICE,
|
|
TvTeletext = ffi::AKEYCODE_TV_TELETEXT,
|
|
TvNumberEntry = ffi::AKEYCODE_TV_NUMBER_ENTRY,
|
|
TvTerrestrialAnalog = ffi::AKEYCODE_TV_TERRESTRIAL_ANALOG,
|
|
TvTerrestrialDigital = ffi::AKEYCODE_TV_TERRESTRIAL_DIGITAL,
|
|
TvSatellite = ffi::AKEYCODE_TV_SATELLITE,
|
|
TvSatelliteBs = ffi::AKEYCODE_TV_SATELLITE_BS,
|
|
TvSatelliteCs = ffi::AKEYCODE_TV_SATELLITE_CS,
|
|
TvSatelliteService = ffi::AKEYCODE_TV_SATELLITE_SERVICE,
|
|
TvNetwork = ffi::AKEYCODE_TV_NETWORK,
|
|
TvAntennaCable = ffi::AKEYCODE_TV_ANTENNA_CABLE,
|
|
TvInputHdmi1 = ffi::AKEYCODE_TV_INPUT_HDMI_1,
|
|
TvInputHdmi2 = ffi::AKEYCODE_TV_INPUT_HDMI_2,
|
|
TvInputHdmi3 = ffi::AKEYCODE_TV_INPUT_HDMI_3,
|
|
TvInputHdmi4 = ffi::AKEYCODE_TV_INPUT_HDMI_4,
|
|
TvInputComposite1 = ffi::AKEYCODE_TV_INPUT_COMPOSITE_1,
|
|
TvInputComposite2 = ffi::AKEYCODE_TV_INPUT_COMPOSITE_2,
|
|
TvInputComponent1 = ffi::AKEYCODE_TV_INPUT_COMPONENT_1,
|
|
TvInputComponent2 = ffi::AKEYCODE_TV_INPUT_COMPONENT_2,
|
|
TvInputVga1 = ffi::AKEYCODE_TV_INPUT_VGA_1,
|
|
TvAudioDescription = ffi::AKEYCODE_TV_AUDIO_DESCRIPTION,
|
|
TvAudioDescriptionMixUp = ffi::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP,
|
|
TvAudioDescriptionMixDown = ffi::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN,
|
|
TvZoomMode = ffi::AKEYCODE_TV_ZOOM_MODE,
|
|
TvContentsMenu = ffi::AKEYCODE_TV_CONTENTS_MENU,
|
|
TvMediaContextMenu = ffi::AKEYCODE_TV_MEDIA_CONTEXT_MENU,
|
|
TvTimerProgramming = ffi::AKEYCODE_TV_TIMER_PROGRAMMING,
|
|
Help = ffi::AKEYCODE_HELP,
|
|
NavigatePrevious = ffi::AKEYCODE_NAVIGATE_PREVIOUS,
|
|
NavigateNext = ffi::AKEYCODE_NAVIGATE_NEXT,
|
|
NavigateIn = ffi::AKEYCODE_NAVIGATE_IN,
|
|
NavigateOut = ffi::AKEYCODE_NAVIGATE_OUT,
|
|
StemPrimary = ffi::AKEYCODE_STEM_PRIMARY,
|
|
Stem1 = ffi::AKEYCODE_STEM_1,
|
|
Stem2 = ffi::AKEYCODE_STEM_2,
|
|
Stem3 = ffi::AKEYCODE_STEM_3,
|
|
DpadUpLeft = ffi::AKEYCODE_DPAD_UP_LEFT,
|
|
DpadDownLeft = ffi::AKEYCODE_DPAD_DOWN_LEFT,
|
|
DpadUpRight = ffi::AKEYCODE_DPAD_UP_RIGHT,
|
|
DpadDownRight = ffi::AKEYCODE_DPAD_DOWN_RIGHT,
|
|
MediaSkipForward = ffi::AKEYCODE_MEDIA_SKIP_FORWARD,
|
|
MediaSkipBackward = ffi::AKEYCODE_MEDIA_SKIP_BACKWARD,
|
|
MediaStepForward = ffi::AKEYCODE_MEDIA_STEP_FORWARD,
|
|
MediaStepBackward = ffi::AKEYCODE_MEDIA_STEP_BACKWARD,
|
|
SoftSleep = ffi::AKEYCODE_SOFT_SLEEP,
|
|
Cut = ffi::AKEYCODE_CUT,
|
|
Copy = ffi::AKEYCODE_COPY,
|
|
Paste = ffi::AKEYCODE_PASTE,
|
|
SystemNavigationUp = ffi::AKEYCODE_SYSTEM_NAVIGATION_UP,
|
|
SystemNavigationDown = ffi::AKEYCODE_SYSTEM_NAVIGATION_DOWN,
|
|
SystemNavigationLeft = ffi::AKEYCODE_SYSTEM_NAVIGATION_LEFT,
|
|
SystemNavigationRight = ffi::AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
|
|
AllApps = ffi::AKEYCODE_ALL_APPS,
|
|
Refresh = ffi::AKEYCODE_REFRESH,
|
|
ThumbsUp = ffi::AKEYCODE_THUMBS_UP,
|
|
ThumbsDown = ffi::AKEYCODE_THUMBS_DOWN,
|
|
ProfileSwitch = ffi::AKEYCODE_PROFILE_SWITCH,
|
|
}
|
|
|
|
impl KeyEvent {
|
|
/// Constructs a KeyEvent from a pointer to a native [`ffi::AInputEvent`]
|
|
///
|
|
/// # Safety
|
|
/// By calling this method, you assert that the pointer is a valid, non-null pointer to an
|
|
/// [`ffi::AInputEvent`], and that [`ffi::AInputEvent`] is an `AKeyEvent`.
|
|
#[inline]
|
|
pub unsafe fn from_ptr(ptr: NonNull<ffi::AInputEvent>) -> Self {
|
|
Self { ptr }
|
|
}
|
|
|
|
/// Returns a pointer to the native [`ffi::AInputEvent`]
|
|
#[inline]
|
|
pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
|
|
self.ptr
|
|
}
|
|
|
|
/// Returns the key action represented by this event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#akeyevent_getaction)
|
|
#[inline]
|
|
pub fn action(&self) -> KeyAction {
|
|
let action = unsafe { ffi::AKeyEvent_getAction(self.ptr.as_ptr()) as u32 };
|
|
action.try_into().unwrap()
|
|
}
|
|
|
|
/// Get the source of the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#ainputevent_getsource)
|
|
#[inline]
|
|
pub fn source(&self) -> Source {
|
|
let source = unsafe { ffi::AInputEvent_getSource(self.ptr.as_ptr()) as u32 };
|
|
source.try_into().unwrap_or(Source::Unknown)
|
|
}
|
|
|
|
/// Get the device id associated with the event.
|
|
///
|
|
/// See [the NDK
|
|
/// docs](https://developer.android.com/ndk/reference/group/input#ainputevent_getdeviceid)
|
|
#[inline]
|
|
pub fn device_id(&self) -> i32 {
|
|
unsafe { ffi::AInputEvent_getDeviceId(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { ffi::AKeyEvent_getDownTime(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { ffi::AKeyEvent_getEventTime(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 = unsafe { ffi::AKeyEvent_getKeyCode(self.ptr.as_ptr()) 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 {
|
|
unsafe { ffi::AKeyEvent_getRepeatCount(self.ptr.as_ptr()) }
|
|
}
|
|
|
|
/// 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 {
|
|
unsafe { ffi::AKeyEvent_getScanCode(self.ptr.as_ptr()) }
|
|
}
|
|
}
|
|
|
|
/// 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 & ffi::AKEY_EVENT_FLAG_CANCELED != 0
|
|
}
|
|
#[inline]
|
|
pub fn cancelled_long_press(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_CANCELED_LONG_PRESS != 0
|
|
}
|
|
#[inline]
|
|
pub fn editor_action(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_EDITOR_ACTION != 0
|
|
}
|
|
#[inline]
|
|
pub fn fallback(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_FALLBACK != 0
|
|
}
|
|
#[inline]
|
|
pub fn from_system(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_FROM_SYSTEM != 0
|
|
}
|
|
#[inline]
|
|
pub fn keep_touch_mode(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_KEEP_TOUCH_MODE != 0
|
|
}
|
|
#[inline]
|
|
pub fn long_press(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_LONG_PRESS != 0
|
|
}
|
|
#[inline]
|
|
pub fn soft_keyboard(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_SOFT_KEYBOARD != 0
|
|
}
|
|
#[inline]
|
|
pub fn tracking(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_TRACKING != 0
|
|
}
|
|
#[inline]
|
|
pub fn virtual_hard_key(&self) -> bool {
|
|
self.0 & ffi::AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY != 0
|
|
}
|
|
#[inline]
|
|
pub fn woke_here(&self) -> bool {
|
|
self.0 & ffi::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 {
|
|
unsafe { KeyEventFlags(ffi::AKeyEvent_getFlags(self.ptr.as_ptr()) 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 {
|
|
unsafe { MetaState(ffi::AKeyEvent_getMetaState(self.ptr.as_ptr()) as u32) }
|
|
}
|
|
}
|