use iced_wgpu::wgpu;
use raw_window_handle::HasRawWindowHandle;
pub use truce_gui::platform::{ParentWindow, note_linux_scale_factor, query_backing_scale};
#[cfg(target_os = "windows")]
fn current_module_hinstance() -> Option<std::num::NonZeroIsize> {
unsafe extern "system" {
fn GetModuleHandleW(lpModuleName: *const u16) -> isize;
}
let hmodule = unsafe { GetModuleHandleW(std::ptr::null()) };
std::num::NonZeroIsize::new(hmodule)
}
#[must_use]
pub unsafe fn create_wgpu_surface(
instance: &wgpu::Instance,
window: &baseview::Window,
) -> Option<wgpu::Surface<'static>> {
unsafe {
let rwh = window.raw_window_handle();
let target = match rwh {
#[cfg(target_os = "macos")]
raw_window_handle::RawWindowHandle::AppKit(h) => {
let ns_view = std::ptr::NonNull::new(h.ns_view)?;
wgpu::SurfaceTargetUnsafe::RawHandle {
raw_display_handle: wgpu::rwh::RawDisplayHandle::AppKit(
wgpu::rwh::AppKitDisplayHandle::new(),
),
raw_window_handle: wgpu::rwh::RawWindowHandle::AppKit(
wgpu::rwh::AppKitWindowHandle::new(ns_view),
),
}
}
#[cfg(target_os = "windows")]
raw_window_handle::RawWindowHandle::Win32(h) => {
let mut win32 =
wgpu::rwh::Win32WindowHandle::new(std::num::NonZero::new(h.hwnd as isize)?);
win32.hinstance = current_module_hinstance();
wgpu::SurfaceTargetUnsafe::RawHandle {
raw_display_handle: wgpu::rwh::RawDisplayHandle::Windows(
wgpu::rwh::WindowsDisplayHandle::new(),
),
raw_window_handle: wgpu::rwh::RawWindowHandle::Win32(win32),
}
}
#[cfg(target_os = "linux")]
raw_window_handle::RawWindowHandle::Xlib(h) => {
use raw_window_handle::HasRawDisplayHandle;
let raw_window_handle::RawDisplayHandle::Xlib(display) =
window.raw_display_handle()
else {
return None;
};
let display_ptr = std::ptr::NonNull::new(display.display);
wgpu::SurfaceTargetUnsafe::RawHandle {
raw_display_handle: wgpu::rwh::RawDisplayHandle::Xlib(
wgpu::rwh::XlibDisplayHandle::new(display_ptr, display.screen),
),
raw_window_handle: wgpu::rwh::RawWindowHandle::Xlib(
wgpu::rwh::XlibWindowHandle::new(h.window as std::ffi::c_ulong),
),
}
}
_ => return None,
};
instance.create_surface_unsafe(target).ok()
}
}