ohos_xcomponent_binding/events/
native_callbacks.rs1#![allow(clippy::missing_safety_doc)]
2
3use std::mem::MaybeUninit;
4
5use ohos_arkui_input_binding::ArkUIInputEvent;
6use ohos_xcomponent_sys::{
7 OH_NativeXComponent, OH_NativeXComponent_GetKeyEvent, OH_NativeXComponent_GetKeyEventAction,
8 OH_NativeXComponent_GetKeyEventCode, OH_NativeXComponent_GetKeyEventDeviceId,
9 OH_NativeXComponent_GetKeyEventSourceType, OH_NativeXComponent_GetKeyEventTimestamp,
10 OH_NativeXComponent_GetMouseEvent, OH_NativeXComponent_GetTouchEvent,
11 OH_NativeXComponent_GetTouchPointToolType, OH_NativeXComponent_MouseEvent,
12 OH_NativeXComponent_TouchEvent,
13};
14
15use crate::{Action, EventSource, KeyCode, KeyEventData, MouseEventData, WindowRaw, XComponentRaw};
16
17use super::{RawWindow, TouchEventData, RAW_WINDOW};
18
19#[cfg(not(feature = "multi_mode"))]
20use super::X_COMPONENT_CALLBACKS;
21
22#[cfg(feature = "multi_mode")]
23use super::X_COMPONENT_CALLBACKS_MAP;
24#[cfg(feature = "multi_mode")]
25use crate::tool::resolve_id;
26
27pub unsafe extern "C" fn on_surface_created(
28 xcomponent: *mut OH_NativeXComponent,
29 window: *mut std::os::raw::c_void,
30) {
31 let window = WindowRaw(window);
32 let xcomponent = XComponentRaw(xcomponent);
33
34 {
35 let mut guard = (*RAW_WINDOW).write().expect("read raw window failed");
36 guard.replace(RawWindow::new(window.0));
37 }
38
39 #[cfg(not(feature = "multi_mode"))]
40 {
41 let callback = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
42
43 if let Some(callback) = &callback.on_surface_created {
44 callback(xcomponent, window).unwrap();
45 }
46 }
47
48 #[cfg(feature = "multi_mode")]
49 {
50 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
51
52 let id = resolve_id(xcomponent.0).unwrap();
53 if let Some(callback) = cb.get(&id) {
54 if let Some(callback) = &callback.on_surface_created {
55 callback(xcomponent, window).unwrap();
56 }
57 }
58 }
59}
60
61pub unsafe extern "C" fn on_surface_changed(
62 xcomponent: *mut OH_NativeXComponent,
63 window: *mut std::os::raw::c_void,
64) {
65 let window = WindowRaw(window);
66 let xcomponent = XComponentRaw(xcomponent);
67
68 {
69 let mut guard = (*RAW_WINDOW).write().expect("read raw window failed");
70 guard.replace(RawWindow::new(window.0));
71 }
72
73 #[cfg(not(feature = "multi_mode"))]
74 {
75 let callback = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
76 if let Some(callback) = &callback.on_surface_changed {
77 callback(xcomponent, window).unwrap();
78 }
79 }
80
81 #[cfg(feature = "multi_mode")]
82 {
83 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
84
85 let id = resolve_id(xcomponent.0).unwrap();
86 if let Some(callback) = cb.get(&id) {
87 if let Some(callback) = &callback.on_surface_changed {
88 callback(xcomponent, window).unwrap();
89 }
90 }
91 }
92}
93
94pub unsafe extern "C" fn on_surface_destroyed(
95 xcomponent: *mut OH_NativeXComponent,
96 window: *mut std::os::raw::c_void,
97) {
98 let window = WindowRaw(window);
99 let xcomponent = XComponentRaw(xcomponent);
100
101 {
102 let mut guard = (*RAW_WINDOW).write().expect("read raw window failed");
103 *guard = None;
104 }
105
106 #[cfg(not(feature = "multi_mode"))]
107 {
108 let cb = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
109 if let Some(callback) = &cb.on_surface_destroyed {
110 callback(xcomponent, window).unwrap();
111 }
112 }
113
114 #[cfg(feature = "multi_mode")]
115 {
116 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
117
118 let id = resolve_id(xcomponent.0).unwrap();
119 if let Some(callback) = cb.get(&id) {
120 if let Some(callback) = &callback.on_surface_destroyed {
121 callback(xcomponent, window).unwrap();
122 }
123 }
124 }
125}
126
127pub unsafe extern "C" fn dispatch_touch_event(
128 xcomponent: *mut OH_NativeXComponent,
129 window: *mut std::os::raw::c_void,
130) {
131 let mut touch_event = MaybeUninit::<OH_NativeXComponent_TouchEvent>::uninit();
132 let ret = OH_NativeXComponent_GetTouchEvent(xcomponent, window, touch_event.as_mut_ptr());
133 assert!(ret == 0, "Get touch event failed");
134
135 let touch_event_data = touch_event.assume_init();
136 let mut data = TouchEventData::from(touch_event_data);
137
138 data.touch_points.iter_mut().for_each(|point| {
139 let mut tool = 0;
140 let ret = OH_NativeXComponent_GetTouchPointToolType(xcomponent, point.id as _, &mut tool);
141 assert!(ret == 0, "Get touch point tool type failed");
142 point.event_tool_type = tool.into();
143 });
144
145 let window = WindowRaw(window);
146 let xcomponent = XComponentRaw(xcomponent);
147
148 #[cfg(not(feature = "multi_mode"))]
149 {
150 let cb = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
151 if let Some(callback) = &cb.dispatch_touch_event {
152 callback(xcomponent, window, data).unwrap();
153 }
154 }
155
156 #[cfg(feature = "multi_mode")]
157 {
158 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
159
160 let id = resolve_id(xcomponent.0).unwrap();
161 if let Some(callback) = cb.get(&id) {
162 if let Some(callback) = &callback.dispatch_touch_event {
163 callback(xcomponent, window, data).unwrap();
164 }
165 }
166 }
167}
168
169pub unsafe extern "C" fn on_frame_change(
170 xcomponent: *mut OH_NativeXComponent,
171 timestamp: u64,
172 target_timestamp: u64,
173) {
174 let xcomponent = XComponentRaw(xcomponent);
175
176 #[cfg(not(feature = "multi_mode"))]
177 {
178 let cb = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
179 if let Some(callback) = &cb.on_frame_change {
180 callback(xcomponent, timestamp, target_timestamp).unwrap();
181 }
182 }
183
184 #[cfg(feature = "multi_mode")]
185 {
186 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
187
188 let id = resolve_id(xcomponent.0).unwrap();
189 if let Some(callback) = cb.get(&id) {
190 if let Some(callback) = &callback.on_frame_change {
191 callback(xcomponent, timestamp, target_timestamp).unwrap();
192 }
193 }
194 }
195}
196
197pub unsafe extern "C" fn key_event(
198 xcomponent: *mut OH_NativeXComponent,
199 window: *mut std::os::raw::c_void,
200) {
201 let mut event = std::ptr::null_mut();
202 let ret = OH_NativeXComponent_GetKeyEvent(xcomponent, &mut event);
203 assert!(ret == 0, "Get key event failed");
204
205 let mut action = 0;
206 let ret = OH_NativeXComponent_GetKeyEventAction(event, &mut action);
207 assert!(ret == 0, "Get key event action failed");
208
209 let mut code = 0;
210 let ret = OH_NativeXComponent_GetKeyEventCode(event, &mut code);
211 assert!(ret == 0, "Get key event code failed");
212
213 let mut device_id = 0;
214 let ret = OH_NativeXComponent_GetKeyEventDeviceId(event, &mut device_id);
215 assert!(ret == 0, "Get key event device id failed");
216
217 let mut source = 0;
218 let ret = OH_NativeXComponent_GetKeyEventSourceType(event, &mut source);
219 assert!(ret == 0, "Get key event source type failed");
220
221 let mut timestamp = 0;
222 let ret = OH_NativeXComponent_GetKeyEventTimestamp(event, &mut timestamp);
223 assert!(ret == 0, "Get key event timestamp failed");
224
225 let window = WindowRaw(window);
226 let xcomponent = XComponentRaw(xcomponent);
227
228 let key_event_data = KeyEventData {
229 code: KeyCode::from(code),
230 action: Action::from(action),
231 device_id,
232 source: EventSource::from(source),
233 timestamp,
234 };
235
236 #[cfg(not(feature = "multi_mode"))]
237 {
238 let cb = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
239 if let Some(callback) = &cb.on_key_event {
240 callback(xcomponent, window, key_event_data).unwrap();
241 }
242 }
243
244 #[cfg(feature = "multi_mode")]
245 {
246 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
247
248 let id = resolve_id(xcomponent.0).unwrap();
249 if let Some(callback) = cb.get(&id) {
250 if let Some(callback) = &callback.on_key_event {
251 callback(xcomponent, window, key_event_data).unwrap();
252 }
253 }
254 }
255}
256
257pub unsafe extern "C" fn on_mouse_event(
258 xcomponent: *mut OH_NativeXComponent,
259 window: *mut std::os::raw::c_void,
260) {
261 let mut mouse_event = MaybeUninit::<OH_NativeXComponent_MouseEvent>::uninit();
262 let ret = OH_NativeXComponent_GetMouseEvent(xcomponent, window, mouse_event.as_mut_ptr());
263 assert!(ret == 0, "Get mouse event failed");
264
265 let mouse_event_data = mouse_event.assume_init();
266 let data = MouseEventData::from(mouse_event_data);
267
268 let window = WindowRaw(window);
269 let xcomponent = XComponentRaw(xcomponent);
270
271 #[cfg(not(feature = "multi_mode"))]
272 {
273 let cb = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
274 if let Some(callback) = &cb.on_mouse_event {
275 callback(xcomponent, window, data).unwrap();
276 }
277 }
278
279 #[cfg(feature = "multi_mode")]
280 {
281 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
282 let id = resolve_id(xcomponent.0).unwrap();
283 if let Some(callback) = cb.get(&id) {
284 if let Some(callback) = &callback.on_mouse_event {
285 callback(xcomponent, window, data).unwrap();
286 }
287 }
288 }
289}
290
291pub unsafe extern "C" fn on_hover_event(xcomponent: *mut OH_NativeXComponent, is_hover: bool) {
292 let xcomponent = XComponentRaw(xcomponent);
293
294 #[cfg(not(feature = "multi_mode"))]
295 {
296 let cb = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
297 if let Some(callback) = &cb.on_hover_event {
298 callback(xcomponent, is_hover).unwrap();
299 }
300 }
301
302 #[cfg(feature = "multi_mode")]
303 {
304 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
305 let id = resolve_id(xcomponent.0).unwrap();
306 if let Some(callback) = cb.get(&id) {
307 if let Some(callback) = &callback.on_hover_event {
308 callback(xcomponent, is_hover).unwrap();
309 }
310 }
311 }
312}
313
314pub unsafe extern "C" fn on_ui_input_event(
315 xcomponent: *mut OH_NativeXComponent,
316 event: *mut ohos_arkui_input_binding::sys::ArkUI_UIInputEvent,
317 _type_: ohos_arkui_input_binding::sys::ArkUI_UIInputEvent_Type,
318) {
319 let xcomponent = XComponentRaw(xcomponent);
320 let arkui_input_event = ArkUIInputEvent::from_raw(event);
321
322 #[cfg(not(feature = "multi_mode"))]
323 {
324 let cb = X_COMPONENT_CALLBACKS.with_borrow(|cb| cb.clone());
325 if let Some(callback) = &cb.on_ui_input_event {
326 callback(xcomponent, arkui_input_event).unwrap();
327 }
328 }
329
330 #[cfg(feature = "multi_mode")]
331 {
332 let cb = X_COMPONENT_CALLBACKS_MAP.with_borrow(|cb| cb.clone());
333 let id = resolve_id(xcomponent.0).unwrap();
334 if let Some(callback) = cb.get(&id) {
335 if let Some(callback) = &callback.on_ui_input_event {
336 callback(xcomponent, arkui_input_event).unwrap();
337 }
338 }
339 }
340}