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