From a5f60dd8991e00ea84478fed7f9d9b29c6c6833c Mon Sep 17 00:00:00 2001 From: oiupoyt Date: Wed, 30 Sep 2026 08:16:03 +0530 Subject: [PATCH] feat(graphics): implement ANativeWindow C-ABI exported functions --- crates/molotov-core/src/graphics/c_api.rs | 86 +++++++++++++++++++ crates/molotov-core/src/graphics/mod.rs | 1 + .../tests/anativewindow_c_api_test.rs | 26 ++++++ 3 files changed, 113 insertions(+) create mode 100644 crates/molotov-core/src/graphics/c_api.rs create mode 100644 crates/molotov-core/tests/anativewindow_c_api_test.rs diff --git a/crates/molotov-core/src/graphics/c_api.rs b/crates/molotov-core/src/graphics/c_api.rs new file mode 100644 index 0000000..fd73328 --- /dev/null +++ b/crates/molotov-core/src/graphics/c_api.rs @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +#![allow(non_snake_case)] +use super::surface::GraphicsSurface; +use super::types::{ANativeWindow_Buffer, ARect, WindowFormat}; + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_acquire(window: *mut ()) { + if let Some(s) = (window as *mut GraphicsSurface).as_ref() { + s.acquire(); + } +} + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_release(window: *mut ()) { + if !window.is_null() { + let ptr = window as *mut GraphicsSurface; + if (*ptr).release() == 0 { + drop(Box::from_raw(ptr)); + } + } +} + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_getWidth(window: *mut ()) -> i32 { + if let Some(s) = (window as *mut GraphicsSurface).as_ref() { + s.width() + } else { + 0 + } +} + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_getHeight(window: *mut ()) -> i32 { + if let Some(s) = (window as *mut GraphicsSurface).as_ref() { + s.height() + } else { + 0 + } +} + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_getFormat(window: *mut ()) -> i32 { + if let Some(s) = (window as *mut GraphicsSurface).as_ref() { + s.format() as i32 + } else { + 0 + } +} + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_setBuffersGeometry( + window: *mut (), + width: i32, + height: i32, + format: i32, +) -> i32 { + if let Some(s) = (window as *mut GraphicsSurface).as_mut() { + let fmt = WindowFormat::from_i32(format).unwrap_or(WindowFormat::Rgba8888); + s.set_geometry(width, height, fmt); + 0 + } else { + -libc::EINVAL + } +} + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_lock( + window: *mut (), + outBuffer: *mut ANativeWindow_Buffer, + inOutDirtyBounds: *mut ARect, +) -> i32 { + if let Some(s) = (window as *mut GraphicsSurface).as_mut() { + s.lock(outBuffer, inOutDirtyBounds) + } else { + -libc::EINVAL + } +} + +#[no_mangle] +pub unsafe extern "C" fn ANativeWindow_unlockAndPost(window: *mut ()) -> i32 { + if let Some(s) = (window as *mut GraphicsSurface).as_mut() { + s.unlock_and_post() + } else { + -libc::EINVAL + } +} diff --git a/crates/molotov-core/src/graphics/mod.rs b/crates/molotov-core/src/graphics/mod.rs index 5c0761e..05aa24b 100644 --- a/crates/molotov-core/src/graphics/mod.rs +++ b/crates/molotov-core/src/graphics/mod.rs @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later +pub mod c_api; pub mod surface; pub mod types; pub mod window; diff --git a/crates/molotov-core/tests/anativewindow_c_api_test.rs b/crates/molotov-core/tests/anativewindow_c_api_test.rs new file mode 100644 index 0000000..394e83a --- /dev/null +++ b/crates/molotov-core/tests/anativewindow_c_api_test.rs @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +use molotov_core::graphics::c_api::*; +use molotov_core::graphics::surface::GraphicsSurface; +use molotov_core::graphics::types::{ANativeWindow_Buffer, WindowFormat}; + +#[test] +fn test_anativewindow_c_api_lifecycle() { + let surface = Box::new(GraphicsSurface::new(640, 480, WindowFormat::Rgba8888)); + let handle = Box::into_raw(surface) as *mut (); + + unsafe { + assert_eq!(ANativeWindow_getWidth(handle), 640); + assert_eq!(ANativeWindow_getHeight(handle), 480); + assert_eq!(ANativeWindow_getFormat(handle), 1); + + ANativeWindow_setBuffersGeometry(handle, 800, 600, 1); + assert_eq!(ANativeWindow_getWidth(handle), 800); + assert_eq!(ANativeWindow_getHeight(handle), 600); + + let mut buf = std::mem::MaybeUninit::::uninit(); + assert_eq!(ANativeWindow_lock(handle, buf.as_mut_ptr(), std::ptr::null_mut()), 0); + assert_eq!(ANativeWindow_unlockAndPost(handle), 0); + + ANativeWindow_release(handle); + } +}