1 #![cfg(target_os = "android")]
2 
3 extern {
cargo_apk_injected_glue_get_native_window() -> *const c_void4     fn cargo_apk_injected_glue_get_native_window() -> *const c_void;
cargo_apk_injected_glue_add_sender(sender: *mut ())5     fn cargo_apk_injected_glue_add_sender(sender: *mut ());
cargo_apk_injected_glue_add_sender_missing(sender: *mut ())6     fn cargo_apk_injected_glue_add_sender_missing(sender: *mut ());
cargo_apk_injected_glue_add_sync_event_handler(sender: *mut ())7     fn cargo_apk_injected_glue_add_sync_event_handler(sender: *mut ());
cargo_apk_injected_glue_remove_sync_event_handler(sender: *mut ())8     fn cargo_apk_injected_glue_remove_sync_event_handler(sender: *mut ());
cargo_apk_injected_glue_set_multitouch(multitouch: bool)9     fn cargo_apk_injected_glue_set_multitouch(multitouch: bool);
cargo_apk_injected_glue_write_log(ptr: *const (), len: usize)10     fn cargo_apk_injected_glue_write_log(ptr: *const (), len: usize);
cargo_apk_injected_glue_load_asset(ptr: *const (), len: usize) -> *mut c_void11     fn cargo_apk_injected_glue_load_asset(ptr: *const (), len: usize) -> *mut c_void;
cargo_apk_injected_glue_wake_event_loop()12     fn cargo_apk_injected_glue_wake_event_loop();
13 }
14 
15 use std::mem;
16 use std::os::raw::c_void;
17 use std::sync::mpsc::Sender;
18 
19 /// An event triggered by the Android environment.
20 #[derive(Clone, Copy, Debug)]
21 pub enum Event {
22     EventMotion(Motion),
23     EventKeyUp,
24     EventKeyDown,
25     InitWindow,
26     SaveState,
27     TermWindow,
28     GainedFocus,
29     LostFocus,
30     InputChanged,
31     WindowResized,
32     WindowRedrawNeeded,
33     ContentRectChanged,
34     ConfigChanged,
35     LowMemory,
36     Start,
37     Resume,
38     Pause,
39     Stop,
40     Destroy,
41     Wake
42 }
43 
44 /// Data about a motion event.
45 #[derive(Clone, Copy, Debug)]
46 pub struct Motion {
47     pub action: MotionAction,
48     pub pointer_id: i32,
49     pub x: f32,
50     pub y: f32,
51 }
52 
53 /// The type of pointer action in a motion event.
54 #[derive(Clone, Copy, Debug)]
55 pub enum MotionAction {
56     Down,
57     Move,
58     Up,
59     Cancel,
60 }
61 
62 pub enum AssetError {
63     AssetMissing,
64     EmptyBuffer,
65 }
66 
67 // Trait used to dispatch sync events from the polling loop thread.
68 pub trait SyncEventHandler {
handle(&mut self, event: &Event)69     fn handle(&mut self, event: &Event);
70 }
71 
72 /// Adds a sender where events will be sent to.
73 #[inline]
add_sender(sender: Sender<Event>)74 pub fn add_sender(sender: Sender<Event>) {
75     unsafe {
76         let sender = Box::into_raw(Box::new(sender)) as *mut _;
77         cargo_apk_injected_glue_add_sender(sender);
78     }
79 }
80 
81 /// Adds a SyncEventHandler which will receive sync events from the polling loop.
82 #[inline]
add_sync_event_handler(handler: Box<SyncEventHandler>)83 pub fn add_sync_event_handler(handler: Box<SyncEventHandler>) {
84     unsafe {
85         let handler = Box::into_raw(Box::new(handler)) as *mut _;
86         cargo_apk_injected_glue_add_sync_event_handler(handler);
87     }
88 }
89 
90 /// Removes a SyncEventHandler.
91 #[inline]
remove_sync_event_handler(handler: *const SyncEventHandler)92 pub fn remove_sync_event_handler(handler: *const SyncEventHandler) {
93     unsafe {
94         let handler = Box::into_raw(Box::new(handler)) as *mut _;
95         cargo_apk_injected_glue_remove_sync_event_handler(handler);
96     }
97 }
98 
99 #[inline]
set_multitouch(multitouch: bool)100 pub fn set_multitouch(multitouch: bool) {
101     unsafe {
102         cargo_apk_injected_glue_set_multitouch(multitouch);
103     }
104 }
105 
106 /// Adds a sender where events will be sent to, but also sends
107 /// any missing events to the sender object.
108 ///
109 /// The missing events happen when the application starts, but before
110 /// any senders are registered. Since these might be important to certain
111 /// applications, this function provides that support.
112 #[inline]
add_sender_missing(sender: Sender<Event>)113 pub fn add_sender_missing(sender: Sender<Event>) {
114     unsafe {
115         let sender = Box::into_raw(Box::new(sender)) as *mut _;
116         cargo_apk_injected_glue_add_sender_missing(sender);
117     }
118 }
119 
120 /// Returns a handle to the native window.
121 #[inline]
get_native_window() -> *const c_void122 pub unsafe fn get_native_window() -> *const c_void {
123     cargo_apk_injected_glue_get_native_window()
124 }
125 
126 ///
127 #[inline]
write_log(message: &str)128 pub fn write_log(message: &str) {
129     unsafe {
130         let (message_ptr, message_len) = mem::transmute(message);
131         cargo_apk_injected_glue_write_log(message_ptr, message_len);
132     }
133 }
134 
135 #[inline]
load_asset(filename: &str) -> Result<Vec<u8>, AssetError>136 pub fn load_asset(filename: &str) -> Result<Vec<u8>, AssetError> {
137     unsafe {
138         let (filename_ptr, filename_len) = mem::transmute(filename);
139         let data = cargo_apk_injected_glue_load_asset(filename_ptr, filename_len);
140         let data: Box<Result<Vec<u8>, AssetError>> = Box::from_raw(data as *mut _);
141         *data
142     }
143 }
144 
145 // Wakes the event poll asynchronously and sends a Event::Wake event to the senders.
146 // This method can be called on any thread. This method returns immediately.
147 #[inline]
wake_event_loop()148 pub fn wake_event_loop() {
149     unsafe {
150         cargo_apk_injected_glue_wake_event_loop();
151     }
152 }
153