1use std::ptr::NonNull;
14
15#[cfg(feature = "api-level-31")]
16use jni_sys::{jobject, JNIEnv};
17use num_enum::{FromPrimitive, IntoPrimitive};
18
19#[derive(Debug)]
23#[non_exhaustive]
24pub enum InputEvent {
25 MotionEvent(MotionEvent),
26 KeyEvent(KeyEvent),
27}
28
29#[cfg(feature = "api-level-31")]
32#[derive(Debug)]
33pub struct InputEventJava(InputEvent);
34
35#[cfg(feature = "api-level-31")]
36impl Drop for InputEventJava {
37 #[doc(alias = "AInputEvent_release")]
42 fn drop(&mut self) {
43 let ptr = match self.0 {
44 InputEvent::MotionEvent(MotionEvent { ptr })
45 | InputEvent::KeyEvent(KeyEvent { ptr }) => ptr.as_ptr().cast(),
46 };
47 unsafe { ffi::AInputEvent_release(ptr) }
48 }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
53#[repr(i32)]
54#[non_exhaustive]
55pub enum Source {
56 Unknown = ffi::AINPUT_SOURCE_UNKNOWN as i32,
57 Keyboard = ffi::AINPUT_SOURCE_KEYBOARD as i32,
58 Dpad = ffi::AINPUT_SOURCE_DPAD as i32,
59 Gamepad = ffi::AINPUT_SOURCE_GAMEPAD as i32,
60 Touchscreen = ffi::AINPUT_SOURCE_TOUCHSCREEN as i32,
61 Mouse = ffi::AINPUT_SOURCE_MOUSE as i32,
62 Stylus = ffi::AINPUT_SOURCE_STYLUS as i32,
63 BluetoothStylus = ffi::AINPUT_SOURCE_BLUETOOTH_STYLUS as i32,
64 Trackball = ffi::AINPUT_SOURCE_TRACKBALL as i32,
65 MouseRelative = ffi::AINPUT_SOURCE_MOUSE_RELATIVE as i32,
66 Touchpad = ffi::AINPUT_SOURCE_TOUCHPAD as i32,
67 TouchNavigation = ffi::AINPUT_SOURCE_TOUCH_NAVIGATION as i32,
68 Joystick = ffi::AINPUT_SOURCE_JOYSTICK as i32,
69 Hdmi = ffi::AINPUT_SOURCE_HDMI as i32,
70 Sensor = ffi::AINPUT_SOURCE_SENSOR as i32,
71 RotaryEncoder = ffi::AINPUT_SOURCE_ROTARY_ENCODER as i32,
72 Any = ffi::AINPUT_SOURCE_ANY as i32,
73
74 #[doc(hidden)]
75 #[num_enum(catch_all)]
76 __Unknown(i32),
77}
78
79impl Source {
80 pub fn class(self) -> SourceClass {
81 let class = i32::from(self) & ffi::AINPUT_SOURCE_CLASS_MASK as i32;
82 SourceClass::from_bits_retain(class as u8)
84 }
85}
86
87bitflags::bitflags! {
88 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
90 pub struct SourceClass : u8 {
91 #[doc(alias = "AINPUT_SOURCE_CLASS_BUTTON")]
92 const BUTTON = ffi::AINPUT_SOURCE_CLASS_BUTTON as u8;
93 #[doc(alias = "AINPUT_SOURCE_CLASS_POINTER")]
94 const POINTER = ffi::AINPUT_SOURCE_CLASS_POINTER as u8;
95 #[doc(alias = "AINPUT_SOURCE_CLASS_NAVIGATION")]
96 const NAVIGATION = ffi::AINPUT_SOURCE_CLASS_NAVIGATION as u8;
97 #[doc(alias = "AINPUT_SOURCE_CLASS_POSITION")]
98 const POSITION = ffi::AINPUT_SOURCE_CLASS_POSITION as u8;
99 #[doc(alias = "AINPUT_SOURCE_CLASS_JOYSTICK")]
100 const JOYSTICK = ffi::AINPUT_SOURCE_CLASS_JOYSTICK as u8;
101
102 const _ = ffi::AINPUT_SOURCE_CLASS_MASK as u8;
104 }
105}
106
107impl InputEvent {
108 #[inline]
114 pub unsafe fn from_ptr(ptr: NonNull<ffi::AInputEvent>) -> Self {
115 match ffi::AInputEvent_getType(ptr.as_ptr()) as u32 {
116 ffi::AINPUT_EVENT_TYPE_KEY => InputEvent::KeyEvent(KeyEvent::from_ptr(ptr)),
117 ffi::AINPUT_EVENT_TYPE_MOTION => InputEvent::MotionEvent(MotionEvent::from_ptr(ptr)),
118 x => panic!("Bad event type received: {}", x),
119 }
120 }
121
122 #[inline]
124 pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
125 match self {
126 InputEvent::MotionEvent(MotionEvent { ptr }) => *ptr,
127 InputEvent::KeyEvent(KeyEvent { ptr }) => *ptr,
128 }
129 }
130
131 #[inline]
136 pub fn source(&self) -> Source {
137 let source = unsafe { ffi::AInputEvent_getSource(self.ptr().as_ptr()) };
138 source.into()
139 }
140
141 #[inline]
146 pub fn device_id(&self) -> i32 {
147 unsafe { ffi::AInputEvent_getDeviceId(self.ptr().as_ptr()) }
148 }
149}
150
151#[derive(Copy, Clone, Debug, PartialEq, Eq)]
153pub struct MetaState(pub u32);
154
155impl MetaState {
156 #[inline]
157 pub fn alt_on(self) -> bool {
158 self.0 & ffi::AMETA_ALT_ON != 0
159 }
160 #[inline]
161 pub fn alt_left_on(self) -> bool {
162 self.0 & ffi::AMETA_ALT_LEFT_ON != 0
163 }
164 #[inline]
165 pub fn alt_right_on(self) -> bool {
166 self.0 & ffi::AMETA_ALT_RIGHT_ON != 0
167 }
168 #[inline]
169 pub fn shift_on(self) -> bool {
170 self.0 & ffi::AMETA_SHIFT_ON != 0
171 }
172 #[inline]
173 pub fn shift_left_on(self) -> bool {
174 self.0 & ffi::AMETA_SHIFT_LEFT_ON != 0
175 }
176 #[inline]
177 pub fn shift_right_on(self) -> bool {
178 self.0 & ffi::AMETA_SHIFT_RIGHT_ON != 0
179 }
180 #[inline]
181 pub fn sym_on(self) -> bool {
182 self.0 & ffi::AMETA_SYM_ON != 0
183 }
184 #[inline]
185 pub fn function_on(self) -> bool {
186 self.0 & ffi::AMETA_FUNCTION_ON != 0
187 }
188 #[inline]
189 pub fn ctrl_on(self) -> bool {
190 self.0 & ffi::AMETA_CTRL_ON != 0
191 }
192 #[inline]
193 pub fn ctrl_left_on(self) -> bool {
194 self.0 & ffi::AMETA_CTRL_LEFT_ON != 0
195 }
196 #[inline]
197 pub fn ctrl_right_on(self) -> bool {
198 self.0 & ffi::AMETA_CTRL_RIGHT_ON != 0
199 }
200 #[inline]
201 pub fn meta_on(self) -> bool {
202 self.0 & ffi::AMETA_META_ON != 0
203 }
204 #[inline]
205 pub fn meta_left_on(self) -> bool {
206 self.0 & ffi::AMETA_META_LEFT_ON != 0
207 }
208 #[inline]
209 pub fn meta_right_on(self) -> bool {
210 self.0 & ffi::AMETA_META_RIGHT_ON != 0
211 }
212 #[inline]
213 pub fn caps_lock_on(self) -> bool {
214 self.0 & ffi::AMETA_CAPS_LOCK_ON != 0
215 }
216 #[inline]
217 pub fn num_lock_on(self) -> bool {
218 self.0 & ffi::AMETA_NUM_LOCK_ON != 0
219 }
220 #[inline]
221 pub fn scroll_lock_on(self) -> bool {
222 self.0 & ffi::AMETA_SCROLL_LOCK_ON != 0
223 }
224}
225
226#[derive(Clone, Debug)]
235pub struct MotionEvent {
236 ptr: NonNull<ffi::AInputEvent>,
237}
238
239#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
243#[repr(i32)]
244#[non_exhaustive]
245pub enum MotionAction {
246 Down = ffi::AMOTION_EVENT_ACTION_DOWN as i32,
247 Up = ffi::AMOTION_EVENT_ACTION_UP as i32,
248 Move = ffi::AMOTION_EVENT_ACTION_MOVE as i32,
249 Cancel = ffi::AMOTION_EVENT_ACTION_CANCEL as i32,
250 Outside = ffi::AMOTION_EVENT_ACTION_OUTSIDE as i32,
251 PointerDown = ffi::AMOTION_EVENT_ACTION_POINTER_DOWN as i32,
252 PointerUp = ffi::AMOTION_EVENT_ACTION_POINTER_UP as i32,
253 HoverMove = ffi::AMOTION_EVENT_ACTION_HOVER_MOVE as i32,
254 Scroll = ffi::AMOTION_EVENT_ACTION_SCROLL as i32,
255 HoverEnter = ffi::AMOTION_EVENT_ACTION_HOVER_ENTER as i32,
256 HoverExit = ffi::AMOTION_EVENT_ACTION_HOVER_EXIT as i32,
257 ButtonPress = ffi::AMOTION_EVENT_ACTION_BUTTON_PRESS as i32,
258 ButtonRelease = ffi::AMOTION_EVENT_ACTION_BUTTON_RELEASE as i32,
259
260 #[doc(hidden)]
261 #[num_enum(catch_all)]
262 __Unknown(i32),
263}
264
265#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
267#[repr(i32)]
268#[non_exhaustive]
269pub enum Axis {
270 X = ffi::AMOTION_EVENT_AXIS_X as i32,
271 Y = ffi::AMOTION_EVENT_AXIS_Y as i32,
272 Pressure = ffi::AMOTION_EVENT_AXIS_PRESSURE as i32,
273 Size = ffi::AMOTION_EVENT_AXIS_SIZE as i32,
274 TouchMajor = ffi::AMOTION_EVENT_AXIS_TOUCH_MAJOR as i32,
275 TouchMinor = ffi::AMOTION_EVENT_AXIS_TOUCH_MINOR as i32,
276 ToolMajor = ffi::AMOTION_EVENT_AXIS_TOOL_MAJOR as i32,
277 ToolMinor = ffi::AMOTION_EVENT_AXIS_TOOL_MINOR as i32,
278 Orientation = ffi::AMOTION_EVENT_AXIS_ORIENTATION as i32,
279 Vscroll = ffi::AMOTION_EVENT_AXIS_VSCROLL as i32,
280 Hscroll = ffi::AMOTION_EVENT_AXIS_HSCROLL as i32,
281 Z = ffi::AMOTION_EVENT_AXIS_Z as i32,
282 Rx = ffi::AMOTION_EVENT_AXIS_RX as i32,
283 Ry = ffi::AMOTION_EVENT_AXIS_RY as i32,
284 Rz = ffi::AMOTION_EVENT_AXIS_RZ as i32,
285 HatX = ffi::AMOTION_EVENT_AXIS_HAT_X as i32,
286 HatY = ffi::AMOTION_EVENT_AXIS_HAT_Y as i32,
287 Ltrigger = ffi::AMOTION_EVENT_AXIS_LTRIGGER as i32,
288 Rtrigger = ffi::AMOTION_EVENT_AXIS_RTRIGGER as i32,
289 Throttle = ffi::AMOTION_EVENT_AXIS_THROTTLE as i32,
290 Rudder = ffi::AMOTION_EVENT_AXIS_RUDDER as i32,
291 Wheel = ffi::AMOTION_EVENT_AXIS_WHEEL as i32,
292 Gas = ffi::AMOTION_EVENT_AXIS_GAS as i32,
293 Brake = ffi::AMOTION_EVENT_AXIS_BRAKE as i32,
294 Distance = ffi::AMOTION_EVENT_AXIS_DISTANCE as i32,
295 Tilt = ffi::AMOTION_EVENT_AXIS_TILT as i32,
296 Scroll = ffi::AMOTION_EVENT_AXIS_SCROLL as i32,
297 RelativeX = ffi::AMOTION_EVENT_AXIS_RELATIVE_X as i32,
298 RelativeY = ffi::AMOTION_EVENT_AXIS_RELATIVE_Y as i32,
299 Generic1 = ffi::AMOTION_EVENT_AXIS_GENERIC_1 as i32,
300 Generic2 = ffi::AMOTION_EVENT_AXIS_GENERIC_2 as i32,
301 Generic3 = ffi::AMOTION_EVENT_AXIS_GENERIC_3 as i32,
302 Generic4 = ffi::AMOTION_EVENT_AXIS_GENERIC_4 as i32,
303 Generic5 = ffi::AMOTION_EVENT_AXIS_GENERIC_5 as i32,
304 Generic6 = ffi::AMOTION_EVENT_AXIS_GENERIC_6 as i32,
305 Generic7 = ffi::AMOTION_EVENT_AXIS_GENERIC_7 as i32,
306 Generic8 = ffi::AMOTION_EVENT_AXIS_GENERIC_8 as i32,
307 Generic9 = ffi::AMOTION_EVENT_AXIS_GENERIC_9 as i32,
308 Generic10 = ffi::AMOTION_EVENT_AXIS_GENERIC_10 as i32,
309 Generic11 = ffi::AMOTION_EVENT_AXIS_GENERIC_11 as i32,
310 Generic12 = ffi::AMOTION_EVENT_AXIS_GENERIC_12 as i32,
311 Generic13 = ffi::AMOTION_EVENT_AXIS_GENERIC_13 as i32,
312 Generic14 = ffi::AMOTION_EVENT_AXIS_GENERIC_14 as i32,
313 Generic15 = ffi::AMOTION_EVENT_AXIS_GENERIC_15 as i32,
314 Generic16 = ffi::AMOTION_EVENT_AXIS_GENERIC_16 as i32,
315
316 #[doc(hidden)]
317 #[num_enum(catch_all)]
318 __Unknown(i32),
319}
320
321#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
323#[repr(i32)]
324#[non_exhaustive]
325pub enum ToolType {
326 Unknown = ffi::AMOTION_EVENT_TOOL_TYPE_UNKNOWN as i32,
327 Finger = ffi::AMOTION_EVENT_TOOL_TYPE_FINGER as i32,
328 Stylus = ffi::AMOTION_EVENT_TOOL_TYPE_STYLUS as i32,
329 Mouse = ffi::AMOTION_EVENT_TOOL_TYPE_MOUSE as i32,
330 Eraser = ffi::AMOTION_EVENT_TOOL_TYPE_ERASER as i32,
331 Palm = ffi::AMOTION_EVENT_TOOL_TYPE_PALM as i32,
332
333 #[doc(hidden)]
334 #[num_enum(catch_all)]
335 __Unknown(i32),
336}
337
338#[derive(Copy, Clone, Debug, PartialEq, Eq)]
340pub struct ButtonState(pub u32);
341
342impl ButtonState {
343 #[inline]
344 pub fn primary(self) -> bool {
345 self.0 & ffi::AMOTION_EVENT_BUTTON_PRIMARY != 0
346 }
347 #[inline]
348 pub fn secondary(self) -> bool {
349 self.0 & ffi::AMOTION_EVENT_BUTTON_SECONDARY != 0
350 }
351 #[inline]
352 pub fn teriary(self) -> bool {
353 self.0 & ffi::AMOTION_EVENT_BUTTON_TERTIARY != 0
354 }
355 #[inline]
356 pub fn back(self) -> bool {
357 self.0 & ffi::AMOTION_EVENT_BUTTON_BACK != 0
358 }
359 #[inline]
360 pub fn forward(self) -> bool {
361 self.0 & ffi::AMOTION_EVENT_BUTTON_FORWARD != 0
362 }
363 #[inline]
364 pub fn stylus_primary(self) -> bool {
365 self.0 & ffi::AMOTION_EVENT_BUTTON_STYLUS_PRIMARY != 0
366 }
367 #[inline]
368 pub fn stylus_secondary(self) -> bool {
369 self.0 & ffi::AMOTION_EVENT_BUTTON_STYLUS_SECONDARY != 0
370 }
371}
372
373#[derive(Copy, Clone, Debug, PartialEq, Eq)]
375pub struct EdgeFlags(pub u32);
376
377impl EdgeFlags {
378 #[inline]
379 pub fn top(self) -> bool {
380 self.0 & ffi::AMOTION_EVENT_EDGE_FLAG_TOP != 0
381 }
382 #[inline]
383 pub fn bottom(self) -> bool {
384 self.0 & ffi::AMOTION_EVENT_EDGE_FLAG_BOTTOM != 0
385 }
386 #[inline]
387 pub fn left(self) -> bool {
388 self.0 & ffi::AMOTION_EVENT_EDGE_FLAG_LEFT != 0
389 }
390 #[inline]
391 pub fn right(self) -> bool {
392 self.0 & ffi::AMOTION_EVENT_EDGE_FLAG_RIGHT != 0
393 }
394}
395
396#[derive(Copy, Clone, Debug, PartialEq, Eq)]
398pub struct MotionEventFlags(pub u32);
399
400impl MotionEventFlags {
401 #[inline]
402 pub fn window_is_obscured(self) -> bool {
403 self.0 & ffi::AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED != 0
404 }
405}
406
407impl MotionEvent {
408 #[inline]
415 pub unsafe fn from_ptr(ptr: NonNull<ffi::AInputEvent>) -> Self {
416 Self { ptr }
417 }
418
419 #[cfg(feature = "api-level-31")]
430 #[doc(alias = "AMotionEvent_fromJava")]
431 pub unsafe fn from_java(env: *mut JNIEnv, key_event: jobject) -> Option<InputEventJava> {
432 let ptr = unsafe { ffi::AMotionEvent_fromJava(env, key_event) };
433 Some(InputEventJava(InputEvent::MotionEvent(Self::from_ptr(
434 NonNull::new(ptr.cast_mut())?,
435 ))))
436 }
437
438 #[inline]
440 pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
441 self.ptr
442 }
443
444 #[inline]
449 pub fn source(&self) -> Source {
450 let source = unsafe { ffi::AInputEvent_getSource(self.ptr.as_ptr()) };
451 source.into()
452 }
453
454 #[inline]
459 pub fn device_id(&self) -> i32 {
460 unsafe { ffi::AInputEvent_getDeviceId(self.ptr.as_ptr()) }
461 }
462
463 #[inline]
468 pub fn action(&self) -> MotionAction {
469 let action = unsafe { ffi::AMotionEvent_getAction(self.ptr.as_ptr()) }
470 & ffi::AMOTION_EVENT_ACTION_MASK as i32;
471 action.into()
472 }
473
474 #[inline]
483 pub fn pointer_index(&self) -> usize {
484 let action = unsafe { ffi::AMotionEvent_getAction(self.ptr.as_ptr()) as u32 };
485 let index = (action & ffi::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
486 >> ffi::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
487 index as usize
488 }
489
490 #[inline]
507 pub fn pointer_count(&self) -> usize {
508 unsafe { ffi::AMotionEvent_getPointerCount(self.ptr.as_ptr()) }
509 }
510
511 #[inline]
513 pub fn pointers(&self) -> PointersIter<'_> {
514 PointersIter {
515 event: self.ptr,
516 next_index: 0,
517 count: self.pointer_count(),
518 _marker: std::marker::PhantomData,
519 }
520 }
521
522 #[inline]
526 pub fn pointer_at_index(&self, index: usize) -> Pointer<'_> {
527 if index >= self.pointer_count() {
528 panic!("Pointer index {} is out of bounds", index);
529 }
530 Pointer {
531 event: self.ptr,
532 index,
533 _marker: std::marker::PhantomData,
534 }
535 }
536
537 #[inline]
542 pub fn history_size(&self) -> usize {
543 unsafe { ffi::AMotionEvent_getHistorySize(self.ptr.as_ptr()) }
544 }
545
546 #[inline]
548 pub fn history(&self) -> HistoricalMotionEventsIter<'_> {
549 HistoricalMotionEventsIter {
550 event: self.ptr,
551 next_history_index: 0,
552 history_size: self.history_size(),
553 _marker: std::marker::PhantomData,
554 }
555 }
556
557 #[inline]
562 pub fn meta_state(&self) -> MetaState {
563 unsafe { MetaState(ffi::AMotionEvent_getMetaState(self.ptr.as_ptr()) as u32) }
564 }
565
566 #[inline]
571 pub fn button_state(&self) -> ButtonState {
572 unsafe { ButtonState(ffi::AMotionEvent_getButtonState(self.ptr.as_ptr()) as u32) }
573 }
574
575 #[inline]
581 pub fn down_time(&self) -> i64 {
582 unsafe { ffi::AMotionEvent_getDownTime(self.ptr.as_ptr()) }
583 }
584
585 #[inline]
590 pub fn edge_flags(&self) -> EdgeFlags {
591 unsafe { EdgeFlags(ffi::AMotionEvent_getEdgeFlags(self.ptr.as_ptr()) as u32) }
592 }
593
594 #[inline]
599 pub fn event_time(&self) -> i64 {
600 unsafe { ffi::AMotionEvent_getEventTime(self.ptr.as_ptr()) }
601 }
602
603 #[inline]
608 pub fn flags(&self) -> MotionEventFlags {
609 unsafe { MotionEventFlags(ffi::AMotionEvent_getFlags(self.ptr.as_ptr()) as u32) }
610 }
611
612 #[inline]
617 pub fn x_offset(&self) -> f32 {
618 unsafe { ffi::AMotionEvent_getXOffset(self.ptr.as_ptr()) }
619 }
620
621 #[inline]
626 pub fn y_offset(&self) -> f32 {
627 unsafe { ffi::AMotionEvent_getYOffset(self.ptr.as_ptr()) }
628 }
629
630 #[inline]
635 pub fn x_precision(&self) -> f32 {
636 unsafe { ffi::AMotionEvent_getXPrecision(self.ptr.as_ptr()) }
637 }
638
639 #[inline]
644 pub fn y_precision(&self) -> f32 {
645 unsafe { ffi::AMotionEvent_getYPrecision(self.ptr.as_ptr()) }
646 }
647}
648
649#[derive(Debug)]
651pub struct Pointer<'a> {
652 event: NonNull<ffi::AInputEvent>,
653 index: usize,
654 _marker: std::marker::PhantomData<&'a MotionEvent>,
655}
656
657impl<'a> Pointer<'a> {
660 #[inline]
661 pub fn pointer_index(&self) -> usize {
662 self.index
663 }
664
665 #[inline]
666 pub fn pointer_id(&self) -> i32 {
667 unsafe { ffi::AMotionEvent_getPointerId(self.event.as_ptr(), self.index) }
668 }
669
670 #[inline]
671 pub fn axis_value(&self, axis: Axis) -> f32 {
672 unsafe { ffi::AMotionEvent_getAxisValue(self.event.as_ptr(), axis.into(), self.index) }
673 }
674
675 #[inline]
676 pub fn orientation(&self) -> f32 {
677 unsafe { ffi::AMotionEvent_getOrientation(self.event.as_ptr(), self.index) }
678 }
679
680 #[inline]
681 pub fn pressure(&self) -> f32 {
682 unsafe { ffi::AMotionEvent_getPressure(self.event.as_ptr(), self.index) }
683 }
684
685 #[inline]
686 pub fn raw_x(&self) -> f32 {
687 unsafe { ffi::AMotionEvent_getRawX(self.event.as_ptr(), self.index) }
688 }
689
690 #[inline]
691 pub fn raw_y(&self) -> f32 {
692 unsafe { ffi::AMotionEvent_getRawY(self.event.as_ptr(), self.index) }
693 }
694
695 #[inline]
696 pub fn x(&self) -> f32 {
697 unsafe { ffi::AMotionEvent_getX(self.event.as_ptr(), self.index) }
698 }
699
700 #[inline]
701 pub fn y(&self) -> f32 {
702 unsafe { ffi::AMotionEvent_getY(self.event.as_ptr(), self.index) }
703 }
704
705 #[inline]
706 pub fn size(&self) -> f32 {
707 unsafe { ffi::AMotionEvent_getSize(self.event.as_ptr(), self.index) }
708 }
709
710 #[inline]
711 pub fn tool_major(&self) -> f32 {
712 unsafe { ffi::AMotionEvent_getToolMajor(self.event.as_ptr(), self.index) }
713 }
714
715 #[inline]
716 pub fn tool_minor(&self) -> f32 {
717 unsafe { ffi::AMotionEvent_getToolMinor(self.event.as_ptr(), self.index) }
718 }
719
720 #[inline]
721 pub fn touch_major(&self) -> f32 {
722 unsafe { ffi::AMotionEvent_getTouchMajor(self.event.as_ptr(), self.index) }
723 }
724
725 #[inline]
726 pub fn touch_minor(&self) -> f32 {
727 unsafe { ffi::AMotionEvent_getTouchMinor(self.event.as_ptr(), self.index) }
728 }
729
730 #[inline]
731 pub fn tool_type(&self) -> ToolType {
732 let tool_type = unsafe { ffi::AMotionEvent_getToolType(self.event.as_ptr(), self.index) };
733 tool_type.into()
734 }
735}
736
737#[derive(Debug)]
739pub struct PointersIter<'a> {
740 event: NonNull<ffi::AInputEvent>,
741 next_index: usize,
742 count: usize,
743 _marker: std::marker::PhantomData<&'a MotionEvent>,
744}
745
746impl<'a> Iterator for PointersIter<'a> {
749 type Item = Pointer<'a>;
750 fn next(&mut self) -> Option<Pointer<'a>> {
751 if self.next_index < self.count {
752 let ptr = Pointer {
753 event: self.event,
754 index: self.next_index,
755 _marker: std::marker::PhantomData,
756 };
757 self.next_index += 1;
758 Some(ptr)
759 } else {
760 None
761 }
762 }
763
764 fn size_hint(&self) -> (usize, Option<usize>) {
765 let size = self.count - self.next_index;
766 (size, Some(size))
767 }
768}
769impl<'a> ExactSizeIterator for PointersIter<'a> {
770 fn len(&self) -> usize {
771 self.count - self.next_index
772 }
773}
774
775#[derive(Debug)]
777pub struct HistoricalMotionEvent<'a> {
778 event: NonNull<ffi::AInputEvent>,
779 history_index: usize,
780 _marker: std::marker::PhantomData<&'a MotionEvent>,
781}
782
783impl<'a> HistoricalMotionEvent<'a> {
786 #[inline]
788 pub fn history_index(&self) -> usize {
789 self.history_index
790 }
791
792 #[inline]
797 pub fn event_time(&self) -> i64 {
798 unsafe { ffi::AMotionEvent_getHistoricalEventTime(self.event.as_ptr(), self.history_index) }
799 }
800
801 #[inline]
803 pub fn pointers(&self) -> HistoricalPointersIter<'a> {
804 HistoricalPointersIter {
805 event: self.event,
806 history_index: self.history_index,
807 next_pointer_index: 0,
808 pointer_count: unsafe { ffi::AMotionEvent_getPointerCount(self.event.as_ptr()) },
809 _marker: std::marker::PhantomData,
810 }
811 }
812}
813
814#[derive(Debug)]
818pub struct HistoricalMotionEventsIter<'a> {
819 event: NonNull<ffi::AInputEvent>,
820 next_history_index: usize,
821 history_size: usize,
822 _marker: std::marker::PhantomData<&'a MotionEvent>,
823}
824
825impl<'a> Iterator for HistoricalMotionEventsIter<'a> {
828 type Item = HistoricalMotionEvent<'a>;
829
830 fn next(&mut self) -> Option<HistoricalMotionEvent<'a>> {
831 if self.next_history_index < self.history_size {
832 let res = HistoricalMotionEvent {
833 event: self.event,
834 history_index: self.next_history_index,
835 _marker: std::marker::PhantomData,
836 };
837 self.next_history_index += 1;
838 Some(res)
839 } else {
840 None
841 }
842 }
843
844 fn size_hint(&self) -> (usize, Option<usize>) {
845 let size = self.history_size - self.next_history_index;
846 (size, Some(size))
847 }
848}
849impl ExactSizeIterator for HistoricalMotionEventsIter<'_> {
850 fn len(&self) -> usize {
851 self.history_size - self.next_history_index
852 }
853}
854impl<'a> DoubleEndedIterator for HistoricalMotionEventsIter<'a> {
855 fn next_back(&mut self) -> Option<HistoricalMotionEvent<'a>> {
856 if self.next_history_index < self.history_size {
857 self.history_size -= 1;
858 Some(HistoricalMotionEvent {
859 event: self.event,
860 history_index: self.history_size,
861 _marker: std::marker::PhantomData,
862 })
863 } else {
864 None
865 }
866 }
867}
868
869#[derive(Debug)]
871pub struct HistoricalPointer<'a> {
872 event: NonNull<ffi::AInputEvent>,
873 pointer_index: usize,
874 history_index: usize,
875 _marker: std::marker::PhantomData<&'a MotionEvent>,
876}
877
878impl<'a> HistoricalPointer<'a> {
881 #[inline]
882 pub fn pointer_index(&self) -> usize {
883 self.pointer_index
884 }
885
886 #[inline]
887 pub fn pointer_id(&self) -> i32 {
888 unsafe { ffi::AMotionEvent_getPointerId(self.event.as_ptr(), self.pointer_index) }
889 }
890
891 #[inline]
892 pub fn history_index(&self) -> usize {
893 self.history_index
894 }
895
896 #[inline]
897 pub fn axis_value(&self, axis: Axis) -> f32 {
898 unsafe {
899 ffi::AMotionEvent_getHistoricalAxisValue(
900 self.event.as_ptr(),
901 axis.into(),
902 self.pointer_index,
903 self.history_index,
904 )
905 }
906 }
907
908 #[inline]
909 pub fn orientation(&self) -> f32 {
910 unsafe {
911 ffi::AMotionEvent_getHistoricalOrientation(
912 self.event.as_ptr(),
913 self.pointer_index,
914 self.history_index,
915 )
916 }
917 }
918
919 #[inline]
920 pub fn pressure(&self) -> f32 {
921 unsafe {
922 ffi::AMotionEvent_getHistoricalPressure(
923 self.event.as_ptr(),
924 self.pointer_index,
925 self.history_index,
926 )
927 }
928 }
929
930 #[inline]
931 pub fn raw_x(&self) -> f32 {
932 unsafe {
933 ffi::AMotionEvent_getHistoricalRawX(
934 self.event.as_ptr(),
935 self.pointer_index,
936 self.history_index,
937 )
938 }
939 }
940
941 #[inline]
942 pub fn raw_y(&self) -> f32 {
943 unsafe {
944 ffi::AMotionEvent_getHistoricalRawY(
945 self.event.as_ptr(),
946 self.pointer_index,
947 self.history_index,
948 )
949 }
950 }
951
952 #[inline]
953 pub fn x(&self) -> f32 {
954 unsafe {
955 ffi::AMotionEvent_getHistoricalX(
956 self.event.as_ptr(),
957 self.pointer_index,
958 self.history_index,
959 )
960 }
961 }
962
963 #[inline]
964 pub fn y(&self) -> f32 {
965 unsafe {
966 ffi::AMotionEvent_getHistoricalY(
967 self.event.as_ptr(),
968 self.pointer_index,
969 self.history_index,
970 )
971 }
972 }
973
974 #[inline]
975 pub fn size(&self) -> f32 {
976 unsafe {
977 ffi::AMotionEvent_getHistoricalSize(
978 self.event.as_ptr(),
979 self.pointer_index,
980 self.history_index,
981 )
982 }
983 }
984
985 #[inline]
986 pub fn tool_major(&self) -> f32 {
987 unsafe {
988 ffi::AMotionEvent_getHistoricalToolMajor(
989 self.event.as_ptr(),
990 self.pointer_index,
991 self.history_index,
992 )
993 }
994 }
995
996 #[inline]
997 pub fn tool_minor(&self) -> f32 {
998 unsafe {
999 ffi::AMotionEvent_getHistoricalToolMinor(
1000 self.event.as_ptr(),
1001 self.pointer_index,
1002 self.history_index,
1003 )
1004 }
1005 }
1006
1007 #[inline]
1008 pub fn touch_major(&self) -> f32 {
1009 unsafe {
1010 ffi::AMotionEvent_getHistoricalTouchMajor(
1011 self.event.as_ptr(),
1012 self.pointer_index,
1013 self.history_index,
1014 )
1015 }
1016 }
1017
1018 #[inline]
1019 pub fn touch_minor(&self) -> f32 {
1020 unsafe {
1021 ffi::AMotionEvent_getHistoricalTouchMinor(
1022 self.event.as_ptr(),
1023 self.pointer_index,
1024 self.history_index,
1025 )
1026 }
1027 }
1028}
1029
1030#[derive(Debug)]
1032pub struct HistoricalPointersIter<'a> {
1033 event: NonNull<ffi::AInputEvent>,
1034 history_index: usize,
1035 next_pointer_index: usize,
1036 pointer_count: usize,
1037 _marker: std::marker::PhantomData<&'a MotionEvent>,
1038}
1039
1040impl<'a> Iterator for HistoricalPointersIter<'a> {
1043 type Item = HistoricalPointer<'a>;
1044
1045 fn next(&mut self) -> Option<HistoricalPointer<'a>> {
1046 if self.next_pointer_index < self.pointer_count {
1047 let ptr = HistoricalPointer {
1048 event: self.event,
1049 history_index: self.history_index,
1050 pointer_index: self.next_pointer_index,
1051 _marker: std::marker::PhantomData,
1052 };
1053 self.next_pointer_index += 1;
1054 Some(ptr)
1055 } else {
1056 None
1057 }
1058 }
1059
1060 fn size_hint(&self) -> (usize, Option<usize>) {
1061 let size = self.pointer_count - self.next_pointer_index;
1062 (size, Some(size))
1063 }
1064}
1065impl ExactSizeIterator for HistoricalPointersIter<'_> {
1066 fn len(&self) -> usize {
1067 self.pointer_count - self.next_pointer_index
1068 }
1069}
1070
1071#[derive(Debug)]
1080pub struct KeyEvent {
1081 ptr: NonNull<ffi::AInputEvent>,
1082}
1083
1084#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
1089#[repr(i32)]
1090#[non_exhaustive]
1091pub enum KeyAction {
1092 Down = ffi::AKEY_EVENT_ACTION_DOWN as i32,
1093 Up = ffi::AKEY_EVENT_ACTION_UP as i32,
1094 Multiple = ffi::AKEY_EVENT_ACTION_MULTIPLE as i32,
1095
1096 #[doc(hidden)]
1097 #[num_enum(catch_all)]
1098 __Unknown(i32),
1099}
1100
1101#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
1103#[repr(i32)]
1104#[non_exhaustive]
1105pub enum Keycode {
1106 Unknown = ffi::AKEYCODE_UNKNOWN as i32,
1107 SoftLeft = ffi::AKEYCODE_SOFT_LEFT as i32,
1108 SoftRight = ffi::AKEYCODE_SOFT_RIGHT as i32,
1109 Home = ffi::AKEYCODE_HOME as i32,
1110 Back = ffi::AKEYCODE_BACK as i32,
1111 Call = ffi::AKEYCODE_CALL as i32,
1112 Endcall = ffi::AKEYCODE_ENDCALL as i32,
1113 Keycode0 = ffi::AKEYCODE_0 as i32,
1114 Keycode1 = ffi::AKEYCODE_1 as i32,
1115 Keycode2 = ffi::AKEYCODE_2 as i32,
1116 Keycode3 = ffi::AKEYCODE_3 as i32,
1117 Keycode4 = ffi::AKEYCODE_4 as i32,
1118 Keycode5 = ffi::AKEYCODE_5 as i32,
1119 Keycode6 = ffi::AKEYCODE_6 as i32,
1120 Keycode7 = ffi::AKEYCODE_7 as i32,
1121 Keycode8 = ffi::AKEYCODE_8 as i32,
1122 Keycode9 = ffi::AKEYCODE_9 as i32,
1123 Star = ffi::AKEYCODE_STAR as i32,
1124 Pound = ffi::AKEYCODE_POUND as i32,
1125 DpadUp = ffi::AKEYCODE_DPAD_UP as i32,
1126 DpadDown = ffi::AKEYCODE_DPAD_DOWN as i32,
1127 DpadLeft = ffi::AKEYCODE_DPAD_LEFT as i32,
1128 DpadRight = ffi::AKEYCODE_DPAD_RIGHT as i32,
1129 DpadCenter = ffi::AKEYCODE_DPAD_CENTER as i32,
1130 VolumeUp = ffi::AKEYCODE_VOLUME_UP as i32,
1131 VolumeDown = ffi::AKEYCODE_VOLUME_DOWN as i32,
1132 Power = ffi::AKEYCODE_POWER as i32,
1133 Camera = ffi::AKEYCODE_CAMERA as i32,
1134 Clear = ffi::AKEYCODE_CLEAR as i32,
1135 A = ffi::AKEYCODE_A as i32,
1136 B = ffi::AKEYCODE_B as i32,
1137 C = ffi::AKEYCODE_C as i32,
1138 D = ffi::AKEYCODE_D as i32,
1139 E = ffi::AKEYCODE_E as i32,
1140 F = ffi::AKEYCODE_F as i32,
1141 G = ffi::AKEYCODE_G as i32,
1142 H = ffi::AKEYCODE_H as i32,
1143 I = ffi::AKEYCODE_I as i32,
1144 J = ffi::AKEYCODE_J as i32,
1145 K = ffi::AKEYCODE_K as i32,
1146 L = ffi::AKEYCODE_L as i32,
1147 M = ffi::AKEYCODE_M as i32,
1148 N = ffi::AKEYCODE_N as i32,
1149 O = ffi::AKEYCODE_O as i32,
1150 P = ffi::AKEYCODE_P as i32,
1151 Q = ffi::AKEYCODE_Q as i32,
1152 R = ffi::AKEYCODE_R as i32,
1153 S = ffi::AKEYCODE_S as i32,
1154 T = ffi::AKEYCODE_T as i32,
1155 U = ffi::AKEYCODE_U as i32,
1156 V = ffi::AKEYCODE_V as i32,
1157 W = ffi::AKEYCODE_W as i32,
1158 X = ffi::AKEYCODE_X as i32,
1159 Y = ffi::AKEYCODE_Y as i32,
1160 Z = ffi::AKEYCODE_Z as i32,
1161 Comma = ffi::AKEYCODE_COMMA as i32,
1162 Period = ffi::AKEYCODE_PERIOD as i32,
1163 AltLeft = ffi::AKEYCODE_ALT_LEFT as i32,
1164 AltRight = ffi::AKEYCODE_ALT_RIGHT as i32,
1165 ShiftLeft = ffi::AKEYCODE_SHIFT_LEFT as i32,
1166 ShiftRight = ffi::AKEYCODE_SHIFT_RIGHT as i32,
1167 Tab = ffi::AKEYCODE_TAB as i32,
1168 Space = ffi::AKEYCODE_SPACE as i32,
1169 Sym = ffi::AKEYCODE_SYM as i32,
1170 Explorer = ffi::AKEYCODE_EXPLORER as i32,
1171 Envelope = ffi::AKEYCODE_ENVELOPE as i32,
1172 Enter = ffi::AKEYCODE_ENTER as i32,
1173 Del = ffi::AKEYCODE_DEL as i32,
1174 Grave = ffi::AKEYCODE_GRAVE as i32,
1175 Minus = ffi::AKEYCODE_MINUS as i32,
1176 Equals = ffi::AKEYCODE_EQUALS as i32,
1177 LeftBracket = ffi::AKEYCODE_LEFT_BRACKET as i32,
1178 RightBracket = ffi::AKEYCODE_RIGHT_BRACKET as i32,
1179 Backslash = ffi::AKEYCODE_BACKSLASH as i32,
1180 Semicolon = ffi::AKEYCODE_SEMICOLON as i32,
1181 Apostrophe = ffi::AKEYCODE_APOSTROPHE as i32,
1182 Slash = ffi::AKEYCODE_SLASH as i32,
1183 At = ffi::AKEYCODE_AT as i32,
1184 Num = ffi::AKEYCODE_NUM as i32,
1185 Headsethook = ffi::AKEYCODE_HEADSETHOOK as i32,
1186 Focus = ffi::AKEYCODE_FOCUS as i32,
1187 Plus = ffi::AKEYCODE_PLUS as i32,
1188 Menu = ffi::AKEYCODE_MENU as i32,
1189 Notification = ffi::AKEYCODE_NOTIFICATION as i32,
1190 Search = ffi::AKEYCODE_SEARCH as i32,
1191 MediaPlayPause = ffi::AKEYCODE_MEDIA_PLAY_PAUSE as i32,
1192 MediaStop = ffi::AKEYCODE_MEDIA_STOP as i32,
1193 MediaNext = ffi::AKEYCODE_MEDIA_NEXT as i32,
1194 MediaPrevious = ffi::AKEYCODE_MEDIA_PREVIOUS as i32,
1195 MediaRewind = ffi::AKEYCODE_MEDIA_REWIND as i32,
1196 MediaFastForward = ffi::AKEYCODE_MEDIA_FAST_FORWARD as i32,
1197 Mute = ffi::AKEYCODE_MUTE as i32,
1198 PageUp = ffi::AKEYCODE_PAGE_UP as i32,
1199 PageDown = ffi::AKEYCODE_PAGE_DOWN as i32,
1200 Pictsymbols = ffi::AKEYCODE_PICTSYMBOLS as i32,
1201 SwitchCharset = ffi::AKEYCODE_SWITCH_CHARSET as i32,
1202 ButtonA = ffi::AKEYCODE_BUTTON_A as i32,
1203 ButtonB = ffi::AKEYCODE_BUTTON_B as i32,
1204 ButtonC = ffi::AKEYCODE_BUTTON_C as i32,
1205 ButtonX = ffi::AKEYCODE_BUTTON_X as i32,
1206 ButtonY = ffi::AKEYCODE_BUTTON_Y as i32,
1207 ButtonZ = ffi::AKEYCODE_BUTTON_Z as i32,
1208 ButtonL1 = ffi::AKEYCODE_BUTTON_L1 as i32,
1209 ButtonR1 = ffi::AKEYCODE_BUTTON_R1 as i32,
1210 ButtonL2 = ffi::AKEYCODE_BUTTON_L2 as i32,
1211 ButtonR2 = ffi::AKEYCODE_BUTTON_R2 as i32,
1212 ButtonThumbl = ffi::AKEYCODE_BUTTON_THUMBL as i32,
1213 ButtonThumbr = ffi::AKEYCODE_BUTTON_THUMBR as i32,
1214 ButtonStart = ffi::AKEYCODE_BUTTON_START as i32,
1215 ButtonSelect = ffi::AKEYCODE_BUTTON_SELECT as i32,
1216 ButtonMode = ffi::AKEYCODE_BUTTON_MODE as i32,
1217 Escape = ffi::AKEYCODE_ESCAPE as i32,
1218 ForwardDel = ffi::AKEYCODE_FORWARD_DEL as i32,
1219 CtrlLeft = ffi::AKEYCODE_CTRL_LEFT as i32,
1220 CtrlRight = ffi::AKEYCODE_CTRL_RIGHT as i32,
1221 CapsLock = ffi::AKEYCODE_CAPS_LOCK as i32,
1222 ScrollLock = ffi::AKEYCODE_SCROLL_LOCK as i32,
1223 MetaLeft = ffi::AKEYCODE_META_LEFT as i32,
1224 MetaRight = ffi::AKEYCODE_META_RIGHT as i32,
1225 Function = ffi::AKEYCODE_FUNCTION as i32,
1226 Sysrq = ffi::AKEYCODE_SYSRQ as i32,
1227 Break = ffi::AKEYCODE_BREAK as i32,
1228 MoveHome = ffi::AKEYCODE_MOVE_HOME as i32,
1229 MoveEnd = ffi::AKEYCODE_MOVE_END as i32,
1230 Insert = ffi::AKEYCODE_INSERT as i32,
1231 Forward = ffi::AKEYCODE_FORWARD as i32,
1232 MediaPlay = ffi::AKEYCODE_MEDIA_PLAY as i32,
1233 MediaPause = ffi::AKEYCODE_MEDIA_PAUSE as i32,
1234 MediaClose = ffi::AKEYCODE_MEDIA_CLOSE as i32,
1235 MediaEject = ffi::AKEYCODE_MEDIA_EJECT as i32,
1236 MediaRecord = ffi::AKEYCODE_MEDIA_RECORD as i32,
1237 F1 = ffi::AKEYCODE_F1 as i32,
1238 F2 = ffi::AKEYCODE_F2 as i32,
1239 F3 = ffi::AKEYCODE_F3 as i32,
1240 F4 = ffi::AKEYCODE_F4 as i32,
1241 F5 = ffi::AKEYCODE_F5 as i32,
1242 F6 = ffi::AKEYCODE_F6 as i32,
1243 F7 = ffi::AKEYCODE_F7 as i32,
1244 F8 = ffi::AKEYCODE_F8 as i32,
1245 F9 = ffi::AKEYCODE_F9 as i32,
1246 F10 = ffi::AKEYCODE_F10 as i32,
1247 F11 = ffi::AKEYCODE_F11 as i32,
1248 F12 = ffi::AKEYCODE_F12 as i32,
1249 NumLock = ffi::AKEYCODE_NUM_LOCK as i32,
1250 Numpad0 = ffi::AKEYCODE_NUMPAD_0 as i32,
1251 Numpad1 = ffi::AKEYCODE_NUMPAD_1 as i32,
1252 Numpad2 = ffi::AKEYCODE_NUMPAD_2 as i32,
1253 Numpad3 = ffi::AKEYCODE_NUMPAD_3 as i32,
1254 Numpad4 = ffi::AKEYCODE_NUMPAD_4 as i32,
1255 Numpad5 = ffi::AKEYCODE_NUMPAD_5 as i32,
1256 Numpad6 = ffi::AKEYCODE_NUMPAD_6 as i32,
1257 Numpad7 = ffi::AKEYCODE_NUMPAD_7 as i32,
1258 Numpad8 = ffi::AKEYCODE_NUMPAD_8 as i32,
1259 Numpad9 = ffi::AKEYCODE_NUMPAD_9 as i32,
1260 NumpadDivide = ffi::AKEYCODE_NUMPAD_DIVIDE as i32,
1261 NumpadMultiply = ffi::AKEYCODE_NUMPAD_MULTIPLY as i32,
1262 NumpadSubtract = ffi::AKEYCODE_NUMPAD_SUBTRACT as i32,
1263 NumpadAdd = ffi::AKEYCODE_NUMPAD_ADD as i32,
1264 NumpadDot = ffi::AKEYCODE_NUMPAD_DOT as i32,
1265 NumpadComma = ffi::AKEYCODE_NUMPAD_COMMA as i32,
1266 NumpadEnter = ffi::AKEYCODE_NUMPAD_ENTER as i32,
1267 NumpadEquals = ffi::AKEYCODE_NUMPAD_EQUALS as i32,
1268 NumpadLeftParen = ffi::AKEYCODE_NUMPAD_LEFT_PAREN as i32,
1269 NumpadRightParen = ffi::AKEYCODE_NUMPAD_RIGHT_PAREN as i32,
1270 VolumeMute = ffi::AKEYCODE_VOLUME_MUTE as i32,
1271 Info = ffi::AKEYCODE_INFO as i32,
1272 ChannelUp = ffi::AKEYCODE_CHANNEL_UP as i32,
1273 ChannelDown = ffi::AKEYCODE_CHANNEL_DOWN as i32,
1274 ZoomIn = ffi::AKEYCODE_ZOOM_IN as i32,
1275 ZoomOut = ffi::AKEYCODE_ZOOM_OUT as i32,
1276 Tv = ffi::AKEYCODE_TV as i32,
1277 Window = ffi::AKEYCODE_WINDOW as i32,
1278 Guide = ffi::AKEYCODE_GUIDE as i32,
1279 Dvr = ffi::AKEYCODE_DVR as i32,
1280 Bookmark = ffi::AKEYCODE_BOOKMARK as i32,
1281 Captions = ffi::AKEYCODE_CAPTIONS as i32,
1282 Settings = ffi::AKEYCODE_SETTINGS as i32,
1283 TvPower = ffi::AKEYCODE_TV_POWER as i32,
1284 TvInput = ffi::AKEYCODE_TV_INPUT as i32,
1285 StbPower = ffi::AKEYCODE_STB_POWER as i32,
1286 StbInput = ffi::AKEYCODE_STB_INPUT as i32,
1287 AvrPower = ffi::AKEYCODE_AVR_POWER as i32,
1288 AvrInput = ffi::AKEYCODE_AVR_INPUT as i32,
1289 ProgRed = ffi::AKEYCODE_PROG_RED as i32,
1290 ProgGreen = ffi::AKEYCODE_PROG_GREEN as i32,
1291 ProgYellow = ffi::AKEYCODE_PROG_YELLOW as i32,
1292 ProgBlue = ffi::AKEYCODE_PROG_BLUE as i32,
1293 AppSwitch = ffi::AKEYCODE_APP_SWITCH as i32,
1294 Button1 = ffi::AKEYCODE_BUTTON_1 as i32,
1295 Button2 = ffi::AKEYCODE_BUTTON_2 as i32,
1296 Button3 = ffi::AKEYCODE_BUTTON_3 as i32,
1297 Button4 = ffi::AKEYCODE_BUTTON_4 as i32,
1298 Button5 = ffi::AKEYCODE_BUTTON_5 as i32,
1299 Button6 = ffi::AKEYCODE_BUTTON_6 as i32,
1300 Button7 = ffi::AKEYCODE_BUTTON_7 as i32,
1301 Button8 = ffi::AKEYCODE_BUTTON_8 as i32,
1302 Button9 = ffi::AKEYCODE_BUTTON_9 as i32,
1303 Button10 = ffi::AKEYCODE_BUTTON_10 as i32,
1304 Button11 = ffi::AKEYCODE_BUTTON_11 as i32,
1305 Button12 = ffi::AKEYCODE_BUTTON_12 as i32,
1306 Button13 = ffi::AKEYCODE_BUTTON_13 as i32,
1307 Button14 = ffi::AKEYCODE_BUTTON_14 as i32,
1308 Button15 = ffi::AKEYCODE_BUTTON_15 as i32,
1309 Button16 = ffi::AKEYCODE_BUTTON_16 as i32,
1310 LanguageSwitch = ffi::AKEYCODE_LANGUAGE_SWITCH as i32,
1311 MannerMode = ffi::AKEYCODE_MANNER_MODE as i32,
1312 Keycode3dMode = ffi::AKEYCODE_3D_MODE as i32,
1313 Contacts = ffi::AKEYCODE_CONTACTS as i32,
1314 Calendar = ffi::AKEYCODE_CALENDAR as i32,
1315 Music = ffi::AKEYCODE_MUSIC as i32,
1316 Calculator = ffi::AKEYCODE_CALCULATOR as i32,
1317 ZenkakuHankaku = ffi::AKEYCODE_ZENKAKU_HANKAKU as i32,
1318 Eisu = ffi::AKEYCODE_EISU as i32,
1319 Muhenkan = ffi::AKEYCODE_MUHENKAN as i32,
1320 Henkan = ffi::AKEYCODE_HENKAN as i32,
1321 KatakanaHiragana = ffi::AKEYCODE_KATAKANA_HIRAGANA as i32,
1322 Yen = ffi::AKEYCODE_YEN as i32,
1323 Ro = ffi::AKEYCODE_RO as i32,
1324 Kana = ffi::AKEYCODE_KANA as i32,
1325 Assist = ffi::AKEYCODE_ASSIST as i32,
1326 BrightnessDown = ffi::AKEYCODE_BRIGHTNESS_DOWN as i32,
1327 BrightnessUp = ffi::AKEYCODE_BRIGHTNESS_UP as i32,
1328 MediaAudioTrack = ffi::AKEYCODE_MEDIA_AUDIO_TRACK as i32,
1329 Sleep = ffi::AKEYCODE_SLEEP as i32,
1330 Wakeup = ffi::AKEYCODE_WAKEUP as i32,
1331 Pairing = ffi::AKEYCODE_PAIRING as i32,
1332 MediaTopMenu = ffi::AKEYCODE_MEDIA_TOP_MENU as i32,
1333 Keycode11 = ffi::AKEYCODE_11 as i32,
1334 Keycode12 = ffi::AKEYCODE_12 as i32,
1335 LastChannel = ffi::AKEYCODE_LAST_CHANNEL as i32,
1336 TvDataService = ffi::AKEYCODE_TV_DATA_SERVICE as i32,
1337 VoiceAssist = ffi::AKEYCODE_VOICE_ASSIST as i32,
1338 TvRadioService = ffi::AKEYCODE_TV_RADIO_SERVICE as i32,
1339 TvTeletext = ffi::AKEYCODE_TV_TELETEXT as i32,
1340 TvNumberEntry = ffi::AKEYCODE_TV_NUMBER_ENTRY as i32,
1341 TvTerrestrialAnalog = ffi::AKEYCODE_TV_TERRESTRIAL_ANALOG as i32,
1342 TvTerrestrialDigital = ffi::AKEYCODE_TV_TERRESTRIAL_DIGITAL as i32,
1343 TvSatellite = ffi::AKEYCODE_TV_SATELLITE as i32,
1344 TvSatelliteBs = ffi::AKEYCODE_TV_SATELLITE_BS as i32,
1345 TvSatelliteCs = ffi::AKEYCODE_TV_SATELLITE_CS as i32,
1346 TvSatelliteService = ffi::AKEYCODE_TV_SATELLITE_SERVICE as i32,
1347 TvNetwork = ffi::AKEYCODE_TV_NETWORK as i32,
1348 TvAntennaCable = ffi::AKEYCODE_TV_ANTENNA_CABLE as i32,
1349 TvInputHdmi1 = ffi::AKEYCODE_TV_INPUT_HDMI_1 as i32,
1350 TvInputHdmi2 = ffi::AKEYCODE_TV_INPUT_HDMI_2 as i32,
1351 TvInputHdmi3 = ffi::AKEYCODE_TV_INPUT_HDMI_3 as i32,
1352 TvInputHdmi4 = ffi::AKEYCODE_TV_INPUT_HDMI_4 as i32,
1353 TvInputComposite1 = ffi::AKEYCODE_TV_INPUT_COMPOSITE_1 as i32,
1354 TvInputComposite2 = ffi::AKEYCODE_TV_INPUT_COMPOSITE_2 as i32,
1355 TvInputComponent1 = ffi::AKEYCODE_TV_INPUT_COMPONENT_1 as i32,
1356 TvInputComponent2 = ffi::AKEYCODE_TV_INPUT_COMPONENT_2 as i32,
1357 TvInputVga1 = ffi::AKEYCODE_TV_INPUT_VGA_1 as i32,
1358 TvAudioDescription = ffi::AKEYCODE_TV_AUDIO_DESCRIPTION as i32,
1359 TvAudioDescriptionMixUp = ffi::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP as i32,
1360 TvAudioDescriptionMixDown = ffi::AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN as i32,
1361 TvZoomMode = ffi::AKEYCODE_TV_ZOOM_MODE as i32,
1362 TvContentsMenu = ffi::AKEYCODE_TV_CONTENTS_MENU as i32,
1363 TvMediaContextMenu = ffi::AKEYCODE_TV_MEDIA_CONTEXT_MENU as i32,
1364 TvTimerProgramming = ffi::AKEYCODE_TV_TIMER_PROGRAMMING as i32,
1365 Help = ffi::AKEYCODE_HELP as i32,
1366 NavigatePrevious = ffi::AKEYCODE_NAVIGATE_PREVIOUS as i32,
1367 NavigateNext = ffi::AKEYCODE_NAVIGATE_NEXT as i32,
1368 NavigateIn = ffi::AKEYCODE_NAVIGATE_IN as i32,
1369 NavigateOut = ffi::AKEYCODE_NAVIGATE_OUT as i32,
1370 StemPrimary = ffi::AKEYCODE_STEM_PRIMARY as i32,
1371 Stem1 = ffi::AKEYCODE_STEM_1 as i32,
1372 Stem2 = ffi::AKEYCODE_STEM_2 as i32,
1373 Stem3 = ffi::AKEYCODE_STEM_3 as i32,
1374 DpadUpLeft = ffi::AKEYCODE_DPAD_UP_LEFT as i32,
1375 DpadDownLeft = ffi::AKEYCODE_DPAD_DOWN_LEFT as i32,
1376 DpadUpRight = ffi::AKEYCODE_DPAD_UP_RIGHT as i32,
1377 DpadDownRight = ffi::AKEYCODE_DPAD_DOWN_RIGHT as i32,
1378 MediaSkipForward = ffi::AKEYCODE_MEDIA_SKIP_FORWARD as i32,
1379 MediaSkipBackward = ffi::AKEYCODE_MEDIA_SKIP_BACKWARD as i32,
1380 MediaStepForward = ffi::AKEYCODE_MEDIA_STEP_FORWARD as i32,
1381 MediaStepBackward = ffi::AKEYCODE_MEDIA_STEP_BACKWARD as i32,
1382 SoftSleep = ffi::AKEYCODE_SOFT_SLEEP as i32,
1383 Cut = ffi::AKEYCODE_CUT as i32,
1384 Copy = ffi::AKEYCODE_COPY as i32,
1385 Paste = ffi::AKEYCODE_PASTE as i32,
1386 SystemNavigationUp = ffi::AKEYCODE_SYSTEM_NAVIGATION_UP as i32,
1387 SystemNavigationDown = ffi::AKEYCODE_SYSTEM_NAVIGATION_DOWN as i32,
1388 SystemNavigationLeft = ffi::AKEYCODE_SYSTEM_NAVIGATION_LEFT as i32,
1389 SystemNavigationRight = ffi::AKEYCODE_SYSTEM_NAVIGATION_RIGHT as i32,
1390 AllApps = ffi::AKEYCODE_ALL_APPS as i32,
1391 Refresh = ffi::AKEYCODE_REFRESH as i32,
1392 ThumbsUp = ffi::AKEYCODE_THUMBS_UP as i32,
1393 ThumbsDown = ffi::AKEYCODE_THUMBS_DOWN as i32,
1394 ProfileSwitch = ffi::AKEYCODE_PROFILE_SWITCH as i32,
1395
1396 #[doc(hidden)]
1397 #[num_enum(catch_all)]
1398 __Unknown(i32),
1399}
1400
1401impl KeyEvent {
1402 #[inline]
1408 pub unsafe fn from_ptr(ptr: NonNull<ffi::AInputEvent>) -> Self {
1409 Self { ptr }
1410 }
1411
1412 #[cfg(feature = "api-level-31")]
1423 #[doc(alias = "AKeyEvent_fromJava")]
1424 pub unsafe fn from_java(env: *mut JNIEnv, key_event: jobject) -> Option<InputEventJava> {
1425 let ptr = unsafe { ffi::AKeyEvent_fromJava(env, key_event) };
1426 Some(InputEventJava(InputEvent::KeyEvent(Self::from_ptr(
1427 NonNull::new(ptr.cast_mut())?,
1428 ))))
1429 }
1430
1431 #[inline]
1433 pub fn ptr(&self) -> NonNull<ffi::AInputEvent> {
1434 self.ptr
1435 }
1436
1437 #[inline]
1442 pub fn action(&self) -> KeyAction {
1443 let action = unsafe { ffi::AKeyEvent_getAction(self.ptr.as_ptr()) };
1444 action.into()
1445 }
1446
1447 #[inline]
1452 pub fn source(&self) -> Source {
1453 let source = unsafe { ffi::AInputEvent_getSource(self.ptr.as_ptr()) };
1454 source.into()
1455 }
1456
1457 #[inline]
1462 pub fn device_id(&self) -> i32 {
1463 unsafe { ffi::AInputEvent_getDeviceId(self.ptr.as_ptr()) }
1464 }
1465
1466 #[inline]
1472 pub fn down_time(&self) -> i64 {
1473 unsafe { ffi::AKeyEvent_getDownTime(self.ptr.as_ptr()) }
1474 }
1475
1476 #[inline]
1482 pub fn event_time(&self) -> i64 {
1483 unsafe { ffi::AKeyEvent_getEventTime(self.ptr.as_ptr()) }
1484 }
1485
1486 #[inline]
1491 pub fn key_code(&self) -> Keycode {
1492 let keycode = unsafe { ffi::AKeyEvent_getKeyCode(self.ptr.as_ptr()) };
1493 keycode.into()
1494 }
1495
1496 #[inline]
1501 pub fn repeat_count(&self) -> i32 {
1502 unsafe { ffi::AKeyEvent_getRepeatCount(self.ptr.as_ptr()) }
1503 }
1504
1505 #[inline]
1510 pub fn scan_code(&self) -> i32 {
1511 unsafe { ffi::AKeyEvent_getScanCode(self.ptr.as_ptr()) }
1512 }
1513}
1514
1515#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1517pub struct KeyEventFlags(pub u32);
1518
1519impl KeyEventFlags {
1520 #[inline]
1521 pub fn cancelled(&self) -> bool {
1522 self.0 & ffi::AKEY_EVENT_FLAG_CANCELED != 0
1523 }
1524 #[inline]
1525 pub fn cancelled_long_press(&self) -> bool {
1526 self.0 & ffi::AKEY_EVENT_FLAG_CANCELED_LONG_PRESS != 0
1527 }
1528 #[inline]
1529 pub fn editor_action(&self) -> bool {
1530 self.0 & ffi::AKEY_EVENT_FLAG_EDITOR_ACTION != 0
1531 }
1532 #[inline]
1533 pub fn fallback(&self) -> bool {
1534 self.0 & ffi::AKEY_EVENT_FLAG_FALLBACK != 0
1535 }
1536 #[inline]
1537 pub fn from_system(&self) -> bool {
1538 self.0 & ffi::AKEY_EVENT_FLAG_FROM_SYSTEM != 0
1539 }
1540 #[inline]
1541 pub fn keep_touch_mode(&self) -> bool {
1542 self.0 & ffi::AKEY_EVENT_FLAG_KEEP_TOUCH_MODE != 0
1543 }
1544 #[inline]
1545 pub fn long_press(&self) -> bool {
1546 self.0 & ffi::AKEY_EVENT_FLAG_LONG_PRESS != 0
1547 }
1548 #[inline]
1549 pub fn soft_keyboard(&self) -> bool {
1550 self.0 & ffi::AKEY_EVENT_FLAG_SOFT_KEYBOARD != 0
1551 }
1552 #[inline]
1553 pub fn tracking(&self) -> bool {
1554 self.0 & ffi::AKEY_EVENT_FLAG_TRACKING != 0
1555 }
1556 #[inline]
1557 pub fn virtual_hard_key(&self) -> bool {
1558 self.0 & ffi::AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY != 0
1559 }
1560 #[inline]
1561 pub fn woke_here(&self) -> bool {
1562 self.0 & ffi::AKEY_EVENT_FLAG_WOKE_HERE != 0
1563 }
1564}
1565
1566impl KeyEvent {
1567 #[inline]
1571 pub fn flags(&self) -> KeyEventFlags {
1572 unsafe { KeyEventFlags(ffi::AKeyEvent_getFlags(self.ptr.as_ptr()) as u32) }
1573 }
1574
1575 #[inline]
1580 pub fn meta_state(&self) -> MetaState {
1581 unsafe { MetaState(ffi::AKeyEvent_getMetaState(self.ptr.as_ptr()) as u32) }
1582 }
1583}