Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 46 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,31 @@ pub mod date {

pub type Context = dyn RenderingBackend;

use std::sync::{Mutex, OnceLock};
use crate::native::NativeDisplayData;
use std::sync::{Mutex, MutexGuard};

static NATIVE_DISPLAY: OnceLock<Mutex<native::NativeDisplayData>> = OnceLock::new();
static mut NATIVE_DISPLAY: Option<Mutex<NativeDisplayData>> = None;

fn set_display(display: native::NativeDisplayData) {
NATIVE_DISPLAY
.set(Mutex::new(display))
.unwrap_or_else(|_| panic!("NATIVE_DISPLAY already set"));
fn set_display(display: NativeDisplayData) {
unsafe {
NATIVE_DISPLAY = Some(Mutex::new(display));
}
}
fn native_display() -> &'static Mutex<native::NativeDisplayData> {
NATIVE_DISPLAY
.get()
.expect("Backend has not initialized NATIVE_DISPLAY yet.") //|| Mutex::new(Default::default()))

fn native_display_blocking() -> MutexGuard<'static, NativeDisplayData> {
native_display().lock().unwrap()
}

fn native_display_nonblocking() -> MutexGuard<'static, NativeDisplayData> {
native_display().try_lock().unwrap()
}

fn native_display() -> &'static Mutex<NativeDisplayData> {
unsafe {
NATIVE_DISPLAY
.as_ref()
.expect("Backend has not initialized NATIVE_DISPLAY yet.")
}
}

/// Window and associated to window rendering context related functions.
Expand Down Expand Up @@ -133,26 +145,26 @@ pub mod window {
/// The current framebuffer size in pixels
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn screen_size() -> (f32, f32) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
(d.screen_width as f32, d.screen_height as f32)
}

/// The dpi scaling factor (window pixels to framebuffer pixels)
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn dpi_scale() -> f32 {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.dpi_scale
}

/// True when high_dpi was requested and actually running in a high-dpi scenario
/// NOTE: [High DPI Rendering](../conf/index.html#high-dpi-rendering)
pub fn high_dpi() -> bool {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.high_dpi
}

pub fn blocking_event_loop() -> bool {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.blocking_event_loop
}

Expand All @@ -164,7 +176,7 @@ pub mod window {
/// happen in the order_quit implmentation) and execution might continue for some time after
/// But the window is going to be inevitably closed at some point.
pub fn order_quit() {
let mut d = native_display().lock().unwrap();
let mut d = native_display_blocking();
d.quit_ordered = true;
}

Expand All @@ -179,7 +191,7 @@ pub mod window {
/// If the event handler callback does nothing, the application will be quit as usual.
/// To prevent this, call the function "cancel_quit()"" from inside the event handler.
pub fn request_quit() {
let mut d = native_display().lock().unwrap();
let mut d = native_display_blocking();
d.quit_requested = true;
}

Expand All @@ -189,7 +201,7 @@ pub mod window {
/// function makes sense is from inside the event handler callback when
/// the "quit_requested_event" event has been received
pub fn cancel_quit() {
let mut d = native_display().lock().unwrap();
let mut d = native_display_blocking();
d.quit_requested = false;
}
/// Capture mouse cursor to the current window
Expand All @@ -199,7 +211,7 @@ pub mod window {
/// so set_cursor_grab(false) on window's focus lost is recommended.
/// TODO: implement window focus events
pub fn set_cursor_grab(grab: bool) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::SetCursorGrab(grab))
.unwrap();
Expand All @@ -213,7 +225,7 @@ pub mod window {
pub fn schedule_update() {
#[cfg(not(target_arch = "wasm32"))]
{
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::ScheduleUpdate)
.unwrap();
Expand All @@ -227,23 +239,23 @@ pub mod window {

/// Show or hide the mouse cursor
pub fn show_mouse(shown: bool) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::ShowMouse(shown))
.unwrap();
}

/// Set the mouse cursor icon.
pub fn set_mouse_cursor(cursor_icon: CursorIcon) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::SetMouseCursor(cursor_icon))
.unwrap();
}

/// Set the application's window size.
pub fn set_window_size(new_width: u32, new_height: u32) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::SetWindowSize {
new_width,
Expand All @@ -253,7 +265,7 @@ pub mod window {
}

pub fn set_window_position(new_x: u32, new_y: u32) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::SetWindowPosition { new_x, new_y })
.unwrap();
Expand All @@ -263,63 +275,63 @@ pub mod window {
/// TODO: implement for other platforms
#[cfg(any(target_os = "windows", target_os = "linux"))]
pub fn get_window_position() -> (u32, u32) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.screen_position
}

pub fn set_fullscreen(fullscreen: bool) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::SetFullscreen(fullscreen))
.unwrap();
}

/// Get current OS clipboard value
pub fn clipboard_get() -> Option<String> {
let mut d = native_display().lock().unwrap();
let mut d = native_display_blocking();
d.clipboard.get()
}

