mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-01 20:31:27 +00:00
C++: Make the platform support work without the "std" feature
Add a experimental-platform feature that doesn't include skia
This commit is contained in:
parent
03bca95bef
commit
4a505c6788
3 changed files with 152 additions and 143 deletions
|
|
@ -38,7 +38,8 @@ renderer-winit-software = ["i-slint-backend-selector/renderer-winit-software"]
|
|||
gettext = ["i-slint-core/gettext-rs"]
|
||||
accessibility = ["i-slint-backend-selector/accessibility"]
|
||||
|
||||
experimental = ["i-slint-renderer-skia", "raw-window-handle", "std"]
|
||||
experimental = ["i-slint-renderer-skia", "raw-window-handle", "experimental-platform"]
|
||||
experimental-platform = []
|
||||
|
||||
std = ["image", "i-slint-core/default", "i-slint-backend-selector"]
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use alloc::rc::Rc;
|
|||
use core::ffi::c_void;
|
||||
use i_slint_core::window::{ffi::WindowAdapterRcOpaque, WindowAdapter};
|
||||
|
||||
#[cfg(feature = "experimental")]
|
||||
#[cfg(feature = "experimental-platform")]
|
||||
pub mod platform;
|
||||
|
||||
#[cfg(feature = "i-slint-backend-selector")]
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use i_slint_core::renderer::Renderer;
|
|||
use i_slint_core::software_renderer::{RepaintBufferType, SoftwareRenderer};
|
||||
use i_slint_core::window::ffi::WindowAdapterRcOpaque;
|
||||
use i_slint_core::window::{WindowAdapter, WindowAdapterInternal};
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||
|
||||
type WindowAdapterUserData = *mut c_void;
|
||||
|
||||
|
|
@ -214,146 +213,155 @@ pub unsafe extern "C" fn slint_software_renderer_handle(r: SoftwareRendererOpaqu
|
|||
core::mem::transmute(r)
|
||||
}
|
||||
|
||||
type SkiaRendererOpaque = *const c_void;
|
||||
type SkiaRenderer = i_slint_renderer_skia::SkiaRenderer;
|
||||
#[cfg(all(feature = "i-slint-renderer-skia", feature = "raw-window-handle"))]
|
||||
pub mod skia {
|
||||
use super::*;
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
||||
|
||||
struct CppRawHandle(RawWindowHandle, RawDisplayHandle);
|
||||
struct CppRawHandle(RawWindowHandle, RawDisplayHandle);
|
||||
|
||||
// the raw handle type are #[non_exhaustive], so they can't be initialize with the convenient syntax. Work that around.
|
||||
macro_rules! init_raw {
|
||||
($ty:ty { $($var:ident),* }) => {
|
||||
{
|
||||
let mut h = <$ty>::empty();
|
||||
$(h.$var = $var;)*
|
||||
h
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
type CppRawHandleOpaque = *const c_void;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_win32(
|
||||
hwnd: *mut c_void,
|
||||
hinstance: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Win32(init_raw!(raw_window_handle::Win32WindowHandle { hwnd, hinstance })),
|
||||
RawDisplayHandle::Windows(raw_window_handle::WindowsDisplayHandle::empty()),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_x11(
|
||||
window: u32,
|
||||
visual_id: u32,
|
||||
connection: *mut c_void,
|
||||
screen: core::ffi::c_int,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Xcb(init_raw!(XcbWindowHandle { window, visual_id })),
|
||||
RawDisplayHandle::Xcb(init_raw!(XcbDisplayHandle { connection, screen })),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_wayland(
|
||||
surface: *mut c_void,
|
||||
display: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Wayland(init_raw!(WaylandWindowHandle { surface })),
|
||||
RawDisplayHandle::Wayland(init_raw!(WaylandDisplayHandle { display })),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_appkit(
|
||||
ns_view: *mut c_void,
|
||||
ns_window: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::AppKit(init_raw!(AppKitWindowHandle { ns_view, ns_window })),
|
||||
RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_raw_window_handle_drop(handle: CppRawHandleOpaque) {
|
||||
drop(Box::from_raw(handle as *mut CppRawHandle))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_new(
|
||||
handle_opaque: CppRawHandleOpaque,
|
||||
size: IntSize,
|
||||
) -> SkiaRendererOpaque {
|
||||
let handle = &*(handle_opaque as *const CppRawHandle);
|
||||
|
||||
// Safety: This is safe because the handle remains valid; the next rwh release provides `new()` without unsafe.
|
||||
let active_handle = unsafe { raw_window_handle::ActiveHandle::new_unchecked() };
|
||||
|
||||
// Safety: the C++ code should ensure that the handle is valid
|
||||
let (window_handle, display_handle) = unsafe {
|
||||
(
|
||||
raw_window_handle::WindowHandle::borrow_raw(handle.0, active_handle),
|
||||
raw_window_handle::DisplayHandle::borrow_raw(handle.1),
|
||||
)
|
||||
};
|
||||
|
||||
let boxed_renderer: Box<SkiaRenderer> = Box::new(
|
||||
SkiaRenderer::new(
|
||||
window_handle,
|
||||
display_handle,
|
||||
PhysicalSize { width: size.width, height: size.height },
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
Box::into_raw(boxed_renderer) as SkiaRendererOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_drop(r: SkiaRendererOpaque) {
|
||||
drop(Box::from_raw(r as *mut SkiaRenderer))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_show(r: SkiaRendererOpaque) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.show().unwrap()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_hide(r: SkiaRendererOpaque) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.hide().unwrap()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_resize(r: SkiaRendererOpaque, size: IntSize) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.resize_event(PhysicalSize { width: size.width, height: size.height }).unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_render(
|
||||
r: SkiaRendererOpaque,
|
||||
window: *const WindowAdapterRcOpaque,
|
||||
) {
|
||||
let window_adapter = &*(window as *const Rc<dyn WindowAdapter>);
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.render(window_adapter.window()).unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_handle(r: SkiaRendererOpaque) -> RendererPtr {
|
||||
let r = (r as *const SkiaRenderer) as *const dyn Renderer;
|
||||
core::mem::transmute(r)
|
||||
// the raw handle type are #[non_exhaustive], so they can't be initialize with the convenient syntax. Work that around.
|
||||
macro_rules! init_raw {
|
||||
($ty:ty { $($var:ident),* }) => {
|
||||
{
|
||||
let mut h = <$ty>::empty();
|
||||
$(h.$var = $var;)*
|
||||
h
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
type CppRawHandleOpaque = *const c_void;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_win32(
|
||||
hwnd: *mut c_void,
|
||||
hinstance: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Win32(init_raw!(raw_window_handle::Win32WindowHandle {
|
||||
hwnd,
|
||||
hinstance
|
||||
})),
|
||||
RawDisplayHandle::Windows(raw_window_handle::WindowsDisplayHandle::empty()),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_x11(
|
||||
window: u32,
|
||||
visual_id: u32,
|
||||
connection: *mut c_void,
|
||||
screen: core::ffi::c_int,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Xcb(init_raw!(XcbWindowHandle { window, visual_id })),
|
||||
RawDisplayHandle::Xcb(init_raw!(XcbDisplayHandle { connection, screen })),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_wayland(
|
||||
surface: *mut c_void,
|
||||
display: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::Wayland(init_raw!(WaylandWindowHandle { surface })),
|
||||
RawDisplayHandle::Wayland(init_raw!(WaylandDisplayHandle { display })),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_new_raw_window_handle_appkit(
|
||||
ns_view: *mut c_void,
|
||||
ns_window: *mut c_void,
|
||||
) -> CppRawHandleOpaque {
|
||||
use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle};
|
||||
let handle = CppRawHandle(
|
||||
RawWindowHandle::AppKit(init_raw!(AppKitWindowHandle { ns_view, ns_window })),
|
||||
RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()),
|
||||
);
|
||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_raw_window_handle_drop(handle: CppRawHandleOpaque) {
|
||||
drop(Box::from_raw(handle as *mut CppRawHandle))
|
||||
}
|
||||
|
||||
type SkiaRendererOpaque = *const c_void;
|
||||
type SkiaRenderer = i_slint_renderer_skia::SkiaRenderer;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_new(
|
||||
handle_opaque: CppRawHandleOpaque,
|
||||
size: IntSize,
|
||||
) -> SkiaRendererOpaque {
|
||||
let handle = &*(handle_opaque as *const CppRawHandle);
|
||||
|
||||
// Safety: This is safe because the handle remains valid; the next rwh release provides `new()` without unsafe.
|
||||
let active_handle = unsafe { raw_window_handle::ActiveHandle::new_unchecked() };
|
||||
|
||||
// Safety: the C++ code should ensure that the handle is valid
|
||||
let (window_handle, display_handle) = unsafe {
|
||||
(
|
||||
raw_window_handle::WindowHandle::borrow_raw(handle.0, active_handle),
|
||||
raw_window_handle::DisplayHandle::borrow_raw(handle.1),
|
||||
)
|
||||
};
|
||||
|
||||
let boxed_renderer: Box<SkiaRenderer> = Box::new(
|
||||
SkiaRenderer::new(
|
||||
window_handle,
|
||||
display_handle,
|
||||
PhysicalSize { width: size.width, height: size.height },
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
Box::into_raw(boxed_renderer) as SkiaRendererOpaque
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_drop(r: SkiaRendererOpaque) {
|
||||
drop(Box::from_raw(r as *mut SkiaRenderer))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_show(r: SkiaRendererOpaque) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.show().unwrap()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_hide(r: SkiaRendererOpaque) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.hide().unwrap()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_resize(r: SkiaRendererOpaque, size: IntSize) {
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.resize_event(PhysicalSize { width: size.width, height: size.height }).unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_render(
|
||||
r: SkiaRendererOpaque,
|
||||
window: *const WindowAdapterRcOpaque,
|
||||
) {
|
||||
let window_adapter = &*(window as *const Rc<dyn WindowAdapter>);
|
||||
let r = &*(r as *const SkiaRenderer);
|
||||
r.render(window_adapter.window()).unwrap();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_skia_renderer_handle(r: SkiaRendererOpaque) -> RendererPtr {
|
||||
let r = (r as *const SkiaRenderer) as *const dyn Renderer;
|
||||
core::mem::transmute(r)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue