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"]
|
gettext = ["i-slint-core/gettext-rs"]
|
||||||
accessibility = ["i-slint-backend-selector/accessibility"]
|
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"]
|
std = ["image", "i-slint-core/default", "i-slint-backend-selector"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use alloc::rc::Rc;
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use i_slint_core::window::{ffi::WindowAdapterRcOpaque, WindowAdapter};
|
use i_slint_core::window::{ffi::WindowAdapterRcOpaque, WindowAdapter};
|
||||||
|
|
||||||
#[cfg(feature = "experimental")]
|
#[cfg(feature = "experimental-platform")]
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
|
|
||||||
#[cfg(feature = "i-slint-backend-selector")]
|
#[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::software_renderer::{RepaintBufferType, SoftwareRenderer};
|
||||||
use i_slint_core::window::ffi::WindowAdapterRcOpaque;
|
use i_slint_core::window::ffi::WindowAdapterRcOpaque;
|
||||||
use i_slint_core::window::{WindowAdapter, WindowAdapterInternal};
|
use i_slint_core::window::{WindowAdapter, WindowAdapterInternal};
|
||||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
|
|
||||||
|
|
||||||
type WindowAdapterUserData = *mut c_void;
|
type WindowAdapterUserData = *mut c_void;
|
||||||
|
|
||||||
|
|
@ -214,146 +213,155 @@ pub unsafe extern "C" fn slint_software_renderer_handle(r: SoftwareRendererOpaqu
|
||||||
core::mem::transmute(r)
|
core::mem::transmute(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
type SkiaRendererOpaque = *const c_void;
|
#[cfg(all(feature = "i-slint-renderer-skia", feature = "raw-window-handle"))]
|
||||||
type SkiaRenderer = i_slint_renderer_skia::SkiaRenderer;
|
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.
|
// the raw handle type are #[non_exhaustive], so they can't be initialize with the convenient syntax. Work that around.
|
||||||
macro_rules! init_raw {
|
macro_rules! init_raw {
|
||||||
($ty:ty { $($var:ident),* }) => {
|
($ty:ty { $($var:ident),* }) => {
|
||||||
{
|
{
|
||||||
let mut h = <$ty>::empty();
|
let mut h = <$ty>::empty();
|
||||||
$(h.$var = $var;)*
|
$(h.$var = $var;)*
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
type CppRawHandleOpaque = *const c_void;
|
type CppRawHandleOpaque = *const c_void;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn slint_new_raw_window_handle_win32(
|
pub unsafe extern "C" fn slint_new_raw_window_handle_win32(
|
||||||
hwnd: *mut c_void,
|
hwnd: *mut c_void,
|
||||||
hinstance: *mut c_void,
|
hinstance: *mut c_void,
|
||||||
) -> CppRawHandleOpaque {
|
) -> CppRawHandleOpaque {
|
||||||
let handle = CppRawHandle(
|
let handle = CppRawHandle(
|
||||||
RawWindowHandle::Win32(init_raw!(raw_window_handle::Win32WindowHandle { hwnd, hinstance })),
|
RawWindowHandle::Win32(init_raw!(raw_window_handle::Win32WindowHandle {
|
||||||
RawDisplayHandle::Windows(raw_window_handle::WindowsDisplayHandle::empty()),
|
hwnd,
|
||||||
);
|
hinstance
|
||||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
})),
|
||||||
}
|
RawDisplayHandle::Windows(raw_window_handle::WindowsDisplayHandle::empty()),
|
||||||
|
);
|
||||||
#[no_mangle]
|
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||||
pub unsafe extern "C" fn slint_new_raw_window_handle_x11(
|
}
|
||||||
window: u32,
|
|
||||||
visual_id: u32,
|
#[no_mangle]
|
||||||
connection: *mut c_void,
|
pub unsafe extern "C" fn slint_new_raw_window_handle_x11(
|
||||||
screen: core::ffi::c_int,
|
window: u32,
|
||||||
) -> CppRawHandleOpaque {
|
visual_id: u32,
|
||||||
use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle};
|
connection: *mut c_void,
|
||||||
let handle = CppRawHandle(
|
screen: core::ffi::c_int,
|
||||||
RawWindowHandle::Xcb(init_raw!(XcbWindowHandle { window, visual_id })),
|
) -> CppRawHandleOpaque {
|
||||||
RawDisplayHandle::Xcb(init_raw!(XcbDisplayHandle { connection, screen })),
|
use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle};
|
||||||
);
|
let handle = CppRawHandle(
|
||||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
RawWindowHandle::Xcb(init_raw!(XcbWindowHandle { window, visual_id })),
|
||||||
}
|
RawDisplayHandle::Xcb(init_raw!(XcbDisplayHandle { connection, screen })),
|
||||||
|
);
|
||||||
#[no_mangle]
|
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||||
pub unsafe extern "C" fn slint_new_raw_window_handle_wayland(
|
}
|
||||||
surface: *mut c_void,
|
|
||||||
display: *mut c_void,
|
#[no_mangle]
|
||||||
) -> CppRawHandleOpaque {
|
pub unsafe extern "C" fn slint_new_raw_window_handle_wayland(
|
||||||
use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle};
|
surface: *mut c_void,
|
||||||
let handle = CppRawHandle(
|
display: *mut c_void,
|
||||||
RawWindowHandle::Wayland(init_raw!(WaylandWindowHandle { surface })),
|
) -> CppRawHandleOpaque {
|
||||||
RawDisplayHandle::Wayland(init_raw!(WaylandDisplayHandle { display })),
|
use raw_window_handle::{WaylandDisplayHandle, WaylandWindowHandle};
|
||||||
);
|
let handle = CppRawHandle(
|
||||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
RawWindowHandle::Wayland(init_raw!(WaylandWindowHandle { surface })),
|
||||||
}
|
RawDisplayHandle::Wayland(init_raw!(WaylandDisplayHandle { display })),
|
||||||
|
);
|
||||||
#[no_mangle]
|
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||||
pub unsafe extern "C" fn slint_new_raw_window_handle_appkit(
|
}
|
||||||
ns_view: *mut c_void,
|
|
||||||
ns_window: *mut c_void,
|
#[no_mangle]
|
||||||
) -> CppRawHandleOpaque {
|
pub unsafe extern "C" fn slint_new_raw_window_handle_appkit(
|
||||||
use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle};
|
ns_view: *mut c_void,
|
||||||
let handle = CppRawHandle(
|
ns_window: *mut c_void,
|
||||||
RawWindowHandle::AppKit(init_raw!(AppKitWindowHandle { ns_view, ns_window })),
|
) -> CppRawHandleOpaque {
|
||||||
RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()),
|
use raw_window_handle::{AppKitDisplayHandle, AppKitWindowHandle};
|
||||||
);
|
let handle = CppRawHandle(
|
||||||
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
RawWindowHandle::AppKit(init_raw!(AppKitWindowHandle { ns_view, ns_window })),
|
||||||
}
|
RawDisplayHandle::AppKit(AppKitDisplayHandle::empty()),
|
||||||
|
);
|
||||||
#[no_mangle]
|
Box::into_raw(Box::new(handle)) as CppRawHandleOpaque
|
||||||
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_raw_window_handle_drop(handle: CppRawHandleOpaque) {
|
||||||
#[no_mangle]
|
drop(Box::from_raw(handle as *mut CppRawHandle))
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_new(
|
}
|
||||||
handle_opaque: CppRawHandleOpaque,
|
|
||||||
size: IntSize,
|
type SkiaRendererOpaque = *const c_void;
|
||||||
) -> SkiaRendererOpaque {
|
type SkiaRenderer = i_slint_renderer_skia::SkiaRenderer;
|
||||||
let handle = &*(handle_opaque as *const CppRawHandle);
|
|
||||||
|
#[no_mangle]
|
||||||
// Safety: This is safe because the handle remains valid; the next rwh release provides `new()` without unsafe.
|
pub unsafe extern "C" fn slint_skia_renderer_new(
|
||||||
let active_handle = unsafe { raw_window_handle::ActiveHandle::new_unchecked() };
|
handle_opaque: CppRawHandleOpaque,
|
||||||
|
size: IntSize,
|
||||||
// Safety: the C++ code should ensure that the handle is valid
|
) -> SkiaRendererOpaque {
|
||||||
let (window_handle, display_handle) = unsafe {
|
let handle = &*(handle_opaque as *const CppRawHandle);
|
||||||
(
|
|
||||||
raw_window_handle::WindowHandle::borrow_raw(handle.0, active_handle),
|
// Safety: This is safe because the handle remains valid; the next rwh release provides `new()` without unsafe.
|
||||||
raw_window_handle::DisplayHandle::borrow_raw(handle.1),
|
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 {
|
||||||
let boxed_renderer: Box<SkiaRenderer> = Box::new(
|
(
|
||||||
SkiaRenderer::new(
|
raw_window_handle::WindowHandle::borrow_raw(handle.0, active_handle),
|
||||||
window_handle,
|
raw_window_handle::DisplayHandle::borrow_raw(handle.1),
|
||||||
display_handle,
|
)
|
||||||
PhysicalSize { width: size.width, height: size.height },
|
};
|
||||||
)
|
|
||||||
.unwrap(),
|
let boxed_renderer: Box<SkiaRenderer> = Box::new(
|
||||||
);
|
SkiaRenderer::new(
|
||||||
Box::into_raw(boxed_renderer) as SkiaRendererOpaque
|
window_handle,
|
||||||
}
|
display_handle,
|
||||||
|
PhysicalSize { width: size.width, height: size.height },
|
||||||
#[no_mangle]
|
)
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_drop(r: SkiaRendererOpaque) {
|
.unwrap(),
|
||||||
drop(Box::from_raw(r as *mut SkiaRenderer))
|
);
|
||||||
}
|
Box::into_raw(boxed_renderer) as SkiaRendererOpaque
|
||||||
|
}
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_show(r: SkiaRendererOpaque) {
|
#[no_mangle]
|
||||||
let r = &*(r as *const SkiaRenderer);
|
pub unsafe extern "C" fn slint_skia_renderer_drop(r: SkiaRendererOpaque) {
|
||||||
r.show().unwrap()
|
drop(Box::from_raw(r as *mut SkiaRenderer))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_hide(r: SkiaRendererOpaque) {
|
pub unsafe extern "C" fn slint_skia_renderer_show(r: SkiaRendererOpaque) {
|
||||||
let r = &*(r as *const SkiaRenderer);
|
let r = &*(r as *const SkiaRenderer);
|
||||||
r.hide().unwrap()
|
r.show().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_resize(r: SkiaRendererOpaque, size: IntSize) {
|
pub unsafe extern "C" fn slint_skia_renderer_hide(r: SkiaRendererOpaque) {
|
||||||
let r = &*(r as *const SkiaRenderer);
|
let r = &*(r as *const SkiaRenderer);
|
||||||
r.resize_event(PhysicalSize { width: size.width, height: size.height }).unwrap();
|
r.hide().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_render(
|
pub unsafe extern "C" fn slint_skia_renderer_resize(r: SkiaRendererOpaque, size: IntSize) {
|
||||||
r: SkiaRendererOpaque,
|
let r = &*(r as *const SkiaRenderer);
|
||||||
window: *const WindowAdapterRcOpaque,
|
r.resize_event(PhysicalSize { width: size.width, height: size.height }).unwrap();
|
||||||
) {
|
}
|
||||||
let window_adapter = &*(window as *const Rc<dyn WindowAdapter>);
|
|
||||||
let r = &*(r as *const SkiaRenderer);
|
#[no_mangle]
|
||||||
r.render(window_adapter.window()).unwrap();
|
pub unsafe extern "C" fn slint_skia_renderer_render(
|
||||||
}
|
r: SkiaRendererOpaque,
|
||||||
|
window: *const WindowAdapterRcOpaque,
|
||||||
#[no_mangle]
|
) {
|
||||||
pub unsafe extern "C" fn slint_skia_renderer_handle(r: SkiaRendererOpaque) -> RendererPtr {
|
let window_adapter = &*(window as *const Rc<dyn WindowAdapter>);
|
||||||
let r = (r as *const SkiaRenderer) as *const dyn Renderer;
|
let r = &*(r as *const SkiaRenderer);
|
||||||
core::mem::transmute(r)
|
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