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