From f1a7cb89e54b35d55eccaa4b08d8800482727aea Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 17 May 2026 16:02:39 +0800 Subject: [PATCH] feat: add ext status for cdylib --- wfassoc-cdylib/src/lib.rs | 59 ++++++++++++++++++++++++++++++++++-- wfassoc/src/win32/concept.rs | 12 ++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/wfassoc-cdylib/src/lib.rs b/wfassoc-cdylib/src/lib.rs index e3f0fb0..55ff353 100644 --- a/wfassoc-cdylib/src/lib.rs +++ b/wfassoc-cdylib/src/lib.rs @@ -191,6 +191,9 @@ static SCHEMA_POOL: LazyLock>> = static PROGRAM_POOL: LazyLock>> = LazyLock::new(|| RwLock::new(ObjectPool::new())); +static EXT_STATUE_POOL: LazyLock>> = + LazyLock::new(|| RwLock::new(ObjectPool::new())); + // endregion // region: Exposed Types @@ -241,6 +244,7 @@ pub extern "C" fn WFStartup() -> bool { cffi_wrapper!(|| { let _pool = pull_writer!(SCHEMA_POOL)?; let _pool = pull_writer!(PROGRAM_POOL)?; + let _pool = pull_writer!(EXT_STATUE_POOL)?; Ok(()) }) } @@ -253,6 +257,8 @@ pub extern "C" fn WFShutdown() -> bool { pool.clear(); let mut pool = pull_writer!(PROGRAM_POOL)?; pool.clear(); + let mut pool = pull_writer!(EXT_STATUE_POOL)?; + pool.clear(); Ok(()) }) } @@ -527,8 +533,8 @@ pub extern "C" fn WFProgramIsRegistered( out_is_registered: out_param_ty!(bool), ) -> bool { cffi_wrapper!(|in_program: Token, in_scope: u32| -> (out_is_registered: bool) { - let mut pool = pull_writer!(PROGRAM_POOL)?; - let program = pool.get_mut(in_program)?; + let pool = pull_reader!(PROGRAM_POOL)?; + let program = pool.get(in_program)?; let scope = resolve_enum!(Scope, in_scope)?; Ok(program.is_registered(scope.into())?) }) @@ -564,6 +570,53 @@ pub extern "C" fn WFProgramUnlinkExt( }) } -// endregion +#[unsafe(no_mangle)] +pub extern "C" fn WFProgramQueryExt( + in_program: in_param_ty!(Token), + in_view: in_param_ty!(u32), + in_index: in_param_ty!(usize), + out_ext_status: out_param_ty!(Token), +) -> bool { + cffi_wrapper!(|in_program: Token, in_view: u32, in_index: usize| -> (out_ext_status: Token) { + let pool = pull_reader!(PROGRAM_POOL)?; + let program = pool.get(in_program)?; + let view = resolve_enum!(View, in_view)?; + + let ext_status = program.query_ext(view.into(), in_index)?; + todo!(); + let mut pool = pull_writer!(EXT_STATUE_POOL)?; + Ok(pool.allocate(ext_status)?) + }) +} + +// endregion + +#[unsafe(no_mangle)] +pub extern "C" fn WFExtStatusDestroy(in_ext_status: in_param_ty!(Token)) -> bool { + cffi_wrapper!(|in_ext_status: Token| { + let mut pool = pull_writer!(EXT_STATUE_POOL)?; + Ok(pool.free(in_ext_status)?) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFExtStatuGetName(in_ext_status: in_param_ty!(Token), out_name: out_param_ty!(CStyleString)) -> bool { + cffi_wrapper!(|in_ext_status: Token| -> (out_name: CStyleString) { + let pool = pull_reader!(EXT_STATUE_POOL)?; + let ext_status = pool.get(in_ext_status)?; + + cstr_ffi::set_ffi_string(ext_status.get_name())?; + Ok(cstr_ffi::get_ffi_string()) + }) +} + +#[unsafe(no_mangle)] +pub extern "C" fn WFExtStatuGetIcon(in_ext_status: in_param_ty!(Token), out_icon: out_param_ty!(HICON)) -> bool { + cffi_wrapper!(|in_ext_status: Token| -> (out_icon: HICON) { + let pool = pull_reader!(EXT_STATUE_POOL)?; + let ext_status = pool.get(in_ext_status)?; + Ok(ext_status.get_icon()) + }) +} // endregion diff --git a/wfassoc/src/win32/concept.rs b/wfassoc/src/win32/concept.rs index 7daf38c..be19c88 100644 --- a/wfassoc/src/win32/concept.rs +++ b/wfassoc/src/win32/concept.rs @@ -575,6 +575,18 @@ impl Drop for IconRc { } } +// SAFETY: +// Win32 HICON can be safely moved between different threads naturally. +unsafe impl Send for IconRc {} + +// SAFETY: +// When multiple threads calling this struct, there is no conflict between them, +// because this struct only provide HICON itself. +// +// However, the caller should ensure that all calls using this HICON +// follow Win32 thread model. +unsafe impl Sync for IconRc {} + // endregion // region: String Resource