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