Skip to content

Commit

Permalink
C++: add a "std" feature to the slint-cpp crate
Browse files Browse the repository at this point in the history
And make it no_std otherwise

This is a first step towards getting C++ on MCU (#2136)
  • Loading branch information
ogoffart committed Jul 5, 2023
1 parent 9afadf5 commit aa8ef4e
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 13 deletions.
1 change: 1 addition & 0 deletions api/cpp/CMakeLists.txt
Expand Up @@ -137,6 +137,7 @@ set_property(
TARGET slint-cpp
PROPERTY CORROSION_FEATURES
${features}
std
)
set_property(
TARGET slint-cpp
Expand Down
12 changes: 7 additions & 5 deletions api/cpp/Cargo.toml
Expand Up @@ -38,19 +38,21 @@ 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"]
experimental = ["i-slint-renderer-skia", "raw-window-handle", "std"]

default = ["backend-winit", "renderer-winit-femtovg", "backend-qt", "experimental"]
std = ["image", "i-slint-core/default", "i-slint-backend-selector"]

default = ["std", "backend-winit", "renderer-winit-femtovg", "backend-qt", "experimental"]

[dependencies]
i-slint-backend-selector = { version = "=1.1.1", path="../../internal/backends/selector" }
i-slint-backend-selector = { version = "=1.1.1", path="../../internal/backends/selector", optional = true }
i-slint-backend-testing = { version = "=1.1.1", path="../../internal/backends/testing", optional = true }
i-slint-renderer-skia = { version = "=1.1.1", path="../../internal/renderers/skia", optional = true, features = ["x11", "wayland"] }
i-slint-core = { version = "=1.1.1", path="../../internal/core", features = ["ffi"] }
i-slint-core = { version = "=1.1.1", path="../../internal/core", default-features = false, features = ["ffi"] }
slint-interpreter = { version = "=1.1.1", path="../../internal/interpreter", default-features = false, features = ["ffi", "compat-1-0"], optional = true }
raw-window-handle = { version = "0.5", optional = true }
# Enable image-rs' default features to make all image formats to C++ users
image = { version = "0.24.0" }
image = { version = "0.24.0", optional = true }

[build-dependencies]
anyhow = "1.0"
Expand Down
25 changes: 21 additions & 4 deletions api/cpp/lib.rs
Expand Up @@ -3,13 +3,28 @@

/*! This crate just expose the function used by the C++ integration */

#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;

use alloc::rc::Rc;
use core::ffi::c_void;
use i_slint_core::window::{ffi::WindowAdapterRcOpaque, WindowAdapter};
use std::rc::Rc;

#[cfg(feature = "experimental")]
pub mod platform;

#[cfg(feature = "i-slint-backend-selector")]
use i_slint_backend_selector::with_platform;

#[cfg(not(feature = "i-slint-backend-selector"))]
pub fn with_platform<R>(
f: impl FnOnce(
&dyn i_slint_core::platform::Platform,
) -> Result<R, i_slint_core::platform::PlatformError>,
) -> Result<R, i_slint_core::platform::PlatformError> {
i_slint_core::with_platform(|| Err(i_slint_core::platform::PlatformError::NoPlatform), f)
}

/// One need to make sure something from the crate is exported,
/// otherwise its symbols are not going to be in the final binary
#[cfg(feature = "slint-interpreter")]
Expand All @@ -21,13 +36,13 @@ pub unsafe extern "C" fn slint_windowrc_init(out: *mut WindowAdapterRcOpaque) {
core::mem::size_of::<Rc<dyn WindowAdapter>>(),
core::mem::size_of::<WindowAdapterRcOpaque>()
);
let win = i_slint_backend_selector::with_platform(|b| b.create_window_adapter()).unwrap();
let win = with_platform(|b| b.create_window_adapter()).unwrap();
core::ptr::write(out as *mut Rc<dyn WindowAdapter>, win);
}

#[no_mangle]
pub unsafe extern "C" fn slint_ensure_backend() {
i_slint_backend_selector::with_platform(|_b| {
with_platform(|_b| {
// Nothing to do, just make sure a backend was created
Ok(())
})
Expand All @@ -36,7 +51,7 @@ pub unsafe extern "C" fn slint_ensure_backend() {

#[no_mangle]
pub unsafe extern "C" fn slint_run_event_loop() {
i_slint_backend_selector::with_platform(|b| b.run_event_loop()).unwrap();
with_platform(|b| b.run_event_loop()).unwrap();
}

/// Will execute the given functor in the main thread
Expand Down Expand Up @@ -72,6 +87,7 @@ pub unsafe extern "C" fn slint_quit_event_loop() {
i_slint_core::api::quit_event_loop().unwrap();
}

#[cfg(feature = "std")]
#[no_mangle]
pub unsafe extern "C" fn slint_register_font_from_path(
win: *const WindowAdapterRcOpaque,
Expand All @@ -89,6 +105,7 @@ pub unsafe extern "C" fn slint_register_font_from_path(
)
}

#[cfg(feature = "std")]
#[no_mangle]
pub unsafe extern "C" fn slint_register_font_from_data(
win: *const WindowAdapterRcOpaque,
Expand Down
3 changes: 2 additions & 1 deletion api/cpp/platform.rs
@@ -1,6 +1,8 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.0 OR LicenseRef-Slint-commercial

use alloc::boxed::Box;
use alloc::rc::Rc;
use core::ffi::c_void;
use i_slint_core::api::{PhysicalSize, Window};
use i_slint_core::graphics::{IntSize, Rgb8Pixel};
Expand All @@ -10,7 +12,6 @@ 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};
use std::rc::Rc;

type WindowAdapterUserData = *mut c_void;

Expand Down
1 change: 1 addition & 0 deletions internal/core/graphics.rs
Expand Up @@ -194,5 +194,6 @@ pub(crate) mod ffi {
y: f32,
}

#[cfg(feature = "std")]
pub use super::path::ffi::*;
}
6 changes: 4 additions & 2 deletions internal/core/graphics/image.rs
Expand Up @@ -775,21 +775,23 @@ pub(crate) mod ffi {
a: u8,
}

#[cfg(feature = "image-decoders")]
#[no_mangle]
pub unsafe extern "C" fn slint_image_load_from_path(path: &SharedString, image: *mut Image) {
std::ptr::write(
core::ptr::write(
image,
Image::load_from_path(std::path::Path::new(path.as_str())).unwrap_or(Image::default()),
)
}

#[cfg(feature = "std")]
#[no_mangle]
pub unsafe extern "C" fn slint_image_load_from_embedded_data(
data: Slice<'static, u8>,
format: Slice<'static, u8>,
image: *mut Image,
) {
std::ptr::write(image, super::load_image_from_embedded_data(data, format));
core::ptr::write(image, super::load_image_from_embedded_data(data, format));
}

#[no_mangle]
Expand Down
2 changes: 1 addition & 1 deletion tests/driver/cpp/Cargo.toml
Expand Up @@ -14,7 +14,7 @@ path = "main.rs"
name = "test-driver-cpp"

[dependencies]
slint-cpp = { path = "../../../api/cpp", default-features = false, features = ["testing"] }
slint-cpp = { path = "../../../api/cpp", default-features = false, features = ["testing", "std"] }

[dev-dependencies]
i-slint-compiler = { path = "../../../internal/compiler", features = ["cpp", "display-diagnostics"] }
Expand Down

0 comments on commit aa8ef4e

Please sign in to comment.