android_ndk/
input_queue.rs

1// TODO: mod docs
2
3use std::os::raw::c_int;
4use std::ptr;
5use std::ptr::NonNull;
6
7use crate::event::InputEvent;
8
9// TODO docs
10#[derive(Debug)]
11pub struct InputQueue {
12    ptr: NonNull<ffi::AInputQueue>,
13}
14
15// It gets shared between threads in android_native_app_glue
16unsafe impl Send for InputQueue {}
17unsafe impl Sync for InputQueue {}
18
19#[derive(Debug)]
20pub struct InputQueueError;
21
22impl InputQueue {
23    /// Construct an `InputQueue` from the native pointer.
24    ///
25    /// By calling this function, you assert that the pointer is a valid pointer to an NDK `AInputQueue`.
26    pub unsafe fn from_ptr(ptr: NonNull<ffi::AInputQueue>) -> Self {
27        Self { ptr }
28    }
29
30    pub fn ptr(&self) -> NonNull<ffi::AInputQueue> {
31        self.ptr
32    }
33
34    pub fn get_event(&self) -> Option<InputEvent> {
35        unsafe {
36            let mut out_event = ptr::null_mut();
37            if ffi::AInputQueue_getEvent(self.ptr.as_ptr(), &mut out_event) < 0 {
38                None
39            } else {
40                debug_assert!(out_event != ptr::null_mut());
41                Some(InputEvent::from_ptr(NonNull::new_unchecked(out_event)))
42            }
43        }
44    }
45
46    pub fn has_events(&self) -> Result<bool, InputQueueError> {
47        unsafe {
48            match ffi::AInputQueue_hasEvents(self.ptr.as_ptr()) {
49                0 => Ok(false),
50                1 => Ok(true),
51                x if x < 0 => Err(InputQueueError),
52                x => unreachable!("AInputQueue_hasEvents returned {}", x),
53            }
54        }
55    }
56
57    pub fn pre_dispatch(&self, event: InputEvent) -> Option<InputEvent> {
58        unsafe {
59            if ffi::AInputQueue_preDispatchEvent(self.ptr.as_ptr(), event.ptr().as_ptr()) == 0 {
60                Some(event)
61            } else {
62                None
63            }
64        }
65    }
66
67    pub fn finish_event(&self, event: InputEvent, handled: bool) {
68        unsafe {
69            ffi::AInputQueue_finishEvent(self.ptr.as_ptr(), event.ptr().as_ptr(), handled as c_int);
70        }
71    }
72}