Skip to main content

dear_imgui_sys/
lib.rs

1//! Low-level FFI bindings for Dear ImGui (via cimgui C API) with docking support
2//!
3//! This crate provides raw, unsafe bindings to Dear ImGui using the cimgui C API,
4//! specifically targeting the docking branch (multi-viewport capable).
5//!
6//! ## Features
7//!
8//! - **docking**: Always enabled in this crate
9//! - **freetype**: Enable FreeType font rasterizer support
10//! - **wasm**: Enable WebAssembly compatibility
11//! - **backend-shim-\***: Expose selected repository-owned backend shim modules
12//!   for low-level integrations
13//!
14//! ## WebAssembly Support
15//!
16//! When the `wasm` feature is enabled, this crate provides full WASM compatibility:
17//! - Disables platform-specific functions (file I/O, shell functions, etc.)
18//! - Configures Dear ImGui for WASM environment
19//! - Compatible with wasm-bindgen and web targets
20//!
21//! ## Safety
22//!
23//! This crate provides raw FFI bindings and is inherently unsafe. Users should
24//! prefer the high-level `dear-imgui-rs` crate for safe Rust bindings.
25//!
26//! ## Usage
27//!
28//! This crate is typically not used directly. Instead, use the `dear-imgui-rs` crate
29//! which provides safe, idiomatic Rust bindings built on top of these FFI bindings.
30//!
31//! ## Backend Shim Modules
32//!
33//! For downstream backend crates, engine integrations, and platform-specific
34//! application glue, `dear-imgui-sys` can expose selected official backend
35//! pieces through `backend_shim::*`.
36//!
37//! Important boundary:
38//!
39//! - these modules expose the repository-owned C shim ABI
40//! - they do not expose upstream `imgui_impl_*` C++ symbol names as a stable
41//!   Rust-facing contract
42//! - enabling `backend-shim-*` features does not imply that `dear-imgui-rs`
43//!   already owns a safe wrapper for those backends
44//!
45//! Typical feature gates:
46//!
47//! - `backend-shim-opengl3`
48//! - `backend-shim-sdlrenderer3`
49//! - `backend-shim-android`
50//! - `backend-shim-win32`
51//! - `backend-shim-dx11`
52//!
53//! ## Android Direction
54//!
55//! The current Android story is intentionally low-level but supported.
56//!
57//! ```toml
58//! [dependencies]
59//! dear-imgui-rs = "0.10"
60//! dear-imgui-sys = { version = "0.10", features = ["backend-shim-android", "backend-shim-opengl3"] }
61//! ```
62//!
63//! Recommended split of responsibilities:
64//!
65//! - `dear-imgui-rs` owns the safe core `Context`, `Io`, frame lifecycle, and
66//!   render snapshots
67//! - `dear-imgui-sys::backend_shim::{android, opengl3}` exposes the low-level
68//!   official backend pieces
69//! - the Android application still owns lifecycle glue, input translation
70//!   strategy, EGL / GLES context creation, and packaging
71//!
72//! The repository's concrete reference for this path is
73//! `examples-android/dear-imgui-android-smoke/`, which now carries a minimal
74//! NativeActivity + EGL / GLES3 render loop proving that downstream users can
75//! build Android support on top of `dear-imgui-rs` + `dear-imgui-sys` even
76//! before a dedicated first-party Android convenience crate exists.
77
78#![allow(non_upper_case_globals)]
79#![allow(non_camel_case_types)]
80#![allow(non_snake_case)]
81#![allow(dead_code)]
82#![allow(unnecessary_transmutes)]
83#![allow(clippy::all)]
84// Bindgen may derive Eq/Hash for structs containing function pointers.
85// New Clippy lint warns these comparisons are unpredictable; suppress for raw FFI types.
86#![allow(unpredictable_function_pointer_comparisons)]
87
88// Bindings are generated into OUT_DIR and included via a submodule so that
89// possible inner attributes in the generated file are accepted at module root.
90mod ffi;
91pub use ffi::*;
92
93/// Optional backend shim entry points for downstream integrations.
94///
95/// These modules expose the repository-owned C shim ABI for selected official
96/// Dear ImGui backends. They do not expose the upstream C++ symbols directly,
97/// and they do not imply that `dear-imgui-sys` or `dear-imgui-rs` owns full
98/// safe integration for those backends.
99pub mod backend_shim;
100
101// This project always builds Dear ImGui with `IMGUI_USE_WCHAR32`, so `ImWchar` must be 32-bit.
102const _: [(); 4] = [(); std::mem::size_of::<ImWchar>()];
103
104// Ensure common ImGui typedefs are available even if bindgen doesn't emit them explicitly
105
106// cimgui exposes typed vectors (e.g., ImVector_ImVec2) instead of a generic ImVector<T>.
107// The sys crate intentionally avoids adding higher-level helpers here.
108
109// cimgui C API avoids C++ ABI pitfalls; no MSVC-specific conversions are required.
110
111/// Whether this build linked the repository-owned PlatformIO out-parameter hook shim.
112pub const HAS_PLATFORM_IO_OUT_PARAM_HOOKS: bool = cfg!(dear_imgui_rs_platform_io_hooks);
113
114unsafe extern "C" {
115    fn dear_imgui_stack_begin_horizontal_str(
116        str_id: *const std::os::raw::c_char,
117        size: ImVec2,
118        align: f32,
119    );
120    fn dear_imgui_stack_begin_horizontal_ptr(
121        ptr_id: *const std::ffi::c_void,
122        size: ImVec2,
123        align: f32,
124    );
125    fn dear_imgui_stack_begin_horizontal_int(id: std::os::raw::c_int, size: ImVec2, align: f32);
126    fn dear_imgui_stack_begin_horizontal_id(id: ImGuiID, size: ImVec2, align: f32);
127    fn dear_imgui_stack_end_horizontal();
128    fn dear_imgui_stack_begin_vertical_str(
129        str_id: *const std::os::raw::c_char,
130        size: ImVec2,
131        align: f32,
132    );
133    fn dear_imgui_stack_begin_vertical_ptr(
134        ptr_id: *const std::ffi::c_void,
135        size: ImVec2,
136        align: f32,
137    );
138    fn dear_imgui_stack_begin_vertical_int(id: std::os::raw::c_int, size: ImVec2, align: f32);
139    fn dear_imgui_stack_begin_vertical_id(id: ImGuiID, size: ImVec2, align: f32);
140    fn dear_imgui_stack_end_vertical();
141    fn dear_imgui_stack_spring(weight: f32, spacing: f32);
142    fn dear_imgui_stack_suspend_layout();
143    fn dear_imgui_stack_resume_layout();
144}
145
146/// Start a stack-layout horizontal group using a string ID.
147///
148/// This is a repository-owned compatibility shim for the stack layout extension
149/// used by `imgui-node-editor` examples; it is not an official Dear ImGui API.
150///
151/// # Safety
152///
153/// Requires an active Dear ImGui context and current window. `str_id` must point
154/// to a valid NUL-terminated string for the duration of the call.
155#[inline]
156pub unsafe fn ImGuiStack_BeginHorizontal_Str(
157    str_id: *const std::os::raw::c_char,
158    size: ImVec2,
159    align: f32,
160) {
161    unsafe { dear_imgui_stack_begin_horizontal_str(str_id, size, align) }
162}
163
164/// Start a stack-layout horizontal group using a pointer ID.
165///
166/// # Safety
167///
168/// Requires an active Dear ImGui context and current window. `ptr_id` is used as
169/// an ID value only and is not dereferenced.
170#[inline]
171pub unsafe fn ImGuiStack_BeginHorizontal_Ptr(
172    ptr_id: *const std::ffi::c_void,
173    size: ImVec2,
174    align: f32,
175) {
176    unsafe { dear_imgui_stack_begin_horizontal_ptr(ptr_id, size, align) }
177}
178
179/// Start a stack-layout horizontal group using an integer ID.
180///
181/// # Safety
182///
183/// Requires an active Dear ImGui context and current window.
184#[inline]
185pub unsafe fn ImGuiStack_BeginHorizontal_Int(id: std::os::raw::c_int, size: ImVec2, align: f32) {
186    unsafe { dear_imgui_stack_begin_horizontal_int(id, size, align) }
187}
188
189/// Start a stack-layout horizontal group using a precomputed ImGui ID.
190///
191/// # Safety
192///
193/// Requires an active Dear ImGui context and current window.
194#[inline]
195pub unsafe fn ImGuiStack_BeginHorizontal_Id(id: ImGuiID, size: ImVec2, align: f32) {
196    unsafe { dear_imgui_stack_begin_horizontal_id(id, size, align) }
197}
198
199/// End the current stack-layout horizontal group.
200///
201/// # Safety
202///
203/// Must match a previous `ImGuiStack_BeginHorizontal_*` call.
204#[inline]
205pub unsafe fn ImGuiStack_EndHorizontal() {
206    unsafe { dear_imgui_stack_end_horizontal() }
207}
208
209/// Start a stack-layout vertical group using a string ID.
210///
211/// # Safety
212///
213/// Requires an active Dear ImGui context and current window. `str_id` must point
214/// to a valid NUL-terminated string for the duration of the call.
215#[inline]
216pub unsafe fn ImGuiStack_BeginVertical_Str(
217    str_id: *const std::os::raw::c_char,
218    size: ImVec2,
219    align: f32,
220) {
221    unsafe { dear_imgui_stack_begin_vertical_str(str_id, size, align) }
222}
223
224/// Start a stack-layout vertical group using a pointer ID.
225///
226/// # Safety
227///
228/// Requires an active Dear ImGui context and current window. `ptr_id` is used as
229/// an ID value only and is not dereferenced.
230#[inline]
231pub unsafe fn ImGuiStack_BeginVertical_Ptr(
232    ptr_id: *const std::ffi::c_void,
233    size: ImVec2,
234    align: f32,
235) {
236    unsafe { dear_imgui_stack_begin_vertical_ptr(ptr_id, size, align) }
237}
238
239/// Start a stack-layout vertical group using an integer ID.
240///
241/// # Safety
242///
243/// Requires an active Dear ImGui context and current window.
244#[inline]
245pub unsafe fn ImGuiStack_BeginVertical_Int(id: std::os::raw::c_int, size: ImVec2, align: f32) {
246    unsafe { dear_imgui_stack_begin_vertical_int(id, size, align) }
247}
248
249/// Start a stack-layout vertical group using a precomputed ImGui ID.
250///
251/// # Safety
252///
253/// Requires an active Dear ImGui context and current window.
254#[inline]
255pub unsafe fn ImGuiStack_BeginVertical_Id(id: ImGuiID, size: ImVec2, align: f32) {
256    unsafe { dear_imgui_stack_begin_vertical_id(id, size, align) }
257}
258
259/// End the current stack-layout vertical group.
260///
261/// # Safety
262///
263/// Must match a previous `ImGuiStack_BeginVertical_*` call.
264#[inline]
265pub unsafe fn ImGuiStack_EndVertical() {
266    unsafe { dear_imgui_stack_end_vertical() }
267}
268
269/// Insert a spring separator into the current stack layout.
270///
271/// # Safety
272///
273/// Requires an active stack layout.
274#[inline]
275pub unsafe fn ImGuiStack_Spring(weight: f32, spacing: f32) {
276    unsafe { dear_imgui_stack_spring(weight, spacing) }
277}
278
279/// Temporarily suspend the current stack layout.
280///
281/// # Safety
282///
283/// Requires an active stack layout and must be matched by resume.
284#[inline]
285pub unsafe fn ImGuiStack_SuspendLayout() {
286    unsafe { dear_imgui_stack_suspend_layout() }
287}
288
289/// Resume a suspended stack layout.
290///
291/// # Safety
292///
293/// Must match a previous suspend call.
294#[inline]
295pub unsafe fn ImGuiStack_ResumeLayout() {
296    unsafe { dear_imgui_stack_resume_layout() }
297}
298
299#[cfg(dear_imgui_rs_platform_io_hooks)]
300unsafe extern "C" {
301    fn dear_imgui_rs_platform_io_set_platform_get_window_pos(
302        platform_io: *mut ImGuiPlatformIO,
303        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2)>,
304    );
305
306    fn dear_imgui_rs_platform_io_set_platform_get_window_size(
307        platform_io: *mut ImGuiPlatformIO,
308        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2)>,
309    );
310
311    fn dear_imgui_rs_platform_io_set_platform_get_window_framebuffer_scale(
312        platform_io: *mut ImGuiPlatformIO,
313        user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2)>,
314    );
315
316    fn dear_imgui_rs_platform_io_set_platform_get_window_work_area_insets(
317        platform_io: *mut ImGuiPlatformIO,
318        user_callback: Option<
319            unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4),
320        >,
321    );
322}
323
324/// Install a C-compatible out-parameter callback for `ImGuiPlatformIO::Platform_GetWindowPos`.
325///
326/// This avoids exposing Rust callbacks through the small-aggregate `ImVec2` return ABI used by
327/// Dear ImGui's C++ callback slot. The shim keeps its own per-`ImGuiPlatformIO` storage and does
328/// not occupy `ImGuiIO::BackendLanguageUserData`.
329///
330/// # Safety
331///
332/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
333/// must obey Dear ImGui's platform callback contract and must not unwind.
334#[inline]
335pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam(
336    platform_io: *mut ImGuiPlatformIO,
337    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_pos: *mut ImVec2)>,
338) {
339    #[cfg(dear_imgui_rs_platform_io_hooks)]
340    unsafe {
341        dear_imgui_rs_platform_io_set_platform_get_window_pos(platform_io, user_callback)
342    }
343
344    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
345    {
346        let _ = platform_io;
347        if user_callback.is_some() {
348            panic!(
349                "dear-imgui-sys was built without PlatformIO out-parameter hooks; \
350                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowPos callbacks"
351            );
352        }
353    }
354}
355
356/// Install a C-compatible out-parameter callback for `ImGuiPlatformIO::Platform_GetWindowSize`.
357///
358/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
359///
360/// # Safety
361///
362/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
363/// must obey Dear ImGui's platform callback contract and must not unwind.
364#[inline]
365pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowSize_OutParam(
366    platform_io: *mut ImGuiPlatformIO,
367    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_size: *mut ImVec2)>,
368) {
369    #[cfg(dear_imgui_rs_platform_io_hooks)]
370    unsafe {
371        dear_imgui_rs_platform_io_set_platform_get_window_size(platform_io, user_callback)
372    }
373
374    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
375    {
376        let _ = platform_io;
377        if user_callback.is_some() {
378            panic!(
379                "dear-imgui-sys was built without PlatformIO out-parameter hooks; \
380                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowSize callbacks"
381            );
382        }
383    }
384}
385
386/// Install a C-compatible out-parameter callback for
387/// `ImGuiPlatformIO::Platform_GetWindowFramebufferScale`.
388///
389/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
390///
391/// # Safety
392///
393/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
394/// must obey Dear ImGui's platform callback contract and must not unwind.
395#[inline]
396pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowFramebufferScale_OutParam(
397    platform_io: *mut ImGuiPlatformIO,
398    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_scale: *mut ImVec2)>,
399) {
400    #[cfg(dear_imgui_rs_platform_io_hooks)]
401    unsafe {
402        dear_imgui_rs_platform_io_set_platform_get_window_framebuffer_scale(
403            platform_io,
404            user_callback,
405        )
406    }
407
408    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
409    {
410        let _ = platform_io;
411        if user_callback.is_some() {
412            panic!(
413                "dear-imgui-sys was built without PlatformIO out-parameter hooks; \
414                 rebuild without IMGUI_SYS_SKIP_CC to install \
415                 Platform_GetWindowFramebufferScale callbacks"
416            );
417        }
418    }
419}
420
421/// Install a C-compatible out-parameter callback for
422/// `ImGuiPlatformIO::Platform_GetWindowWorkAreaInsets`.
423///
424/// See [`ImGuiPlatformIO_Set_Platform_GetWindowPos_OutParam`] for the ABI rationale.
425///
426/// # Safety
427///
428/// `platform_io` must be null or point to a live `ImGuiPlatformIO`. `user_callback`, when present,
429/// must obey Dear ImGui's platform callback contract and must not unwind.
430#[inline]
431pub unsafe fn ImGuiPlatformIO_Set_Platform_GetWindowWorkAreaInsets_OutParam(
432    platform_io: *mut ImGuiPlatformIO,
433    user_callback: Option<unsafe extern "C" fn(vp: *mut ImGuiViewport, out_insets: *mut ImVec4)>,
434) {
435    #[cfg(dear_imgui_rs_platform_io_hooks)]
436    unsafe {
437        dear_imgui_rs_platform_io_set_platform_get_window_work_area_insets(
438            platform_io,
439            user_callback,
440        )
441    }
442
443    #[cfg(not(dear_imgui_rs_platform_io_hooks))]
444    {
445        let _ = platform_io;
446        if user_callback.is_some() {
447            panic!(
448                "dear-imgui-sys was built without PlatformIO out-parameter hooks; \
449                 rebuild without IMGUI_SYS_SKIP_CC to install Platform_GetWindowWorkAreaInsets \
450                 callbacks"
451            );
452        }
453    }
454}
455
456// Re-export commonly used types for convenience
457pub use ImColor as Color;
458pub use ImVec2 as Vector2;
459pub use ImVec4 as Vector4;
460
461/// Version information for the Dear ImGui library
462pub const IMGUI_VERSION: &str = env!("CARGO_PKG_VERSION");
463
464/// Docking features are always available in this crate
465pub const HAS_DOCKING: bool = true;
466
467/// Check if FreeType support is available
468#[cfg(feature = "freetype")]
469pub const HAS_FREETYPE: bool = true;
470
471#[cfg(not(feature = "freetype"))]
472pub const HAS_FREETYPE: bool = false;
473
474/// Check if WASM support is available
475#[cfg(feature = "wasm")]
476pub const HAS_WASM: bool = true;
477
478#[cfg(not(feature = "wasm"))]
479pub const HAS_WASM: bool = false;
480
481// (No wasm-specific shims are required when using shared memory import style.)
482
483impl ImVec2 {
484    #[inline]
485    pub const fn new(x: f32, y: f32) -> ImVec2 {
486        ImVec2 { x, y }
487    }
488
489    #[inline]
490    pub const fn zero() -> ImVec2 {
491        ImVec2 { x: 0.0, y: 0.0 }
492    }
493}
494
495impl From<[f32; 2]> for ImVec2 {
496    #[inline]
497    fn from(array: [f32; 2]) -> ImVec2 {
498        ImVec2::new(array[0], array[1])
499    }
500}
501
502impl From<(f32, f32)> for ImVec2 {
503    #[inline]
504    fn from((x, y): (f32, f32)) -> ImVec2 {
505        ImVec2::new(x, y)
506    }
507}
508
509impl From<ImVec2> for [f32; 2] {
510    #[inline]
511    fn from(v: ImVec2) -> [f32; 2] {
512        [v.x, v.y]
513    }
514}
515
516impl From<ImVec2> for (f32, f32) {
517    #[inline]
518    fn from(v: ImVec2) -> (f32, f32) {
519        (v.x, v.y)
520    }
521}
522
523impl From<mint::Vector2<f32>> for ImVec2 {
524    #[inline]
525    fn from(v: mint::Vector2<f32>) -> ImVec2 {
526        ImVec2::new(v.x, v.y)
527    }
528}
529
530#[cfg(feature = "glam")]
531impl From<glam::Vec2> for ImVec2 {
532    #[inline]
533    fn from(v: glam::Vec2) -> ImVec2 {
534        ImVec2::new(v.x, v.y)
535    }
536}
537
538impl ImVec4 {
539    #[inline]
540    pub const fn new(x: f32, y: f32, z: f32, w: f32) -> ImVec4 {
541        ImVec4 { x, y, z, w }
542    }
543
544    #[inline]
545    pub const fn zero() -> ImVec4 {
546        ImVec4 {
547            x: 0.0,
548            y: 0.0,
549            z: 0.0,
550            w: 0.0,
551        }
552    }
553}
554
555impl From<[f32; 4]> for ImVec4 {
556    #[inline]
557    fn from(array: [f32; 4]) -> ImVec4 {
558        ImVec4::new(array[0], array[1], array[2], array[3])
559    }
560}
561
562impl From<(f32, f32, f32, f32)> for ImVec4 {
563    #[inline]
564    fn from((x, y, z, w): (f32, f32, f32, f32)) -> ImVec4 {
565        ImVec4::new(x, y, z, w)
566    }
567}
568
569impl From<ImVec4> for [f32; 4] {
570    #[inline]
571    fn from(v: ImVec4) -> [f32; 4] {
572        [v.x, v.y, v.z, v.w]
573    }
574}
575
576impl From<ImVec4> for (f32, f32, f32, f32) {
577    #[inline]
578    fn from(v: ImVec4) -> (f32, f32, f32, f32) {
579        (v.x, v.y, v.z, v.w)
580    }
581}
582
583impl From<mint::Vector4<f32>> for ImVec4 {
584    #[inline]
585    fn from(v: mint::Vector4<f32>) -> ImVec4 {
586        ImVec4::new(v.x, v.y, v.z, v.w)
587    }
588}
589
590#[cfg(feature = "glam")]
591impl From<glam::Vec4> for ImVec4 {
592    #[inline]
593    fn from(v: glam::Vec4) -> ImVec4 {
594        ImVec4::new(v.x, v.y, v.z, v.w)
595    }
596}