Skip to main content

dear_imgui_sys/
lib.rs

1//! Low-level FFI bindings for Dear ImGui (via cimgui C API) with docking support
2//!
3//! This crate provides raw, unsafe bindings to Dear ImGui using the cimgui C API,
4//! specifically targeting the docking branch (multi-viewport capable).
5//!
6//! ## Features
7//!
8//! - **docking**: Always enabled in this crate
9//! - **freetype**: Enable FreeType font rasterizer support
10//! - **wasm**: Enable WebAssembly compatibility
11//! - **stack-layout**: Enable the native patched core artifact used by blueprint-style layouts
12//! - **prebuilt**: Allow downloading a compatible native prebuilt artifact
13//! - **build-from-source**: Force compilation of the native artifact from vendored sources
14//! - **test-engine**: Enable native test engine hooks and force a source build
15//! - **backend-shim-\***: Expose selected repository-owned backend shim modules
16//!   for low-level integrations
17//!
18//! ## WebAssembly Support
19//!
20//! When the `wasm` feature is enabled, this crate provides full WASM compatibility:
21//! - Disables platform-specific functions (file I/O, shell functions, etc.)
22//! - Configures Dear ImGui for WASM environment
23//! - Compatible with wasm-bindgen and web targets
24//!
25//! ## Safety
26//!
27//! This crate provides raw FFI bindings and is inherently unsafe. Users should
28//! prefer the high-level `dear-imgui-rs` crate for safe Rust bindings.
29//!
30//! ## Usage
31//!
32//! This crate is typically not used directly. Instead, use the `dear-imgui-rs` crate
33//! which provides safe, idiomatic Rust bindings built on top of these FFI bindings.
34//!
35//! ## Backend Shim Modules
36//!
37//! For downstream backend crates, engine integrations, and platform-specific
38//! application glue, `dear-imgui-sys` can expose selected official backend
39//! pieces through `backend_shim::*`.
40//!
41//! Important boundary:
42//!
43//! - these modules expose the repository-owned C shim ABI
44//! - they do not expose upstream `imgui_impl_*` C++ symbol names as a stable
45//!   Rust-facing contract
46//! - enabling `backend-shim-*` features does not imply that `dear-imgui-rs`
47//!   already owns a safe wrapper for those backends
48//!
49//! Typical feature gates:
50//!
51//! - `backend-shim-opengl3`
52//! - `backend-shim-android`
53//! - `backend-shim-win32`
54//! - `backend-shim-dx11`
55//!
56//! SDLRenderer3 and SDLGPU3 renderer shims are owned by `dear-imgui-sdl3`.
57//!
58//! ## Android Direction
59//!
60//! The current Android story is intentionally low-level but supported.
61//!
62//! ```toml
63//! [dependencies]
64//! dear-imgui-rs = "0.10"
65//! dear-imgui-sys = { version = "0.10", features = ["backend-shim-android", "backend-shim-opengl3"] }
66//! ```
67//!
68//! Recommended split of responsibilities:
69//!
70//! - `dear-imgui-rs` owns the safe core `Context`, `Io`, frame lifecycle, and
71//!   render snapshots
72//! - `dear-imgui-sys::backend_shim::{android, opengl3}` exposes the low-level
73//!   official backend pieces
74//! - the Android application still owns lifecycle glue, input translation
75//!   strategy, EGL / GLES context creation, and packaging
76//!
77//! The repository's concrete reference for this path is
78//! `examples-android/dear-imgui-android-smoke/`, which now carries a minimal
79//! NativeActivity + EGL / GLES3 render loop proving that downstream users can
80//! build Android support on top of `dear-imgui-rs` + `dear-imgui-sys` even
81//! before a dedicated first-party Android convenience crate exists.
82
83#![allow(non_upper_case_globals)]
84#![allow(non_camel_case_types)]
85#![allow(non_snake_case)]
86#![allow(dead_code)]
87#![allow(unnecessary_transmutes)]
88#![allow(clippy::all)]
89// Bindgen may derive Eq/Hash for structs containing function pointers.
90// New Clippy lint warns these comparisons are unpredictable; suppress for raw FFI types.
91#![allow(unpredictable_function_pointer_comparisons)]
92
93#[cfg(all(feature = "stack-layout", dear_imgui_rs_wasm_import_target))]
94compile_error!("feature `stack-layout` is native-only and cannot be combined with WASM");
95
96#[cfg(all(feature = "test-engine", dear_imgui_rs_wasm_import_target))]
97compile_error!("feature `test-engine` is native source-only and cannot be combined with WASM");
98
99#[cfg(all(feature = "prebuilt", dear_imgui_rs_wasm_import_target))]
100compile_error!("feature `prebuilt` is native-only and cannot be combined with WASM");
101
102// Bindings are generated into OUT_DIR and included via a submodule so that
103// possible inner attributes in the generated file are accepted at module root.
104mod ffi;
105pub use ffi::*;
106
107#[cfg_attr(
108    dear_imgui_rs_wasm_import_target,
109    link(wasm_import_module = "imgui-sys-v1")
110)]
111unsafe extern "C" {
112    pub fn dear_imgui_rs_show_demo_window_without_font_atlas(p_open: *mut bool);
113    pub fn dear_imgui_rs_show_metrics_window_without_font_atlas(p_open: *mut bool);
114    pub fn dear_imgui_rs_show_style_editor_without_font_atlas(ref_: *mut ImGuiStyle);
115    pub fn dear_imgui_rs_show_font_atlas_debug_panel();
116    pub fn dear_imgui_rs_dock_builder_keep_root_alive(root_id: ImGuiID) -> ::std::os::raw::c_int;
117    pub fn dear_imgui_rs_dock_builder_root_has_active_content_window(
118        root_id: ImGuiID,
119    ) -> ::std::os::raw::c_int;
120    pub fn dear_imgui_rs_dock_builder_copy_node(
121        source_root_id: ImGuiID,
122        destination_root_id: ImGuiID,
123        remap_data: *mut ImGuiID,
124        remap_capacity: ::std::os::raw::c_int,
125    ) -> ::std::os::raw::c_int;
126}
127
128/// Optional backend shim entry points for downstream integrations.
129///
130/// These modules expose the repository-owned C shim ABI for selected official
131/// Dear ImGui backends. They do not expose the upstream C++ symbols directly,
132/// and they do not imply that `dear-imgui-sys` or `dear-imgui-rs` owns full
133/// safe integration for those backends.
134pub mod backend_shim;
135
136// This project always builds Dear ImGui with `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` so the native
137// layouts match cimgui's generated struct definitions, and with `IMGUI_USE_WCHAR32` so `ImWchar`
138// must be 32-bit.
139const _: [(); 4] = [(); std::mem::size_of::<ImWchar>()];
140
141// Ensure common ImGui typedefs are available even if bindgen doesn't emit them explicitly
142
143// cimgui exposes typed vectors (e.g., ImVector_ImVec2) instead of a generic ImVector<T>.
144// The sys crate intentionally avoids adding higher-level helpers here.
145
146// Core cimgui calls use the C ABI. PlatformIO aggregate callbacks retain C++ ABI-sensitive
147// signatures, so repository-owned shims translate them to pointer/out-parameter callbacks.
148
149/// Whether this build linked the repository-owned PlatformIO aggregate ABI hook shim.
150pub const HAS_PLATFORM_IO_AGGREGATE_HOOKS: bool = cfg!(dear_imgui_rs_platform_io_hooks);
151
152#[cfg(feature = "stack-layout")]
153mod stack_layout {
154    use super::*;
155
156    unsafe extern "C" {
157        fn dear_imgui_stack_begin_horizontal_str(
158            str_id: *const std::os::raw::c_char,
159            size: ImVec2,
160            align: f32,
161        );
162        fn dear_imgui_stack_begin_horizontal_ptr(
163            ptr_id: *const std::ffi::c_void,
164            size: ImVec2,
165            align: f32,
166        );
167        fn dear_imgui_stack_begin_horizontal_int(id: std::os::raw::c_int, size: ImVec2, align: f32);
168        fn dear_imgui_stack_begin_horizontal_id(id: ImGuiID, size: ImVec2, align: f32);
169        fn dear_imgui_stack_end_horizontal();
170        fn dear_imgui_stack_begin_vertical_str(
171            str_id: *const std::os::raw::c_char,
172            size: ImVec2,
173            align: f32,
174        );
175        fn dear_imgui_stack_begin_vertical_ptr(
176            ptr_id: *const std::ffi::c_void,
177            size: ImVec2,
178            align: f32,
179        );
180        fn dear_imgui_stack_begin_vertical_int(id: std::os::raw::c_int, size: ImVec2, align: f32);
181        fn dear_imgui_stack_begin_vertical_id(id: ImGuiID, size: ImVec2, align: f32);
182        fn dear_imgui_stack_end_vertical();
183        fn dear_imgui_stack_spring(weight: f32, spacing: f32);
184        fn dear_imgui_stack_suspend_layout();
185        fn dear_imgui_stack_resume_layout();
186        fn dear_imgui_stack_destroy_context_state(context: *mut ImGuiContext);
187        fn dear_imgui_stack_state_count() -> usize;
188    }
189
190    /// Start a stack-layout horizontal group using a string ID.
191    ///
192    /// This is a repository-owned compatibility shim for the stack layout extension
193    /// used by `imgui-node-editor` examples; it is not an official Dear ImGui API.
194    ///
195    /// # Safety
196    ///
197    /// Requires an active Dear ImGui context and current window. `str_id` must point
198    /// to a valid NUL-terminated string for the duration of the call.
199    #[inline]
200    pub unsafe fn ImGuiStack_BeginHorizontal_Str(
201        str_id: *const std::os::raw::c_char,
202        size: ImVec2,
203        align: f32,
204    ) {
205        unsafe { dear_imgui_stack_begin_horizontal_str(str_id, size, align) }
206    }
207
208    /// Start a stack-layout horizontal group using a pointer ID.
209    ///
210    /// # Safety
211    ///
212    /// Requires an active Dear ImGui context and current window. `ptr_id` is used as
213    /// an ID value only and is not dereferenced.
214    #[inline]
215    pub unsafe fn ImGuiStack_BeginHorizontal_Ptr(
216        ptr_id: *const std::ffi::c_void,
217        size: ImVec2,
218        align: f32,
219    ) {
220        unsafe { dear_imgui_stack_begin_horizontal_ptr(ptr_id, size, align) }
221    }
222
223    /// Start a stack-layout horizontal group using an integer ID.
224    ///
225    /// # Safety
226    ///
227    /// Requires an active Dear ImGui context and current window.
228    #[inline]
229    pub unsafe fn ImGuiStack_BeginHorizontal_Int(
230        id: std::os::raw::c_int,
231        size: ImVec2,
232        align: f32,
233    ) {
234        unsafe { dear_imgui_stack_begin_horizontal_int(id, size, align) }
235    }
236
237    /// Start a stack-layout horizontal group using a precomputed ImGui ID.
238    ///
239    /// # Safety
240    ///
241    /// Requires an active Dear ImGui context and current window.
242    #[inline]
243    pub unsafe fn ImGuiStack_BeginHorizontal_Id(id: ImGuiID, size: ImVec2, align: f32) {
244        unsafe { dear_imgui_stack_begin_horizontal_id(id, size, align) }
245    }
246
247    /// End the current stack-layout horizontal group.
248    ///
249    /// # Safety
250    ///
251    /// Must match a previous `ImGuiStack_BeginHorizontal_*` call.
252    #[inline]
253    pub unsafe fn ImGuiStack_EndHorizontal() {
254        unsafe { dear_imgui_stack_end_horizontal() }
255    }
256
257    /// Start a stack-layout vertical group using a string ID.
258    ///
259    /// # Safety
260    ///
261    /// Requires an active Dear ImGui context and current window. `str_id` must point
262    /// to a valid NUL-terminated string for the duration of the call.
263    #[inline]
264    pub unsafe fn ImGuiStack_BeginVertical_Str(
265        str_id: *const std::os::raw::c_char,
266        size: ImVec2,
267        align: f32,
268    ) {
269        unsafe { dear_imgui_stack_begin_vertical_str(str_id, size, align) }
270    }
271
272    /// Start a stack-layout vertical group using a pointer ID.
273    ///
274    /// # Safety
275    ///
276    /// Requires an active Dear ImGui context and current window. `ptr_id` is used as
277    /// an ID value only and is not dereferenced.
278    #[inline]
279    pub unsafe fn ImGuiStack_BeginVertical_Ptr(
280        ptr_id: *const std::ffi::c_void,
281        size: ImVec2,
282        align: f32,
283    ) {
284        unsafe { dear_imgui_stack_begin_vertical_ptr(ptr_id, size, align) }
285    }
286
287    /// Start a stack-layout vertical group using an integer ID.
288    ///
289    /// # Safety
290    ///
291    /// Requires an active Dear ImGui context and current window.
292    #[inline]
293    pub unsafe fn ImGuiStack_BeginVertical_Int(id: std::os::raw::c_int, size: ImVec2, align: f32) {
294        unsafe { dear_imgui_stack_begin_vertical_int(id, size, align) }
295    }
296
297    /// Start a stack-layout vertical group using a precomputed ImGui ID.
298    ///
299    /// # Safety
300    ///
301    /// Requires an active Dear ImGui context and current window.
302    #[inline]
303    pub unsafe fn ImGuiStack_BeginVertical_Id(id: ImGuiID, size: ImVec2, align: f32) {
304        unsafe { dear_imgui_stack_begin_vertical_id(id, size, align) }
305    }
306
307    /// End the current stack-layout vertical group.
308    ///
309    /// # Safety
310    ///
311    /// Must match a previous `ImGuiStack_BeginVertical_*` call.
312    #[inline]
313    pub unsafe fn ImGuiStack_EndVertical() {
314        unsafe { dear_imgui_stack_end_vertical() }
315    }
316
317    /// Insert a spring separator into the current stack layout.
318    ///
319    /// # Safety
320    ///
321    /// Requires an active stack layout.
322    #[inline]
323    pub unsafe fn ImGuiStack_Spring(weight: f32, spacing: f32) {
324        unsafe { dear_imgui_stack_spring(weight, spacing) }
325    }
326
327    /// Temporarily suspend the current stack layout.
328    ///
329    /// # Safety
330    ///
331    /// Requires an active stack layout and must be matched by resume.
332    #[inline]
333    pub unsafe fn ImGuiStack_SuspendLayout() {
334        unsafe { dear_imgui_stack_suspend_layout() }
335    }
336
337    /// Resume a suspended stack layout.
338    ///
339    /// # Safety
340    ///
341    /// Must match a previous suspend call.
342    #[inline]
343    pub unsafe fn ImGuiStack_ResumeLayout() {
344        unsafe { dear_imgui_stack_resume_layout() }
345    }
346
347    /// Remove all stack-layout state owned by an ImGui context.
348    ///
349    /// # Safety
350    ///
351    /// `context` must be null or point to a live ImGui context. Call this before destroying that
352    /// context and while no stack-layout operation is active concurrently.
353    #[inline]
354    pub unsafe fn ImGuiStack_DestroyContextState(context: *mut ImGuiContext) {
355        unsafe { dear_imgui_stack_destroy_context_state(context) }
356    }
357
358    /// Return the number of ImGui contexts with retained stack-layout state.
359    ///
360    /// # Safety
361    ///
362    /// No stack-layout operation may mutate the native state concurrently.
363    #[doc(hidden)]
364    #[inline]
365    pub unsafe fn ImGuiStack_StateCount() -> usize {
366        unsafe { dear_imgui_stack_state_count() }
367    }
368}
369
370#[cfg(feature = "stack-layout")]
371pub use stack_layout::*;
372
373#[cfg(dear_imgui_rs_platform_io_hooks)]
374unsafe extern "C" {
375    fn dear_imgui_rs_platform_io_set_platform_set_window_pos(
376        platform_io: *mut ImGuiPlatformIO,
377        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, pos: *const ImVec2)>,
378    );
379
380    fn dear_imgui_rs_platform_io_set_platform_get_window_pos(
381        platform_io: *mut ImGuiPlatformIO,
382        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2)>,
383    );
384
385    fn dear_imgui_rs_platform_io_set_platform_set_window_size(
386        platform_io: *mut ImGuiPlatformIO,
387        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)>,
388    );
389
390    fn dear_imgui_rs_platform_io_set_platform_get_window_size(
391        platform_io: *mut ImGuiPlatformIO,
392        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2)>,
393    );
394
395    fn dear_imgui_rs_platform_io_set_platform_get_window_framebuffer_scale(
396        platform_io: *mut ImGuiPlatformIO,
397        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2)>,
398    );
399
400    fn dear_imgui_rs_platform_io_set_platform_get_window_work_area_insets(
401        platform_io: *mut ImGuiPlatformIO,
402        user_callback: Option<
403            unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4),
404        >,
405    );
406
407    fn dear_imgui_rs_platform_io_clear_platform_set_window_pos_if_pointer_param(
408        platform_io: *mut ImGuiPlatformIO,
409        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, pos: *const ImVec2),
410    ) -> std::os::raw::c_int;
411
412    fn dear_imgui_rs_platform_io_clear_platform_set_window_size_if_pointer_param(
413        platform_io: *mut ImGuiPlatformIO,
414        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
415    ) -> std::os::raw::c_int;
416
417    fn dear_imgui_rs_platform_io_clear_platform_get_window_pos_if_out_param(
418        platform_io: *mut ImGuiPlatformIO,
419        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2),
420    ) -> std::os::raw::c_int;
421
422    fn dear_imgui_rs_platform_io_clear_platform_get_window_size_if_out_param(
423        platform_io: *mut ImGuiPlatformIO,
424        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2),
425    ) -> std::os::raw::c_int;
426
427    fn dear_imgui_rs_platform_io_clear_platform_get_window_framebuffer_scale_if_out_param(
428        platform_io: *mut ImGuiPlatformIO,
429        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2),
430    ) -> std::os::raw::c_int;
431
432    fn dear_imgui_rs_platform_io_get_platform_set_window_pos_pointer_param(
433        platform_io: *mut ImGuiPlatformIO,
434        out_callback: *mut Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, pos: *const ImVec2)>,
435    ) -> std::os::raw::c_int;
436
437    fn dear_imgui_rs_platform_io_get_platform_set_window_size_pointer_param(
438        platform_io: *mut ImGuiPlatformIO,
439        out_callback: *mut Option<
440            unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
441        >,
442    ) -> std::os::raw::c_int;
443
444    fn dear_imgui_rs_platform_io_get_platform_get_window_pos_out_param(
445        platform_io: *mut ImGuiPlatformIO,
446        out_callback: *mut Option<
447            unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2),
448        >,
449    ) -> std::os::raw::c_int;
450
451    fn dear_imgui_rs_platform_io_get_platform_get_window_size_out_param(
452        platform_io: *mut ImGuiPlatformIO,
453        out_callback: *mut Option<
454            unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2),
455        >,
456    ) -> std::os::raw::c_int;
457
458    fn dear_imgui_rs_platform_io_get_platform_get_window_framebuffer_scale_out_param(
459        platform_io: *mut ImGuiPlatformIO,
460        out_callback: *mut Option<
461            unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2),
462        >,
463    ) -> std::os::raw::c_int;
464
465    fn dear_imgui_rs_platform_io_clear_platform_get_window_work_area_insets_if_out_param(
466        platform_io: *mut ImGuiPlatformIO,
467        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4),
468    ) -> std::os::raw::c_int;
469
470    fn dear_imgui_rs_platform_io_set_renderer_set_window_size(
471        platform_io: *mut ImGuiPlatformIO,
472        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)>,
473    );
474
475    fn dear_imgui_rs_platform_io_renderer_set_window_size_matches_pointer_param(
476        platform_io: *mut ImGuiPlatformIO,
477        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
478    ) -> std::os::raw::c_int;
479
480    fn dear_imgui_rs_platform_io_get_renderer_set_window_size_pointer_param(
481        platform_io: *mut ImGuiPlatformIO,
482        out_callback: *mut Option<
483            unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
484        >,
485    ) -> std::os::raw::c_int;
486
487    fn dear_imgui_rs_platform_io_clear_renderer_set_window_size_if_pointer_param(
488        platform_io: *mut ImGuiPlatformIO,
489        user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
490    ) -> std::os::raw::c_int;
491
492    fn dear_imgui_rs_platform_io_probe_aggregate_callbacks(
493        platform_io: *mut ImGuiPlatformIO,
494        out_result: *mut DearImguiRsPlatformIoAggregateProbeResult,
495    ) -> std::os::raw::c_int;
496
497    fn dear_imgui_rs_platform_io_invoke_platform_set_window_pos(
498        callbacks: *const ImGuiPlatformIO,
499        viewport: *mut ImGuiViewport,
500        pos: *const ImVec2,
501    ) -> std::os::raw::c_int;
502
503    fn dear_imgui_rs_platform_io_invoke_platform_set_window_size(
504        callbacks: *const ImGuiPlatformIO,
505        viewport: *mut ImGuiViewport,
506        size: *const ImVec2,
507    ) -> std::os::raw::c_int;
508
509    fn dear_imgui_rs_platform_io_invoke_platform_get_window_pos(
510        callbacks: *const ImGuiPlatformIO,
511        viewport: *mut ImGuiViewport,
512        out_pos: *mut ImVec2,
513    ) -> std::os::raw::c_int;
514
515    fn dear_imgui_rs_platform_io_invoke_platform_get_window_size(
516        callbacks: *const ImGuiPlatformIO,
517        viewport: *mut ImGuiViewport,
518        out_size: *mut ImVec2,
519    ) -> std::os::raw::c_int;
520
521    fn dear_imgui_rs_platform_io_invoke_platform_get_window_framebuffer_scale(
522        callbacks: *const ImGuiPlatformIO,
523        viewport: *mut ImGuiViewport,
524        out_scale: *mut ImVec2,
525    ) -> std::os::raw::c_int;
526
527    fn dear_imgui_rs_platform_io_invoke_renderer_set_window_size(
528        callbacks: *const ImGuiPlatformIO,
529        viewport: *mut ImGuiViewport,
530        size: *const ImVec2,
531    ) -> std::os::raw::c_int;
532
533    fn dear_imgui_rs_platform_io_aggregate_callback_storage_count() -> std::os::raw::c_int;
534
535    fn dear_imgui_rs_find_live_viewport_by_address(
536        context: *mut ImGuiContext,
537        address: usize,
538    ) -> *mut ImGuiViewport;
539}
540
541/// Resolve a retained viewport address through the current Context's internal live registry.
542///
543/// Dear ImGui may change a viewport's numeric ID in place while docking transfers ownership.
544/// This repository-owned helper therefore compares the address against `ImGuiContext::Viewports`
545/// without dereferencing the retained address.
546///
547/// # Safety
548///
549/// `context` must be the current live Context. The returned pointer remains valid only while that
550/// Context stays current and no Dear ImGui operation removes the viewport.
551#[doc(hidden)]
552#[inline]
553pub unsafe fn ImGuiContext_FindLiveViewportByAddress(
554    context: *mut ImGuiContext,
555    address: usize,
556) -> *mut ImGuiViewport {
557    #[cfg(dear_imgui_rs_platform_io_hooks)]
558    {
559        unsafe { dear_imgui_rs_find_live_viewport_by_address(context, address) }
560    }
561    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
562    {
563        let _ = (context, address);
564        std::ptr::null_mut()
565    }
566}
567
568/// Results returned by [`ImGuiPlatformIO_ProbeAggregateCallbacks`].
569///
570/// This test-support ABI is intentionally defined by the repository-owned C++ shim. It lets Rust
571/// tests exercise Dear ImGui's real C++ callback slots without calling Rust trampolines directly.
572#[repr(C)]
573#[derive(Clone, Copy, Debug, Default, PartialEq)]
574pub struct DearImguiRsPlatformIoAggregateProbeResult {
575    pub PlatformGetWindowPos: ImVec2,
576    pub PlatformGetWindowSize: ImVec2,
577    pub PlatformGetWindowFramebufferScale: ImVec2,
578    pub PlatformGetWindowWorkAreaInsets: ImVec4,
579}
580
581/// C++ measurements for selected public Dear ImGui aggregate layouts.
582///
583/// This is an internal CI-only ABI probe enabled by the `abi-probe` feature.
584#[cfg(feature = "abi-probe")]
585#[doc(hidden)]
586#[repr(C)]
587#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
588pub struct DearImguiRsPublicAggregateLayoutProbe {
589    pub ImDrawDataSize: usize,
590    pub ImDrawDataAlign: usize,
591    pub ImDrawDataFrameCountOffset: usize,
592    pub ImDrawDataCmdListsOffset: usize,
593    pub ImDrawDataTexturesOffset: usize,
594    pub ImTextureDataSize: usize,
595    pub ImTextureDataAlign: usize,
596    pub ImTextureDataUniqueIDOffset: usize,
597    pub ImTextureDataQueueUserDataOffset: usize,
598    pub ImTextureDataTexIDOffset: usize,
599    pub ImTextureDataUpdatesOffset: usize,
600    pub ImTextureDataWantDestroyNextFrameOffset: usize,
601    pub ImGuiPlatformIOSize: usize,
602    pub ImGuiPlatformIOAlign: usize,
603    pub ImGuiPlatformIOSessionDateOffset: usize,
604    pub ImGuiPlatformIORenderStateOffset: usize,
605    pub ImGuiPlatformIOPlatformCreateWindowOffset: usize,
606    pub ImGuiPlatformIORendererCreateWindowOffset: usize,
607    pub ImGuiPlatformIOMonitorsOffset: usize,
608    pub ImGuiPlatformIOTexturesOffset: usize,
609    pub ImGuiPlatformIOViewportsOffset: usize,
610}
611
612#[cfg(feature = "abi-probe")]
613unsafe extern "C" {
614    fn dear_imgui_rs_probe_public_aggregate_layouts(
615        out_probe: *mut DearImguiRsPublicAggregateLayoutProbe,
616    ) -> std::os::raw::c_int;
617}
618
619/// Ask the native C++ translation unit to measure selected aggregate layouts.
620///
621/// This is test support, not a stable downstream API.
622#[cfg(feature = "abi-probe")]
623#[doc(hidden)]
624#[inline]
625pub fn ImGui_ProbePublicAggregateLayouts(
626    out_probe: &mut DearImguiRsPublicAggregateLayoutProbe,
627) -> bool {
628    unsafe { dear_imgui_rs_probe_public_aggregate_layouts(out_probe) != 0 }
629}
630
631/// Install a C-compatible pointer-parameter callback for
632/// `ImGuiPlatformIO::Platform_SetWindowPos`.
633///
634/// # Safety
635///
636/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
637/// must obey Dear ImGui's platform callback contract and must not unwind.
638#[inline]
639pub unsafe fn ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam(
640    platform_io: *mut ImGuiPlatformIO,
641    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, pos: *const ImVec2)>,
642) {
643    #[cfg(dear_imgui_rs_platform_io_hooks)]
644    unsafe {
645        dear_imgui_rs_platform_io_set_platform_set_window_pos(platform_io, user_callback)
646    }
647
648    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
649    {
650        if user_callback.is_some() {
651            panic!(
652                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
653                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_SetWindowPos callbacks"
654            );
655        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
656            platform_io.Platform_SetWindowPos = None;
657        }
658    }
659}
660
661/// Install a C-compatible out-parameter callback for `ImGuiPlatformIO::Platform_GetWindowPos`.
662///
663/// This avoids exposing Rust callbacks through the small-aggregate `ImVec2` return ABI used by
664/// Dear ImGui's C++ callback slot. The shim keeps its own per-`ImGuiPlatformIO` storage and does
665/// not occupy `ImGuiIO::BackendLanguageUserData`.
666///
667/// # Safety
668///
669/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
670/// must obey Dear ImGui's platform callback contract and must not unwind.
671#[inline]
672pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam(
673    platform_io: *mut ImGuiPlatformIO,
674    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2)>,
675) {
676    #[cfg(dear_imgui_rs_platform_io_hooks)]
677    unsafe {
678        dear_imgui_rs_platform_io_set_platform_get_window_pos(platform_io, user_callback)
679    }
680
681    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
682    {
683        if user_callback.is_some() {
684            panic!(
685                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
686                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowPos callbacks"
687            );
688        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
689            platform_io.Platform_GetWindowPos = None;
690        }
691    }
692}
693
694/// Install a C-compatible pointer-parameter callback for
695/// `ImGuiPlatformIO::Platform_SetWindowSize`.
696///
697/// # Safety
698///
699/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
700/// must obey Dear ImGui's platform callback contract and must not unwind.
701#[inline]
702pub unsafe fn ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam(
703    platform_io: *mut ImGuiPlatformIO,
704    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)>,
705) {
706    #[cfg(dear_imgui_rs_platform_io_hooks)]
707    unsafe {
708        dear_imgui_rs_platform_io_set_platform_set_window_size(platform_io, user_callback)
709    }
710
711    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
712    {
713        if user_callback.is_some() {
714            panic!(
715                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
716                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_SetWindowSize callbacks"
717            );
718        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
719            platform_io.Platform_SetWindowSize = None;
720        }
721    }
722}
723
724/// Install a C-compatible out-parameter callback for `ImGuiPlatformIO::Platform_GetWindowSize`.
725///
726/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
727///
728/// # Safety
729///
730/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
731/// must obey Dear ImGui's platform callback contract and must not unwind.
732#[inline]
733pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam(
734    platform_io: *mut ImGuiPlatformIO,
735    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2)>,
736) {
737    #[cfg(dear_imgui_rs_platform_io_hooks)]
738    unsafe {
739        dear_imgui_rs_platform_io_set_platform_get_window_size(platform_io, user_callback)
740    }
741
742    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
743    {
744        if user_callback.is_some() {
745            panic!(
746                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
747                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowSize callbacks"
748            );
749        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
750            platform_io.Platform_GetWindowSize = None;
751        }
752    }
753}
754
755/// Install a C-compatible out-parameter callback for
756/// `ImGuiPlatformIO::Platform_GetWindowFramebufferScale`.
757///
758/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
759///
760/// # Safety
761///
762/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
763/// must obey Dear ImGui's platform callback contract and must not unwind.
764#[inline]
765pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam(
766    platform_io: *mut ImGuiPlatformIO,
767    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2)>,
768) {
769    #[cfg(dear_imgui_rs_platform_io_hooks)]
770    unsafe {
771        dear_imgui_rs_platform_io_set_platform_get_window_framebuffer_scale(
772            platform_io,
773            user_callback,
774        )
775    }
776
777    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
778    {
779        if user_callback.is_some() {
780            panic!(
781                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
782                 rebuild without IMGUI_SYS_SKIP_CC to install \
783                 Platform_GetWindowFramebufferScale callbacks"
784            );
785        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
786            platform_io.Platform_GetWindowFramebufferScale = None;
787        }
788    }
789}
790
791/// Install a C-compatible out-parameter callback for
792/// `ImGuiPlatformIO::Platform_GetWindowWorkAreaInsets`.
793///
794/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
795///
796/// # Safety
797///
798/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
799/// must obey Dear ImGui's platform callback contract and must not unwind.
800#[inline]
801pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowWorkAreaInsets_OutParam(
802    platform_io: *mut ImGuiPlatformIO,
803    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4)>,
804) {
805    #[cfg(dear_imgui_rs_platform_io_hooks)]
806    unsafe {
807        dear_imgui_rs_platform_io_set_platform_get_window_work_area_insets(
808            platform_io,
809            user_callback,
810        )
811    }
812
813    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
814    {
815        if user_callback.is_some() {
816            panic!(
817                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
818                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowWorkAreaInsets \
819                 callbacks"
820            );
821        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
822            platform_io.Platform_GetWindowWorkAreaInsets = None;
823        }
824    }
825}
826
827/// Clear `Platform_SetWindowPos` only when it is still owned by the given pointer callback.
828#[doc(hidden)]
829#[inline]
830pub unsafe fn ImGuiPlatformIO_ClearPlatformSetWindowPosIfPointerParam(
831    platform_io: *mut ImGuiPlatformIO,
832    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, pos: *const ImVec2),
833) -> bool {
834    #[cfg(dear_imgui_rs_platform_io_hooks)]
835    unsafe {
836        return dear_imgui_rs_platform_io_clear_platform_set_window_pos_if_pointer_param(
837            platform_io,
838            user_callback,
839        ) != 0;
840    }
841
842    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
843    {
844        let _ = platform_io;
845        let _ = user_callback;
846        false
847    }
848}
849
850/// Clear `Platform_SetWindowSize` only when it is still owned by the given pointer callback.
851#[doc(hidden)]
852#[inline]
853pub unsafe fn ImGuiPlatformIO_ClearPlatformSetWindowSizeIfPointerParam(
854    platform_io: *mut ImGuiPlatformIO,
855    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
856) -> bool {
857    #[cfg(dear_imgui_rs_platform_io_hooks)]
858    unsafe {
859        return dear_imgui_rs_platform_io_clear_platform_set_window_size_if_pointer_param(
860            platform_io,
861            user_callback,
862        ) != 0;
863    }
864
865    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
866    {
867        let _ = platform_io;
868        let _ = user_callback;
869        false
870    }
871}
872
873/// Clear `Platform_GetWindowPos` only when it is still owned by the given out-parameter callback.
874#[doc(hidden)]
875#[inline]
876pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowPosIfOutParam(
877    platform_io: *mut ImGuiPlatformIO,
878    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2),
879) -> bool {
880    #[cfg(dear_imgui_rs_platform_io_hooks)]
881    unsafe {
882        return dear_imgui_rs_platform_io_clear_platform_get_window_pos_if_out_param(
883            platform_io,
884            user_callback,
885        ) != 0;
886    }
887
888    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
889    {
890        let _ = platform_io;
891        let _ = user_callback;
892        false
893    }
894}
895
896/// Clear `Platform_GetWindowSize` only when it is still owned by the given out-parameter callback.
897#[doc(hidden)]
898#[inline]
899pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowSizeIfOutParam(
900    platform_io: *mut ImGuiPlatformIO,
901    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2),
902) -> bool {
903    #[cfg(dear_imgui_rs_platform_io_hooks)]
904    unsafe {
905        return dear_imgui_rs_platform_io_clear_platform_get_window_size_if_out_param(
906            platform_io,
907            user_callback,
908        ) != 0;
909    }
910
911    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
912    {
913        let _ = platform_io;
914        let _ = user_callback;
915        false
916    }
917}
918
919/// Clear `Platform_GetWindowFramebufferScale` only when it is still owned by the given callback.
920#[doc(hidden)]
921#[inline]
922pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowFramebufferScaleIfOutParam(
923    platform_io: *mut ImGuiPlatformIO,
924    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2),
925) -> bool {
926    #[cfg(dear_imgui_rs_platform_io_hooks)]
927    unsafe {
928        return dear_imgui_rs_platform_io_clear_platform_get_window_framebuffer_scale_if_out_param(
929            platform_io,
930            user_callback,
931        ) != 0;
932    }
933
934    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
935    {
936        let _ = platform_io;
937        let _ = user_callback;
938        false
939    }
940}
941
942macro_rules! define_platform_callback_getter {
943    ($name:ident, $native:ident, $callback:ty) => {
944        /// Return the exact callback stored behind a shared C++ aggregate hook.
945        ///
946        /// The query is observationally read-only and returns `None` when the raw slot no longer
947        /// points at this repository's hook.
948        #[doc(hidden)]
949        #[inline]
950        pub unsafe fn $name(platform_io: *mut ImGuiPlatformIO) -> Option<$callback> {
951            #[cfg(dear_imgui_rs_platform_io_hooks)]
952            unsafe {
953                let mut callback = None;
954                if $native(platform_io, &mut callback) != 0 {
955                    return callback;
956                }
957                None
958            }
959
960            #[cfg(not(dear_imgui_rs_platform_io_hooks))]
961            {
962                let _ = platform_io;
963                None
964            }
965        }
966    };
967}
968
969define_platform_callback_getter!(
970    ImGuiPlatformIO_PlatformSetWindowPosPointerParam,
971    dear_imgui_rs_platform_io_get_platform_set_window_pos_pointer_param,
972    unsafe extern "C" fn(*mut ImGuiViewport, *const ImVec2)
973);
974define_platform_callback_getter!(
975    ImGuiPlatformIO_PlatformSetWindowSizePointerParam,
976    dear_imgui_rs_platform_io_get_platform_set_window_size_pointer_param,
977    unsafe extern "C" fn(*mut ImGuiViewport, *const ImVec2)
978);
979define_platform_callback_getter!(
980    ImGuiPlatformIO_PlatformGetWindowPosOutParam,
981    dear_imgui_rs_platform_io_get_platform_get_window_pos_out_param,
982    unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2)
983);
984define_platform_callback_getter!(
985    ImGuiPlatformIO_PlatformGetWindowSizeOutParam,
986    dear_imgui_rs_platform_io_get_platform_get_window_size_out_param,
987    unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2)
988);
989define_platform_callback_getter!(
990    ImGuiPlatformIO_PlatformGetWindowFramebufferScaleOutParam,
991    dear_imgui_rs_platform_io_get_platform_get_window_framebuffer_scale_out_param,
992    unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2)
993);
994
995/// Clear `Platform_GetWindowWorkAreaInsets` only when it is still owned by the given callback.
996#[doc(hidden)]
997#[inline]
998pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowWorkAreaInsetsIfOutParam(
999    platform_io: *mut ImGuiPlatformIO,
1000    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4),
1001) -> bool {
1002    #[cfg(dear_imgui_rs_platform_io_hooks)]
1003    unsafe {
1004        return dear_imgui_rs_platform_io_clear_platform_get_window_work_area_insets_if_out_param(
1005            platform_io,
1006            user_callback,
1007        ) != 0;
1008    }
1009
1010    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1011    {
1012        let _ = platform_io;
1013        let _ = user_callback;
1014        false
1015    }
1016}
1017
1018/// Install a C-compatible pointer-parameter callback for
1019/// `ImGuiPlatformIO::Renderer_SetWindowSize`.
1020///
1021/// # Safety
1022///
1023/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
1024/// must obey Dear ImGui's renderer callback contract and must not unwind.
1025#[inline]
1026pub unsafe fn ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam(
1027    platform_io: *mut ImGuiPlatformIO,
1028    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)>,
1029) {
1030    #[cfg(dear_imgui_rs_platform_io_hooks)]
1031    unsafe {
1032        dear_imgui_rs_platform_io_set_renderer_set_window_size(platform_io, user_callback)
1033    }
1034
1035    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1036    {
1037        if user_callback.is_some() {
1038            panic!(
1039                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
1040                 rebuild without IMGUI_SYS_SKIP_CC to install Renderer_SetWindowSize callbacks"
1041            );
1042        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
1043            platform_io.Renderer_SetWindowSize = None;
1044        }
1045    }
1046}
1047
1048/// Whether `Renderer_SetWindowSize` is currently owned by the given pointer callback.
1049///
1050/// This is an internal ownership primitive for renderer backends. It recognizes only callbacks
1051/// installed through [`ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam`].
1052#[doc(hidden)]
1053#[inline]
1054pub unsafe fn ImGuiPlatformIO_RendererSetWindowSizeMatchesPointerParam(
1055    platform_io: *mut ImGuiPlatformIO,
1056    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
1057) -> bool {
1058    #[cfg(dear_imgui_rs_platform_io_hooks)]
1059    unsafe {
1060        return dear_imgui_rs_platform_io_renderer_set_window_size_matches_pointer_param(
1061            platform_io,
1062            user_callback,
1063        ) != 0;
1064    }
1065
1066    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1067    {
1068        let _ = platform_io;
1069        let _ = user_callback;
1070        false
1071    }
1072}
1073
1074/// Return the pointer-parameter callback currently stored for `Renderer_SetWindowSize`.
1075///
1076/// This is an internal ownership primitive for backends that must preserve a foreign aggregate
1077/// callback replacement even though all pointer-parameter callbacks share one C++ hook address.
1078#[doc(hidden)]
1079#[inline]
1080pub unsafe fn ImGuiPlatformIO_RendererSetWindowSizePointerParam(
1081    platform_io: *mut ImGuiPlatformIO,
1082) -> Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)> {
1083    #[cfg(dear_imgui_rs_platform_io_hooks)]
1084    unsafe {
1085        let mut callback = None;
1086        if dear_imgui_rs_platform_io_get_renderer_set_window_size_pointer_param(
1087            platform_io,
1088            &mut callback,
1089        ) != 0
1090        {
1091            return callback;
1092        }
1093        None
1094    }
1095
1096    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1097    {
1098        let _ = platform_io;
1099        None
1100    }
1101}
1102
1103/// Clear `Renderer_SetWindowSize` only when it is still owned by the given pointer callback.
1104///
1105/// This is an internal ownership primitive for renderer backends.
1106#[doc(hidden)]
1107#[inline]
1108pub unsafe fn ImGuiPlatformIO_ClearRendererSetWindowSizeIfPointerParam(
1109    platform_io: *mut ImGuiPlatformIO,
1110    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
1111) -> bool {
1112    #[cfg(dear_imgui_rs_platform_io_hooks)]
1113    unsafe {
1114        return dear_imgui_rs_platform_io_clear_renderer_set_window_size_if_pointer_param(
1115            platform_io,
1116            user_callback,
1117        ) != 0;
1118    }
1119
1120    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1121    {
1122        let _ = platform_io;
1123        let _ = user_callback;
1124        false
1125    }
1126}
1127
1128/// Invoke all aggregate PlatformIO callback slots through C++.
1129///
1130/// This is a test-support ABI for validating that callbacks installed by the safe layer cross the
1131/// C++/Rust seam through pointers or out parameters rather than small aggregates by value.
1132///
1133/// # Safety
1134///
1135/// `platform_io` and `out_result` must point to valid live values. The current ImGui context must
1136/// own `platform_io`.
1137#[inline]
1138pub unsafe fn ImGuiPlatformIO_ProbeAggregateCallbacks(
1139    platform_io: *mut ImGuiPlatformIO,
1140    out_result: *mut DearImguiRsPlatformIoAggregateProbeResult,
1141) -> bool {
1142    #[cfg(dear_imgui_rs_platform_io_hooks)]
1143    unsafe {
1144        return dear_imgui_rs_platform_io_probe_aggregate_callbacks(platform_io, out_result) != 0;
1145    }
1146
1147    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1148    {
1149        let _ = platform_io;
1150        let _ = out_result;
1151        false
1152    }
1153}
1154
1155/// Invoke a saved native `Platform_SetWindowPos` callback through C++.
1156///
1157/// This prevents Rust from directly calling a C++ callback slot whose signature contains an
1158/// aggregate by value.
1159///
1160/// # Safety
1161///
1162/// Every non-null pointer must remain valid for the duration of the call. When all pointers are
1163/// non-null, `callbacks` must be readable, `viewport` must identify a live viewport accepted by
1164/// the saved callback, and `pos` must be readable. The populated callback slot must have been
1165/// copied from a C++ ABI-compatible Dear ImGui backend callback table and must remain callable.
1166/// The callback must not throw or unwind across the C ABI boundary.
1167#[doc(hidden)]
1168#[inline]
1169pub unsafe fn ImGuiPlatformIO_InvokePlatformSetWindowPos(
1170    callbacks: *const ImGuiPlatformIO,
1171    viewport: *mut ImGuiViewport,
1172    pos: *const ImVec2,
1173) -> bool {
1174    #[cfg(dear_imgui_rs_platform_io_hooks)]
1175    unsafe {
1176        return dear_imgui_rs_platform_io_invoke_platform_set_window_pos(callbacks, viewport, pos)
1177            != 0;
1178    }
1179
1180    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1181    {
1182        let _ = callbacks;
1183        let _ = viewport;
1184        let _ = pos;
1185        false
1186    }
1187}
1188
1189/// Invoke a saved native `Platform_SetWindowSize` callback through C++.
1190///
1191/// This prevents Rust from directly calling a C++ callback slot whose signature contains an
1192/// aggregate by value.
1193///
1194/// # Safety
1195///
1196/// Every non-null pointer must remain valid for the duration of the call. When all pointers are
1197/// non-null, `callbacks` must be readable, `viewport` must identify a live viewport accepted by
1198/// the saved callback, and `size` must be readable. The populated callback slot must have been
1199/// copied from a C++ ABI-compatible Dear ImGui backend callback table and must remain callable.
1200/// The callback must not throw or unwind across the C ABI boundary.
1201#[doc(hidden)]
1202#[inline]
1203pub unsafe fn ImGuiPlatformIO_InvokePlatformSetWindowSize(
1204    callbacks: *const ImGuiPlatformIO,
1205    viewport: *mut ImGuiViewport,
1206    size: *const ImVec2,
1207) -> bool {
1208    #[cfg(dear_imgui_rs_platform_io_hooks)]
1209    unsafe {
1210        return dear_imgui_rs_platform_io_invoke_platform_set_window_size(
1211            callbacks, viewport, size,
1212        ) != 0;
1213    }
1214
1215    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1216    {
1217        let _ = callbacks;
1218        let _ = viewport;
1219        let _ = size;
1220        false
1221    }
1222}
1223
1224/// Invoke a saved native `Platform_GetWindowPos` callback through C++.
1225///
1226/// # Safety
1227///
1228/// Every non-null pointer must remain valid for the duration of the call. `out_pos` must be null or
1229/// valid for writes. A non-null output is initialized to zero before the other arguments are
1230/// validated and is overwritten with the callback result on success. When the callback is invoked,
1231/// `callbacks` must be readable, `viewport` must identify a live viewport accepted by the callback,
1232/// and the populated slot must have been copied from a C++ ABI-compatible Dear ImGui backend
1233/// callback table and remain callable. The callback must not throw or unwind across the C ABI
1234/// boundary.
1235#[doc(hidden)]
1236#[inline]
1237pub unsafe fn ImGuiPlatformIO_InvokePlatformGetWindowPos(
1238    callbacks: *const ImGuiPlatformIO,
1239    viewport: *mut ImGuiViewport,
1240    out_pos: *mut ImVec2,
1241) -> bool {
1242    #[cfg(dear_imgui_rs_platform_io_hooks)]
1243    unsafe {
1244        return dear_imgui_rs_platform_io_invoke_platform_get_window_pos(
1245            callbacks, viewport, out_pos,
1246        ) != 0;
1247    }
1248
1249    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1250    unsafe {
1251        if !out_pos.is_null() {
1252            out_pos.write(ImVec2 { x: 0.0, y: 0.0 });
1253        }
1254        let _ = callbacks;
1255        let _ = viewport;
1256        false
1257    }
1258}
1259
1260/// Invoke a saved native `Platform_GetWindowSize` callback through C++.
1261///
1262/// # Safety
1263///
1264/// Every non-null pointer must remain valid for the duration of the call. `out_size` must be null or
1265/// valid for writes. A non-null output is initialized to zero before the other arguments are
1266/// validated and is overwritten with the callback result on success. When the callback is invoked,
1267/// `callbacks` must be readable, `viewport` must identify a live viewport accepted by the callback,
1268/// and the populated slot must have been copied from a C++ ABI-compatible Dear ImGui backend
1269/// callback table and remain callable. The callback must not throw or unwind across the C ABI
1270/// boundary.
1271#[doc(hidden)]
1272#[inline]
1273pub unsafe fn ImGuiPlatformIO_InvokePlatformGetWindowSize(
1274    callbacks: *const ImGuiPlatformIO,
1275    viewport: *mut ImGuiViewport,
1276    out_size: *mut ImVec2,
1277) -> bool {
1278    #[cfg(dear_imgui_rs_platform_io_hooks)]
1279    unsafe {
1280        return dear_imgui_rs_platform_io_invoke_platform_get_window_size(
1281            callbacks, viewport, out_size,
1282        ) != 0;
1283    }
1284
1285    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1286    unsafe {
1287        if !out_size.is_null() {
1288            out_size.write(ImVec2 { x: 0.0, y: 0.0 });
1289        }
1290        let _ = callbacks;
1291        let _ = viewport;
1292        false
1293    }
1294}
1295
1296/// Invoke a saved native `Platform_GetWindowFramebufferScale` callback through C++.
1297///
1298/// # Safety
1299///
1300/// Every non-null pointer must remain valid for the duration of the call. `out_scale` must be null
1301/// or valid for writes. A non-null output is initialized to zero before the other arguments are
1302/// validated and is overwritten with the callback result on success. When the callback is invoked,
1303/// `callbacks` must be readable, `viewport` must identify a live viewport accepted by the callback,
1304/// and the populated slot must have been copied from a C++ ABI-compatible Dear ImGui backend
1305/// callback table and remain callable. The callback must not throw or unwind across the C ABI
1306/// boundary.
1307#[doc(hidden)]
1308#[inline]
1309pub unsafe fn ImGuiPlatformIO_InvokePlatformGetWindowFramebufferScale(
1310    callbacks: *const ImGuiPlatformIO,
1311    viewport: *mut ImGuiViewport,
1312    out_scale: *mut ImVec2,
1313) -> bool {
1314    #[cfg(dear_imgui_rs_platform_io_hooks)]
1315    unsafe {
1316        return dear_imgui_rs_platform_io_invoke_platform_get_window_framebuffer_scale(
1317            callbacks, viewport, out_scale,
1318        ) != 0;
1319    }
1320
1321    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1322    unsafe {
1323        if !out_scale.is_null() {
1324            out_scale.write(ImVec2 { x: 0.0, y: 0.0 });
1325        }
1326        let _ = callbacks;
1327        let _ = viewport;
1328        false
1329    }
1330}
1331
1332/// Invoke a saved native `Renderer_SetWindowSize` callback through C++.
1333///
1334/// # Safety
1335///
1336/// Every non-null pointer must remain valid for the duration of the call. When all pointers are
1337/// non-null, `callbacks` must be readable, `viewport` must identify a live viewport accepted by
1338/// the saved callback, and `size` must be readable. The populated callback slot must have been
1339/// copied from a C++ ABI-compatible Dear ImGui backend callback table and must remain callable.
1340/// The callback must not throw or unwind across the C ABI boundary.
1341#[doc(hidden)]
1342#[inline]
1343pub unsafe fn ImGuiPlatformIO_InvokeRendererSetWindowSize(
1344    callbacks: *const ImGuiPlatformIO,
1345    viewport: *mut ImGuiViewport,
1346    size: *const ImVec2,
1347) -> bool {
1348    #[cfg(dear_imgui_rs_platform_io_hooks)]
1349    unsafe {
1350        return dear_imgui_rs_platform_io_invoke_renderer_set_window_size(
1351            callbacks, viewport, size,
1352        ) != 0;
1353    }
1354
1355    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1356    {
1357        let _ = callbacks;
1358        let _ = viewport;
1359        let _ = size;
1360        false
1361    }
1362}
1363
1364/// Return the number of live aggregate callback storage entries.
1365///
1366/// This is an internal test-support API. It is not a stable public ABI.
1367///
1368/// # Safety
1369///
1370/// The C++ hook storage follows Dear ImGui's single-threaded context model. Serialize this read
1371/// with every aggregate callback install, clear, and context destruction.
1372#[doc(hidden)]
1373#[inline]
1374pub unsafe fn ImGuiPlatformIO_AggregateCallbackStorageCount() -> usize {
1375    #[cfg(dear_imgui_rs_platform_io_hooks)]
1376    unsafe {
1377        return dear_imgui_rs_platform_io_aggregate_callback_storage_count() as usize;
1378    }
1379
1380    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1381    {
1382        0
1383    }
1384}
1385
1386// Re-export commonly used types for convenience
1387pub use ImColor as Color;
1388pub use ImVec2 as Vector2;
1389pub use ImVec4 as Vector4;
1390
1391/// Version of this Rust binding release.
1392///
1393/// Use [`igGetVersion`] when the linked Dear ImGui runtime version is required.
1394pub const BINDING_VERSION: &str = env!("CARGO_PKG_VERSION");
1395
1396/// Docking features are always available in this crate
1397pub const HAS_DOCKING: bool = true;
1398
1399/// Check if FreeType support is available
1400#[cfg(feature = "freetype")]
1401pub const HAS_FREETYPE: bool = true;
1402
1403#[cfg(not(feature = "freetype"))]
1404pub const HAS_FREETYPE: bool = false;
1405
1406/// Check if WASM support is available
1407#[cfg(all(dear_imgui_rs_wasm_import_target, feature = "wasm"))]
1408pub const HAS_WASM: bool = true;
1409
1410#[cfg(not(all(dear_imgui_rs_wasm_import_target, feature = "wasm")))]
1411pub const HAS_WASM: bool = false;
1412
1413#[cfg(test)]
1414mod target_contract_tests {
1415    #[test]
1416    fn wasm_availability_requires_the_build_selected_import_target() {
1417        assert_eq!(
1418            super::HAS_WASM,
1419            cfg!(all(dear_imgui_rs_wasm_import_target, feature = "wasm"))
1420        );
1421    }
1422}
1423
1424#[cfg(all(test, not(dear_imgui_rs_platform_io_hooks)))]
1425mod aggregate_setter_fallback_tests {
1426    use std::panic::{AssertUnwindSafe, catch_unwind};
1427    use std::ptr;
1428
1429    use super::*;
1430
1431    unsafe extern "C" fn set_vec2_pointer(_viewport: *mut ImGuiViewport, _value: *const ImVec2) {}
1432
1433    unsafe extern "C" fn get_vec2_out(_viewport: *mut ImGuiViewport, _value: *mut ImVec2) {}
1434
1435    unsafe extern "C" fn get_vec4_out(_viewport: *mut ImGuiViewport, _value: *mut ImVec4) {}
1436
1437    unsafe extern "C" fn raw_set_vec2(_viewport: *mut ImGuiViewport, _value: ImVec2) {}
1438
1439    unsafe extern "C" fn raw_get_vec2(_viewport: *mut ImGuiViewport) -> ImVec2 {
1440        ImVec2::zero()
1441    }
1442
1443    unsafe extern "C" fn raw_get_vec4(_viewport: *mut ImGuiViewport) -> ImVec4 {
1444        ImVec4::zero()
1445    }
1446
1447    fn assert_panics(action: impl FnOnce()) {
1448        assert!(catch_unwind(AssertUnwindSafe(action)).is_err());
1449    }
1450
1451    #[test]
1452    fn aggregate_setters_without_cpp_hooks_reject_some_callbacks() {
1453        assert_panics(|| unsafe {
1454            ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam(
1455                ptr::null_mut(),
1456                Some(set_vec2_pointer),
1457            );
1458        });
1459        assert_panics(|| unsafe {
1460            ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam(ptr::null_mut(), Some(get_vec2_out));
1461        });
1462        assert_panics(|| unsafe {
1463            ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam(
1464                ptr::null_mut(),
1465                Some(set_vec2_pointer),
1466            );
1467        });
1468        assert_panics(|| unsafe {
1469            ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam(
1470                ptr::null_mut(),
1471                Some(get_vec2_out),
1472            );
1473        });
1474        assert_panics(|| unsafe {
1475            ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam(
1476                ptr::null_mut(),
1477                Some(get_vec2_out),
1478            );
1479        });
1480        assert_panics(|| unsafe {
1481            ImGuiPlatformIO_Set_Platform_GetWindowWorkAreaInsets_OutParam(
1482                ptr::null_mut(),
1483                Some(get_vec4_out),
1484            );
1485        });
1486        assert_panics(|| unsafe {
1487            ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam(
1488                ptr::null_mut(),
1489                Some(set_vec2_pointer),
1490            );
1491        });
1492    }
1493
1494    #[test]
1495    fn aggregate_setters_without_cpp_hooks_clear_matching_raw_slots() {
1496        let mut platform_io = ImGuiPlatformIO {
1497            Platform_SetWindowPos: Some(raw_set_vec2),
1498            Platform_GetWindowPos: Some(raw_get_vec2),
1499            Platform_SetWindowSize: Some(raw_set_vec2),
1500            Platform_GetWindowSize: Some(raw_get_vec2),
1501            Platform_GetWindowFramebufferScale: Some(raw_get_vec2),
1502            Platform_GetWindowWorkAreaInsets: Some(raw_get_vec4),
1503            Renderer_SetWindowSize: Some(raw_set_vec2),
1504            ..ImGuiPlatformIO::default()
1505        };
1506
1507        unsafe {
1508            ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam(&mut platform_io, None);
1509        }
1510        assert!(platform_io.Platform_SetWindowPos.is_none());
1511        assert!(platform_io.Platform_GetWindowPos.is_some());
1512
1513        unsafe {
1514            ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam(&mut platform_io, None);
1515        }
1516        assert!(platform_io.Platform_GetWindowPos.is_none());
1517        assert!(platform_io.Platform_SetWindowSize.is_some());
1518
1519        unsafe {
1520            ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam(&mut platform_io, None);
1521        }
1522        assert!(platform_io.Platform_SetWindowSize.is_none());
1523        assert!(platform_io.Platform_GetWindowSize.is_some());
1524
1525        unsafe {
1526            ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam(&mut platform_io, None);
1527        }
1528        assert!(platform_io.Platform_GetWindowSize.is_none());
1529        assert!(platform_io.Platform_GetWindowFramebufferScale.is_some());
1530
1531        unsafe {
1532            ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam(&mut platform_io, None);
1533        }
1534        assert!(platform_io.Platform_GetWindowFramebufferScale.is_none());
1535        assert!(platform_io.Platform_GetWindowWorkAreaInsets.is_some());
1536
1537        unsafe {
1538            ImGuiPlatformIO_Set_Platform_GetWindowWorkAreaInsets_OutParam(&mut platform_io, None);
1539        }
1540        assert!(platform_io.Platform_GetWindowWorkAreaInsets.is_none());
1541        assert!(platform_io.Renderer_SetWindowSize.is_some());
1542
1543        unsafe {
1544            ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam(&mut platform_io, None);
1545        }
1546        assert!(platform_io.Renderer_SetWindowSize.is_none());
1547    }
1548}
1549
1550#[cfg(all(test, dear_imgui_rs_platform_io_hooks))]
1551mod aggregate_callback_identity_tests {
1552    use super::*;
1553
1554    type SetCallback = unsafe extern "C" fn(*mut ImGuiViewport, *const ImVec2);
1555    type GetCallback = unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2);
1556
1557    unsafe extern "C" fn set_a(_viewport: *mut ImGuiViewport, _value: *const ImVec2) {}
1558
1559    unsafe extern "C" fn set_b(_viewport: *mut ImGuiViewport, _value: *const ImVec2) {}
1560
1561    unsafe extern "C" fn get_a(_viewport: *mut ImGuiViewport, _value: *mut ImVec2) {}
1562
1563    unsafe extern "C" fn get_b(_viewport: *mut ImGuiViewport, _value: *mut ImVec2) {}
1564
1565    fn assert_set_identity(
1566        platform_io: &mut ImGuiPlatformIO,
1567        install: unsafe fn(*mut ImGuiPlatformIO, Option<SetCallback>),
1568        raw_slot_address: fn(&ImGuiPlatformIO) -> usize,
1569        query: unsafe fn(*mut ImGuiPlatformIO) -> Option<SetCallback>,
1570    ) {
1571        unsafe { install(platform_io, Some(set_a)) };
1572        let hook = raw_slot_address(platform_io);
1573        unsafe { install(platform_io, Some(set_b)) };
1574        assert_eq!(raw_slot_address(platform_io), hook);
1575        assert!(std::ptr::fn_addr_eq(
1576            unsafe { query(platform_io) }.unwrap(),
1577            set_b as SetCallback
1578        ));
1579        assert!(
1580            raw_slot_address(platform_io) == hook,
1581            "query must not mutate the raw slot"
1582        );
1583        assert!(
1584            std::ptr::fn_addr_eq(unsafe { query(platform_io) }.unwrap(), set_b as SetCallback),
1585            "query must not mutate hook storage"
1586        );
1587        unsafe { install(platform_io, None) };
1588    }
1589
1590    fn assert_get_identity(
1591        platform_io: &mut ImGuiPlatformIO,
1592        install: unsafe fn(*mut ImGuiPlatformIO, Option<GetCallback>),
1593        raw_slot_address: fn(&ImGuiPlatformIO) -> usize,
1594        query: unsafe fn(*mut ImGuiPlatformIO) -> Option<GetCallback>,
1595    ) {
1596        unsafe { install(platform_io, Some(get_a)) };
1597        let hook = raw_slot_address(platform_io);
1598        unsafe { install(platform_io, Some(get_b)) };
1599        assert_eq!(raw_slot_address(platform_io), hook);
1600        assert!(std::ptr::fn_addr_eq(
1601            unsafe { query(platform_io) }.unwrap(),
1602            get_b as GetCallback
1603        ));
1604        assert!(
1605            raw_slot_address(platform_io) == hook,
1606            "query must not mutate the raw slot"
1607        );
1608        assert!(
1609            std::ptr::fn_addr_eq(unsafe { query(platform_io) }.unwrap(), get_b as GetCallback),
1610            "query must not mutate hook storage"
1611        );
1612        unsafe { install(platform_io, None) };
1613    }
1614
1615    #[test]
1616    fn platform_vec2_hooks_expose_exact_callback_identity_without_mutation() {
1617        let mut platform_io = ImGuiPlatformIO::default();
1618
1619        assert_set_identity(
1620            &mut platform_io,
1621            ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam,
1622            |io| io.Platform_SetWindowPos.unwrap() as usize,
1623            ImGuiPlatformIO_PlatformSetWindowPosPointerParam,
1624        );
1625        assert_set_identity(
1626            &mut platform_io,
1627            ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam,
1628            |io| io.Platform_SetWindowSize.unwrap() as usize,
1629            ImGuiPlatformIO_PlatformSetWindowSizePointerParam,
1630        );
1631        assert_get_identity(
1632            &mut platform_io,
1633            ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam,
1634            |io| io.Platform_GetWindowPos.unwrap() as usize,
1635            ImGuiPlatformIO_PlatformGetWindowPosOutParam,
1636        );
1637        assert_get_identity(
1638            &mut platform_io,
1639            ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam,
1640            |io| io.Platform_GetWindowSize.unwrap() as usize,
1641            ImGuiPlatformIO_PlatformGetWindowSizeOutParam,
1642        );
1643        assert_get_identity(
1644            &mut platform_io,
1645            ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam,
1646            |io| io.Platform_GetWindowFramebufferScale.unwrap() as usize,
1647            ImGuiPlatformIO_PlatformGetWindowFramebufferScaleOutParam,
1648        );
1649    }
1650}
1651
1652// (No wasm-specific shims are required when using shared memory import style.)
1653
1654impl ImVec2 {
1655    #[inline]
1656    pub const fn new(x: f32, y: f32) -> ImVec2 {
1657        ImVec2 { x, y }
1658    }
1659
1660    #[inline]
1661    pub const fn zero() -> ImVec2 {
1662        ImVec2 { x: 0.0, y: 0.0 }
1663    }
1664}
1665
1666impl From<[f32; 2]> for ImVec2 {
1667    #[inline]
1668    fn from(array: [f32; 2]) -> ImVec2 {
1669        ImVec2::new(array[0], array[1])
1670    }
1671}
1672
1673impl From<(f32, f32)> for ImVec2 {
1674    #[inline]
1675    fn from((x, y): (f32, f32)) -> ImVec2 {
1676        ImVec2::new(x, y)
1677    }
1678}
1679
1680impl From<ImVec2> for [f32; 2] {
1681    #[inline]
1682    fn from(v: ImVec2) -> [f32; 2] {
1683        [v.x, v.y]
1684    }
1685}
1686
1687impl From<ImVec2> for (f32, f32) {
1688    #[inline]
1689    fn from(v: ImVec2) -> (f32, f32) {
1690        (v.x, v.y)
1691    }
1692}
1693
1694impl From<mint::Vector2<f32>> for ImVec2 {
1695    #[inline]
1696    fn from(v: mint::Vector2<f32>) -> ImVec2 {
1697        ImVec2::new(v.x, v.y)
1698    }
1699}
1700
1701#[cfg(feature = "glam")]
1702impl From<glam::Vec2> for ImVec2 {
1703    #[inline]
1704    fn from(v: glam::Vec2) -> ImVec2 {
1705        ImVec2::new(v.x, v.y)
1706    }
1707}
1708
1709impl ImVec4 {
1710    #[inline]
1711    pub const fn new(x: f32, y: f32, z: f32, w: f32) -> ImVec4 {
1712        ImVec4 { x, y, z, w }
1713    }
1714
1715    #[inline]
1716    pub const fn zero() -> ImVec4 {
1717        ImVec4 {
1718            x: 0.0,
1719            y: 0.0,
1720            z: 0.0,
1721            w: 0.0,
1722        }
1723    }
1724}
1725
1726impl From<[f32; 4]> for ImVec4 {
1727    #[inline]
1728    fn from(array: [f32; 4]) -> ImVec4 {
1729        ImVec4::new(array[0], array[1], array[2], array[3])
1730    }
1731}
1732
1733impl From<(f32, f32, f32, f32)> for ImVec4 {
1734    #[inline]
1735    fn from((x, y, z, w): (f32, f32, f32, f32)) -> ImVec4 {
1736        ImVec4::new(x, y, z, w)
1737    }
1738}
1739
1740impl From<ImVec4> for [f32; 4] {
1741    #[inline]
1742    fn from(v: ImVec4) -> [f32; 4] {
1743        [v.x, v.y, v.z, v.w]
1744    }
1745}
1746
1747impl From<ImVec4> for (f32, f32, f32, f32) {
1748    #[inline]
1749    fn from(v: ImVec4) -> (f32, f32, f32, f32) {
1750        (v.x, v.y, v.z, v.w)
1751    }
1752}
1753
1754impl From<mint::Vector4<f32>> for ImVec4 {
1755    #[inline]
1756    fn from(v: mint::Vector4<f32>) -> ImVec4 {
1757        ImVec4::new(v.x, v.y, v.z, v.w)
1758    }
1759}
1760
1761#[cfg(feature = "glam")]
1762impl From<glam::Vec4> for ImVec4 {
1763    #[inline]
1764    fn from(v: glam::Vec4) -> ImVec4 {
1765        ImVec4::new(v.x, v.y, v.z, v.w)
1766    }
1767}