aboutsummaryrefslogtreecommitdiff
path: root/libs/nak_ffi/src
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-12 13:48:25 -0500
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-03-12 13:48:25 -0500
commit84a43a2e6afbdfab92c610d47aa75e3876ffacd6 (patch)
treeea624ec287181905441fbf1247c645976bdb8fc9 /libs/nak_ffi/src
parent3ba283d9350783c038cc2844450f4938ad125f08 (diff)
Replace wrestool with native Rust PE icon extraction (pelite)
- Add icons.rs to nak crate: parses PE resource sections, extracts RT_GROUP_ICON/RT_ICON and builds ICO files in memory - Expose nak_extract_exe_icon() FFI for C++ consumption - Update iconForExecutable() to use Rust FFI instead of shelling out to wrestool; reads all ICO entries for correct color depth - Fix BasicGamePlugin::gameIcon() to call iconForExecutable() (was returning empty QIcon, causing placeholder icons for BG3/Cyberpunk) - Move app icon setup: setDesktopFileName + setWindowIcon to MOApplication constructor (fixes Wayland taskbar/decoration icon) - Move data/com.fluorine.* to data/icons/, install to XDG paths at launch for Wayland compositor icon resolution - Remove icoutils dependency from Docker image and build output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/nak_ffi/src')
-rw-r--r--libs/nak_ffi/src/lib.rs51
1 files changed, 51 insertions, 0 deletions
diff --git a/libs/nak_ffi/src/lib.rs b/libs/nak_ffi/src/lib.rs
index 65592fa..c45481b 100644
--- a/libs/nak_ffi/src/lib.rs
+++ b/libs/nak_ffi/src/lib.rs
@@ -615,6 +615,57 @@ pub extern "C" fn nak_get_dxvk_conf_path() -> *mut c_char {
}
// ============================================================================
+// Tier 8: PE Icon Extraction
+// ============================================================================
+
+/// Result of icon extraction
+#[repr(C)]
+pub struct NakIconData {
+ /// Raw ICO file bytes (caller must free with nak_icon_data_free)
+ pub data: *mut u8,
+ /// Length of the data in bytes (0 if extraction failed)
+ pub len: usize,
+}
+
+/// Extract the best icon from a Windows PE executable (.exe/.dll).
+///
+/// Returns NakIconData with the raw ICO file bytes.
+/// If extraction fails, data is null and len is 0.
+/// Caller must free the result with nak_icon_data_free().
+#[no_mangle]
+pub unsafe extern "C" fn nak_extract_exe_icon(exe_path: *const c_char) -> NakIconData {
+ let path_str = unsafe { from_cstr(exe_path) };
+ if path_str.is_empty() {
+ return NakIconData {
+ data: ptr::null_mut(),
+ len: 0,
+ };
+ }
+
+ match nak_rust::icons::extract_icon(std::path::Path::new(path_str)) {
+ Some(bytes) => {
+ let len = bytes.len();
+ let mut boxed = bytes.into_boxed_slice();
+ let ptr = boxed.as_mut_ptr();
+ std::mem::forget(boxed);
+ NakIconData { data: ptr, len }
+ }
+ None => NakIconData {
+ data: ptr::null_mut(),
+ len: 0,
+ },
+ }
+}
+
+/// Free icon data returned by nak_extract_exe_icon
+#[no_mangle]
+pub unsafe extern "C" fn nak_icon_data_free(icon: NakIconData) {
+ if !icon.data.is_null() && icon.len > 0 {
+ let _ = unsafe { Vec::from_raw_parts(icon.data, icon.len, icon.len) };
+ }
+}
+
+// ============================================================================
// General: String free
// ============================================================================