summaryrefslogtreecommitdiff
path: root/glfw
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-10-07 20:00:16 +0200
committerHampusM <hampus@hampusmat.com>2023-10-07 20:00:16 +0200
commitb34b393f7b07495ca92ff5b0ce79d4c391abe0ca (patch)
tree062ae1cf150596bdde32abd7b52346b0b0e817bc /glfw
parentd1be0566969974bd70f2d77915b6936095c894c6 (diff)
feat(glfw): add function to set framebuffer size callback
Diffstat (limited to 'glfw')
-rw-r--r--glfw/src/window.rs52
1 files changed, 51 insertions, 1 deletions
diff --git a/glfw/src/window.rs b/glfw/src/window.rs
index e3e6383..a080161 100644
--- a/glfw/src/window.rs
+++ b/glfw/src/window.rs
@@ -1,4 +1,6 @@
-use std::ffi::{CStr, CString};
+use std::cell::RefCell;
+use std::ffi::{c_int, CStr, CString};
+use std::panic::catch_unwind;
use std::ptr::null_mut;
use crate::init::{initialize, Glfw};
@@ -140,6 +142,22 @@ impl Window
height: height as u32,
})
}
+
+ pub fn set_framebuffer_size_callback(&self, callback: impl Fn(Size) + 'static)
+ {
+ FRAMEBUFFER_SIZE_CB.with_borrow_mut(|framebuffer_size_cb| {
+ *framebuffer_size_cb = Some(Box::new(callback));
+ });
+
+ // SAFETY: The initialize function (called when the window is created) makes sure
+ // the current thread is the main thread
+ unsafe {
+ crate::ffi::glfwSetFramebufferSizeCallback(
+ self.handle,
+ Some(framebuffer_size_callback),
+ );
+ }
+ }
}
/// Window size.
@@ -148,3 +166,35 @@ pub struct Size
pub width: u32,
pub height: u32,
}
+
+type FramebufferSizeCb = Box<dyn Fn(Size)>;
+
+thread_local! {
+static FRAMEBUFFER_SIZE_CB: RefCell<Option<FramebufferSizeCb>> = RefCell::new(None);
+}
+
+extern "C" fn framebuffer_size_callback(
+ _window: *mut crate::ffi::GLFWwindow,
+ c_width: c_int,
+ c_height: c_int,
+)
+{
+ // Width and height can't possibly have their sign bit set
+ let width = u32::from_le_bytes(c_width.to_le_bytes());
+ let height = u32::from_le_bytes(c_height.to_le_bytes());
+
+ // Unwinds are catched because unwinding from Rust code into foreign code is UB.
+ let res = catch_unwind(|| {
+ FRAMEBUFFER_SIZE_CB
+ .try_with(|framebuffer_size_cb| {
+ if let Some(cb) = framebuffer_size_cb.borrow().as_deref() {
+ cb(Size { width, height });
+ }
+ })
+ .ok();
+ });
+
+ if res.is_err() {
+ println!("ERROR: Panic in framebuffer size callback");
+ }
+}