Skip to main content

ohos_xcomponent_binding/events/
native_callbacks.rs

1#![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}