/// Save value to OS clipboard
pub fn clipboard_set(data: &str) {
let mut d = native_display().lock().unwrap();
let mut d = native_display_blocking();
d.clipboard.set(data)
}
pub fn dropped_file_count() -> usize {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.dropped_files.bytes.len()
}
pub fn dropped_file_bytes(index: usize) -> Option<Vec<u8>> {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.dropped_files.bytes.get(index).cloned()
}
pub fn dropped_file_path(index: usize) -> Option<std::path::PathBuf> {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.dropped_files.paths.get(index).cloned()
}

/// Show/hide onscreen keyboard.
/// Only works on Android right now.
pub fn show_keyboard(show: bool) {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.native_requests
.send(native::Request::ShowKeyboard(show))
.unwrap();
}

#[cfg(target_vendor = "apple")]
pub fn apple_gfx_api() -> crate::conf::AppleGfxApi {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.gfx_api
}
#[cfg(target_vendor = "apple")]
pub fn apple_view() -> crate::native::apple::frameworks::ObjcId {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.view
}
#[cfg(target_os = "ios")]
pub fn apple_view_ctrl() -> crate::native::apple::frameworks::ObjcId {
let d = native_display().lock().unwrap();
let d = native_display_blocking();
d.view_ctrl
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/native/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl MainThreadState {
}

{
let mut d = crate::native_display().lock().unwrap();
let mut d = crate::native_display_blocking();
d.screen_width = width as _;
d.screen_height = height as _;
}
Expand Down
12 changes: 6 additions & 6 deletions src/native/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use {
},
NativeDisplayData,
},
native_display,
native_display_blocking,
},
std::{
cell::RefCell,
Expand Down Expand Up @@ -140,7 +140,7 @@ pub fn define_glk_or_mtk_view(superclass: &Class) -> *const Class {
let ios_touch: ObjcId = msg_send![enumerator, nextObject];
let mut ios_pos: NSPoint = msg_send![ios_touch, locationInView: this];

if native_display().lock().unwrap().high_dpi {
if native_display_blocking().high_dpi {
ios_pos.x *= 2.;
ios_pos.y *= 2.;
} else {
Expand Down Expand Up @@ -314,7 +314,7 @@ pub fn define_glk_or_mtk_view_dlg(superclass: &Class) -> *const Class {

let main_screen: ObjcId = unsafe { msg_send![class!(UIScreen), mainScreen] };
let screen_rect: NSRect = unsafe { msg_send![main_screen, bounds] };
let high_dpi = native_display().lock().unwrap().high_dpi;
let high_dpi = native_display_blocking().high_dpi;

let (screen_width, screen_height) = if high_dpi {
(
Expand All @@ -329,11 +329,11 @@ pub fn define_glk_or_mtk_view_dlg(superclass: &Class) -> *const Class {
)
};

if native_display().lock().unwrap().screen_width != screen_width
|| native_display().lock().unwrap().screen_height != screen_height
if native_display_blocking().screen_width != screen_width
|| native_display_blocking().screen_height != screen_height
{
{
let mut d = native_display().lock().unwrap();
let mut d = native_display_blocking();
d.screen_width = screen_width;
d.screen_height = screen_height;
}
Expand Down
12 changes: 6 additions & 6 deletions src/native/linux_x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ impl X11Display {
event_handler.window_minimized_event();
}
22 => {
let mut d = crate::native_display().try_lock().unwrap();
let mut d = crate::native_display_nonblocking();
let left = event.xconfigure.x;
let top = event.xconfigure.y;
d.screen_position = (left as _, top as _);
Expand All @@ -155,7 +155,7 @@ impl X11Display {
// ClientMessage
33 => match event.xclient.message_type {
t if t == self.libx11.extensions.wm_protocols => {
let mut d = crate::native_display().try_lock().unwrap();
let mut d = crate::native_display_nonblocking();
let protocol = event.xclient.data.l[0 as libc::c_int as usize] as Atom;
if protocol == self.libx11.extensions.wm_delete_window {
d.quit_requested = true;
Expand Down Expand Up @@ -235,11 +235,11 @@ impl X11Display {
_ => {}
};

let d = crate::native_display().try_lock().unwrap();
let d = crate::native_display_nonblocking();
if d.quit_requested && !d.quit_ordered {
drop(d);
event_handler.quit_requested_event();
let mut d = crate::native_display().try_lock().unwrap();
let mut d = crate::native_display_nonblocking();
if d.quit_requested {
d.quit_ordered = true
}
Expand Down Expand Up @@ -481,7 +481,7 @@ where

let mut event_handler = (f.take().unwrap())();

while !crate::native_display().try_lock().unwrap().quit_ordered {
while !crate::native_display_nonblocking().quit_ordered {
while let Ok(request) = rx.try_recv() {
display.process_request(request);
}
Expand Down Expand Up @@ -593,7 +593,7 @@ where

let mut event_handler = (f.take().unwrap())();

while !crate::native_display().try_lock().unwrap().quit_ordered {
while !crate::native_display_nonblocking().quit_ordered {
while let Ok(request) = rx.try_recv() {
display.process_request(request);
}
Expand Down
Loading