#![doc = include_str!("../README.md")]
#![allow(warnings)]
pub mod conf;
mod event;
pub mod fs;
pub mod graphics;
mod native;
#[cfg(feature = "log-impl")]
pub mod log;
pub use event::*;
pub use graphics::*;
mod default_icon;
pub use native::gl;
pub mod date {
#[cfg(not(target_arch = "wasm32"))]
pub fn now() -> f64 {
use std::time::SystemTime;
let time = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or_else(|e| panic!("{}", e));
time.as_secs_f64()
}
#[cfg(target_arch = "wasm32")]
pub fn now() -> f64 {
use crate::native;
unsafe { native::wasm::now() }
}
}
pub type Context = dyn RenderingBackend;
use std::sync::{Mutex, OnceLock};
static NATIVE_DISPLAY: OnceLock<Mutex<native::NativeDisplayData>> = OnceLock::new();
fn set_display(display: native::NativeDisplayData) {
NATIVE_DISPLAY.set(Mutex::new(display));
}
fn native_display() -> &'static Mutex<native::NativeDisplayData> {
NATIVE_DISPLAY
.get()
.expect("Backend has not initialized NATIVE_DISPLAY yet.") }
pub mod window {
use super::*;
pub fn new_rendering_backend() -> Box<dyn RenderingBackend> {
#[cfg(target_vendor = "apple")]
{
if window::apple_gfx_api() == conf::AppleGfxApi::Metal {
Box::new(MetalContext::new())
} else {
Box::new(GlContext::new())
}
}
#[cfg(not(target_vendor = "apple"))]
Box::new(GlContext::new())
}
pub fn screen_size() -> (f32, f32) {
let d = native_display().lock().unwrap();
(d.screen_width as f32, d.screen_height as f32)
}
pub fn dpi_scale() -> f32 {
let d = native_display().lock().unwrap();
d.dpi_scale
}
pub fn high_dpi() -> bool {
let d = native_display().lock().unwrap();
d.high_dpi
}
pub fn order_quit() {
let mut d = native_display().lock().unwrap();
d.quit_ordered = true;
}
pub fn quit() {
order_quit()
}
pub fn request_quit() {
let mut d = native_display().lock().unwrap();
d.quit_requested = true;
}
pub fn cancel_quit() {
let mut d = native_display().lock().unwrap();
d.quit_requested = false;
}
pub fn set_cursor_grab(grab: bool) {
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::SetCursorGrab(grab));
}
pub fn show_mouse(shown: bool) {
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::ShowMouse(shown));
}
pub fn set_mouse_cursor(cursor_icon: CursorIcon) {
let mut d = native_display().lock().unwrap();
d.native_requests
.send(native::Request::SetMouseCursor(cursor_icon));
}
pub fn set_window_size(new_width: u32, new_height: u32) {
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::SetWindowSize {
new_width,
new_height,
});
}
pub fn set_fullscreen(fullscreen: bool) {
let mut d = native_display().lock().unwrap();
d.native_requests
.send(native::Request::SetFullscreen(fullscreen));
}
pub fn clipboard_get() -> Option<String> {
let mut d = native_display().lock().unwrap();
d.clipboard.get()
}
pub fn clipboard_set(data: &str) {
let mut d = native_display().lock().unwrap();
d.clipboard.set(data)
}
pub fn dropped_file_count() -> usize {
let d = native_display().lock().unwrap();
d.dropped_files.bytes.len()
}
pub fn dropped_file_bytes(index: usize) -> Option<Vec<u8>> {
let d = native_display().lock().unwrap();
d.dropped_files.bytes.get(index).cloned()
}
pub fn dropped_file_path(index: usize) -> Option<std::path::PathBuf> {
let d = native_display().lock().unwrap();
d.dropped_files.paths.get(index).cloned()
}
pub fn show_keyboard(show: bool) {
let mut d = native_display().lock().unwrap();
d.native_requests.send(native::Request::ShowKeyboard(show));
}
#[cfg(target_vendor = "apple")]
pub fn apple_gfx_api() -> crate::conf::AppleGfxApi {
let d = native_display().lock().unwrap();
d.gfx_api
}
#[cfg(target_vendor = "apple")]
pub fn apple_view() -> crate::native::apple::frameworks::ObjcId {
let d = native_display().lock().unwrap();
d.view
}
#[cfg(target_ios = "ios")]
pub fn apple_view_ctrl() -> crate::native::apple::frameworks::ObjcId {
let d = native_display().lock().unwrap();
d.view_ctrl
}
}
#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)]
pub enum CursorIcon {
Default,
Help,
Pointer,
Wait,
Crosshair,
Text,
Move,
NotAllowed,
EWResize,
NSResize,
NESWResize,
NWSEResize,
}
pub fn start<F>(conf: conf::Conf, f: F)
where
F: 'static + FnOnce() -> Box<dyn EventHandler>,
{
#[cfg(target_os = "linux")]
{
let mut f = Some(f);
let f = &mut f;
match conf.platform.linux_backend {
conf::LinuxBackend::X11Only => {
native::linux_x11::run(&conf, f).expect("X11 backend failed")
}
conf::LinuxBackend::WaylandOnly => {
native::linux_wayland::run(&conf, f).expect("Wayland backend failed")
}
conf::LinuxBackend::X11WithWaylandFallback => {
if native::linux_x11::run(&conf, f).is_none() {
eprintln!("Failed to initialize through X11! Trying wayland instead");
native::linux_wayland::run(&conf, f);
}
}
conf::LinuxBackend::WaylandWithX11Fallback => {
if native::linux_wayland::run(&conf, f).is_none() {
eprintln!("Failed to initialize through wayland! Trying X11 instead");
native::linux_x11::run(&conf, f);
}
}
}
}
#[cfg(target_os = "android")]
unsafe {
native::android::run(conf, f);
}
#[cfg(target_arch = "wasm32")]
{
native::wasm::run(&conf, f);
}
#[cfg(target_os = "windows")]
{
native::windows::run(&conf, f);
}
#[cfg(target_os = "macos")]
unsafe {
native::macos::run(conf, f);
}
#[cfg(target_os = "ios")]
unsafe {
native::ios::run(conf, f);
}
}