i_slint_backend_linuxkms/
lib.rs

1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4#![doc = include_str!("README.md")]
5#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
6
7#[cfg(target_os = "linux")]
8mod fullscreenwindowadapter;
9
10#[cfg(target_os = "linux")]
11use std::os::fd::OwnedFd;
12
13#[cfg(target_os = "linux")]
14type DeviceOpener<'a> = dyn Fn(&std::path::Path) -> Result<std::rc::Rc<OwnedFd>, i_slint_core::platform::PlatformError>
15    + 'a;
16
17#[cfg(all(target_os = "linux", feature = "drm"))]
18mod drmoutput;
19
20#[cfg(target_os = "linux")]
21mod display;
22
23#[cfg(target_os = "linux")]
24mod renderer {
25    use i_slint_core::platform::PlatformError;
26
27    use crate::fullscreenwindowadapter::FullscreenRenderer;
28
29    #[cfg(any(feature = "renderer-skia-opengl", feature = "renderer-skia-vulkan"))]
30    pub mod skia;
31
32    #[cfg(feature = "renderer-femtovg")]
33    pub mod femtovg;
34
35    #[cfg(feature = "renderer-software")]
36    pub mod sw;
37
38    pub fn try_skia_then_femtovg_then_software(
39        _device_opener: &crate::DeviceOpener,
40    ) -> Result<Box<dyn FullscreenRenderer>, PlatformError> {
41        #[allow(unused)]
42        type FactoryFn =
43            fn(&crate::DeviceOpener) -> Result<Box<(dyn FullscreenRenderer)>, PlatformError>;
44
45        let renderers = [
46            #[cfg(any(feature = "renderer-skia-opengl", feature = "renderer-skia-vulkan"))]
47            (
48                "Skia",
49                skia::SkiaRendererAdapter::new_try_vulkan_then_opengl_then_software as FactoryFn,
50            ),
51            #[cfg(feature = "renderer-femtovg")]
52            ("FemtoVG", femtovg::FemtoVGRendererAdapter::new as FactoryFn),
53            #[cfg(feature = "renderer-software")]
54            ("Software", sw::SoftwareRendererAdapter::new as FactoryFn),
55            ("", |_| Err(PlatformError::NoPlatform)),
56        ];
57
58        let mut renderer_errors: Vec<String> = Vec::new();
59        for (name, factory) in renderers {
60            match factory(_device_opener) {
61                Ok(renderer) => return Ok(renderer),
62                Err(err) => {
63                    renderer_errors.push(if !name.is_empty() {
64                        format!("Error from {} renderer: {}", name, err).into()
65                    } else {
66                        "No renderers configured.".into()
67                    });
68                }
69            }
70        }
71
72        Err(PlatformError::Other(format!(
73            "Could not initialize any renderer for LinuxKMS backend.\n{}",
74            renderer_errors.join("\n")
75        )))
76    }
77}
78
79#[cfg(target_os = "linux")]
80mod calloop_backend;
81
82#[cfg(target_os = "linux")]
83use calloop_backend::*;
84
85#[cfg(not(target_os = "linux"))]
86mod noop_backend;
87use i_slint_core::api::PlatformError;
88#[cfg(not(target_os = "linux"))]
89use noop_backend::*;
90
91#[derive(Default)]
92pub struct BackendBuilder {
93    pub(crate) renderer_name: Option<String>,
94    #[cfg(target_os = "linux")]
95    pub(crate) libinput_event_hook: Option<Box<dyn Fn(&input::Event) -> bool>>,
96}
97
98impl BackendBuilder {
99    pub fn with_renderer_name(mut self, name: String) -> Self {
100        self.renderer_name = Some(name);
101        self
102    }
103
104    #[cfg(target_os = "linux")]
105    pub fn with_libinput_event_hook(
106        mut self,
107        event_hook: Box<dyn Fn(&input::Event) -> bool>,
108    ) -> Self {
109        self.libinput_event_hook = Some(event_hook);
110        self
111    }
112
113    pub fn build(self) -> Result<Backend, PlatformError> {
114        Backend::build(self)
115    }
116}
117
118#[doc(hidden)]
119pub type NativeWidgets = ();
120#[doc(hidden)]
121pub type NativeGlobals = ();
122#[doc(hidden)]
123pub const HAS_NATIVE_STYLE: bool = false;
124#[doc(hidden)]
125pub mod native_widgets {}