Skip to main content

android_activity/
input.rs

1use std::iter::FusedIterator;
2
3use bitflags::bitflags;
4
5pub use crate::activity_impl::input::*;
6use crate::InputStatus;
7
8mod sdk;
9pub use sdk::*;
10
11/// An enum representing the source of an [`MotionEvent`] or [`KeyEvent`]
12///
13/// See [the InputDevice docs](https://developer.android.com/reference/android/view/InputDevice#SOURCE_ANY)
14///
15/// # Android Extensible Enum
16///
17/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
18/// should be handled similar to a `#[non_exhaustive]` enum to maintain
19/// forwards compatibility.
20///
21/// This implements `Into<u32>` and `From<u32>` for converting to/from Android
22/// SDK integer values.
23///
24#[derive(Debug, Clone, Copy, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
25#[non_exhaustive]
26#[repr(u32)]
27pub enum Source {
28    BluetoothStylus = 0x0000c002,
29    Dpad = 0x00000201,
30    /// Either a gamepad or a joystick
31    Gamepad = 0x00000401,
32    Hdmi = 0x02000001,
33    /// Either a gamepad or a joystick
34    Joystick = 0x01000010,
35    /// Pretty much any device with buttons. Query the keyboard type to determine
36    /// if it has alphabetic keys and can be used for text entry.
37    Keyboard = 0x00000101,
38    /// A pointing device, such as a mouse or trackpad
39    Mouse = 0x00002002,
40    /// A pointing device, such as a mouse or trackpad whose relative motions should be treated as navigation events
41    MouseRelative = 0x00020004,
42    /// An input device akin to a scroll wheel
43    RotaryEncoder = 0x00400000,
44    Sensor = 0x04000000,
45    Stylus = 0x00004002,
46    Touchpad = 0x00100008,
47    Touchscreen = 0x00001002,
48    TouchNavigation = 0x00200000,
49    Trackball = 0x00010004,
50
51    // We need to consider that the enum variants may be extended across
52    // different versions of Android (i.e. effectively at runtime) but at the
53    // same time we don't want it to be an API break to extend this enum in
54    // future releases of `android-activity` with new variants from the latest
55    // NDK/SDK.
56    //
57    // We can't just use `#[non_exhaustive]` because that only really helps
58    // when adding new variants in sync with android-activity releases.
59    //
60    // On the other hand we also can't rely on a catch-all `Unknown(u32)` that
61    // only really helps with unknown variants seen at runtime.
62    //
63    // What we aim for instead is to have a hidden catch-all variant that
64    // is considered (practically) unmatchable so code is forced to have
65    // a `unknown => {}` catch-all pattern match that will cover unknown variants
66    // either in the form of Rust variants added in future versions or
67    // in the form of an `__Unknown(u32)` integer that represents an unknown
68    // variant seen at runtime.
69    //
70    // Any `unknown => {}` pattern match can rely on `IntoPrimitive` to convert
71    // the `unknown` variant to the integer that comes from the Android SDK
72    // in case that values needs to be passed on, even without knowing its
73    // semantic meaning at compile time.
74    #[doc(hidden)]
75    #[num_enum(catch_all)]
76    __Unknown(u32),
77}
78
79// ndk_sys doesn't currently have the `TRACKBALL` flag so we define our
80// own internal class constants for now
81bitflags! {
82    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
83    struct SourceFlags: u32 {
84        const CLASS_MASK = 0x000000ff;
85
86        const BUTTON = 0x00000001;
87        const POINTER = 0x00000002;
88        const TRACKBALL = 0x00000004;
89        const POSITION = 0x00000008;
90        const JOYSTICK = 0x00000010;
91        const NONE = 0;
92    }
93}
94
95impl Source {
96    #[inline]
97    pub fn is_button_class(self) -> bool {
98        let class = SourceFlags::from_bits_truncate(self.into());
99        class.contains(SourceFlags::BUTTON)
100    }
101    #[inline]
102    pub fn is_pointer_class(self) -> bool {
103        let class = SourceFlags::from_bits_truncate(self.into());
104        class.contains(SourceFlags::POINTER)
105    }
106    #[inline]
107    pub fn is_trackball_class(self) -> bool {
108        let class = SourceFlags::from_bits_truncate(self.into());
109        class.contains(SourceFlags::TRACKBALL)
110    }
111    #[inline]
112    pub fn is_position_class(self) -> bool {
113        let class = SourceFlags::from_bits_truncate(self.into());
114        class.contains(SourceFlags::POSITION)
115    }
116    #[inline]
117    pub fn is_joystick_class(self) -> bool {
118        let class = SourceFlags::from_bits_truncate(self.into());
119        class.contains(SourceFlags::JOYSTICK)
120    }
121}
122
123/// A bitfield representing the state of modifier keys during an event.
124///
125/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-25)
126#[derive(Copy, Clone, Debug, PartialEq, Eq)]
127pub struct MetaState(pub u32);
128
129impl MetaState {
130    #[inline]
131    pub fn alt_on(self) -> bool {
132        self.0 & ndk_sys::AMETA_ALT_ON != 0
133    }
134    #[inline]
135    pub fn alt_left_on(self) -> bool {
136        self.0 & ndk_sys::AMETA_ALT_LEFT_ON != 0
137    }
138    #[inline]
139    pub fn alt_right_on(self) -> bool {
140        self.0 & ndk_sys::AMETA_ALT_RIGHT_ON != 0
141    }
142    #[inline]
143    pub fn shift_on(self) -> bool {
144        self.0 & ndk_sys::AMETA_SHIFT_ON != 0
145    }
146    #[inline]
147    pub fn shift_left_on(self) -> bool {
148        self.0 & ndk_sys::AMETA_SHIFT_LEFT_ON != 0
149    }
150    #[inline]
151    pub fn shift_right_on(self) -> bool {
152        self.0 & ndk_sys::AMETA_SHIFT_RIGHT_ON != 0
153    }
154    #[inline]
155    pub fn sym_on(self) -> bool {
156        self.0 & ndk_sys::AMETA_SYM_ON != 0
157    }
158    #[inline]
159    pub fn function_on(self) -> bool {
160        self.0 & ndk_sys::AMETA_FUNCTION_ON != 0
161    }
162    #[inline]
163    pub fn ctrl_on(self) -> bool {
164        self.0 & ndk_sys::AMETA_CTRL_ON != 0
165    }
166    #[inline]
167    pub fn ctrl_left_on(self) -> bool {
168        self.0 & ndk_sys::AMETA_CTRL_LEFT_ON != 0
169    }
170    #[inline]
171    pub fn ctrl_right_on(self) -> bool {
172        self.0 & ndk_sys::AMETA_CTRL_RIGHT_ON != 0
173    }
174    #[inline]
175    pub fn meta_on(self) -> bool {
176        self.0 & ndk_sys::AMETA_META_ON != 0
177    }
178    #[inline]
179    pub fn meta_left_on(self) -> bool {
180        self.0 & ndk_sys::AMETA_META_LEFT_ON != 0
181    }
182    #[inline]
183    pub fn meta_right_on(self) -> bool {
184        self.0 & ndk_sys::AMETA_META_RIGHT_ON != 0
185    }
186    #[inline]
187    pub fn caps_lock_on(self) -> bool {
188        self.0 & ndk_sys::AMETA_CAPS_LOCK_ON != 0
189    }
190    #[inline]
191    pub fn num_lock_on(self) -> bool {
192        self.0 & ndk_sys::AMETA_NUM_LOCK_ON != 0
193    }
194    #[inline]
195    pub fn scroll_lock_on(self) -> bool {
196        self.0 & ndk_sys::AMETA_SCROLL_LOCK_ON != 0
197    }
198}
199
200impl From<ndk::event::MetaState> for MetaState {
201    fn from(value: ndk::event::MetaState) -> Self {
202        Self(value.0)
203    }
204}
205
206/// A motion action.
207///
208/// See [the NDK
209/// docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-29)
210///
211/// # Android Extensible Enum
212///
213/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
214/// should be handled similar to a `#[non_exhaustive]` enum to maintain
215/// forwards compatibility.
216///
217/// This implements `Into<u32>` and `From<u32>` for converting to/from Android
218/// SDK integer values.
219///
220#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
221#[non_exhaustive]
222#[repr(u32)]
223pub enum MotionAction {
224    Down = ndk_sys::AMOTION_EVENT_ACTION_DOWN,
225    Up = ndk_sys::AMOTION_EVENT_ACTION_UP,
226    Move = ndk_sys::AMOTION_EVENT_ACTION_MOVE,
227    Cancel = ndk_sys::AMOTION_EVENT_ACTION_CANCEL,
228    Outside = ndk_sys::AMOTION_EVENT_ACTION_OUTSIDE,
229    PointerDown = ndk_sys::AMOTION_EVENT_ACTION_POINTER_DOWN,
230    PointerUp = ndk_sys::AMOTION_EVENT_ACTION_POINTER_UP,
231    HoverMove = ndk_sys::AMOTION_EVENT_ACTION_HOVER_MOVE,
232    Scroll = ndk_sys::AMOTION_EVENT_ACTION_SCROLL,
233    HoverEnter = ndk_sys::AMOTION_EVENT_ACTION_HOVER_ENTER,
234    HoverExit = ndk_sys::AMOTION_EVENT_ACTION_HOVER_EXIT,
235    ButtonPress = ndk_sys::AMOTION_EVENT_ACTION_BUTTON_PRESS,
236    ButtonRelease = ndk_sys::AMOTION_EVENT_ACTION_BUTTON_RELEASE,
237
238    #[doc(hidden)]
239    #[num_enum(catch_all)]
240    __Unknown(u32),
241}
242
243/// Identifies buttons that are associated with motion events.
244///
245/// See [the NDK
246/// docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-47)
247///
248/// # Android Extensible Enum
249///
250/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
251/// should be handled similar to a `#[non_exhaustive]` enum to maintain
252/// forwards compatibility.
253///
254/// This implements `Into<u32>` and `From<u32>` for converting to/from Android
255/// SDK integer values.
256///
257#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
258#[non_exhaustive]
259#[repr(u32)]
260pub enum Button {
261    Back = ndk_sys::AMOTION_EVENT_BUTTON_BACK,
262    Forward = ndk_sys::AMOTION_EVENT_BUTTON_FORWARD,
263    Primary = ndk_sys::AMOTION_EVENT_BUTTON_PRIMARY,
264    Secondary = ndk_sys::AMOTION_EVENT_BUTTON_SECONDARY,
265    StylusPrimary = ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY,
266    StylusSecondary = ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_SECONDARY,
267    Tertiary = ndk_sys::AMOTION_EVENT_BUTTON_TERTIARY,
268
269    #[doc(hidden)]
270    #[num_enum(catch_all)]
271    __Unknown(u32),
272}
273
274/// An axis of a motion event.
275///
276/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-32)
277///
278/// # Android Extensible Enum
279///
280/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
281/// should be handled similar to a `#[non_exhaustive]` enum to maintain
282/// forwards compatibility.
283///
284/// This implements `Into<u32>` and `From<u32>` for converting to/from Android
285/// SDK integer values.
286///
287#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
288#[non_exhaustive]
289#[repr(u32)]
290pub enum Axis {
291    X = ndk_sys::AMOTION_EVENT_AXIS_X,
292    Y = ndk_sys::AMOTION_EVENT_AXIS_Y,
293    Pressure = ndk_sys::AMOTION_EVENT_AXIS_PRESSURE,
294    Size = ndk_sys::AMOTION_EVENT_AXIS_SIZE,
295    TouchMajor = ndk_sys::AMOTION_EVENT_AXIS_TOUCH_MAJOR,
296    TouchMinor = ndk_sys::AMOTION_EVENT_AXIS_TOUCH_MINOR,
297    ToolMajor = ndk_sys::AMOTION_EVENT_AXIS_TOOL_MAJOR,
298    ToolMinor = ndk_sys::AMOTION_EVENT_AXIS_TOOL_MINOR,
299    Orientation = ndk_sys::AMOTION_EVENT_AXIS_ORIENTATION,
300    Vscroll = ndk_sys::AMOTION_EVENT_AXIS_VSCROLL,
301    Hscroll = ndk_sys::AMOTION_EVENT_AXIS_HSCROLL,
302    Z = ndk_sys::AMOTION_EVENT_AXIS_Z,
303    Rx = ndk_sys::AMOTION_EVENT_AXIS_RX,
304    Ry = ndk_sys::AMOTION_EVENT_AXIS_RY,
305    Rz = ndk_sys::AMOTION_EVENT_AXIS_RZ,
306    HatX = ndk_sys::AMOTION_EVENT_AXIS_HAT_X,
307    HatY = ndk_sys::AMOTION_EVENT_AXIS_HAT_Y,
308    Ltrigger = ndk_sys::AMOTION_EVENT_AXIS_LTRIGGER,
309    Rtrigger = ndk_sys::AMOTION_EVENT_AXIS_RTRIGGER,
310    Throttle = ndk_sys::AMOTION_EVENT_AXIS_THROTTLE,
311    Rudder = ndk_sys::AMOTION_EVENT_AXIS_RUDDER,
312    Wheel = ndk_sys::AMOTION_EVENT_AXIS_WHEEL,
313    Gas = ndk_sys::AMOTION_EVENT_AXIS_GAS,
314    Brake = ndk_sys::AMOTION_EVENT_AXIS_BRAKE,
315    Distance = ndk_sys::AMOTION_EVENT_AXIS_DISTANCE,
316    Tilt = ndk_sys::AMOTION_EVENT_AXIS_TILT,
317    Scroll = ndk_sys::AMOTION_EVENT_AXIS_SCROLL,
318    RelativeX = ndk_sys::AMOTION_EVENT_AXIS_RELATIVE_X,
319    RelativeY = ndk_sys::AMOTION_EVENT_AXIS_RELATIVE_Y,
320    Generic1 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_1,
321    Generic2 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_2,
322    Generic3 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_3,
323    Generic4 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_4,
324    Generic5 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_5,
325    Generic6 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_6,
326    Generic7 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_7,
327    Generic8 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_8,
328    Generic9 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_9,
329    Generic10 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_10,
330    Generic11 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_11,
331    Generic12 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_12,
332    Generic13 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_13,
333    Generic14 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_14,
334    Generic15 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_15,
335    Generic16 = ndk_sys::AMOTION_EVENT_AXIS_GENERIC_16,
336
337    #[doc(hidden)]
338    #[num_enum(catch_all)]
339    __Unknown(u32),
340}
341
342/// The tool type of a pointer.
343///
344/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-48)
345///
346/// # Android Extensible Enum
347///
348/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
349/// should be handled similar to a `#[non_exhaustive]` enum to maintain
350/// forwards compatibility.
351///
352/// Implements `Into<u32>` and `From<u32>` for converting to/from Android SDK
353/// integer values.
354///
355#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
356#[non_exhaustive]
357#[repr(u32)]
358pub enum ToolType {
359    /// Unknown tool type.
360    ///
361    /// This constant is used when the tool type is not known or is not relevant, such as for a trackball or other non-pointing device.
362    Unknown = ndk_sys::AMOTION_EVENT_TOOL_TYPE_UNKNOWN,
363
364    /// The tool is a finger.
365    Finger = ndk_sys::AMOTION_EVENT_TOOL_TYPE_FINGER,
366
367    /// The tool is a stylus.
368    Stylus = ndk_sys::AMOTION_EVENT_TOOL_TYPE_STYLUS,
369
370    ///  The tool is a mouse.
371    Mouse = ndk_sys::AMOTION_EVENT_TOOL_TYPE_MOUSE,
372
373    /// The tool is an eraser or a stylus being used in an inverted posture.
374    Eraser = ndk_sys::AMOTION_EVENT_TOOL_TYPE_ERASER,
375
376    /// The tool is a palm and should be rejected
377    Palm = ndk_sys::AMOTION_EVENT_TOOL_TYPE_PALM,
378
379    #[doc(hidden)]
380    #[num_enum(catch_all)]
381    __Unknown(u32),
382}
383
384/// A bitfield representing the state of buttons during a motion event.
385///
386/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-33)
387#[derive(Copy, Clone, Debug, PartialEq, Eq)]
388pub struct ButtonState(pub u32);
389
390impl ButtonState {
391    #[inline]
392    pub fn primary(self) -> bool {
393        self.0 & ndk_sys::AMOTION_EVENT_BUTTON_PRIMARY != 0
394    }
395    #[inline]
396    pub fn secondary(self) -> bool {
397        self.0 & ndk_sys::AMOTION_EVENT_BUTTON_SECONDARY != 0
398    }
399    #[inline]
400    pub fn teriary(self) -> bool {
401        self.0 & ndk_sys::AMOTION_EVENT_BUTTON_TERTIARY != 0
402    }
403    #[inline]
404    pub fn back(self) -> bool {
405        self.0 & ndk_sys::AMOTION_EVENT_BUTTON_BACK != 0
406    }
407    #[inline]
408    pub fn forward(self) -> bool {
409        self.0 & ndk_sys::AMOTION_EVENT_BUTTON_FORWARD != 0
410    }
411    #[inline]
412    pub fn stylus_primary(self) -> bool {
413        self.0 & ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY != 0
414    }
415    #[inline]
416    pub fn stylus_secondary(self) -> bool {
417        self.0 & ndk_sys::AMOTION_EVENT_BUTTON_STYLUS_SECONDARY != 0
418    }
419}
420
421impl From<ndk::event::ButtonState> for ButtonState {
422    fn from(value: ndk::event::ButtonState) -> Self {
423        Self(value.0)
424    }
425}
426
427/// A bitfield representing which edges were touched by a motion event.
428///
429/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-31)
430#[derive(Copy, Clone, Debug, PartialEq, Eq)]
431pub struct EdgeFlags(pub u32);
432
433impl EdgeFlags {
434    #[inline]
435    pub fn top(self) -> bool {
436        self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_TOP != 0
437    }
438    #[inline]
439    pub fn bottom(self) -> bool {
440        self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_BOTTOM != 0
441    }
442    #[inline]
443    pub fn left(self) -> bool {
444        self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_LEFT != 0
445    }
446    #[inline]
447    pub fn right(self) -> bool {
448        self.0 & ndk_sys::AMOTION_EVENT_EDGE_FLAG_RIGHT != 0
449    }
450}
451
452impl From<ndk::event::EdgeFlags> for EdgeFlags {
453    fn from(value: ndk::event::EdgeFlags) -> Self {
454        Self(value.0)
455    }
456}
457
458/// Flags associated with this [`MotionEvent`].
459///
460/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-30)
461#[derive(Copy, Clone, Debug, PartialEq, Eq)]
462pub struct MotionEventFlags(pub u32);
463
464impl MotionEventFlags {
465    #[inline]
466    pub fn window_is_obscured(self) -> bool {
467        self.0 & ndk_sys::AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED != 0
468    }
469}
470
471impl From<ndk::event::MotionEventFlags> for MotionEventFlags {
472    fn from(value: ndk::event::MotionEventFlags) -> Self {
473        Self(value.0)
474    }
475}
476
477/// Key actions.
478///
479/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-27)
480///
481/// # Android Extensible Enum
482///
483/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
484/// should be handled similar to a `#[non_exhaustive]` enum to maintain
485/// forwards compatibility.
486///
487/// Implements `Into<u32>` and `From<u32>` for converting to/from Android SDK
488/// integer values.
489///
490#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
491#[non_exhaustive]
492#[repr(u32)]
493pub enum KeyAction {
494    Down = ndk_sys::AKEY_EVENT_ACTION_DOWN,
495    Up = ndk_sys::AKEY_EVENT_ACTION_UP,
496    Multiple = ndk_sys::AKEY_EVENT_ACTION_MULTIPLE,
497
498    #[doc(hidden)]
499    #[num_enum(catch_all)]
500    __Unknown(u32),
501}
502
503/// Key codes.
504///
505/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-39)
506///
507/// # Android Extensible Enum
508///
509/// This is a runtime [extensible enum](`crate#android-extensible-enums`) and
510/// should be handled similar to a `#[non_exhaustive]` enum to maintain
511/// forwards compatibility.
512///
513/// Implements `Into<u32>` and `From<u32>` for converting to/from Android SDK
514/// integer values.
515///
516#[derive(Copy, Clone, Debug, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
517#[non_exhaustive]
518#[repr(u32)]
519pub enum Keycode {
520    Unknown = ndk_sys::AKEYCODE_UNKNOWN,
521    SoftLeft = ndk_sys::AKEYCODE_SOFT_LEFT,
522    SoftRight = ndk_sys::AKEYCODE_SOFT_RIGHT,
523    Home = ndk_sys::AKEYCODE_HOME,
524    Back = ndk_sys::AKEYCODE_BACK,
525    Call = ndk_sys::AKEYCODE_CALL,
526    Endcall = ndk_sys::AKEYCODE_ENDCALL,
527    Keycode0 = ndk_sys::AKEYCODE_0,
528    Keycode1 = ndk_sys::AKEYCODE_1,
529    Keycode2 = ndk_sys::AKEYCODE_2,
530    Keycode3 = ndk_sys::AKEYCODE_3,
531    Keycode4 = ndk_sys::AKEYCODE_4,
532    Keycode5 = ndk_sys::AKEYCODE_5,
533    Keycode6 = ndk_sys::AKEYCODE_6,
534    Keycode7 = ndk_sys::AKEYCODE_7,
535    Keycode8 = ndk_sys::AKEYCODE_8,
536    Keycode9 = ndk_sys::AKEYCODE_9,
537    Star = ndk_sys::AKEYCODE_STAR,
538    Pound = ndk_sys::AKEYCODE_POUND,
539    DpadUp = ndk_sys::AKEYCODE_DPAD_UP,
540    DpadDown = ndk_sys::AKEYCODE_DPAD_DOWN,
541    DpadLeft = ndk_sys::AKEYCODE_DPAD_LEFT,
542    DpadRight = ndk_sys::AKEYCODE_DPAD_RIGHT,
543    DpadCenter = ndk_sys::AKEYCODE_DPAD_CENTER,
544    VolumeUp = ndk_sys::AKEYCODE_VOLUME_UP,
545    VolumeDown = ndk_sys::AKEYCODE_VOLUME_DOWN,
546    Power = ndk_sys::AKEYCODE_POWER,
547    Camera = ndk_sys::AKEYCODE_CAMERA,
548    Clear = ndk_sys::AKEYCODE_CLEAR,
549    A = ndk_sys::AKEYCODE_A,
550    B = ndk_sys::AKEYCODE_B,
551    C = ndk_sys::AKEYCODE_C,
552    D = ndk_sys::AKEYCODE_D,
553    E = ndk_sys::AKEYCODE_E,
554    F = ndk_sys::AKEYCODE_F,
555    G = ndk_sys::AKEYCODE_G,
556    H = ndk_sys::AKEYCODE_H,
557    I = ndk_sys::AKEYCODE_I,
558    J = ndk_sys::AKEYCODE_J,
559    K = ndk_sys::AKEYCODE_K,
560    L = ndk_sys::AKEYCODE_L,
561    M = ndk_sys::AKEYCODE_M,
562    N = ndk_sys::AKEYCODE_N,
563    O = ndk_sys::AKEYCODE_O,
564    P = ndk_sys::AKEYCODE_P,
565    Q = ndk_sys::AKEYCODE_Q,
566    R = ndk_sys::AKEYCODE_R,
567    S = ndk_sys::AKEYCODE_S,
568    T = ndk_sys::AKEYCODE_T,
569    U = ndk_sys::AKEYCODE_U,
570    V = ndk_sys::AKEYCODE_V,
571    W = ndk_sys::AKEYCODE_W,
572    X = ndk_sys::AKEYCODE_X,
573    Y = ndk_sys::AKEYCODE_Y,
574    Z = ndk_sys::AKEYCODE_Z,
575    Comma = ndk_sys::AKEYCODE_COMMA,
576    Period = ndk_sys::AKEYCODE_PERIOD,
577    AltLeft = ndk_sys::AKEYCODE_ALT_LEFT,
578    AltRight = ndk_sys::AKEYCODE_ALT_RIGHT,
579    ShiftLeft = ndk_sys::AKEYCODE_SHIFT_LEFT,
580    ShiftRight = ndk_sys::AKEYCODE_SHIFT_RIGHT,
581    Tab = ndk_sys::AKEYCODE_TAB,
582    Space = ndk_sys::AKEYCODE_SPACE,
583    Sym = ndk_sys::AKEYCODE_SYM,
584    Explorer = ndk_sys::AKEYCODE_EXPLORER,
585    Envelope = ndk_sys::AKEYCODE_ENVELOPE,
586    Enter = ndk_sys::AKEYCODE_ENTER,
587    Del = ndk_sys::AKEYCODE_DEL,
588    Grave = ndk_sys::AKEYCODE_GRAVE,
589    Minus = ndk_sys::AKEYCODE_MINUS,
590    Equals = ndk_sys::AKEYCODE_EQUALS,
591    LeftBracket = ndk_sys::AKEYCODE_LEFT_BRACKET,
592    RightBracket = ndk_sys::AKEYCODE_RIGHT_BRACKET,
593    Backslash = ndk_sys::AKEYCODE_BACKSLASH,
594    Semicolon = ndk_sys::AKEYCODE_SEMICOLON,
595    Apostrophe = ndk_sys::AKEYCODE_APOSTROPHE,
596    Slash = ndk_sys::AKEYCODE_SLASH,
597    At = ndk_sys::AKEYCODE_AT,
598    Num = ndk_sys::AKEYCODE_NUM,
599    Headsethook = ndk_sys::AKEYCODE_HEADSETHOOK,
600    Focus = ndk_sys::AKEYCODE_FOCUS,
601    Plus = ndk_sys::AKEYCODE_PLUS,
602    Menu = ndk_sys::AKEYCODE_MENU,
603    Notification = ndk_sys::AKEYCODE_NOTIFICATION,
604    Search = ndk_sys::AKEYCODE_SEARCH,
605    MediaPlayPause = ndk_sys::AKEYCODE_MEDIA_PLAY_PAUSE,
606    MediaStop = ndk_sys::AKEYCODE_MEDIA_STOP,
607    MediaNext = ndk_sys::AKEYCODE_MEDIA_NEXT,
608    MediaPrevious = ndk_sys::AKEYCODE_MEDIA_PREVIOUS,
609    MediaRewind = ndk_sys::AKEYCODE_MEDIA_REWIND,
610    MediaFastForward = ndk_sys::AKEYCODE_MEDIA_FAST_FORWARD,
611    Mute = ndk_sys::AKEYCODE_MUTE,
612    PageUp = ndk_sys::AKEYCODE_PAGE_UP,
613    PageDown = ndk_sys::AKEYCODE_PAGE_DOWN,
614    Pictsymbols = ndk_sys::AKEYCODE_PICTSYMBOLS,
615    SwitchCharset = ndk_sys::AKEYCODE_SWITCH_CHARSET,
616    ButtonA = ndk_sys::AKEYCODE_BUTTON_A,
617    ButtonB = ndk_sys::AKEYCODE_BUTTON_B,
618    ButtonC = ndk_sys::AKEYCODE_BUTTON_C,
619    ButtonX = ndk_sys::AKEYCODE_BUTTON_X,
620    ButtonY = ndk_sys::AKEYCODE_BUTTON_Y,
621    ButtonZ = ndk_sys::AKEYCODE_BUTTON_Z,
622    ButtonL1 = ndk_sys::AKEYCODE_BUTTON_L1,
623    ButtonR1 = ndk_sys::AKEYCODE_BUTTON_R1,
624    ButtonL2 = ndk_sys::AKEYCODE_BUTTON_L2,
625    ButtonR2 = ndk_sys::AKEYCODE_BUTTON_R2,
626    ButtonThumbl = ndk_sys::AKEYCODE_BUTTON_THUMBL,
627    ButtonThumbr = ndk_sys::AKEYCODE_BUTTON_THUMBR,
628    ButtonStart = ndk_sys::AKEYCODE_BUTTON_START,
629    ButtonSelect = ndk_sys::AKEYCODE_BUTTON_SELECT,
630    ButtonMode = ndk_sys::AKEYCODE_BUTTON_MODE,
631    Escape = ndk_sys::AKEYCODE_ESCAPE,
632    ForwardDel = ndk_sys::AKEYCODE_FORWARD_DEL,
633    CtrlLeft = ndk_sys::AKEYCODE_CTRL_LEFT,
634    CtrlRight = ndk_sys::AKEYCODE_CTRL_RIGHT,
635    CapsLock = ndk_sys::AKEYCODE_CAPS_LOCK,
636    ScrollLock = ndk_sys::AKEYCODE_SCROLL_LOCK,
637    MetaLeft = ndk_sys::AKEYCODE_META_LEFT,
638    MetaRight = ndk_sys::AKEYCODE_META_RIGHT,
639    Function = ndk_sys::AKEYCODE_FUNCTION,
640    Sysrq = ndk_sys::AKEYCODE_SYSRQ,
641    Break = ndk_sys::AKEYCODE_BREAK,
642    MoveHome = ndk_sys::AKEYCODE_MOVE_HOME,
643    MoveEnd = ndk_sys::AKEYCODE_MOVE_END,
644    Insert = ndk_sys::AKEYCODE_INSERT,
645    Forward = ndk_sys::AKEYCODE_FORWARD,
646    MediaPlay = ndk_sys::AKEYCODE_MEDIA_PLAY,
647    MediaPause = ndk_sys::AKEYCODE_MEDIA_PAUSE,
648    MediaClose = ndk_sys::AKEYCODE_MEDIA_CLOSE,
649    MediaEject = ndk_sys::AKEYCODE_MEDIA_EJECT,
650    MediaRecord = ndk_sys::AKEYCODE_MEDIA_RECORD,
651    F1 = ndk_sys::AKEYCODE_F1,
652    F2 = ndk_sys::AKEYCODE_F2,
653    F3 = ndk_sys::AKEYCODE_F3,
654    F4 = ndk_sys::AKEYCODE_F4,
655    F5 = ndk_sys::AKEYCODE_F5,
656    F6 = ndk_sys::AKEYCODE_F6,
657    F7 = ndk_sys::AKEYCODE_F7,
658    F8 = ndk_sys::AKEYCODE_F8,
659    F9 = ndk_sys::AKEYCODE_F9,
660    F10 = ndk_sys::AKEYCODE_F10,
661    F11 = ndk_sys::AKEYCODE_F11,
662    F12 = ndk_sys::AKEYCODE_F12,
663    NumLock = ndk_sys::AKEYCODE_NUM_LOCK,
664    Numpad0 = ndk_sys::AKEYCODE_NUMPAD_0,
665    Numpad1 = ndk_sys::AKEYCODE_NUMPAD_1,
666    Numpad2 = ndk_sys::AKEYCODE_NUMPAD_2,
667    Numpad3 = ndk_sys::AKEYCODE_NUMPAD_3,
668    Numpad4 = ndk_sys::AKEYCODE_NUMPAD_4,
669    Numpad5 = ndk_sys::AKEYCODE_NUMPAD_5,
670    Numpad6 = ndk_sys::AKEYCODE_NUMPAD_6,
671    Numpad7 = ndk_sys::AKEYCODE_NUMPAD_7,
672    Numpad8 = ndk_sys::AKEYCODE_NUMPAD_8,
673    Numpad9 = ndk_sys::AKEYCODE_NUMPAD_9,
674    NumpadDivide = ndk_sys::AKEYCODE_NUMPAD_DIVIDE,
675    NumpadMultiply = ndk_sys::AKEYCODE_NUMPAD_MULTIPLY,
676    NumpadSubtract = ndk_sys::AKEYCODE_NUMPAD_SUBTRACT,
677    NumpadAdd = ndk_sys::AKEYCODE_NUMPAD_ADD,
678    NumpadDot = ndk_sys::AKEYCODE_NUMPAD_DOT,
679    NumpadComma = ndk_sys::AKEYCODE_NUMPAD_COMMA,
680    NumpadEnter = ndk_sys::AKEYCODE_NUMPAD_ENTER,
681    NumpadEquals = ndk_sys::AKEYCODE_NUMPAD_EQUALS,
682    NumpadLeftParen = ndk_sys::AKEYCODE_NUMPAD_LEFT_PAREN,
683    NumpadRightParen = ndk_sys::AKEYCODE_NUMPAD_RIGHT_PAREN,
684    VolumeMute = ndk_sys::AKEYCODE_VOLUME_MUTE,
685    Info = ndk_sys::AKEYCODE_INFO,
686    ChannelUp = ndk_sys::AKEYCODE_CHANNEL_UP,
687    ChannelDown = ndk_sys::AKEYCODE_CHANNEL_DOWN,
688    ZoomIn = ndk_sys::AKEYCODE_ZOOM_IN,
689    ZoomOut = ndk_sys::AKEYCODE_ZOOM_OUT,
690    Tv = ndk_sys::AKEYCODE_TV,
691    Window = ndk_sys::AKEYCODE_WINDOW,
692    Guide = ndk_sys::AKEYCODE_GUIDE,
693    Dvr = ndk_sys::AKEYCODE_DVR,
694    Bookmark = ndk_sys::AKEYCODE_BOOKMARK,
695    Captions = ndk_sys::AKEYCODE_CAPTIONS,
696    Settings = ndk_sys::AKEYCODE_SETTINGS,
697    TvPower = ndk_sys::AKEYCODE_TV_POWER,
698    TvInput = ndk_sys::AKEYCODE_TV_INPUT,
699    StbPower = ndk_sys::AKEYCODE_STB_POWER,
700    StbInput = ndk_sys::AKEYCODE_STB_INPUT,
701    AvrPower = ndk_sys::AKEYCODE_AVR_POWER,
702    AvrInput = ndk_sys::AKEYCODE_AVR_INPUT,
703    ProgRed = ndk_sys::AKEYCODE_PROG_RED,
704    ProgGreen = ndk_sys::AKEYCODE_PROG_GREEN,
705    ProgYellow = ndk_sys::AKEYCODE_PROG_YELLOW,
706    ProgBlue = ndk_sys::AKEYCODE_PROG_BLUE,
707    AppSwitch = ndk_sys::AKEYCODE_APP_SWITCH,
708    Button1 = ndk_sys::AKEYCODE_BUTTON_1,
709    Button2 = ndk_sys::AKEYCODE_BUTTON_2,
710    Button3 = ndk_sys::AKEYCODE_BUTTON_3,
711    Button4 = ndk_sys::AKEYCODE_BUTTON_4,
712    Button5 = ndk_sys::AKEYCODE_BUTTON_5,
713    Button6 = ndk_sys::AKEYCODE_BUTTON_6,
714    Button7 = ndk_sys::AKEYCODE_BUTTON_7,
715    Button8 = ndk_sys::AKEYCODE_BUTTON_8,
716    Button9 = ndk_sys::AKEYCODE_BUTTON_9,
717    Button10 = ndk_sys::AKEYCODE_BUTTON_10,
718    Button11 = ndk_sys::AKEYCODE_BUTTON_11,
719    Button12 = ndk_sys::AKEYCODE_BUTTON_12,
720    Button13 = ndk_sys::AKEYCODE_BUTTON_13,
721    Button14 = ndk_sys::AKEYCODE_BUTTON_14,
722    Button15 = ndk_sys::AKEYCODE_BUTTON_15,
723    Button16 = ndk_sys::AKEYCODE_BUTTON_16,
724    LanguageSwitch = ndk_sys::AKEYCODE_LANGUAGE_SWITCH,
725    MannerMode = ndk_sys::AKEYCODE_MANNER_MODE,
726    Keycode3dMode = ndk_sys::AKEYCODE_3D_MODE,
727    Contacts = ndk_sys::AKEYCODE_CONTACTS,
728    Calendar = ndk_sys::AKEYCODE_CALENDAR,
729    Music = ndk_sys::AKEYCODE_MUSIC,
730    Calculator = ndk_sys::AKEYCODE_CALCULATOR,
731    ZenkakuHankaku = ndk_sys::AKEYCODE_ZENKAKU_HANKAKU,
732    Eisu = ndk_sys::AKEYCODE_EISU,
733    Muhenkan = ndk_sys::AKEYCODE_MUHENKAN,
734    Henkan = ndk_sys::AKEYCODE_HENKAN,
735    KatakanaHiragana = ndk_sys::AKEYCODE_KATAKANA_HIRAGANA,
736    Yen = ndk_sys::AKEYCODE_YEN,
737    Ro = ndk_sys::AKEYCODE_RO,
738    Kana = ndk_sys::AKEYCODE_KANA,
739    Assist = ndk_sys::AKEYCODE_ASSIST,
740    BrightnessDown = ndk_sys::AKEYCODE_BRIGHTNESS_DOWN,
741    BrightnessUp = ndk_sys::AKEYCODE_BRIGHTNESS_UP,
742    MediaAudioTrack = ndk_sys::AKEYCODE_MEDIA_AUDIO_TRACK,
743    Sleep = ndk_sys::AKEYCODE_SLEEP,
744    Wakeup = ndk_sys::AKEYCODE_WAKEUP,
745    Pairing = ndk_sys::AKEYCODE_PAIRING,
746    MediaTopMenu = ndk_sys::AKEYCODE_MEDIA_TOP_MENU,
747    Keycode11 = ndk_sys::AKEYCODE_11,
748    Keycode12 = ndk_sys::AKEYCODE_12,
749    LastChannel = ndk_sys::AKEYCODE_LAST_CHANNEL,
750    TvDataService = ndk_sys::AKEYCODE_TV_DATA_SERVICE,
751    VoiceAssist = ndk_sys::AKEYCODE_VOICE_ASSIST,
752    TvRadioService = ndk_sys::AKEYCODE_TV_RADIO_SERVICE,
753    TvTeletext = ndk_sys::AKEYCODE_TV_TELETEXT,
754    TvNumberEntry = ndk_sys::AKEYCODE_TV_NUMBER_ENTRY,
755    TvTerrestrialAnalog = ndk_sys::AKEYCODE_TV_TERRESTRIAL_ANALOG,
756    TvTerrestrialDigital = ndk_sys::AKEYCODE_TV_TERRESTRIAL_DIGITAL,
757    TvSatellite = ndk_sys::AKEYCODE_TV_SATELLITE,
758    TvSatelliteBs = ndk_sys::AKEYCODE_TV_SATELLITE_BS,
759    TvSatelliteCs = ndk_sys::AKEYCODE_TV_SATELLITE_CS,
760    TvSatelliteService = ndk_sys::AKEYCODE_TV_SATELLITE_SERVICE,
761    TvNetwork = ndk_sys::AKEYCODE_TV_NETWORK,
762    TvAntennaCable = ndk_sys::AKEYCODE_TV_ANTENNA_CABLE,
763    TvInputHdmi1 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_1,
764    TvInputHdmi2 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_2,
765    TvInputHdmi3 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_3,
766    TvInputHdmi4 = ndk_sys::AKEYCODE_TV_INPUT_HDMI_4,
767    TvInputComposite1 = ndk_sys::AKEYCODE_TV_INPUT_COMPOSITE_1,
768    TvInputComposite2 = ndk_sys::AKEYCODE_TV_INPUT_COMPOSITE_2,
769    TvInputComponent1 = ndk_sys::AKEYCODE_TV_INPUT_COMPONENT_1,
770    TvInputComponent2 = ndk_sys::AKEYCODE_TV_INPUT_COMPONENT_2,
771    TvInputVga1 = ndk_sys::AKEYCODE_TV_INPUT_VGA_1,
772    TvAudioDescription = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION,
773    TvAudioDescriptionMixUp = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP,
774    TvAudioDescriptionMixDown = ndk_sys::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN,
775    TvZoomMode = ndk_sys::AKEYCODE_TV_ZOOM_MODE,
776    TvContentsMenu = ndk_sys::AKEYCODE_TV_CONTENTS_MENU,
777    TvMediaContextMenu = ndk_sys::AKEYCODE_TV_MEDIA_CONTEXT_MENU,
778    TvTimerProgramming = ndk_sys::AKEYCODE_TV_TIMER_PROGRAMMING,
779    Help = ndk_sys::AKEYCODE_HELP,
780    NavigatePrevious = ndk_sys::AKEYCODE_NAVIGATE_PREVIOUS,
781    NavigateNext = ndk_sys::AKEYCODE_NAVIGATE_NEXT,
782    NavigateIn = ndk_sys::AKEYCODE_NAVIGATE_IN,
783    NavigateOut = ndk_sys::AKEYCODE_NAVIGATE_OUT,
784    StemPrimary = ndk_sys::AKEYCODE_STEM_PRIMARY,
785    Stem1 = ndk_sys::AKEYCODE_STEM_1,
786    Stem2 = ndk_sys::AKEYCODE_STEM_2,
787    Stem3 = ndk_sys::AKEYCODE_STEM_3,
788    DpadUpLeft = ndk_sys::AKEYCODE_DPAD_UP_LEFT,
789    DpadDownLeft = ndk_sys::AKEYCODE_DPAD_DOWN_LEFT,
790    DpadUpRight = ndk_sys::AKEYCODE_DPAD_UP_RIGHT,
791    DpadDownRight = ndk_sys::AKEYCODE_DPAD_DOWN_RIGHT,
792    MediaSkipForward = ndk_sys::AKEYCODE_MEDIA_SKIP_FORWARD,
793    MediaSkipBackward = ndk_sys::AKEYCODE_MEDIA_SKIP_BACKWARD,
794    MediaStepForward = ndk_sys::AKEYCODE_MEDIA_STEP_FORWARD,
795    MediaStepBackward = ndk_sys::AKEYCODE_MEDIA_STEP_BACKWARD,
796    SoftSleep = ndk_sys::AKEYCODE_SOFT_SLEEP,
797    Cut = ndk_sys::AKEYCODE_CUT,
798    Copy = ndk_sys::AKEYCODE_COPY,
799    Paste = ndk_sys::AKEYCODE_PASTE,
800    SystemNavigationUp = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_UP,
801    SystemNavigationDown = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_DOWN,
802    SystemNavigationLeft = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_LEFT,
803    SystemNavigationRight = ndk_sys::AKEYCODE_SYSTEM_NAVIGATION_RIGHT,
804    AllApps = ndk_sys::AKEYCODE_ALL_APPS,
805    Refresh = ndk_sys::AKEYCODE_REFRESH,
806    ThumbsUp = ndk_sys::AKEYCODE_THUMBS_UP,
807    ThumbsDown = ndk_sys::AKEYCODE_THUMBS_DOWN,
808    ProfileSwitch = ndk_sys::AKEYCODE_PROFILE_SWITCH,
809
810    #[doc(hidden)]
811    #[num_enum(catch_all)]
812    __Unknown(u32),
813}
814
815/// Flags associated with [`KeyEvent`].
816///
817/// See [the NDK docs](https://developer.android.com/ndk/reference/group/input#anonymous-enum-28)
818#[derive(Copy, Clone, Debug, PartialEq, Eq)]
819pub struct KeyEventFlags(pub u32);
820
821impl KeyEventFlags {
822    #[inline]
823    pub fn cancelled(&self) -> bool {
824        self.0 & ndk_sys::AKEY_EVENT_FLAG_CANCELED != 0
825    }
826    #[inline]
827    pub fn cancelled_long_press(&self) -> bool {
828        self.0 & ndk_sys::AKEY_EVENT_FLAG_CANCELED_LONG_PRESS != 0
829    }
830    #[inline]
831    pub fn editor_action(&self) -> bool {
832        self.0 & ndk_sys::AKEY_EVENT_FLAG_EDITOR_ACTION != 0
833    }
834    #[inline]
835    pub fn fallback(&self) -> bool {
836        self.0 & ndk_sys::AKEY_EVENT_FLAG_FALLBACK != 0
837    }
838    #[inline]
839    pub fn from_system(&self) -> bool {
840        self.0 & ndk_sys::AKEY_EVENT_FLAG_FROM_SYSTEM != 0
841    }
842    #[inline]
843    pub fn keep_touch_mode(&self) -> bool {
844        self.0 & ndk_sys::AKEY_EVENT_FLAG_KEEP_TOUCH_MODE != 0
845    }
846    #[inline]
847    pub fn long_press(&self) -> bool {
848        self.0 & ndk_sys::AKEY_EVENT_FLAG_LONG_PRESS != 0
849    }
850    #[inline]
851    pub fn soft_keyboard(&self) -> bool {
852        self.0 & ndk_sys::AKEY_EVENT_FLAG_SOFT_KEYBOARD != 0
853    }
854    #[inline]
855    pub fn tracking(&self) -> bool {
856        self.0 & ndk_sys::AKEY_EVENT_FLAG_TRACKING != 0
857    }
858    #[inline]
859    pub fn virtual_hard_key(&self) -> bool {
860        self.0 & ndk_sys::AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY != 0
861    }
862    #[inline]
863    pub fn woke_here(&self) -> bool {
864        self.0 & ndk_sys::AKEY_EVENT_FLAG_WOKE_HERE != 0
865    }
866}
867
868impl From<ndk::event::KeyEventFlags> for KeyEventFlags {
869    fn from(value: ndk::event::KeyEventFlags) -> Self {
870        Self(value.0)
871    }
872}
873
874/// This struct holds a span within a region of text from `start` to `end`.
875///
876/// The `start` index may be greater than the `end` index (swapping `start` and `end` will represent the same span)
877///
878/// The lower index is inclusive and the higher index is exclusive.
879///
880/// An empty span or cursor position is specified with `start == end`.
881///
882#[derive(Debug, Clone, Copy)]
883pub struct TextSpan {
884    /// The start of the span (inclusive)
885    pub start: usize,
886
887    /// The end of the span (exclusive)
888    pub end: usize,
889}
890
891#[derive(Debug, Clone)]
892pub struct TextInputState {
893    pub text: String,
894
895    /// A selection defined on the text.
896    ///
897    /// To set the cursor position, start and end should have the same value.
898    ///
899    /// Changing the selection has no effect on the compose_region.
900    pub selection: TextSpan,
901
902    /// A composing region defined on the text.
903    ///
904    /// When being set, then if there was a composing region, the region is replaced.
905    ///
906    /// The given indices will be clamped to the `text` bounds
907    ///
908    /// If the resulting region is zero-sized, no region is marked (equivalent to passing `None`)
909    pub compose_region: Option<TextSpan>,
910}
911
912impl Default for TextInputState {
913    fn default() -> Self {
914        Self {
915            text: String::new(),
916            selection: TextSpan { start: 0, end: 0 },
917            compose_region: None,
918        }
919    }
920}
921
922// Represents the action button on a soft keyboard.
923#[derive(Debug, Clone, Copy, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
924#[non_exhaustive]
925#[repr(i32)]
926pub enum TextInputAction {
927    /// Let receiver decide what logical action to perform
928    Unspecified = 0,
929    /// No action - receiver could instead interpret as an "enter" key that inserts a newline character
930    None = 1,
931    /// Navigate to the input location (such as a URL)
932    Go = 2,
933    /// Search based on the input text
934    Search = 3,
935    /// Send the input to the target
936    Send = 4,
937    /// Move to the next input field
938    Next = 5,
939    /// Indicate that input is done
940    Done = 6,
941    /// Move to the previous input field
942    Previous = 7,
943
944    #[doc(hidden)]
945    #[num_enum(catch_all)]
946    __Unknown(i32),
947}
948
949bitflags! {
950    /// Flags for [`AndroidApp::set_ime_editor_info`]
951    /// as per the [android.view.inputmethod.EditorInfo Java API](https://developer.android.com/reference/android/view/inputmethod/EditorInfo)
952    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
953    pub struct ImeOptions: u32 {
954
955        /// The mask of bits that configure alternative actions for the "enter" key. This helps the
956        /// IME provide clear feedback for what the key will do and provide alternative mechanisms
957        /// for taking the same action.
958        const IME_MASK_ACTION = 0x000000ff;
959
960        /// Indicates that ascii input is a priority (such as for entering an account ID)
961        const IME_FLAG_FORCE_ASCII = 0x80000000;
962
963        /// Indicates that it's possible to navigate focus forwards to something.
964        ///
965        /// This is similar to using `IME_ACTION_NEXT` except it allows for multi-line input with
966        /// an enter key in addition to forward navigation for focus.
967        ///
968        /// This may not be supported by all IMEs (especially on small screens)
969        const IME_FLAG_NAVIGATE_NEXT = 0x08000000;
970
971        /// Similar to `IME_FLAG_NAVIGATE_NEXT`, except it indicates that it's possible to navigate
972        /// focus backwards to something.
973        const IME_FLAG_NAVIGATE_PREVIOUS = 0x04000000;
974
975        /// This requests that the IME should not show any accessory actions next to the extracted
976        /// text UI, when it is in fullscreen mode.
977        ///
978        /// The implication is that you think it's more important to prioritize having room for
979        /// previewing more text, instead of showing accessory actions.
980        ///
981        /// Note: In some cases this can make the action unavailable.
982        const IME_FLAG_NO_ACCESSORY_ACTION = 0x20000000;
983
984        /// If this flag is not set, IMEs will normally replace the "enter" key with the action
985        /// supplied. This flag indicates that the action should not be available in-line as a
986        /// replacement for the "enter" key. Typically this is because the action has such a
987        /// significant impact or is not recoverable enough that accidentally hitting it should be
988        /// avoided, such as sending a message.
989        const IME_FLAG_NO_ENTER_ACTION = 0x40000000;
990
991        /// Don't show any "extracted-text UI" as part of the on-screen IME.
992        ///
993        /// Some keyboards may show an additional text box above the keyboard for previewing what
994        /// you type (referred to as the extracted text UI) and it can sometimes be quite large.
995        ///
996        /// The exact semantics of this flag can be unclear sometimes and the UI that becomes
997        /// visible may not respond to input as you would expect.
998        ///
999        /// This flag may be deprecated in the future and it's recommend to use
1000        /// `IME_FLAG_NO_FULLSCREEN` instead, to avoid having the extracted text UI appear to cover
1001        /// the full screen.
1002        const IMG_FLAG_NO_EXTRACT_UI = 0x10000000;
1003
1004        /// Request that the IME should avoid ever entering a fullscreen mode and should always
1005        /// leave some room for the application UI.
1006        ///
1007        /// Note: It's not guaranteed that an IME will honor this state
1008        const IME_FLAG_NO_FULLSCREEN = 0x02000000;
1009
1010        /// Request that the IME should not update personalized data, such as typing history.
1011        ///
1012        /// Note: It's not guaranteed that an IME will honor this state
1013        const IME_FLAG_NO_PERSONALIZED_LEARNING = 0x01000000;
1014
1015        /// Generic unspecified type for ImeOptions
1016        const IME_NULL = 0;
1017    }
1018}
1019
1020impl ImeOptions {
1021    /// Specify what action the IME's "enter" key should perform.
1022    ///
1023    /// This helps the IME provide clear feedback for what the key will do and provide alternative
1024    /// mechanisms for taking the same action.
1025    pub fn set_action(&mut self, action: TextInputAction) {
1026        let action: i32 = action.into();
1027        let action = action as u32;
1028        *self = Self::from_bits_truncate(
1029            (self.bits() & !Self::IME_MASK_ACTION.bits()) | (action & Self::IME_MASK_ACTION.bits()),
1030        );
1031    }
1032
1033    /// Get the current action of the IME's "enter" key.
1034    pub fn action(&self) -> TextInputAction {
1035        let action_bits = self.bits() & Self::IME_MASK_ACTION.bits();
1036        TextInputAction::from(action_bits as i32)
1037    }
1038}
1039
1040#[derive(Debug, Clone, Copy, PartialEq, Eq, num_enum::FromPrimitive, num_enum::IntoPrimitive)]
1041#[non_exhaustive]
1042#[repr(u32)]
1043pub enum InputTypeClass {
1044    /// Special content type for when no explicit type has been specified.
1045    ///
1046    /// This should be interpreted to mean that the target input connection is
1047    /// not rich, it can not process and show things like candidate text nor
1048    /// retrieve the current text, so the input method will need to run in a
1049    /// limited "generate key events" mode, if it supports it.
1050    ///
1051    /// Note that some input methods may not support it, for example a
1052    /// voice-based input method will likely not be able to generate key events
1053    /// even if this flag is set.
1054    Null = 0,
1055
1056    ///  Class for normal text.
1057    ///
1058    /// This class supports the following flags (only one of which should be set):
1059    /// - TYPE_TEXT_FLAG_CAP_CHARACTERS
1060    /// - TYPE_TEXT_FLAG_CAP_WORDS
1061    /// - TYPE_TEXT_FLAG_CAP_SENTENCES.
1062    ///
1063    /// It also supports the following variations:
1064    /// - TYPE_TEXT_VARIATION_NORMAL
1065    /// - TYPE_TEXT_VARIATION_URI
1066    ///
1067    /// *If you do not recognize the variation, normal should be assumed.*
1068    Text = 1,
1069
1070    /// Class for numeric text.
1071    ///
1072    /// This class supports the following flags:
1073    /// - `TYPE_NUMBER_FLAG_SIGNED`
1074    /// - `TYPE_NUMBER_FLAG_DECIMAL`
1075    ///
1076    /// It also supports the following variations:
1077    /// - `TYPE_NUMBER_VARIATION_NORMAL`
1078    /// - `TYPE_NUMBER_VARIATION_PASSWORD`
1079    ///
1080    /// *IME authors: If you do not recognize the variation, normal should be assumed.*
1081    Number = 2,
1082
1083    ///  Class for a phone number.
1084    ///
1085    /// This class currently supports no variations or flags.
1086    Phone = 3,
1087
1088    ///  Class for dates and times.
1089    ///
1090    /// It supports the following variations:
1091    /// - TYPE_DATETIME_VARIATION_NORMAL
1092    /// - TYPE_DATETIME_VARIATION_DATE
1093    /// - TYPE_DATETIME_VARIATION_TIME
1094    DateTime = 4,
1095
1096    #[doc(hidden)]
1097    #[num_enum(catch_all)]
1098    __Unknown(u32),
1099}
1100
1101bitflags! {
1102    /// Flags specifying the content type of text being input.
1103    ///
1104    /// Corresponds to the Android SDK [InputType](https://developer.android.com/reference/android/text/InputType) API
1105    #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1106    pub struct InputType: u32 {
1107        ///  Mask of bits that determine the overall class of text being given. Currently
1108        ///  supported classes are: TYPE_CLASS_TEXT, TYPE_CLASS_NUMBER, TYPE_CLASS_PHONE,
1109        ///  TYPE_CLASS_DATETIME. IME authors: If the class is not one you understand, assume
1110        ///  TYPE_CLASS_TEXT with NO variation or flags.
1111        const TYPE_MASK_CLASS = 0x0000000f;
1112
1113        ///  Mask of bits that determine the variation of the base content class.
1114        const TYPE_MASK_VARIATION = 0x00000ff0;
1115
1116        ///  Mask of bits that provide addition bit flags of options.
1117        const TYPE_MASK_FLAGS = 0x00fff000;
1118
1119        ///  Special content type for when no explicit type has been specified. This should be
1120        ///  interpreted to mean that the target input connection is not rich, it can not process
1121        ///  and show things like candidate text nor retrieve the current text, so the input
1122        ///  method will need to run in a limited "generate key events" mode, if it supports
1123        ///  it. Note that some input methods may not support it, for example a voice-based
1124        ///  input method will likely not be able to generate key events even if this flag is
1125        ///  set.
1126        const TYPE_NULL = 0;
1127
1128        ///  Class for normal text. This class supports the following flags (only one of which
1129        ///  should be set): TYPE_TEXT_FLAG_CAP_CHARACTERS, TYPE_TEXT_FLAG_CAP_WORDS, and.
1130        ///  TYPE_TEXT_FLAG_CAP_SENTENCES.  It also supports the following variations:
1131        ///  TYPE_TEXT_VARIATION_NORMAL, and TYPE_TEXT_VARIATION_URI. If you do not recognize the
1132        ///  variation, normal should be assumed.
1133        const TYPE_CLASS_TEXT = 1;
1134
1135        ///  Flag for TYPE_CLASS_TEXT: capitalize all characters.  Overrides
1136        ///  #TYPE_TEXT_FLAG_CAP_WORDS} and  #TYPE_TEXT_FLAG_CAP_SENTENCES}.  This value is
1137        ///  explicitly defined to be the same as  TextUtils#CAP_MODE_CHARACTERS}. Of
1138        ///  course, this only affects languages where there are upper-case and lower-case
1139        ///  letters.
1140        const TYPE_TEXT_FLAG_CAP_CHARACTERS = 0x00001000;
1141
1142        ///  Flag for TYPE_CLASS_TEXT: capitalize the first character of every word.
1143        ///  Overrides TYPE_TEXT_FLAG_CAP_SENTENCES.  This value is explicitly defined
1144        ///  to be the same as TextUtils#CAP_MODE_WORDS. Of course, this only affects
1145        ///  languages where there are upper-case and lower-case letters.
1146        const TYPE_TEXT_FLAG_CAP_WORDS = 0x00002000;
1147
1148        ///  Flag for TYPE_CLASS_TEXT: capitalize the first character of each sentence.  This value
1149        ///  is explicitly defined to be the same as TextUtils#CAP_MODE_SENTENCES. For example in
1150        ///  English it means to capitalize after a period and a space (note that other languages
1151        ///  may have different characters for period, or not use spaces, or use different
1152        ///  grammatical rules). Of course, this only affects languages where there are upper-case
1153        ///  and lower-case letters.
1154        const TYPE_TEXT_FLAG_CAP_SENTENCES = 0x00004000;
1155
1156        ///  Flag for TYPE_CLASS_TEXT: the user is entering free-form text that should have
1157        ///  auto-correction applied to it. Without this flag, the IME will not try to correct
1158        ///  typos. You should always set this flag unless you really expect users to type
1159        ///  non-words in this field, for example to choose a name for a character in a game.
1160        ///  Contrast this with  TYPE_TEXT_FLAG_AUTO_COMPLETE and TYPE_TEXT_FLAG_NO_SUGGESTIONS:
1161        ///  TYPE_TEXT_FLAG_AUTO_CORRECT means that the IME will try to auto-correct typos as the
1162        ///  user is typing, but does not define whether the IME offers an interface to show
1163        ///  suggestions.
1164        const TYPE_TEXT_FLAG_AUTO_CORRECT = 0x00008000;
1165
1166        ///  Flag for TYPE_CLASS_TEXT: the text editor (which means the application) is performing
1167        ///  auto-completion of the text being entered based on its own semantics, which it will
1168        ///  present to the user as they type. This generally means that the input method should
1169        ///  not be showing candidates itself, but can expect the editor to supply its own
1170        ///  completions/candidates from
1171        ///  android.view.inputmethod.InputMethodSession#displayCompletions
1172        ///  InputMethodSession.displayCompletions()} as a result of the editor calling
1173        ///  android.view.inputmethod.InputMethodManager#displayCompletions
1174        ///  InputMethodManager.displayCompletions()}. Note the contrast with
1175        ///  TYPE_TEXT_FLAG_AUTO_CORRECT and  TYPE_TEXT_FLAG_NO_SUGGESTIONS:
1176        ///  TYPE_TEXT_FLAG_AUTO_COMPLETE means the editor should show an interface for displaying
1177        ///  suggestions, but instead of supplying its own it will rely on the Editor to pass
1178        ///  completions/corrections.
1179        const TYPE_TEXT_FLAG_AUTO_COMPLETE = 0x00010000;
1180
1181        ///  Flag for TYPE_CLASS_TEXT: multiple lines of text can be entered into the
1182        ///  field.  If this flag is not set, the text field will be constrained to a single
1183        ///  line. The IME may also choose not to display an enter key when this flag is not set,
1184        ///  as there should be no need to create new lines.
1185        const TYPE_TEXT_FLAG_MULTI_LINE = 0x00020000;
1186
1187        ///  Flag for TYPE_CLASS_TEXT: the regular text view associated with this should
1188        ///  not be multi-line, but when a fullscreen input method is providing text it should
1189        ///  use multiple lines if it can.
1190        const TYPE_TEXT_FLAG_IME_MULTI_LINE = 0x00040000;
1191
1192        ///  Flag for TYPE_CLASS_TEXT: the input method does not need to display any
1193        ///  dictionary-based candidates. This is useful for text views that do not contain words
1194        ///  from the language and do not benefit from any dictionary-based completions or
1195        ///  corrections. It overrides the TYPE_TEXT_FLAG_AUTO_CORRECT value when set.  Please
1196        ///  avoid using this unless you are certain this is what you want. Many input methods need
1197        ///  suggestions to work well, for example the ones based on gesture typing.  Consider
1198        ///  clearing TYPE_TEXT_FLAG_AUTO_CORRECT instead if you just do not want the IME to
1199        ///  correct typos. Note the contrast with TYPE_TEXT_FLAG_AUTO_CORRECT and
1200        ///  TYPE_TEXT_FLAG_AUTO_COMPLETE: TYPE_TEXT_FLAG_NO_SUGGESTIONS means the IME does not
1201        ///  need to show an interface to display suggestions. Most IMEs will also take this to
1202        ///  mean they do not need to try to auto-correct what the user is typing.
1203        const TYPE_TEXT_FLAG_NO_SUGGESTIONS = 0x00080000;
1204
1205        ///  Flag for TYPE_CLASS_TEXT: Let the IME know the text conversion suggestions are
1206        ///  required by the application. Text conversion suggestion is for the transliteration
1207        ///  languages which has pronunciation characters and target characters.  When the user is
1208        ///  typing the pronunciation charactes, the IME could provide the possible target
1209        ///  characters to the user. When this flag is set, the IME should insert the text
1210        ///  conversion suggestions through  Builder#setTextConversionSuggestions(List)} and the
1211        ///  TextAttribute} with initialized with the text conversion suggestions is provided by
1212        ///  the IME to the application. To receive the additional information, the application
1213        ///  needs to implement  InputConnection#setComposingText(CharSequence, int,
1214        ///  TextAttribute)},  InputConnection#setComposingRegion(int, int, TextAttribute)}, and
1215        ///  InputConnection#commitText(CharSequence, int, TextAttribute)}.
1216        const TYPE_TEXT_FLAG_ENABLE_TEXT_CONVERSION_SUGGESTIONS = 0x00100000;
1217
1218        /// Flag for TYPE_CLASS_TEXT: Let the IME know that conversion candidate selection
1219        /// information is requested by the application. Text conversion suggestion is for the
1220        /// transliteration languages, which have the notions of pronunciation and target
1221        /// characters. When the user actively selects a candidate from the conversion suggestions,
1222        /// notifying when candidate selection is occurring helps assistive technologies generate
1223        /// more effective feedback. When this flag is set, and there is an active selected
1224        /// suggestion, the IME should set that a conversion suggestion is selected when
1225        /// initializing the TextAttribute. To receive this information, the application should
1226        /// implement InputConnection.setComposingText(CharSequence, int, TextAttribute),
1227        /// InputConnection.setComposingRegion(int, int, TextAttribute), and
1228        /// InputConnection.commitText(CharSequence, int, TextAttribute)
1229        const TYPE_TEXT_FLAG_ENABLE_TEXT_SUGGESTION_SELECTED = 0x00200000;
1230
1231        ///  Default variation of TYPE_CLASS_TEXT: plain old normal text.
1232        const TYPE_TEXT_VARIATION_NORMAL = 0;
1233        ///  Variation of TYPE_CLASS_TEXT: entering a URI.
1234        const TYPE_TEXT_VARIATION_URI = 0x00000010;
1235        ///  Variation of TYPE_CLASS_TEXT: entering an e-mail address.
1236        const TYPE_TEXT_VARIATION_EMAIL_ADDRESS = 0x00000020;
1237        ///  Variation of TYPE_CLASS_TEXT: entering the subject line of an e-mail.
1238        const TYPE_TEXT_VARIATION_EMAIL_SUBJECT = 0x00000030;
1239        ///  Variation of TYPE_CLASS_TEXT: entering a short, possibly informal message such as an instant message or a text message.
1240        const TYPE_TEXT_VARIATION_SHORT_MESSAGE = 64;
1241        ///  Variation of TYPE_CLASS_TEXT: entering the content of a long, possibly formal message such as the body of an e-mail.
1242        const TYPE_TEXT_VARIATION_LONG_MESSAGE = 0x00000050;
1243        ///  Variation of TYPE_CLASS_TEXT: entering the name of a person.
1244        const TYPE_TEXT_VARIATION_PERSON_NAME = 0x00000060;
1245        ///  Variation of TYPE_CLASS_TEXT: entering a postal mailing address.
1246        const TYPE_TEXT_VARIATION_POSTAL_ADDRESS = 0x00000070;
1247        ///  Variation of TYPE_CLASS_TEXT: entering a password.
1248        const TYPE_TEXT_VARIATION_PASSWORD = 0x00000080;
1249        ///  Variation of TYPE_CLASS_TEXT: entering a password, which should be visible to the user.
1250        const TYPE_TEXT_VARIATION_VISIBLE_PASSWORD = 0x00000090;
1251        ///  Variation of TYPE_CLASS_TEXT: entering text inside of a web form.
1252        const TYPE_TEXT_VARIATION_WEB_EDIT_TEXT = 0x000000a0;
1253        ///  Variation of TYPE_CLASS_TEXT: entering text to filter contents of a list etc.
1254        const TYPE_TEXT_VARIATION_FILTER = 0x000000b0;
1255        ///  Variation of TYPE_CLASS_TEXT: entering text for phonetic pronunciation, such as a
1256        ///  phonetic name field in contacts. This is mostly useful for languages where one
1257        ///  spelling may have several phonetic readings, like Japanese.
1258        const TYPE_TEXT_VARIATION_PHONETIC = 0x000000c0;
1259        ///  Variation of TYPE_CLASS_TEXT: entering e-mail address inside of a web form.  This
1260        ///  was added in  android.os.Build.VERSION_CODES#HONEYCOMB}.  An IME must target this API
1261        ///  version or later to see this input type; if it doesn't, a request for this type will
1262        ///  be seen as  #TYPE_TEXT_VARIATION_EMAIL_ADDRESS} when passed through
1263        ///  android.view.inputmethod.EditorInfo#makeCompatible(int)
1264        ///  EditorInfo.makeCompatible(int)}.
1265        const TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS = 0x000000d0;
1266        ///  Variation of TYPE_CLASS_TEXT: entering password inside of a web form.  This was
1267        ///  added in  android.os.Build.VERSION_CODES#HONEYCOMB}.  An IME must target this API
1268        ///  version or later to see this input type; if it doesn't, a request for this type will
1269        ///  be seen as  #TYPE_TEXT_VARIATION_PASSWORD} when passed through
1270        ///  android.view.inputmethod.EditorInfo#makeCompatible(int)
1271        ///  EditorInfo.makeCompatible(int)}.
1272        const TYPE_TEXT_VARIATION_WEB_PASSWORD = 0x000000e0;
1273        ///  Class for numeric text.  This class supports the following flags:
1274        ///  #TYPE_NUMBER_FLAG_SIGNED} and  #TYPE_NUMBER_FLAG_DECIMAL}.  It also supports the
1275        ///  following variations:  #TYPE_NUMBER_VARIATION_NORMAL} and
1276        ///  #TYPE_NUMBER_VARIATION_PASSWORD}. <p>IME authors: If you do not recognize the
1277        ///  variation, normal should be assumed.</p>
1278        const TYPE_CLASS_NUMBER = 2;
1279        ///  Flag of TYPE_CLASS_NUMBER: the number is signed, allowing a positive or negative
1280        ///  sign at the start.
1281        const TYPE_NUMBER_FLAG_SIGNED = 0x00001000;
1282        ///  Flag of TYPE_CLASS_NUMBER: the number is decimal, allowing a decimal point to
1283        ///  provide fractional values.
1284        const TYPE_NUMBER_FLAG_DECIMAL = 0x00002000;
1285        ///  Default variation of TYPE_CLASS_NUMBER: plain normal numeric text.  This was added
1286        ///  in  android.os.Build.VERSION_CODES#HONEYCOMB}.  An IME must target this API version or
1287        ///  later to see this input type; if it doesn't, a request for this type will be dropped
1288        ///  when passed through  android.view.inputmethod.EditorInfo#makeCompatible(int)
1289        ///  EditorInfo.makeCompatible(int)}.
1290        const TYPE_NUMBER_VARIATION_NORMAL = 0;
1291        ///  Variation of TYPE_CLASS_NUMBER: entering a numeric password. This was added in
1292        ///  android.os.Build.VERSION_CODES#HONEYCOMB}.  An IME must target this API version or
1293        ///  later to see this input type; if it doesn't, a request for this type will be dropped
1294        ///  when passed through  android.view.inputmethod.EditorInfo#makeCompatible(int)
1295        ///  EditorInfo.makeCompatible(int)}.
1296        const TYPE_NUMBER_VARIATION_PASSWORD = 0x00000010;
1297        ///  Class for a phone number.  This class currently supports no variations or flags.
1298        const TYPE_CLASS_PHONE = 3;
1299        ///  Class for dates and times.  It supports the following variations:
1300        ///  #TYPE_DATETIME_VARIATION_NORMAL}  #TYPE_DATETIME_VARIATION_DATE}, and
1301        ///  #TYPE_DATETIME_VARIATION_TIME}.
1302        const TYPE_CLASS_DATETIME = 4;
1303        ///  Default variation of  #TYPE_CLASS_DATETIME}: allows entering both a date and time.
1304        const TYPE_DATETIME_VARIATION_NORMAL = 0;
1305        ///  Default variation of  #TYPE_CLASS_DATETIME}: allows entering only a date.
1306        const TYPE_DATETIME_VARIATION_DATE = 16;
1307        ///  Default variation of  #TYPE_CLASS_DATETIME}: allows entering only a time.
1308        const TYPE_DATETIME_VARIATION_TIME = 32;
1309
1310    }
1311}
1312
1313impl InputType {
1314    /// Extract just the class of the input type.
1315    pub fn class(&self) -> InputTypeClass {
1316        let class = self.bits() & InputType::TYPE_MASK_CLASS.bits();
1317        InputTypeClass::from(class)
1318    }
1319}
1320
1321/// An exclusive, lending iterator for input events
1322pub struct InputIterator<'a> {
1323    pub(crate) inner: crate::activity_impl::InputIteratorInner<'a>,
1324}
1325
1326impl InputIterator<'_> {
1327    /// Reads and handles the next input event by passing it to the given `callback`
1328    ///
1329    /// `callback` should return [`InputStatus::Unhandled`] for any input events that aren't directly
1330    /// handled by the application, or else [`InputStatus::Handled`]. Unhandled events may lead to a
1331    /// fallback interpretation of the event.
1332    pub fn next<F>(&mut self, callback: F) -> bool
1333    where
1334        F: FnOnce(&crate::activity_impl::input::InputEvent) -> InputStatus,
1335    {
1336        self.inner.next(callback)
1337    }
1338}
1339
1340/// A view into the data of a specific pointer in a motion event.
1341#[derive(Debug)]
1342pub struct Pointer<'a> {
1343    pub(crate) inner: PointerImpl<'a>,
1344}
1345
1346impl Pointer<'_> {
1347    #[inline]
1348    pub fn pointer_index(&self) -> usize {
1349        self.inner.pointer_index()
1350    }
1351
1352    #[inline]
1353    pub fn pointer_id(&self) -> i32 {
1354        self.inner.pointer_id()
1355    }
1356
1357    #[inline]
1358    pub fn axis_value(&self, axis: Axis) -> f32 {
1359        self.inner.axis_value(axis)
1360    }
1361
1362    #[inline]
1363    pub fn orientation(&self) -> f32 {
1364        self.axis_value(Axis::Orientation)
1365    }
1366
1367    #[inline]
1368    pub fn pressure(&self) -> f32 {
1369        self.axis_value(Axis::Pressure)
1370    }
1371
1372    #[inline]
1373    pub fn raw_x(&self) -> f32 {
1374        self.inner.raw_x()
1375    }
1376
1377    #[inline]
1378    pub fn raw_y(&self) -> f32 {
1379        self.inner.raw_y()
1380    }
1381
1382    #[inline]
1383    pub fn x(&self) -> f32 {
1384        self.axis_value(Axis::X)
1385    }
1386
1387    #[inline]
1388    pub fn y(&self) -> f32 {
1389        self.axis_value(Axis::Y)
1390    }
1391
1392    #[inline]
1393    pub fn size(&self) -> f32 {
1394        self.axis_value(Axis::Size)
1395    }
1396
1397    #[inline]
1398    pub fn tool_major(&self) -> f32 {
1399        self.axis_value(Axis::ToolMajor)
1400    }
1401
1402    #[inline]
1403    pub fn tool_minor(&self) -> f32 {
1404        self.axis_value(Axis::ToolMinor)
1405    }
1406
1407    #[inline]
1408    pub fn touch_major(&self) -> f32 {
1409        self.axis_value(Axis::TouchMajor)
1410    }
1411
1412    #[inline]
1413    pub fn touch_minor(&self) -> f32 {
1414        self.axis_value(Axis::TouchMinor)
1415    }
1416
1417    #[inline]
1418    pub fn tool_type(&self) -> ToolType {
1419        self.inner.tool_type()
1420    }
1421
1422    /// Gives access to the historical data of a pointer in a [`MotionEvent`].
1423    ///
1424    /// This provides access to higher-frequency data points that were recorded
1425    /// between the current event and the previous event, which can be used for
1426    /// more accurate gesture detection and smoother animations.
1427    ///
1428    /// For a single [`MotionEvent`] each pointer will have the same number of
1429    /// historical events, and the corresponding historical events will have the
1430    /// same timestamps.
1431    #[inline]
1432    pub fn history(&self) -> PointerHistoryIter<'_> {
1433        self.inner.history()
1434    }
1435}
1436
1437/// An iterator over the pointers in a [`MotionEvent`].
1438#[derive(Debug)]
1439pub struct PointersIter<'a> {
1440    pub(crate) inner: PointersIterImpl<'a>,
1441}
1442
1443impl<'a> Iterator for PointersIter<'a> {
1444    type Item = Pointer<'a>;
1445    fn next(&mut self) -> Option<Pointer<'a>> {
1446        self.inner.next()
1447    }
1448
1449    fn size_hint(&self) -> (usize, Option<usize>) {
1450        self.inner.size_hint()
1451    }
1452}
1453
1454impl ExactSizeIterator for PointersIter<'_> {}
1455
1456/// An iterator over the historical data of a pointer in a [`MotionEvent`].
1457///
1458/// This provides access to higher-frequency data points that were recorded
1459/// between the current event and the previous event, which can be used for more
1460/// accurate gesture detection and smoother animations.
1461///
1462/// For a single [`MotionEvent`] each pointer will have the same number of
1463/// historical events, and the corresponding historical events will have the
1464/// same timestamps.
1465///
1466#[derive(Debug)]
1467pub struct PointerHistoryIter<'a> {
1468    pub(crate) inner: PointerHistoryIterImpl<'a>,
1469}
1470
1471impl<'a> Iterator for PointerHistoryIter<'a> {
1472    type Item = HistoricalPointer<'a>;
1473    fn next(&mut self) -> Option<HistoricalPointer<'a>> {
1474        self.inner.next()
1475    }
1476
1477    fn size_hint(&self) -> (usize, Option<usize>) {
1478        self.inner.size_hint()
1479    }
1480}
1481impl<'a> DoubleEndedIterator for PointerHistoryIter<'a> {
1482    fn next_back(&mut self) -> Option<HistoricalPointer<'a>> {
1483        self.inner.next_back()
1484    }
1485}
1486impl ExactSizeIterator for PointerHistoryIter<'_> {}
1487impl FusedIterator for PointerHistoryIter<'_> {}
1488
1489pub struct HistoricalPointer<'a> {
1490    pub(crate) inner: HistoricalPointerImpl<'a>,
1491}
1492
1493impl HistoricalPointer<'_> {
1494    #[inline]
1495    pub fn history_index(&self) -> usize {
1496        self.inner.history_index()
1497    }
1498
1499    #[inline]
1500    pub fn pointer_index(&self) -> usize {
1501        self.inner.pointer_index()
1502    }
1503
1504    #[inline]
1505    pub fn event_time(&self) -> i64 {
1506        self.inner.event_time()
1507    }
1508
1509    #[inline]
1510    pub fn axis_value(&self, axis: Axis) -> f32 {
1511        self.inner.axis_value(axis)
1512    }
1513
1514    #[inline]
1515    pub fn orientation(&self) -> f32 {
1516        self.axis_value(Axis::Orientation)
1517    }
1518
1519    #[inline]
1520    pub fn pressure(&self) -> f32 {
1521        self.axis_value(Axis::Pressure)
1522    }
1523
1524    #[inline]
1525    pub fn x(&self) -> f32 {
1526        self.axis_value(Axis::X)
1527    }
1528
1529    #[inline]
1530    pub fn y(&self) -> f32 {
1531        self.axis_value(Axis::Y)
1532    }
1533
1534    #[inline]
1535    pub fn size(&self) -> f32 {
1536        self.axis_value(Axis::Size)
1537    }
1538
1539    #[inline]
1540    pub fn tool_major(&self) -> f32 {
1541        self.axis_value(Axis::ToolMajor)
1542    }
1543
1544    #[inline]
1545    pub fn tool_minor(&self) -> f32 {
1546        self.axis_value(Axis::ToolMinor)
1547    }
1548
1549    #[inline]
1550    pub fn touch_major(&self) -> f32 {
1551        self.axis_value(Axis::TouchMajor)
1552    }
1553
1554    #[inline]
1555    pub fn touch_minor(&self) -> f32 {
1556        self.axis_value(Axis::TouchMinor)
1557    }
1558}