summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-10-18 17:14:46 +0200
committerHampusM <hampus@hampusmat.com>2025-10-18 17:14:46 +0200
commit178723c9627a3aebb2f83dc476abe7d23de63eac (patch)
tree7591c4a864f93d7404af85f3e6a82dd9b972d886
parent7083a19bf1029bff21a9550d40cc3260e99aac53 (diff)
chore: remove glfw crate
-rw-r--r--Cargo.lock53
-rw-r--r--Cargo.toml2
-rw-r--r--glfw/Cargo.toml18
-rw-r--r--glfw/build.rs42
-rw-r--r--glfw/glfw.h6
-rw-r--r--glfw/src/ffi.rs9
-rw-r--r--glfw/src/init.rs59
-rw-r--r--glfw/src/lib.rs53
-rw-r--r--glfw/src/util.rs10
-rw-r--r--glfw/src/window.rs863
10 files changed, 3 insertions, 1112 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 991f697..1b57c31 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -107,26 +107,6 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bindgen"
-version = "0.68.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
-dependencies = [
- "bitflags 2.9.0",
- "cexpr",
- "clang-sys",
- "lazy_static",
- "lazycell",
- "peeking_take_while",
- "proc-macro2",
- "quote",
- "regex",
- "rustc-hash 1.1.0",
- "shlex",
- "syn 2.0.100",
-]
-
-[[package]]
-name = "bindgen"
version = "0.71.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
@@ -140,7 +120,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
- "rustc-hash 2.1.1",
+ "rustc-hash",
"shlex",
"syn 2.0.100",
]
@@ -716,17 +696,6 @@ dependencies = [
]
[[package]]
-name = "glfw"
-version = "0.1.0"
-dependencies = [
- "bindgen 0.68.1",
- "bitflags 2.9.0",
- "libc",
- "thiserror",
- "util-macros",
-]
-
-[[package]]
name = "glob"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -792,7 +761,7 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97dbac5b269c7160b78812a9873f548668aa34b62f28f7a64328a6cd94feb47d"
dependencies = [
- "bindgen 0.71.1",
+ "bindgen",
]
[[package]]
@@ -933,12 +902,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
-name = "lazycell"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
-
-[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1446,12 +1409,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
-name = "peeking_take_while"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
-
-[[package]]
name = "percent-encoding"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1688,12 +1645,6 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustc-hash"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
-
-[[package]]
-name = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
diff --git a/Cargo.toml b/Cargo.toml
index 8ba4ecc..21eb777 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[workspace]
-members = ["glfw", "engine", "ecs", "ecs-macros", "util-macros", "opengl-bindings"]
+members = ["engine", "ecs", "ecs-macros", "util-macros", "opengl-bindings"]
[dependencies]
engine = { path = "./engine" }
diff --git a/glfw/Cargo.toml b/glfw/Cargo.toml
deleted file mode 100644
index 0a47e73..0000000
--- a/glfw/Cargo.toml
+++ /dev/null
@@ -1,18 +0,0 @@
-[package]
-name = "glfw"
-version = "0.1.0"
-edition = "2021"
-
-[features]
-opengl = []
-
-[dependencies]
-libc = "0.2.148"
-thiserror = "1.0.49"
-bitflags = "2.4.0"
-util-macros = { path = "../util-macros" }
-
-[build-dependencies.bindgen]
-version = "0.68.1"
-default-features = false
-features = ["runtime"]
diff --git a/glfw/build.rs b/glfw/build.rs
deleted file mode 100644
index 18ac677..0000000
--- a/glfw/build.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use std::env;
-use std::error::Error;
-use std::fs::OpenOptions;
-use std::io::Write;
-use std::path::PathBuf;
-
-use bindgen::{Abi, MacroTypeVariation};
-
-fn main() -> Result<(), Box<dyn Error>>
-{
- println!("cargo:rustc-link-lib=glfw");
-
- println!("cargo:rerun-if-changed=glfw.h");
-
- let bindings = bindgen::Builder::default()
- .header("glfw.h")
- .clang_arg("-fretain-comments-from-system-headers")
- .generate_comments(true)
- .allowlist_function("glfw.*")
- .allowlist_type("GLFW.*")
- .allowlist_var("GLFW.*")
- .blocklist_type("GLFWglproc")
- .default_macro_constant_type(MacroTypeVariation::Signed)
- .override_abi(Abi::CUnwind, ".*")
- .generate()?;
-
- let out_path = PathBuf::from(env::var("OUT_DIR")?);
-
- let bindings_file_path = out_path.join("bindings.rs");
-
- bindings.write_to_file(&bindings_file_path)?;
-
- let mut bindings_file = OpenOptions::new().append(true).open(bindings_file_path)?;
-
- // Cannot be C-unwind :(
- writeln!(
- bindings_file,
- "pub type GLFWglproc = ::std::option::Option<unsafe extern \"C\" fn()>;"
- )?;
-
- Ok(())
-}
diff --git a/glfw/glfw.h b/glfw/glfw.h
deleted file mode 100644
index 7b435c0..0000000
--- a/glfw/glfw.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <GLFW/glfw3.h>
-
-#if GLFW_VERSION_MAJOR != 3
-#error "Unsupported major version of GLFW. Must be 3"
-#endif
-
diff --git a/glfw/src/ffi.rs b/glfw/src/ffi.rs
deleted file mode 100644
index d0affd0..0000000
--- a/glfw/src/ffi.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-#![allow(
- non_snake_case,
- non_camel_case_types,
- non_upper_case_globals,
- unused,
- clippy::unreadable_literal
-)]
-
-include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
diff --git a/glfw/src/init.rs b/glfw/src/init.rs
deleted file mode 100644
index df5a989..0000000
--- a/glfw/src/init.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use std::ffi::c_int;
-use std::ptr::null_mut;
-
-use crate::util::is_main_thread;
-use crate::{get_glfw_error, Error};
-
-/// GLFW 3.x.x is supported
-static SUPPORTED_GLFW_VERSION_MAJOR: c_int = 3;
-
-/// Initializes GLFW and returns a initialization token.
-///
-/// # Errors
-/// Will return `Err` if
-/// - The current thread is not the main thread
-/// - A GLFW error occurs
-pub fn initialize() -> Result<Glfw, Error>
-{
- if !is_main_thread() {
- return Err(Error::NotInMainThread);
- }
-
- let mut major: c_int = 0;
-
- unsafe { crate::ffi::glfwGetVersion(&mut major, null_mut(), null_mut()) };
-
- if major != SUPPORTED_GLFW_VERSION_MAJOR {
- return Err(Error::UnsupportedVersion);
- }
-
- // SAFETY: The current thread is the main thread
- let success = unsafe { crate::ffi::glfwInit() };
-
- if success == crate::ffi::GLFW_FALSE {
- get_glfw_error()?;
- }
-
- Ok(Glfw { _priv: &() })
-}
-
-/// GLFW initialization token.
-#[derive(Debug)]
-pub struct Glfw
-{
- /// This field has two purposes
- /// - To make the struct not constructable without calling [`initialize`].
- /// - To make the struct `!Send` and `!Sync`.
- _priv: *const (),
-}
-
-impl Drop for Glfw
-{
- fn drop(&mut self)
- {
- // SAFETY: The current thread cannot be any other thread than the main thread
- // since the initialize function checks it and the GLFW initialization token is
- // neither Send or Sync
- unsafe { crate::ffi::glfwTerminate() };
- }
-}
diff --git a/glfw/src/lib.rs b/glfw/src/lib.rs
deleted file mode 100644
index f858766..0000000
--- a/glfw/src/lib.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-#![deny(clippy::all, clippy::pedantic)]
-
-use std::ffi::{c_char, CStr};
-use std::ptr::null;
-
-mod ffi;
-mod init;
-mod util;
-
-pub mod window;
-
-pub use window::{Builder as WindowBuilder, Size as WindowSize, Window};
-
-#[derive(Debug, thiserror::Error)]
-pub enum Error
-{
- /// The current thread is not the main thread.
- #[error("The current thread is not the main thread")]
- NotInMainThread,
-
- /// An internal nul byte was found in a window title.
- #[error("An internal nul byte was found in the window title")]
- InternalNulByteInWindowTitle,
-
- #[error("This version of GLFW is unsupported")]
- UnsupportedVersion,
-
- /// GLFW error.
- #[error("GLFW error {0} occured. {1}")]
- GlfwError(i32, String),
-}
-
-fn get_glfw_error() -> Result<(), Error>
-{
- let mut description_ptr: *const c_char = null();
-
- let err = unsafe { crate::ffi::glfwGetError(&mut description_ptr) };
-
- if err == crate::ffi::GLFW_NO_ERROR {
- return Ok(());
- }
-
- // SAFETY: The description is guaranteed by GLFW to be valid UTF-8
- let desc_str = unsafe {
- std::str::from_utf8_unchecked(CStr::from_ptr(description_ptr).to_bytes())
- };
-
- // The description has to be copied because it is guaranteed to be valid only
- // until the next GLFW error occurs or the GLFW library is terminated.
- let description = desc_str.to_string();
-
- Err(Error::GlfwError(err, description))
-}
diff --git a/glfw/src/util.rs b/glfw/src/util.rs
deleted file mode 100644
index f77aaf8..0000000
--- a/glfw/src/util.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-use libc::{c_long, getpid, syscall, SYS_gettid};
-
-pub fn is_main_thread() -> bool
-{
- let ttid = unsafe { syscall(SYS_gettid) };
-
- let pid = c_long::from(unsafe { getpid() });
-
- ttid == pid
-}
diff --git a/glfw/src/window.rs b/glfw/src/window.rs
deleted file mode 100644
index 1e7e777..0000000
--- a/glfw/src/window.rs
+++ /dev/null
@@ -1,863 +0,0 @@
-use std::cell::RefCell;
-use std::ffi::{c_double, c_int, CString};
-use std::hint::unreachable_unchecked;
-use std::io::{stdout, Write};
-use std::ptr::null_mut;
-
-use bitflags::bitflags;
-use util_macros::{FromRepr, VariantArr};
-
-use crate::init::{initialize, Glfw};
-use crate::{get_glfw_error, Error};
-
-#[derive(Debug)]
-pub struct Window
-{
- _init: Glfw,
- handle: *mut crate::ffi::GLFWwindow,
-}
-
-impl Window
-{
- /// Makes the context of the window current for the calling thread.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW platform error occurs or if no OpenGL context is
- /// present.
- #[cfg(feature = "opengl")]
- pub fn make_context_current(&self) -> Result<(), Error>
- {
- unsafe { crate::ffi::glfwMakeContextCurrent(self.handle) };
-
- get_glfw_error()?;
-
- Ok(())
- }
-
- /// Returns the address of the specified OpenGL function, if it is supported by the
- /// current context.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW platform error occurs or if no current context has
- /// been set.
- #[cfg(feature = "opengl")]
- pub fn get_proc_address(
- &self,
- proc_name: &std::ffi::CStr,
- ) -> Result<unsafe extern "C" fn(), Error>
- {
- let proc_addr = unsafe { crate::ffi::glfwGetProcAddress(proc_name.as_ptr()) };
-
- get_glfw_error()?;
-
- // SAFETY: Is only None when a error has occured and that case is handled above
- Ok(unsafe { proc_addr.unwrap_unchecked() })
- }
-
- /// Processes all pending events.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW platform error occurs.
- pub fn poll_events(&self) -> Result<(), Error>
- {
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- unsafe { crate::ffi::glfwPollEvents() };
-
- get_glfw_error()?;
-
- Ok(())
- }
-
- /// Swaps the front and back buffers of the window.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW platform error occurs or if no OpenGL window context
- /// is present.
- pub fn swap_buffers(&self) -> Result<(), Error>
- {
- unsafe {
- crate::ffi::glfwSwapBuffers(self.handle);
- };
-
- get_glfw_error()?;
-
- Ok(())
- }
-
- /// Returns whether or not the window should close.
- #[must_use]
- pub fn should_close(&self) -> bool
- {
- let should_close = unsafe { crate::ffi::glfwWindowShouldClose(self.handle) };
-
- should_close == crate::ffi::GLFW_TRUE
- }
-
- /// Retrieves the size of the window.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW platform error occurs.
- pub fn size(&self) -> Result<Size, Error>
- {
- let mut width = 0;
- let mut height = 0;
-
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- unsafe { crate::ffi::glfwGetWindowSize(self.handle, &mut width, &mut height) };
-
- get_glfw_error()?;
-
- #[allow(clippy::cast_sign_loss)]
- Ok(Size {
- width: width as u32,
- height: height as u32,
- })
- }
-
- /// Sets the callback which is called when the user attempts to close the window.
- pub fn set_close_callback(&self, callback: impl Fn() + 'static)
- {
- CLOSE_CALLBACK.with_borrow_mut(|cb| {
- *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::glfwSetWindowCloseCallback(self.handle, Some(close_callback));
- }
- }
-
- 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),
- );
- }
- }
-
- pub fn set_key_callback(
- &self,
- callback: impl Fn(Key, i32, KeyState, KeyModifiers) + 'static,
- )
- {
- KEY_CALLBACK.with_borrow_mut(|key_callback| {
- *key_callback = 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::glfwSetKeyCallback(self.handle, Some(key_callback));
- }
- }
-
- /// Sets the cursor position callback.
- ///
- /// The callback is provided with the position, in screen coordinates, relative to the
- /// upper-left corner of the content area of the window.
- pub fn set_cursor_pos_callback(&self, callback: impl Fn(CursorPosition) + 'static)
- {
- CURSOR_POS_CALLBACK.with_borrow_mut(|cursor_pos_callback| {
- *cursor_pos_callback = 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::glfwSetCursorPosCallback(self.handle, Some(cursor_pos_callback));
- }
- }
-
- /// Sets the mouse button callback.
- pub fn set_mouse_button_callback(
- &self,
- callback: impl Fn(MouseButton, MouseButtonState, KeyModifiers) + 'static,
- )
- {
- MOUSE_BUTTON_CALLBACK.with_borrow_mut(|mouse_button_callback| {
- *mouse_button_callback = 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::glfwSetMouseButtonCallback(
- self.handle,
- Some(mouse_button_callback),
- );
- }
- }
-
- /// Sets the callback called when the window gains or loses input focus.
- pub fn set_focus_callback(&self, callback: impl Fn(bool) + 'static)
- {
- FOCUS_CALLBACK.with_borrow_mut(|focus_cb| {
- *focus_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::glfwSetWindowFocusCallback(self.handle, Some(focus_callback));
- }
- }
-
- /// Returns the last reported state of a keyboard key.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW error occurs.
- pub fn get_key(&self, key: Key) -> Result<KeyState, Error>
- {
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- let state = unsafe { crate::ffi::glfwGetKey(self.handle, key as i32) };
-
- get_glfw_error()?;
-
- Ok(match state {
- crate::ffi::GLFW_PRESS => KeyState::Pressed,
- crate::ffi::GLFW_RELEASE => KeyState::Released,
- _ => {
- // SAFETY: glfwGetKey can only return GLFW_PRESS or GLFW_RELEASE
- unsafe {
- unreachable_unchecked();
- }
- }
- })
- }
-
- /// Returns the last reported state of a mouse button.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW error occurs.
- pub fn get_mouse_button(
- &self,
- mouse_button: MouseButton,
- ) -> Result<MouseButtonState, Error>
- {
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- let state =
- unsafe { crate::ffi::glfwGetMouseButton(self.handle, mouse_button as i32) };
-
- get_glfw_error()?;
-
- Ok(match state {
- crate::ffi::GLFW_PRESS => MouseButtonState::Pressed,
- crate::ffi::GLFW_RELEASE => MouseButtonState::Released,
- _ => {
- // SAFETY: glfwGetMouseButton can only return GLFW_PRESS or GLFW_RELEASE
- unsafe {
- unreachable_unchecked();
- }
- }
- })
- }
-
- /// Returns the position of the cursor, in screen coordinates, relative to the
- /// upper-left corner of the content area of the window.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW error occurs.
- pub fn get_cursor_position(&self) -> Result<CursorPosition, Error>
- {
- let mut x_pos = 0.0;
- let mut y_pos = 0.0;
-
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- unsafe {
- crate::ffi::glfwGetCursorPos(self.handle, &mut x_pos, &mut y_pos);
- }
-
- get_glfw_error()?;
-
- Ok(CursorPosition { x: x_pos, y: y_pos })
- }
-
- /// Sets a input mode option.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW error occurs.
- pub fn set_input_mode(
- &self,
- input_mode: InputMode,
- enabled: bool,
- ) -> Result<(), Error>
- {
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- unsafe {
- crate::ffi::glfwSetInputMode(
- self.handle,
- input_mode as i32,
- i32::from(enabled),
- );
- }
-
- get_glfw_error()?;
-
- Ok(())
- }
-
- /// Sets the cursor mode.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW error occurs.
- pub fn set_cursor_mode(&self, cursor_mode: CursorMode) -> Result<(), Error>
- {
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- unsafe {
- crate::ffi::glfwSetInputMode(
- self.handle,
- crate::ffi::GLFW_CURSOR,
- cursor_mode as i32,
- );
- }
-
- get_glfw_error()?;
-
- Ok(())
- }
-
- /// Returns whether or not raw mouse motion is supported.
- ///
- /// # Errors
- /// Will return `Err` if a GLFW error occurs.
- pub fn is_raw_mouse_motion_supported(&self) -> Result<bool, Error>
- {
- // SAFETY: The initialize function (called when the window is created) makes sure
- // the current thread is the main thread
- let supported = unsafe { crate::ffi::glfwRawMouseMotionSupported() };
-
- get_glfw_error()?;
-
- Ok(supported == crate::ffi::GLFW_TRUE)
- }
-}
-
-/// [`Window`] builder.
-#[derive(Debug, Clone, Default)]
-pub struct Builder
-{
- hints: Vec<(Hint, HintValue)>,
-}
-
-impl Builder
-{
- #[must_use]
- pub fn new() -> Self
- {
- Self { hints: Vec::new() }
- }
-
- /// Adds a window creation hint to set.
- #[must_use]
- pub fn hint(mut self, hint: Hint, value: HintValue) -> Self
- {
- self.hints.push((hint, value));
-
- self
- }
-
- /// Sets the window hints to set.
- pub fn hints(mut self, hints: impl IntoIterator<Item = (Hint, HintValue)>)
- {
- self.hints = hints.into_iter().collect();
- }
-
- /// Creates a new window.
- ///
- /// # Errors
- /// Will return `Err` if
- /// - The title contains an internal nul byte
- /// - A GLFW error occurs
- pub fn create(&self, size: &Size, title: &str) -> Result<Window, Error>
- {
- let c_title =
- CString::new(title).map_err(|_| Error::InternalNulByteInWindowTitle)?;
-
- let init = initialize()?;
-
- for (hint, value) in &self.hints {
- // SAFETY: The initialize function makes sure the current thread is the main
- // thread
- //
- // Error is not checked for after since the two possible errors
- // (GLFW_NOT_INITIALIZED and GLFW_INVALID_ENUM) cannot occur.
- unsafe {
- crate::ffi::glfwWindowHint(
- *hint as i32,
- match value {
- HintValue::Number(num) => *num,
- HintValue::Bool(boolean) => {
- if *boolean {
- crate::ffi::GLFW_TRUE
- } else {
- crate::ffi::GLFW_FALSE
- }
- }
- },
- );
- }
- }
-
- // SAFETY: The initialize function makes sure the current thread is the main
- // thread
- let handle = unsafe {
- #[allow(clippy::cast_possible_wrap)]
- crate::ffi::glfwCreateWindow(
- size.width as i32,
- size.height as i32,
- c_title.as_ptr(),
- null_mut(),
- null_mut(),
- )
- };
-
- get_glfw_error()?;
-
- Ok(Window { _init: init, handle })
- }
-}
-
-/// Window creation hint
-#[derive(Debug, Clone, Copy)]
-#[repr(i32)]
-#[non_exhaustive]
-pub enum Hint
-{
- /// Specifies whether the OpenGL context should be created in debug mode, which may
- /// provide additional error and diagnostic reporting functionality.
- ///
- /// Valid values are [`HintValue::Bool`].
- OpenGLDebugContext = crate::ffi::GLFW_OPENGL_DEBUG_CONTEXT,
-
- /// Specifies the desired number of samples to use for multisampling. Zero disables
- /// multisampling.
- ///
- /// Valid values are: [`HintValue::Number`].
- Samples = crate::ffi::GLFW_SAMPLES,
-
- /// Specifies whether the framebuffer should be double buffered. You nearly always
- /// want to use double buffering. This is a hard constraint.
- ///
- /// Valid values are [`HintValue::Bool`].
- DoubleBuffer = crate::ffi::GLFW_DOUBLEBUFFER,
-}
-
-/// Window creation hint value.
-#[derive(Debug, Clone)]
-#[non_exhaustive]
-pub enum HintValue
-{
- Number(i32),
- Bool(bool),
-}
-
-/// Window size.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Size
-{
- pub width: u32,
- pub height: u32,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(i32)]
-pub enum InputMode
-{
- /// When sticky keys mode is enabled, the pollable state of a key will remain
- /// [`KeyState::Pressed`] until the state of that key is polled with
- /// [`Window::get_key`]. Once it has been polled, if a key release event had been
- /// processed in the meantime, the state will reset to [`KeyState::Released`],
- /// otherwise it will remain [`KeyState::Pressed`].
- StickyKeys = crate::ffi::GLFW_STICKY_KEYS,
-
- /// When sticky mouse buttons mode is enabled, the pollable state of a mouse button
- /// will remain [`MouseButtonState::Pressed`] until the state of that button is
- /// polled with [`Window::get_mouse_button`]. Once it has been polled, if a mouse
- /// button release event had been processed in the meantime, the state will reset
- /// to [`MouseButtonState::Released`], otherwise it will remain
- /// [`MouseButton::Pressed`].
- StickyMouseButtons = crate::ffi::GLFW_STICKY_MOUSE_BUTTONS,
-
- LockKeyMods = crate::ffi::GLFW_LOCK_KEY_MODS,
-
- /// When the cursor is disabled, raw (unscaled and unaccelerated) mouse motion can be
- /// enabled if available.
- ///
- /// Raw mouse motion is closer to the actual motion of the mouse across a surface. It
- /// is not affected by the scaling and acceleration applied to the motion of the
- /// desktop cursor. That processing is suitable for a cursor while raw motion is
- /// better for controlling for example a 3D camera. Because of this, raw mouse motion
- /// is only provided when the cursor is disabled.
- RawMouseMotion = crate::ffi::GLFW_RAW_MOUSE_MOTION,
-}
-
-#[derive(Debug, Clone, Copy)]
-#[repr(i32)]
-pub enum CursorMode
-{
- /// Hides and grabs the cursor, providing virtual and unlimited cursor movement. This
- /// is useful for implementing for example 3D camera controls.
- Disabled = crate::ffi::GLFW_CURSOR_DISABLED,
-
- /// Makes the cursor invisible when it is over the content area of the window but
- /// does not restrict the cursor from leaving.
- Hidden = crate::ffi::GLFW_CURSOR_HIDDEN,
-
- /// Makes the cursor visible and behaving normally.
- Normal = crate::ffi::GLFW_CURSOR_NORMAL,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, FromRepr, VariantArr)]
-#[variant_arr(name = KEYS)]
-#[repr(i32)]
-pub enum Key
-{
- // Unknown = crate::ffi::GLFW_KEY_UNKNOWN,
- Space = crate::ffi::GLFW_KEY_SPACE,
- Apostrophe = crate::ffi::GLFW_KEY_APOSTROPHE,
- Comma = crate::ffi::GLFW_KEY_COMMA,
- Minus = crate::ffi::GLFW_KEY_MINUS,
- Period = crate::ffi::GLFW_KEY_PERIOD,
- Slash = crate::ffi::GLFW_KEY_SLASH,
- Digit0 = crate::ffi::GLFW_KEY_0,
- Digit1 = crate::ffi::GLFW_KEY_1,
- Digit2 = crate::ffi::GLFW_KEY_2,
- Digit3 = crate::ffi::GLFW_KEY_3,
- Digit4 = crate::ffi::GLFW_KEY_4,
- Digit5 = crate::ffi::GLFW_KEY_5,
- Digit6 = crate::ffi::GLFW_KEY_6,
- Digit7 = crate::ffi::GLFW_KEY_7,
- Digit8 = crate::ffi::GLFW_KEY_8,
- Digit9 = crate::ffi::GLFW_KEY_9,
- Semicolon = crate::ffi::GLFW_KEY_SEMICOLON,
- Equal = crate::ffi::GLFW_KEY_EQUAL,
- A = crate::ffi::GLFW_KEY_A,
- B = crate::ffi::GLFW_KEY_B,
- C = crate::ffi::GLFW_KEY_C,
- D = crate::ffi::GLFW_KEY_D,
- E = crate::ffi::GLFW_KEY_E,
- F = crate::ffi::GLFW_KEY_F,
- G = crate::ffi::GLFW_KEY_G,
- H = crate::ffi::GLFW_KEY_H,
- I = crate::ffi::GLFW_KEY_I,
- J = crate::ffi::GLFW_KEY_J,
- K = crate::ffi::GLFW_KEY_K,
- L = crate::ffi::GLFW_KEY_L,
- M = crate::ffi::GLFW_KEY_M,
- N = crate::ffi::GLFW_KEY_N,
- O = crate::ffi::GLFW_KEY_O,
- P = crate::ffi::GLFW_KEY_P,
- Q = crate::ffi::GLFW_KEY_Q,
- R = crate::ffi::GLFW_KEY_R,
- S = crate::ffi::GLFW_KEY_S,
- T = crate::ffi::GLFW_KEY_T,
- U = crate::ffi::GLFW_KEY_U,
- V = crate::ffi::GLFW_KEY_V,
- W = crate::ffi::GLFW_KEY_W,
- X = crate::ffi::GLFW_KEY_X,
- Y = crate::ffi::GLFW_KEY_Y,
- Z = crate::ffi::GLFW_KEY_Z,
- LeftBracket = crate::ffi::GLFW_KEY_LEFT_BRACKET,
- Backslash = crate::ffi::GLFW_KEY_BACKSLASH,
- RightBracket = crate::ffi::GLFW_KEY_RIGHT_BRACKET,
- GraveAccent = crate::ffi::GLFW_KEY_GRAVE_ACCENT,
- World1 = crate::ffi::GLFW_KEY_WORLD_1,
- World2 = crate::ffi::GLFW_KEY_WORLD_2,
- Escape = crate::ffi::GLFW_KEY_ESCAPE,
- Enter = crate::ffi::GLFW_KEY_ENTER,
- Tab = crate::ffi::GLFW_KEY_TAB,
- Backspace = crate::ffi::GLFW_KEY_BACKSPACE,
- Insert = crate::ffi::GLFW_KEY_INSERT,
- Delete = crate::ffi::GLFW_KEY_DELETE,
- Right = crate::ffi::GLFW_KEY_RIGHT,
- Left = crate::ffi::GLFW_KEY_LEFT,
- Down = crate::ffi::GLFW_KEY_DOWN,
- Up = crate::ffi::GLFW_KEY_UP,
- PageUp = crate::ffi::GLFW_KEY_PAGE_UP,
- PageDown = crate::ffi::GLFW_KEY_PAGE_DOWN,
- Home = crate::ffi::GLFW_KEY_HOME,
- End = crate::ffi::GLFW_KEY_END,
- CapsLock = crate::ffi::GLFW_KEY_CAPS_LOCK,
- ScrollLock = crate::ffi::GLFW_KEY_SCROLL_LOCK,
- NumLock = crate::ffi::GLFW_KEY_NUM_LOCK,
- PrintScreen = crate::ffi::GLFW_KEY_PRINT_SCREEN,
- Pause = crate::ffi::GLFW_KEY_PAUSE,
- F1 = crate::ffi::GLFW_KEY_F1,
- F2 = crate::ffi::GLFW_KEY_F2,
- F3 = crate::ffi::GLFW_KEY_F3,
- F4 = crate::ffi::GLFW_KEY_F4,
- F5 = crate::ffi::GLFW_KEY_F5,
- F6 = crate::ffi::GLFW_KEY_F6,
- F7 = crate::ffi::GLFW_KEY_F7,
- F8 = crate::ffi::GLFW_KEY_F8,
- F9 = crate::ffi::GLFW_KEY_F9,
- F10 = crate::ffi::GLFW_KEY_F10,
- F11 = crate::ffi::GLFW_KEY_F11,
- F12 = crate::ffi::GLFW_KEY_F12,
- F13 = crate::ffi::GLFW_KEY_F13,
- F14 = crate::ffi::GLFW_KEY_F14,
- F15 = crate::ffi::GLFW_KEY_F15,
- F16 = crate::ffi::GLFW_KEY_F16,
- F17 = crate::ffi::GLFW_KEY_F17,
- F18 = crate::ffi::GLFW_KEY_F18,
- F19 = crate::ffi::GLFW_KEY_F19,
- F20 = crate::ffi::GLFW_KEY_F20,
- F21 = crate::ffi::GLFW_KEY_F21,
- F22 = crate::ffi::GLFW_KEY_F22,
- F23 = crate::ffi::GLFW_KEY_F23,
- F24 = crate::ffi::GLFW_KEY_F24,
- F25 = crate::ffi::GLFW_KEY_F25,
- Kp0 = crate::ffi::GLFW_KEY_KP_0,
- Kp1 = crate::ffi::GLFW_KEY_KP_1,
- Kp2 = crate::ffi::GLFW_KEY_KP_2,
- Kp3 = crate::ffi::GLFW_KEY_KP_3,
- Kp4 = crate::ffi::GLFW_KEY_KP_4,
- Kp5 = crate::ffi::GLFW_KEY_KP_5,
- Kp6 = crate::ffi::GLFW_KEY_KP_6,
- Kp7 = crate::ffi::GLFW_KEY_KP_7,
- Kp8 = crate::ffi::GLFW_KEY_KP_8,
- Kp9 = crate::ffi::GLFW_KEY_KP_9,
- KpDecimal = crate::ffi::GLFW_KEY_KP_DECIMAL,
- KpDivide = crate::ffi::GLFW_KEY_KP_DIVIDE,
- KpMultiply = crate::ffi::GLFW_KEY_KP_MULTIPLY,
- KpSubtract = crate::ffi::GLFW_KEY_KP_SUBTRACT,
- KpAdd = crate::ffi::GLFW_KEY_KP_ADD,
- KpEnter = crate::ffi::GLFW_KEY_KP_ENTER,
- KpEqual = crate::ffi::GLFW_KEY_KP_EQUAL,
- LeftShift = crate::ffi::GLFW_KEY_LEFT_SHIFT,
- LeftControl = crate::ffi::GLFW_KEY_LEFT_CONTROL,
- LeftAlt = crate::ffi::GLFW_KEY_LEFT_ALT,
- LeftSuper = crate::ffi::GLFW_KEY_LEFT_SUPER,
- RightShift = crate::ffi::GLFW_KEY_RIGHT_SHIFT,
- RightControl = crate::ffi::GLFW_KEY_RIGHT_CONTROL,
- RightAlt = crate::ffi::GLFW_KEY_RIGHT_ALT,
- RightSuper = crate::ffi::GLFW_KEY_RIGHT_SUPER,
- Menu = crate::ffi::GLFW_KEY_MENU,
-}
-
-#[derive(Debug, Clone, Copy, FromRepr)]
-#[repr(i32)]
-pub enum KeyState
-{
- Pressed = crate::ffi::GLFW_PRESS,
- Released = crate::ffi::GLFW_RELEASE,
- Repeat = crate::ffi::GLFW_REPEAT,
-}
-
-bitflags! {
- #[derive(Debug, Clone, Copy)]
- pub struct KeyModifiers: i32 {
- const SHIFT = crate::ffi::GLFW_MOD_SHIFT;
- const CONTROL = crate::ffi::GLFW_MOD_CONTROL;
- const ALT = crate::ffi::GLFW_MOD_ALT;
- const SUPER = crate::ffi::GLFW_MOD_SUPER;
- const CAPS_LOCK = crate::ffi::GLFW_MOD_CAPS_LOCK;
- const NUM_LOCK = crate::ffi::GLFW_MOD_NUM_LOCK;
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, FromRepr)]
-#[repr(i32)]
-pub enum MouseButton
-{
- One = crate::ffi::GLFW_MOUSE_BUTTON_1,
- Two = crate::ffi::GLFW_MOUSE_BUTTON_2,
- Three = crate::ffi::GLFW_MOUSE_BUTTON_3,
- Four = crate::ffi::GLFW_MOUSE_BUTTON_4,
- Five = crate::ffi::GLFW_MOUSE_BUTTON_5,
- Six = crate::ffi::GLFW_MOUSE_BUTTON_6,
- Seven = crate::ffi::GLFW_MOUSE_BUTTON_7,
- Eight = crate::ffi::GLFW_MOUSE_BUTTON_8,
-}
-
-impl MouseButton
-{
- pub const LEFT: Self = Self::One;
- pub const MIDDLE: Self = Self::Three;
- pub const RIGHT: Self = Self::Two;
-}
-
-#[derive(Debug, Clone, Copy, FromRepr)]
-#[repr(i32)]
-pub enum MouseButtonState
-{
- Pressed = crate::ffi::GLFW_PRESS,
- Released = crate::ffi::GLFW_RELEASE,
-}
-
-#[derive(Debug, Clone)]
-pub struct CursorPosition
-{
- pub x: f64,
- pub y: f64,
-}
-
-type CloseCallback = Box<dyn Fn()>;
-type FramebufferSizeCb = Box<dyn Fn(Size)>;
-type KeyCallback = Box<dyn Fn(Key, i32, KeyState, KeyModifiers)>;
-type CursorPositionCallback = Box<dyn Fn(CursorPosition)>;
-type MouseButtonCallback = Box<dyn Fn(MouseButton, MouseButtonState, KeyModifiers)>;
-type FocusCallback = Box<dyn Fn(bool)>;
-
-thread_local! {
-static CLOSE_CALLBACK: RefCell<Option<CloseCallback>> = RefCell::new(None);
-static FRAMEBUFFER_SIZE_CB: RefCell<Option<FramebufferSizeCb>> = RefCell::new(None);
-static KEY_CALLBACK: RefCell<Option<KeyCallback>> = RefCell::new(None);
-static CURSOR_POS_CALLBACK: RefCell<Option<CursorPositionCallback>> = RefCell::new(None);
-static MOUSE_BUTTON_CALLBACK: RefCell<Option<MouseButtonCallback>> = RefCell::new(None);
-static FOCUS_CALLBACK: RefCell<Option<FocusCallback>> = RefCell::new(None);
-}
-
-extern "C-unwind" fn close_callback(_window: *mut crate::ffi::GLFWwindow)
-{
- CLOSE_CALLBACK
- .try_with(|close_cb| {
- if let Some(cb) = close_cb.borrow().as_deref() {
- cb();
- }
- })
- .ok();
-}
-
-extern "C-unwind" 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());
-
- FRAMEBUFFER_SIZE_CB
- .try_with(|framebuffer_size_cb| {
- if let Some(cb) = framebuffer_size_cb.borrow().as_deref() {
- cb(Size { width, height });
- }
- })
- .ok();
-}
-
-extern "C-unwind" fn key_callback(
- _window: *mut crate::ffi::GLFWwindow,
- key_raw: c_int,
- scancode: c_int,
- action_raw: c_int,
- mods: c_int,
-)
-{
- let Some(key) = Key::from_repr(key_raw) else {
- write!(stdout(), "Unknown key {key_raw}").ok();
- return;
- };
-
- let Some(key_state) = KeyState::from_repr(action_raw) else {
- write!(stdout(), "Unknown key state {action_raw}").ok();
- return;
- };
-
- let Some(key_modifiers) = KeyModifiers::from_bits(mods) else {
- write!(
- stdout(),
- "Key modifiers {action_raw} contain one or more unknown bit(s)"
- )
- .ok();
-
- return;
- };
-
- KEY_CALLBACK
- .try_with(|key_callback| {
- if let Some(cb) = key_callback.borrow().as_deref() {
- cb(key, scancode, key_state, key_modifiers);
- }
- })
- .ok();
-}
-
-extern "C-unwind" fn cursor_pos_callback(
- _window: *mut crate::ffi::GLFWwindow,
- x_pos: c_double,
- y_pos: c_double,
-)
-{
- CURSOR_POS_CALLBACK
- .try_with(|cursor_pos_callback| {
- if let Some(cb) = cursor_pos_callback.borrow().as_deref() {
- cb(CursorPosition { x: x_pos, y: y_pos });
- }
- })
- .ok();
-}
-
-extern "C-unwind" fn mouse_button_callback(
- _window: *mut crate::ffi::GLFWwindow,
- mouse_button_raw: c_int,
- mouse_action: c_int,
- modifier_keys: c_int,
-)
-{
- let Some(mouse_button) = MouseButton::from_repr(mouse_button_raw) else {
- write!(stdout(), "Unknown mouse button {mouse_button_raw}").ok();
- return;
- };
-
- let Some(mouse_button_state) = MouseButtonState::from_repr(mouse_action) else {
- write!(stdout(), "Unknown mouse action {mouse_action}").ok();
- return;
- };
-
- let Some(key_modifiers) = KeyModifiers::from_bits(modifier_keys) else {
- write!(
- stdout(),
- "Key modifiers {modifier_keys:#b} contain one or more unknown bit(s)"
- )
- .ok();
-
- return;
- };
-
- MOUSE_BUTTON_CALLBACK
- .try_with(|mouse_button_callback| {
- if let Some(cb) = mouse_button_callback.borrow().as_deref() {
- cb(mouse_button, mouse_button_state, key_modifiers);
- }
- })
- .ok();
-}
-
-extern "C-unwind" fn focus_callback(_window: *mut crate::ffi::GLFWwindow, focused: c_int)
-{
- let is_focused = if focused == crate::ffi::GLFW_TRUE {
- true
- } else if focused == crate::ffi::GLFW_FALSE {
- false
- } else {
- write!(stdout(), "Invalid focus state {focused}").ok();
- return;
- };
-
- FOCUS_CALLBACK
- .try_with(|focus_callback| {
- if let Some(cb) = focus_callback.borrow().as_deref() {
- cb(is_focused);
- }
- })
- .ok();
-}