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.21", 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    pub ImDrawListSize: usize,
617    pub ImDrawListAlign: usize,
618    pub ImDrawListFlagsStackOffset: usize,
619    pub ImGuiStyleLineEndsOffset: usize,
620    pub ImGuiStyleCurveErrorOffset: usize,
621    pub ImGuiPlatformIOTextureSamplerOffset: usize,
622}
623
624#[cfg(feature = "abi-probe")]
625unsafe extern "C" {
626    fn dear_imgui_rs_probe_public_aggregate_layouts(
627        out_probe: *mut DearImguiRsPublicAggregateLayoutProbe,
628    ) -> std::os::raw::c_int;
629}
630
631/// Ask the native C++ translation unit to measure selected aggregate layouts.
632///
633/// This is test support, not a stable downstream API.
634#[cfg(feature = "abi-probe")]
635#[doc(hidden)]
636#[inline]
637pub fn ImGui_ProbePublicAggregateLayouts(
638    out_probe: &mut DearImguiRsPublicAggregateLayoutProbe,
639) -> bool {
640    unsafe { dear_imgui_rs_probe_public_aggregate_layouts(out_probe) != 0 }
641}
642
643/// Install a C-compatible pointer-parameter callback for
644/// `ImGuiPlatformIO::Platform_SetWindowPos`.
645///
646/// # Safety
647///
648/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
649/// must obey Dear ImGui's platform callback contract and must not unwind.
650#[inline]
651pub unsafe fn ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam(
652    platform_io: *mut ImGuiPlatformIO,
653    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, pos: *const ImVec2)>,
654) {
655    #[cfg(dear_imgui_rs_platform_io_hooks)]
656    unsafe {
657        dear_imgui_rs_platform_io_set_platform_set_window_pos(platform_io, user_callback)
658    }
659
660    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
661    {
662        if user_callback.is_some() {
663            panic!(
664                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
665                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_SetWindowPos callbacks"
666            );
667        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
668            platform_io.Platform_SetWindowPos = None;
669        }
670    }
671}
672
673/// Install a C-compatible out-parameter callback for `ImGuiPlatformIO::Platform_GetWindowPos`.
674///
675/// This avoids exposing Rust callbacks through the small-aggregate `ImVec2` return ABI used by
676/// Dear ImGui's C++ callback slot. The shim keeps its own per-`ImGuiPlatformIO` storage and does
677/// not occupy `ImGuiIO::BackendLanguageUserData`.
678///
679/// # Safety
680///
681/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
682/// must obey Dear ImGui's platform callback contract and must not unwind.
683#[inline]
684pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam(
685    platform_io: *mut ImGuiPlatformIO,
686    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2)>,
687) {
688    #[cfg(dear_imgui_rs_platform_io_hooks)]
689    unsafe {
690        dear_imgui_rs_platform_io_set_platform_get_window_pos(platform_io, user_callback)
691    }
692
693    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
694    {
695        if user_callback.is_some() {
696            panic!(
697                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
698                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowPos callbacks"
699            );
700        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
701            platform_io.Platform_GetWindowPos = None;
702        }
703    }
704}
705
706/// Install a C-compatible pointer-parameter callback for
707/// `ImGuiPlatformIO::Platform_SetWindowSize`.
708///
709/// # Safety
710///
711/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
712/// must obey Dear ImGui's platform callback contract and must not unwind.
713#[inline]
714pub unsafe fn ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam(
715    platform_io: *mut ImGuiPlatformIO,
716    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)>,
717) {
718    #[cfg(dear_imgui_rs_platform_io_hooks)]
719    unsafe {
720        dear_imgui_rs_platform_io_set_platform_set_window_size(platform_io, user_callback)
721    }
722
723    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
724    {
725        if user_callback.is_some() {
726            panic!(
727                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
728                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_SetWindowSize callbacks"
729            );
730        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
731            platform_io.Platform_SetWindowSize = None;
732        }
733    }
734}
735
736/// Install a C-compatible out-parameter callback for `ImGuiPlatformIO::Platform_GetWindowSize`.
737///
738/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
739///
740/// # Safety
741///
742/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
743/// must obey Dear ImGui's platform callback contract and must not unwind.
744#[inline]
745pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam(
746    platform_io: *mut ImGuiPlatformIO,
747    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2)>,
748) {
749    #[cfg(dear_imgui_rs_platform_io_hooks)]
750    unsafe {
751        dear_imgui_rs_platform_io_set_platform_get_window_size(platform_io, user_callback)
752    }
753
754    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
755    {
756        if user_callback.is_some() {
757            panic!(
758                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
759                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowSize callbacks"
760            );
761        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
762            platform_io.Platform_GetWindowSize = None;
763        }
764    }
765}
766
767/// Install a C-compatible out-parameter callback for
768/// `ImGuiPlatformIO::Platform_GetWindowFramebufferScale`.
769///
770/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
771///
772/// # Safety
773///
774/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
775/// must obey Dear ImGui's platform callback contract and must not unwind.
776#[inline]
777pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam(
778    platform_io: *mut ImGuiPlatformIO,
779    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2)>,
780) {
781    #[cfg(dear_imgui_rs_platform_io_hooks)]
782    unsafe {
783        dear_imgui_rs_platform_io_set_platform_get_window_framebuffer_scale(
784            platform_io,
785            user_callback,
786        )
787    }
788
789    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
790    {
791        if user_callback.is_some() {
792            panic!(
793                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
794                 rebuild without IMGUI_SYS_SKIP_CC to install \
795                 Platform_GetWindowFramebufferScale callbacks"
796            );
797        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
798            platform_io.Platform_GetWindowFramebufferScale = None;
799        }
800    }
801}
802
803/// Install a C-compatible out-parameter callback for
804/// `ImGuiPlatformIO::Platform_GetWindowWorkAreaInsets`.
805///
806/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
807///
808/// # Safety
809///
810/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
811/// must obey Dear ImGui's platform callback contract and must not unwind.
812#[inline]
813pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowWorkAreaInsets_OutParam(
814    platform_io: *mut ImGuiPlatformIO,
815    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4)>,
816) {
817    #[cfg(dear_imgui_rs_platform_io_hooks)]
818    unsafe {
819        dear_imgui_rs_platform_io_set_platform_get_window_work_area_insets(
820            platform_io,
821            user_callback,
822        )
823    }
824
825    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
826    {
827        if user_callback.is_some() {
828            panic!(
829                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
830                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowWorkAreaInsets \
831                 callbacks"
832            );
833        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
834            platform_io.Platform_GetWindowWorkAreaInsets = None;
835        }
836    }
837}
838
839/// Clear `Platform_SetWindowPos` only when it is still owned by the given pointer callback.
840#[doc(hidden)]
841#[inline]
842pub unsafe fn ImGuiPlatformIO_ClearPlatformSetWindowPosIfPointerParam(
843    platform_io: *mut ImGuiPlatformIO,
844    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, pos: *const ImVec2),
845) -> bool {
846    #[cfg(dear_imgui_rs_platform_io_hooks)]
847    unsafe {
848        return dear_imgui_rs_platform_io_clear_platform_set_window_pos_if_pointer_param(
849            platform_io,
850            user_callback,
851        ) != 0;
852    }
853
854    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
855    {
856        let _ = platform_io;
857        let _ = user_callback;
858        false
859    }
860}
861
862/// Clear `Platform_SetWindowSize` only when it is still owned by the given pointer callback.
863#[doc(hidden)]
864#[inline]
865pub unsafe fn ImGuiPlatformIO_ClearPlatformSetWindowSizeIfPointerParam(
866    platform_io: *mut ImGuiPlatformIO,
867    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
868) -> bool {
869    #[cfg(dear_imgui_rs_platform_io_hooks)]
870    unsafe {
871        return dear_imgui_rs_platform_io_clear_platform_set_window_size_if_pointer_param(
872            platform_io,
873            user_callback,
874        ) != 0;
875    }
876
877    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
878    {
879        let _ = platform_io;
880        let _ = user_callback;
881        false
882    }
883}
884
885/// Clear `Platform_GetWindowPos` only when it is still owned by the given out-parameter callback.
886#[doc(hidden)]
887#[inline]
888pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowPosIfOutParam(
889    platform_io: *mut ImGuiPlatformIO,
890    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2),
891) -> bool {
892    #[cfg(dear_imgui_rs_platform_io_hooks)]
893    unsafe {
894        return dear_imgui_rs_platform_io_clear_platform_get_window_pos_if_out_param(
895            platform_io,
896            user_callback,
897        ) != 0;
898    }
899
900    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
901    {
902        let _ = platform_io;
903        let _ = user_callback;
904        false
905    }
906}
907
908/// Clear `Platform_GetWindowSize` only when it is still owned by the given out-parameter callback.
909#[doc(hidden)]
910#[inline]
911pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowSizeIfOutParam(
912    platform_io: *mut ImGuiPlatformIO,
913    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2),
914) -> bool {
915    #[cfg(dear_imgui_rs_platform_io_hooks)]
916    unsafe {
917        return dear_imgui_rs_platform_io_clear_platform_get_window_size_if_out_param(
918            platform_io,
919            user_callback,
920        ) != 0;
921    }
922
923    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
924    {
925        let _ = platform_io;
926        let _ = user_callback;
927        false
928    }
929}
930
931/// Clear `Platform_GetWindowFramebufferScale` only when it is still owned by the given callback.
932#[doc(hidden)]
933#[inline]
934pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowFramebufferScaleIfOutParam(
935    platform_io: *mut ImGuiPlatformIO,
936    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2),
937) -> bool {
938    #[cfg(dear_imgui_rs_platform_io_hooks)]
939    unsafe {
940        return dear_imgui_rs_platform_io_clear_platform_get_window_framebuffer_scale_if_out_param(
941            platform_io,
942            user_callback,
943        ) != 0;
944    }
945
946    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
947    {
948        let _ = platform_io;
949        let _ = user_callback;
950        false
951    }
952}
953
954macro_rules! define_platform_callback_getter {
955    ($name:ident, $native:ident, $callback:ty) => {
956        /// Return the exact callback stored behind a shared C++ aggregate hook.
957        ///
958        /// The query is observationally read-only and returns `None` when the raw slot no longer
959        /// points at this repository's hook.
960        #[doc(hidden)]
961        #[inline]
962        pub unsafe fn $name(platform_io: *mut ImGuiPlatformIO) -> Option<$callback> {
963            #[cfg(dear_imgui_rs_platform_io_hooks)]
964            unsafe {
965                let mut callback = None;
966                if $native(platform_io, &mut callback) != 0 {
967                    return callback;
968                }
969                None
970            }
971
972            #[cfg(not(dear_imgui_rs_platform_io_hooks))]
973            {
974                let _ = platform_io;
975                None
976            }
977        }
978    };
979}
980
981define_platform_callback_getter!(
982    ImGuiPlatformIO_PlatformSetWindowPosPointerParam,
983    dear_imgui_rs_platform_io_get_platform_set_window_pos_pointer_param,
984    unsafe extern "C" fn(*mut ImGuiViewport, *const ImVec2)
985);
986define_platform_callback_getter!(
987    ImGuiPlatformIO_PlatformSetWindowSizePointerParam,
988    dear_imgui_rs_platform_io_get_platform_set_window_size_pointer_param,
989    unsafe extern "C" fn(*mut ImGuiViewport, *const ImVec2)
990);
991define_platform_callback_getter!(
992    ImGuiPlatformIO_PlatformGetWindowPosOutParam,
993    dear_imgui_rs_platform_io_get_platform_get_window_pos_out_param,
994    unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2)
995);
996define_platform_callback_getter!(
997    ImGuiPlatformIO_PlatformGetWindowSizeOutParam,
998    dear_imgui_rs_platform_io_get_platform_get_window_size_out_param,
999    unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2)
1000);
1001define_platform_callback_getter!(
1002    ImGuiPlatformIO_PlatformGetWindowFramebufferScaleOutParam,
1003    dear_imgui_rs_platform_io_get_platform_get_window_framebuffer_scale_out_param,
1004    unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2)
1005);
1006
1007/// Clear `Platform_GetWindowWorkAreaInsets` only when it is still owned by the given callback.
1008#[doc(hidden)]
1009#[inline]
1010pub unsafe fn ImGuiPlatformIO_ClearPlatformGetWindowWorkAreaInsetsIfOutParam(
1011    platform_io: *mut ImGuiPlatformIO,
1012    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4),
1013) -> bool {
1014    #[cfg(dear_imgui_rs_platform_io_hooks)]
1015    unsafe {
1016        return dear_imgui_rs_platform_io_clear_platform_get_window_work_area_insets_if_out_param(
1017            platform_io,
1018            user_callback,
1019        ) != 0;
1020    }
1021
1022    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1023    {
1024        let _ = platform_io;
1025        let _ = user_callback;
1026        false
1027    }
1028}
1029
1030/// Install a C-compatible pointer-parameter callback for
1031/// `ImGuiPlatformIO::Renderer_SetWindowSize`.
1032///
1033/// # Safety
1034///
1035/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
1036/// must obey Dear ImGui's renderer callback contract and must not unwind.
1037#[inline]
1038pub unsafe fn ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam(
1039    platform_io: *mut ImGuiPlatformIO,
1040    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)>,
1041) {
1042    #[cfg(dear_imgui_rs_platform_io_hooks)]
1043    unsafe {
1044        dear_imgui_rs_platform_io_set_renderer_set_window_size(platform_io, user_callback)
1045    }
1046
1047    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1048    {
1049        if user_callback.is_some() {
1050            panic!(
1051                "dear-imgui-sys was built without PlatformIO aggregate ABI hooks; \
1052                 rebuild without IMGUI_SYS_SKIP_CC to install Renderer_SetWindowSize callbacks"
1053            );
1054        } else if let Some(platform_io) = unsafe { platform_io.as_mut() } {
1055            platform_io.Renderer_SetWindowSize = None;
1056        }
1057    }
1058}
1059
1060/// Whether `Renderer_SetWindowSize` is currently owned by the given pointer callback.
1061///
1062/// This is an internal ownership primitive for renderer backends. It recognizes only callbacks
1063/// installed through [`ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam`].
1064#[doc(hidden)]
1065#[inline]
1066pub unsafe fn ImGuiPlatformIO_RendererSetWindowSizeMatchesPointerParam(
1067    platform_io: *mut ImGuiPlatformIO,
1068    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
1069) -> bool {
1070    #[cfg(dear_imgui_rs_platform_io_hooks)]
1071    unsafe {
1072        return dear_imgui_rs_platform_io_renderer_set_window_size_matches_pointer_param(
1073            platform_io,
1074            user_callback,
1075        ) != 0;
1076    }
1077
1078    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1079    {
1080        let _ = platform_io;
1081        let _ = user_callback;
1082        false
1083    }
1084}
1085
1086/// Return the pointer-parameter callback currently stored for `Renderer_SetWindowSize`.
1087///
1088/// This is an internal ownership primitive for backends that must preserve a foreign aggregate
1089/// callback replacement even though all pointer-parameter callbacks share one C++ hook address.
1090#[doc(hidden)]
1091#[inline]
1092pub unsafe fn ImGuiPlatformIO_RendererSetWindowSizePointerParam(
1093    platform_io: *mut ImGuiPlatformIO,
1094) -> Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2)> {
1095    #[cfg(dear_imgui_rs_platform_io_hooks)]
1096    unsafe {
1097        let mut callback = None;
1098        if dear_imgui_rs_platform_io_get_renderer_set_window_size_pointer_param(
1099            platform_io,
1100            &mut callback,
1101        ) != 0
1102        {
1103            return callback;
1104        }
1105        None
1106    }
1107
1108    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1109    {
1110        let _ = platform_io;
1111        None
1112    }
1113}
1114
1115/// Clear `Renderer_SetWindowSize` only when it is still owned by the given pointer callback.
1116///
1117/// This is an internal ownership primitive for renderer backends.
1118#[doc(hidden)]
1119#[inline]
1120pub unsafe fn ImGuiPlatformIO_ClearRendererSetWindowSizeIfPointerParam(
1121    platform_io: *mut ImGuiPlatformIO,
1122    user_callback: unsafe extern "C" fn(vp: *mut ImGuiViewport, size: *const ImVec2),
1123) -> bool {
1124    #[cfg(dear_imgui_rs_platform_io_hooks)]
1125    unsafe {
1126        return dear_imgui_rs_platform_io_clear_renderer_set_window_size_if_pointer_param(
1127            platform_io,
1128            user_callback,
1129        ) != 0;
1130    }
1131
1132    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1133    {
1134        let _ = platform_io;
1135        let _ = user_callback;
1136        false
1137    }
1138}
1139
1140/// Invoke all aggregate PlatformIO callback slots through C++.
1141///
1142/// This is a test-support ABI for validating that callbacks installed by the safe layer cross the
1143/// C++/Rust seam through pointers or out parameters rather than small aggregates by value.
1144///
1145/// # Safety
1146///
1147/// `platform_io` and `out_result` must point to valid live values. The current ImGui context must
1148/// own `platform_io`.
1149#[inline]
1150pub unsafe fn ImGuiPlatformIO_ProbeAggregateCallbacks(
1151    platform_io: *mut ImGuiPlatformIO,
1152    out_result: *mut DearImguiRsPlatformIoAggregateProbeResult,
1153) -> bool {
1154    #[cfg(dear_imgui_rs_platform_io_hooks)]
1155    unsafe {
1156        return dear_imgui_rs_platform_io_probe_aggregate_callbacks(platform_io, out_result) != 0;
1157    }
1158
1159    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1160    {
1161        let _ = platform_io;
1162        let _ = out_result;
1163        false
1164    }
1165}
1166
1167/// Invoke a saved native `Platform_SetWindowPos` callback through C++.
1168///
1169/// This prevents Rust from directly calling a C++ callback slot whose signature contains an
1170/// aggregate by value.
1171///
1172/// # Safety
1173///
1174/// Every non-null pointer must remain valid for the duration of the call. When all pointers are
1175/// non-null, `callbacks` must be readable, `viewport` must identify a live viewport accepted by
1176/// the saved callback, and `pos` must be readable. The populated callback slot must have been
1177/// copied from a C++ ABI-compatible Dear ImGui backend callback table and must remain callable.
1178/// The callback must not throw or unwind across the C ABI boundary.
1179#[doc(hidden)]
1180#[inline]
1181pub unsafe fn ImGuiPlatformIO_InvokePlatformSetWindowPos(
1182    callbacks: *const ImGuiPlatformIO,
1183    viewport: *mut ImGuiViewport,
1184    pos: *const ImVec2,
1185) -> bool {
1186    #[cfg(dear_imgui_rs_platform_io_hooks)]
1187    unsafe {
1188        return dear_imgui_rs_platform_io_invoke_platform_set_window_pos(callbacks, viewport, pos)
1189            != 0;
1190    }
1191
1192    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1193    {
1194        let _ = callbacks;
1195        let _ = viewport;
1196        let _ = pos;
1197        false
1198    }
1199}
1200
1201/// Invoke a saved native `Platform_SetWindowSize` callback through C++.
1202///
1203/// This prevents Rust from directly calling a C++ callback slot whose signature contains an
1204/// aggregate by value.
1205///
1206/// # Safety
1207///
1208/// Every non-null pointer must remain valid for the duration of the call. When all pointers are
1209/// non-null, `callbacks` must be readable, `viewport` must identify a live viewport accepted by
1210/// the saved callback, and `size` must be readable. The populated callback slot must have been
1211/// copied from a C++ ABI-compatible Dear ImGui backend callback table and must remain callable.
1212/// The callback must not throw or unwind across the C ABI boundary.
1213#[doc(hidden)]
1214#[inline]
1215pub unsafe fn ImGuiPlatformIO_InvokePlatformSetWindowSize(
1216    callbacks: *const ImGuiPlatformIO,
1217    viewport: *mut ImGuiViewport,
1218    size: *const ImVec2,
1219) -> bool {
1220    #[cfg(dear_imgui_rs_platform_io_hooks)]
1221    unsafe {
1222        return dear_imgui_rs_platform_io_invoke_platform_set_window_size(
1223            callbacks, viewport, size,
1224        ) != 0;
1225    }
1226
1227    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1228    {
1229        let _ = callbacks;
1230        let _ = viewport;
1231        let _ = size;
1232        false
1233    }
1234}
1235
1236/// Invoke a saved native `Platform_GetWindowPos` callback through C++.
1237///
1238/// # Safety
1239///
1240/// Every non-null pointer must remain valid for the duration of the call. `out_pos` must be null or
1241/// valid for writes. A non-null output is initialized to zero before the other arguments are
1242/// validated and is overwritten with the callback result on success. When the callback is invoked,
1243/// `callbacks` must be readable, `viewport` must identify a live viewport accepted by the callback,
1244/// and the populated slot must have been copied from a C++ ABI-compatible Dear ImGui backend
1245/// callback table and remain callable. The callback must not throw or unwind across the C ABI
1246/// boundary.
1247#[doc(hidden)]
1248#[inline]
1249pub unsafe fn ImGuiPlatformIO_InvokePlatformGetWindowPos(
1250    callbacks: *const ImGuiPlatformIO,
1251    viewport: *mut ImGuiViewport,
1252    out_pos: *mut ImVec2,
1253) -> bool {
1254    #[cfg(dear_imgui_rs_platform_io_hooks)]
1255    unsafe {
1256        return dear_imgui_rs_platform_io_invoke_platform_get_window_pos(
1257            callbacks, viewport, out_pos,
1258        ) != 0;
1259    }
1260
1261    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1262    unsafe {
1263        if !out_pos.is_null() {
1264            out_pos.write(ImVec2 { x: 0.0, y: 0.0 });
1265        }
1266        let _ = callbacks;
1267        let _ = viewport;
1268        false
1269    }
1270}
1271
1272/// Invoke a saved native `Platform_GetWindowSize` callback through C++.
1273///
1274/// # Safety
1275///
1276/// Every non-null pointer must remain valid for the duration of the call. `out_size` must be null or
1277/// valid for writes. A non-null output is initialized to zero before the other arguments are
1278/// validated and is overwritten with the callback result on success. When the callback is invoked,
1279/// `callbacks` must be readable, `viewport` must identify a live viewport accepted by the callback,
1280/// and the populated slot must have been copied from a C++ ABI-compatible Dear ImGui backend
1281/// callback table and remain callable. The callback must not throw or unwind across the C ABI
1282/// boundary.
1283#[doc(hidden)]
1284#[inline]
1285pub unsafe fn ImGuiPlatformIO_InvokePlatformGetWindowSize(
1286    callbacks: *const ImGuiPlatformIO,
1287    viewport: *mut ImGuiViewport,
1288    out_size: *mut ImVec2,
1289) -> bool {
1290    #[cfg(dear_imgui_rs_platform_io_hooks)]
1291    unsafe {
1292        return dear_imgui_rs_platform_io_invoke_platform_get_window_size(
1293            callbacks, viewport, out_size,
1294        ) != 0;
1295    }
1296
1297    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1298    unsafe {
1299        if !out_size.is_null() {
1300            out_size.write(ImVec2 { x: 0.0, y: 0.0 });
1301        }
1302        let _ = callbacks;
1303        let _ = viewport;
1304        false
1305    }
1306}
1307
1308/// Invoke a saved native `Platform_GetWindowFramebufferScale` callback through C++.
1309///
1310/// # Safety
1311///
1312/// Every non-null pointer must remain valid for the duration of the call. `out_scale` must be null
1313/// or valid for writes. A non-null output is initialized to zero before the other arguments are
1314/// validated and is overwritten with the callback result on success. When the callback is invoked,
1315/// `callbacks` must be readable, `viewport` must identify a live viewport accepted by the callback,
1316/// and the populated slot must have been copied from a C++ ABI-compatible Dear ImGui backend
1317/// callback table and remain callable. The callback must not throw or unwind across the C ABI
1318/// boundary.
1319#[doc(hidden)]
1320#[inline]
1321pub unsafe fn ImGuiPlatformIO_InvokePlatformGetWindowFramebufferScale(
1322    callbacks: *const ImGuiPlatformIO,
1323    viewport: *mut ImGuiViewport,
1324    out_scale: *mut ImVec2,
1325) -> bool {
1326    #[cfg(dear_imgui_rs_platform_io_hooks)]
1327    unsafe {
1328        return dear_imgui_rs_platform_io_invoke_platform_get_window_framebuffer_scale(
1329            callbacks, viewport, out_scale,
1330        ) != 0;
1331    }
1332
1333    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1334    unsafe {
1335        if !out_scale.is_null() {
1336            out_scale.write(ImVec2 { x: 0.0, y: 0.0 });
1337        }
1338        let _ = callbacks;
1339        let _ = viewport;
1340        false
1341    }
1342}
1343
1344/// Invoke a saved native `Renderer_SetWindowSize` callback through C++.
1345///
1346/// # Safety
1347///
1348/// Every non-null pointer must remain valid for the duration of the call. When all pointers are
1349/// non-null, `callbacks` must be readable, `viewport` must identify a live viewport accepted by
1350/// the saved callback, and `size` must be readable. The populated callback slot must have been
1351/// copied from a C++ ABI-compatible Dear ImGui backend callback table and must remain callable.
1352/// The callback must not throw or unwind across the C ABI boundary.
1353#[doc(hidden)]
1354#[inline]
1355pub unsafe fn ImGuiPlatformIO_InvokeRendererSetWindowSize(
1356    callbacks: *const ImGuiPlatformIO,
1357    viewport: *mut ImGuiViewport,
1358    size: *const ImVec2,
1359) -> bool {
1360    #[cfg(dear_imgui_rs_platform_io_hooks)]
1361    unsafe {
1362        return dear_imgui_rs_platform_io_invoke_renderer_set_window_size(
1363            callbacks, viewport, size,
1364        ) != 0;
1365    }
1366
1367    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1368    {
1369        let _ = callbacks;
1370        let _ = viewport;
1371        let _ = size;
1372        false
1373    }
1374}
1375
1376/// Return the number of live aggregate callback storage entries.
1377///
1378/// This is an internal test-support API. It is not a stable public ABI.
1379///
1380/// # Safety
1381///
1382/// The C++ hook storage follows Dear ImGui's single-threaded context model. Serialize this read
1383/// with every aggregate callback install, clear, and context destruction.
1384#[doc(hidden)]
1385#[inline]
1386pub unsafe fn ImGuiPlatformIO_AggregateCallbackStorageCount() -> usize {
1387    #[cfg(dear_imgui_rs_platform_io_hooks)]
1388    unsafe {
1389        return dear_imgui_rs_platform_io_aggregate_callback_storage_count() as usize;
1390    }
1391
1392    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
1393    {
1394        0
1395    }
1396}
1397
1398// Re-export commonly used types for convenience
1399pub use ImColor as Color;
1400pub use ImVec2 as Vector2;
1401pub use ImVec4 as Vector4;
1402
1403/// Version of this Rust binding release.
1404///
1405/// Use [`igGetVersion`] when the linked Dear ImGui runtime version is required.
1406pub const BINDING_VERSION: &str = env!("CARGO_PKG_VERSION");
1407
1408/// Docking features are always available in this crate
1409pub const HAS_DOCKING: bool = true;
1410
1411/// Check if FreeType support is available
1412#[cfg(feature = "freetype")]
1413pub const HAS_FREETYPE: bool = true;
1414
1415#[cfg(not(feature = "freetype"))]
1416pub const HAS_FREETYPE: bool = false;
1417
1418/// Check if WASM support is available
1419#[cfg(all(dear_imgui_rs_wasm_import_target, feature = "wasm"))]
1420pub const HAS_WASM: bool = true;
1421
1422#[cfg(not(all(dear_imgui_rs_wasm_import_target, feature = "wasm")))]
1423pub const HAS_WASM: bool = false;
1424
1425#[cfg(test)]
1426mod target_contract_tests {
1427    #[test]
1428    fn wasm_availability_requires_the_build_selected_import_target() {
1429        assert_eq!(
1430            super::HAS_WASM,
1431            cfg!(all(dear_imgui_rs_wasm_import_target, feature = "wasm"))
1432        );
1433    }
1434}
1435
1436#[cfg(all(test, not(dear_imgui_rs_platform_io_hooks)))]
1437mod aggregate_setter_fallback_tests {
1438    use std::panic::{AssertUnwindSafe, catch_unwind};
1439    use std::ptr;
1440
1441    use super::*;
1442
1443    unsafe extern "C" fn set_vec2_pointer(_viewport: *mut ImGuiViewport, _value: *const ImVec2) {}
1444
1445    unsafe extern "C" fn get_vec2_out(_viewport: *mut ImGuiViewport, _value: *mut ImVec2) {}
1446
1447    unsafe extern "C" fn get_vec4_out(_viewport: *mut ImGuiViewport, _value: *mut ImVec4) {}
1448
1449    unsafe extern "C" fn raw_set_vec2(_viewport: *mut ImGuiViewport, _value: ImVec2) {}
1450
1451    unsafe extern "C" fn raw_get_vec2(_viewport: *mut ImGuiViewport) -> ImVec2 {
1452        ImVec2::zero()
1453    }
1454
1455    unsafe extern "C" fn raw_get_vec4(_viewport: *mut ImGuiViewport) -> ImVec4 {
1456        ImVec4::zero()
1457    }
1458
1459    fn assert_panics(action: impl FnOnce()) {
1460        assert!(catch_unwind(AssertUnwindSafe(action)).is_err());
1461    }
1462
1463    #[test]
1464    fn aggregate_setters_without_cpp_hooks_reject_some_callbacks() {
1465        assert_panics(|| unsafe {
1466            ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam(
1467                ptr::null_mut(),
1468                Some(set_vec2_pointer),
1469            );
1470        });
1471        assert_panics(|| unsafe {
1472            ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam(ptr::null_mut(), Some(get_vec2_out));
1473        });
1474        assert_panics(|| unsafe {
1475            ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam(
1476                ptr::null_mut(),
1477                Some(set_vec2_pointer),
1478            );
1479        });
1480        assert_panics(|| unsafe {
1481            ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam(
1482                ptr::null_mut(),
1483                Some(get_vec2_out),
1484            );
1485        });
1486        assert_panics(|| unsafe {
1487            ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam(
1488                ptr::null_mut(),
1489                Some(get_vec2_out),
1490            );
1491        });
1492        assert_panics(|| unsafe {
1493            ImGuiPlatformIO_Set_Platform_GetWindowWorkAreaInsets_OutParam(
1494                ptr::null_mut(),
1495                Some(get_vec4_out),
1496            );
1497        });
1498        assert_panics(|| unsafe {
1499            ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam(
1500                ptr::null_mut(),
1501                Some(set_vec2_pointer),
1502            );
1503        });
1504    }
1505
1506    #[test]
1507    fn aggregate_setters_without_cpp_hooks_clear_matching_raw_slots() {
1508        let mut platform_io = ImGuiPlatformIO {
1509            Platform_SetWindowPos: Some(raw_set_vec2),
1510            Platform_GetWindowPos: Some(raw_get_vec2),
1511            Platform_SetWindowSize: Some(raw_set_vec2),
1512            Platform_GetWindowSize: Some(raw_get_vec2),
1513            Platform_GetWindowFramebufferScale: Some(raw_get_vec2),
1514            Platform_GetWindowWorkAreaInsets: Some(raw_get_vec4),
1515            Renderer_SetWindowSize: Some(raw_set_vec2),
1516            ..ImGuiPlatformIO::default()
1517        };
1518
1519        unsafe {
1520            ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam(&mut platform_io, None);
1521        }
1522        assert!(platform_io.Platform_SetWindowPos.is_none());
1523        assert!(platform_io.Platform_GetWindowPos.is_some());
1524
1525        unsafe {
1526            ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam(&mut platform_io, None);
1527        }
1528        assert!(platform_io.Platform_GetWindowPos.is_none());
1529        assert!(platform_io.Platform_SetWindowSize.is_some());
1530
1531        unsafe {
1532            ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam(&mut platform_io, None);
1533        }
1534        assert!(platform_io.Platform_SetWindowSize.is_none());
1535        assert!(platform_io.Platform_GetWindowSize.is_some());
1536
1537        unsafe {
1538            ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam(&mut platform_io, None);
1539        }
1540        assert!(platform_io.Platform_GetWindowSize.is_none());
1541        assert!(platform_io.Platform_GetWindowFramebufferScale.is_some());
1542
1543        unsafe {
1544            ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam(&mut platform_io, None);
1545        }
1546        assert!(platform_io.Platform_GetWindowFramebufferScale.is_none());
1547        assert!(platform_io.Platform_GetWindowWorkAreaInsets.is_some());
1548
1549        unsafe {
1550            ImGuiPlatformIO_Set_Platform_GetWindowWorkAreaInsets_OutParam(&mut platform_io, None);
1551        }
1552        assert!(platform_io.Platform_GetWindowWorkAreaInsets.is_none());
1553        assert!(platform_io.Renderer_SetWindowSize.is_some());
1554
1555        unsafe {
1556            ImGuiPlatformIO_Set_Renderer_SetWindowSize_PointerParam(&mut platform_io, None);
1557        }
1558        assert!(platform_io.Renderer_SetWindowSize.is_none());
1559    }
1560}
1561
1562#[cfg(all(test, dear_imgui_rs_platform_io_hooks))]
1563mod aggregate_callback_identity_tests {
1564    use super::*;
1565
1566    type SetCallback = unsafe extern "C" fn(*mut ImGuiViewport, *const ImVec2);
1567    type GetCallback = unsafe extern "C" fn(*mut ImGuiViewport, *mut ImVec2);
1568
1569    unsafe extern "C" fn set_a(_viewport: *mut ImGuiViewport, _value: *const ImVec2) {}
1570
1571    unsafe extern "C" fn set_b(_viewport: *mut ImGuiViewport, _value: *const ImVec2) {}
1572
1573    unsafe extern "C" fn get_a(_viewport: *mut ImGuiViewport, _value: *mut ImVec2) {}
1574
1575    unsafe extern "C" fn get_b(_viewport: *mut ImGuiViewport, _value: *mut ImVec2) {}
1576
1577    fn assert_set_identity(
1578        platform_io: &mut ImGuiPlatformIO,
1579        install: unsafe fn(*mut ImGuiPlatformIO, Option<SetCallback>),
1580        raw_slot_address: fn(&ImGuiPlatformIO) -> usize,
1581        query: unsafe fn(*mut ImGuiPlatformIO) -> Option<SetCallback>,
1582    ) {
1583        unsafe { install(platform_io, Some(set_a)) };
1584        let hook = raw_slot_address(platform_io);
1585        unsafe { install(platform_io, Some(set_b)) };
1586        assert_eq!(raw_slot_address(platform_io), hook);
1587        assert!(std::ptr::fn_addr_eq(
1588            unsafe { query(platform_io) }.unwrap(),
1589            set_b as SetCallback
1590        ));
1591        assert!(
1592            raw_slot_address(platform_io) == hook,
1593            "query must not mutate the raw slot"
1594        );
1595        assert!(
1596            std::ptr::fn_addr_eq(unsafe { query(platform_io) }.unwrap(), set_b as SetCallback),
1597            "query must not mutate hook storage"
1598        );
1599        unsafe { install(platform_io, None) };
1600    }
1601
1602    fn assert_get_identity(
1603        platform_io: &mut ImGuiPlatformIO,
1604        install: unsafe fn(*mut ImGuiPlatformIO, Option<GetCallback>),
1605        raw_slot_address: fn(&ImGuiPlatformIO) -> usize,
1606        query: unsafe fn(*mut ImGuiPlatformIO) -> Option<GetCallback>,
1607    ) {
1608        unsafe { install(platform_io, Some(get_a)) };
1609        let hook = raw_slot_address(platform_io);
1610        unsafe { install(platform_io, Some(get_b)) };
1611        assert_eq!(raw_slot_address(platform_io), hook);
1612        assert!(std::ptr::fn_addr_eq(
1613            unsafe { query(platform_io) }.unwrap(),
1614            get_b as GetCallback
1615        ));
1616        assert!(
1617            raw_slot_address(platform_io) == hook,
1618            "query must not mutate the raw slot"
1619        );
1620        assert!(
1621            std::ptr::fn_addr_eq(unsafe { query(platform_io) }.unwrap(), get_b as GetCallback),
1622            "query must not mutate hook storage"
1623        );
1624        unsafe { install(platform_io, None) };
1625    }
1626
1627    #[test]
1628    fn platform_vec2_hooks_expose_exact_callback_identity_without_mutation() {
1629        let mut platform_io = ImGuiPlatformIO::default();
1630
1631        assert_set_identity(
1632            &mut platform_io,
1633            ImGuiPlatformIO_Set_Platform_SetWindowPos_PointerParam,
1634            |io| io.Platform_SetWindowPos.unwrap() as usize,
1635            ImGuiPlatformIO_PlatformSetWindowPosPointerParam,
1636        );
1637        assert_set_identity(
1638            &mut platform_io,
1639            ImGuiPlatformIO_Set_Platform_SetWindowSize_PointerParam,
1640            |io| io.Platform_SetWindowSize.unwrap() as usize,
1641            ImGuiPlatformIO_PlatformSetWindowSizePointerParam,
1642        );
1643        assert_get_identity(
1644            &mut platform_io,
1645            ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam,
1646            |io| io.Platform_GetWindowPos.unwrap() as usize,
1647            ImGuiPlatformIO_PlatformGetWindowPosOutParam,
1648        );
1649        assert_get_identity(
1650            &mut platform_io,
1651            ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam,
1652            |io| io.Platform_GetWindowSize.unwrap() as usize,
1653            ImGuiPlatformIO_PlatformGetWindowSizeOutParam,
1654        );
1655        assert_get_identity(
1656            &mut platform_io,
1657            ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam,
1658            |io| io.Platform_GetWindowFramebufferScale.unwrap() as usize,
1659            ImGuiPlatformIO_PlatformGetWindowFramebufferScaleOutParam,
1660        );
1661    }
1662}
1663
1664// (No wasm-specific shims are required when using shared memory import style.)
1665
1666impl ImVec2 {
1667    #[inline]
1668    pub const fn new(x: f32, y: f32) -> ImVec2 {
1669        ImVec2 { x, y }
1670    }
1671
1672    #[inline]
1673    pub const fn zero() -> ImVec2 {
1674        ImVec2 { x: 0.0, y: 0.0 }
1675    }
1676}
1677
1678impl From<[f32; 2]> for ImVec2 {
1679    #[inline]
1680    fn from(array: [f32; 2]) -> ImVec2 {
1681        ImVec2::new(array[0], array[1])
1682    }
1683}
1684
1685impl From<(f32, f32)> for ImVec2 {
1686    #[inline]
1687    fn from((x, y): (f32, f32)) -> ImVec2 {
1688        ImVec2::new(x, y)
1689    }
1690}
1691
1692impl From<ImVec2> for [f32; 2] {
1693    #[inline]
1694    fn from(v: ImVec2) -> [f32; 2] {
1695        [v.x, v.y]
1696    }
1697}
1698
1699impl From<ImVec2> for (f32, f32) {
1700    #[inline]
1701    fn from(v: ImVec2) -> (f32, f32) {
1702        (v.x, v.y)
1703    }
1704}
1705
1706impl From<mint::Vector2<f32>> for ImVec2 {
1707    #[inline]
1708    fn from(v: mint::Vector2<f32>) -> ImVec2 {
1709        ImVec2::new(v.x, v.y)
1710    }
1711}
1712
1713#[cfg(feature = "glam")]
1714impl From<glam::Vec2> for ImVec2 {
1715    #[inline]
1716    fn from(v: glam::Vec2) -> ImVec2 {
1717        ImVec2::new(v.x, v.y)
1718    }
1719}
1720
1721impl ImVec4 {
1722    #[inline]
1723    pub const fn new(x: f32, y: f32, z: f32, w: f32) -> ImVec4 {
1724        ImVec4 { x, y, z, w }
1725    }
1726
1727    #[inline]
1728    pub const fn zero() -> ImVec4 {
1729        ImVec4 {
1730            x: 0.0,
1731            y: 0.0,
1732            z: 0.0,
1733            w: 0.0,
1734        }
1735    }
1736}
1737
1738impl From<[f32; 4]> for ImVec4 {
1739    #[inline]
1740    fn from(array: [f32; 4]) -> ImVec4 {
1741        ImVec4::new(array[0], array[1], array[2], array[3])
1742    }
1743}
1744
1745impl From<(f32, f32, f32, f32)> for ImVec4 {
1746    #[inline]
1747    fn from((x, y, z, w): (f32, f32, f32, f32)) -> ImVec4 {
1748        ImVec4::new(x, y, z, w)
1749    }
1750}
1751
1752impl From<ImVec4> for [f32; 4] {
1753    #[inline]
1754    fn from(v: ImVec4) -> [f32; 4] {
1755        [v.x, v.y, v.z, v.w]
1756    }
1757}
1758
1759impl From<ImVec4> for (f32, f32, f32, f32) {
1760    #[inline]
1761    fn from(v: ImVec4) -> (f32, f32, f32, f32) {
1762        (v.x, v.y, v.z, v.w)
1763    }
1764}
1765
1766impl From<mint::Vector4<f32>> for ImVec4 {
1767    #[inline]
1768    fn from(v: mint::Vector4<f32>) -> ImVec4 {
1769        ImVec4::new(v.x, v.y, v.z, v.w)
1770    }
1771}
1772
1773#[cfg(feature = "glam")]
1774impl From<glam::Vec4> for ImVec4 {
1775    #[inline]
1776    fn from(v: glam::Vec4) -> ImVec4 {
1777        ImVec4::new(v.x, v.y, v.z, v.w)
1778    }
1779}