├── .github └── workflows │ └── check.yaml ├── .gitignore ├── .travis.yml ├── AUTHORS ├── Cargo.toml ├── LICENSE ├── README.md ├── examples ├── clipboard.rs ├── cursor.rs ├── cursor_icon.rs ├── defaults.rs ├── error.rs ├── events.rs ├── fullscreen.rs ├── icon.png ├── modes.rs ├── monitors.rs ├── multiwindow.rs ├── raw_window_handle.rs ├── render_task.rs ├── title.rs ├── unbuffered_events.rs ├── version.rs ├── vulkan.rs ├── window.rs └── window_icon.rs └── src ├── callbacks.rs └── lib.rs /.github/workflows/check.yaml: -------------------------------------------------------------------------------- 1 | # run cargo check on all platforms 2 | name: Check 3 | on: [push] 4 | jobs: 5 | check: 6 | name: Check 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | os: [ubuntu-latest, macos-latest, windows-latest] 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | submodules: true 15 | 16 | - uses: dtolnay/rust-toolchain@stable 17 | - uses: lukka/get-cmake@latest 18 | 19 | - name: Install dependencies 20 | if: matrix.os == 'ubuntu-latest' 21 | run: | 22 | sudo apt update 23 | sudo apt install -y libglfw3-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev libwayland-dev libxkbcommon-dev libglfw3-dev cmake 24 | 25 | # glfw 3.4 is not available on ubuntu yet. So, skip pkg-config check for now. 26 | - name: PreBuilt Libs 27 | if: matrix.os != 'ubuntu-latest' 28 | run: cargo run --example=version --features=prebuilt-libs 29 | 30 | - name: Src Builds 31 | run: | 32 | cargo run --example=version --features=src-build 33 | cargo run --example=version --features=src-build,static-link -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /target/ 3 | /Cargo.lock 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | # refer to the AUTHORS file at the top-level directory of this distribution. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | language: rust 17 | addons: 18 | apt: 19 | sources: 20 | - kubuntu-backports 21 | packages: 22 | - libxinerama-dev 23 | - libxcursor-dev 24 | - xorg-dev 25 | - libwayland-dev 26 | - libxkbcommon-dev 27 | script: 28 | - sudo apt install libgl1 29 | - sudo apt install libgl1-mesa-dev 30 | - cargo build 31 | - cargo test 32 | - cargo build --features "all" 33 | - cargo build --features "image, log, vulkan" 34 | - cargo test --features "all" 35 | - cargo test --features "image, log, vulkan" 36 | - cargo doc --features "all" 37 | - cargo doc --features "image, log, vulkan" 38 | 39 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Initial author: 2 | 3 | Brendan Zabarauskas http://voyager3.tumblr.com 4 | 5 | 6 | With help and contributions from: 7 | 8 | Amey Parulekar http://wirywolf.com/ 9 | Andy http://github.com/alegalle 10 | Brian Anderson http://github.com/brson/ 11 | Colin Sherratt https://github.com/csherratt 12 | Dustin Lacewell http://ldlework.com/ 13 | Jack Moffitt http://metajack.im/ 14 | Jeaye http://github.com/Jeaye 15 | jmgrosen https://github.com/jmgrosen 16 | Keegan McAllister http://mainisusuallyafunction.blogspot.com 17 | Lars Bergstrom http://www.lars.com/ 18 | Marvin Löbel http://github.com/Kimundi 19 | Niko Matsakis http://github.com/nikomatsakis 20 | Sébastien Crozet https://github.com/sebcrozet 21 | Tomasz Stachowiak http://github.com/h3r2tic 22 | Torbjorn Loken https://github.com/Torwegia 23 | zofrex https://github.com/zofrex 24 | Aaron Trent https://github.com/novacrazy 25 | 26 | 27 | The GLFW library was created by: 28 | 29 | Camilla Berglund http://www.elmindreda.org/ 30 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["The glfw-rs developers."] 3 | description = "GLFW3 bindings and idiomatic wrapper for Rust." 4 | keywords = ["windowing", "opengl", "vulkan"] 5 | license = "Apache-2.0" 6 | name = "glfw" 7 | readme = "README.md" 8 | repository = "https://github.com/bjz/glfw-rs" 9 | version = "0.59.0" 10 | edition = "2021" 11 | rust-version = "1.56" 12 | 13 | [dependencies] 14 | bitflags = "1.0.0" 15 | raw-window-handle-0-5 = { package = "raw-window-handle", version = "0.5.0", optional = true } 16 | raw-window-handle-0-6 = { package = "raw-window-handle", version = "0.6.0", optional = true } 17 | # TODO: remove the package attribute after glfw-sys is published 18 | glfw-sys = { version = "6", package = "glfw-sys-passthrough"} 19 | 20 | [target.'cfg(target_os = "macos")'.dependencies] 21 | objc2 = "0.5.1" 22 | 23 | [target.'cfg(target_os = "windows")'.dependencies] 24 | winapi = { version = "0.3", features = ["libloaderapi"] } 25 | 26 | 27 | [dependencies.image] 28 | optional = true 29 | version = "^0.25.1" 30 | 31 | [dependencies.log] 32 | optional = true 33 | version = "0.4" 34 | 35 | 36 | [dependencies.serde] 37 | optional = true 38 | version = "1" 39 | features = ["derive"] 40 | 41 | [dev-dependencies] 42 | log = "0.4" 43 | ash = "0.38" 44 | 45 | [features] 46 | all = ["image", "vulkan", "log", "wayland", "x11", "raw-window-handle-v0-6"] 47 | default = ["all", "prebuilt-libs"] 48 | with-window-handle-v0-5 = ["raw-window-handle-v0-5"] 49 | vulkan = ["glfw-sys/vulkan"] 50 | wayland = ["glfw-sys/wayland"] 51 | x11 = ["glfw-sys/x11"] 52 | native-handles = ["glfw-sys/native-handles"] 53 | src-build = ["glfw-sys/src-build"] 54 | prebuilt-libs = ["glfw-sys/prebuilt-libs"] 55 | static-link = ["glfw-sys/static-link"] 56 | raw-window-handle-v0-6 = ["dep:raw-window-handle-0-6", "native-handles"] 57 | raw-window-handle-v0-5 = ["dep:raw-window-handle-0-5", "native-handles"] 58 | serde = ["dep:serde"] 59 | 60 | 61 | [package.metadata.docs.rs] 62 | features = ["all"] 63 | no-default-features = true 64 | targets = ["x86_64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-pc-windows-msvc"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 17 | 18 | # glfw-rs 19 | 20 | [![Crates.io](https://img.shields.io/crates/v/glfw)](https://crates.io/crates/glfw) 21 | [![Docs.rs](https://docs.rs/glfw/badge.svg)](https://docs.rs/glfw) 22 | [![Build Status](https://travis-ci.org/PistonDevelopers/glfw-rs.svg?branch=master)](https://travis-ci.org/PistonDevelopers/glfw-rs) 23 | 24 | GLFW bindings and wrapper for The Rust Programming Language. 25 | 26 | ## Example 27 | 28 | ~~~rust 29 | extern crate glfw; 30 | 31 | use glfw::{Action, Context, Key}; 32 | 33 | fn main() { 34 | let mut glfw = glfw::init(glfw::fail_on_errors).unwrap(); 35 | 36 | let (mut window, events) = glfw.create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed) 37 | .expect("Failed to create GLFW window."); 38 | 39 | window.set_key_polling(true); 40 | window.make_current(); 41 | 42 | while !window.should_close() { 43 | glfw.poll_events(); 44 | for (_, event) in glfw::flush_messages(&events) { 45 | handle_window_event(&mut window, event); 46 | } 47 | } 48 | } 49 | 50 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 51 | match event { 52 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => { 53 | window.set_should_close(true) 54 | } 55 | _ => {} 56 | } 57 | } 58 | ~~~ 59 | 60 | ## Using glfw-rs 61 | 62 | ### Prerequisites 63 | 64 | Make sure you have [compiled and installed GLFW 3.x](http://www.glfw.org/docs/latest/compile.html). 65 | You might be able to find it on your package manager, for example on OS X: 66 | `brew install glfw3` (you may need to run `brew tap homebrew/versions`). 67 | If not you can download and build the library 68 | [from the source](http://www.glfw.org/docs/latest/compile.html) supplied on the 69 | GLFW website. Note that if you compile GLFW with CMake on Linux, you will have 70 | to supply the `-DCMAKE_C_FLAGS=-fPIC` argument. You may install GLFW to your 71 | `PATH`, otherwise you will have to specify the directory containing the library 72 | binaries when you call `make` or `make lib`: 73 | 74 | ~~~ 75 | GLFW_LIB_DIR=path/to/glfw/lib/directory make 76 | ~~~ 77 | 78 | ### Including glfw-rs in your project 79 | 80 | Add this to your `Cargo.toml`: 81 | 82 | ~~~toml 83 | [dependencies.glfw] 84 | version = "*" 85 | ~~~ 86 | 87 | #### On Windows 88 | 89 | By default, `glfw-rs` will try to compile the `glfw` library. If you want to link to your custom 90 | build of `glfw` or if the build doesn't work (which is probably the case on Windows), you can 91 | disable this: 92 | 93 | ~~~toml 94 | [dependencies.glfw] 95 | version = "*" 96 | default-features = false 97 | ~~~ 98 | 99 | ### Raw window handle 0.5.0 compatibility 100 | 101 | By default, `glfw-rs` uses raw-window-handle at v0.6.0. If your project is depending on `glfw-rs` 102 | with raw-window-handle v0.5.0, then use this line in your Cargo.toml: 103 | ~~~ 104 | glfw = { version = 0.56.0 , default-features = false, features = ["with-window-handle-v0-5"] } 105 | ~~~ 106 | 107 | ## Support 108 | 109 | Contact `bjz` on irc.mozilla.org [#rust](http://mibbit.com/?server=irc.mozilla.org&channel=%23rust) 110 | and [#rust-gamedev](http://mibbit.com/?server=irc.mozilla.org&channel=%23rust-gamedev), 111 | or [post an issue](https://github.com/bjz/glfw-rs/issues/new) on GitHub. 112 | 113 | ## glfw-rs in use 114 | 115 | - [sebcrozet/kiss3d](https://github.com/sebcrozet/kiss3d) 116 | - [Jeaye/q3](https://github.com/Jeaye/q3) 117 | - [cyndis/rsmc](https://github.com/cyndis/rsmc/) 118 | - [ozkriff/zoc](https://github.com/ozkriff/zoc) 119 | 120 | ## glfw-rs with other graphical APIs 121 | 122 | In certain circumstances OpenGL which GLFW uses can conflict with the new handle that the 123 | graphical API is also trying to use, causing crashes, to fix this add 124 | ~~~rust 125 | glfw.window_hint(WindowHint::ClientApi(ClientApiHint::NoApi)); 126 | ~~~ 127 | before creating the window. If using this however you cannot use certain built-in functions, 128 | such as `window.swap_buffers()`, `window.make_current()`, and `glfw.set_swap_interval()`, but 129 | these should have equivalents provided by the graphical API. -------------------------------------------------------------------------------- /examples/clipboard.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::{Action, Context, Key}; 19 | 20 | fn main() { 21 | let mut glfw = glfw::init_no_callbacks().unwrap(); 22 | 23 | let (mut window, events) = glfw 24 | .create_window(300, 300, "Clipboard Test", glfw::WindowMode::Windowed) 25 | .expect("Failed to create GLFW window."); 26 | 27 | window.set_key_polling(true); 28 | window.make_current(); 29 | glfw.set_swap_interval(glfw::SwapInterval::Sync(1)); 30 | 31 | while !window.should_close() { 32 | glfw.poll_events(); 33 | for (_, event) in glfw::flush_messages(&events) { 34 | handle_window_event(&mut window, event); 35 | } 36 | } 37 | } 38 | 39 | #[cfg(target_os = "macos")] 40 | static NATIVE_MOD: glfw::Modifiers = glfw::Modifiers::Super; 41 | 42 | #[cfg(not(target_os = "macos"))] 43 | static NATIVE_MOD: glfw::Modifiers = glfw::Modifiers::Control; 44 | 45 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 46 | match event { 47 | glfw::WindowEvent::Key(key, _, action, mods) => { 48 | if action == Action::Press { 49 | if key == Key::Escape { 50 | window.set_should_close(true); 51 | } 52 | if (key == Key::V) && mods.contains(NATIVE_MOD) { 53 | match window.get_clipboard_string() { 54 | Some(ref s) if !s.is_empty() => println!("Clipboard contains \"{:?}\"", *s), 55 | _ => println!("Clipboard does not contain a string"), 56 | } 57 | } 58 | if (key == Key::C) && mods.contains(NATIVE_MOD) { 59 | let s = "Hello GLFW World!"; 60 | window.set_clipboard_string(s); 61 | println!("Setting clipboard to {:?}", s); 62 | } 63 | } 64 | } 65 | _ => {} 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /examples/cursor.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::{Action, Context, CursorMode, Key}; 19 | 20 | fn main() { 21 | let mut glfw = glfw::init_no_callbacks().unwrap(); 22 | 23 | let (mut window, events) = glfw 24 | .create_window( 25 | 800, 26 | 600, 27 | "Hello, I am a window.", 28 | glfw::WindowMode::Windowed, 29 | ) 30 | .expect("Failed to create GLFW window."); 31 | 32 | window.set_cursor_mode(CursorMode::Disabled); 33 | window.make_current(); 34 | 35 | window.set_cursor_pos_polling(true); 36 | window.set_key_polling(true); 37 | 38 | while !window.should_close() { 39 | glfw.poll_events(); 40 | for (_, event) in glfw::flush_messages(&events) { 41 | handle_window_event(&mut window, event); 42 | } 43 | } 44 | } 45 | 46 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 47 | match event { 48 | glfw::WindowEvent::CursorPos(xpos, ypos) => { 49 | println!("Cursor position: ({:?}, {:?})", xpos, ypos) 50 | } 51 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 52 | glfw::WindowEvent::Key(Key::Space, _, Action::Press, _) => match window.get_cursor_mode() { 53 | CursorMode::Disabled => window.set_cursor_mode(CursorMode::Normal), 54 | CursorMode::Normal => window.set_cursor_mode(CursorMode::Disabled), 55 | _ => {} 56 | }, 57 | _ => {} 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /examples/cursor_icon.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #[cfg(not(feature = "image"))] 17 | fn main() { 18 | eprintln!("run with: --features image") 19 | } 20 | 21 | #[cfg(feature = "image")] 22 | use image::{ 23 | imageops::{resize, Nearest}, 24 | open as open_image, DynamicImage, 25 | }; 26 | 27 | #[cfg(feature = "image")] 28 | use glfw::{Action, Context, Key}; 29 | 30 | #[cfg(feature = "image")] 31 | fn main() { 32 | let mut glfw = glfw::init_no_callbacks().unwrap(); 33 | 34 | let (mut window, events) = glfw 35 | .create_window(600, 600, "Cursor Icon Testing", glfw::WindowMode::Windowed) 36 | .expect("Failed to create GLFW window."); 37 | 38 | window.set_key_polling(true); 39 | window.make_current(); 40 | glfw.set_swap_interval(glfw::SwapInterval::Sync(1)); 41 | 42 | if let DynamicImage::ImageRgba8(icon) = open_image("examples/icon.png").unwrap() { 43 | //Resize icon while preserving aspect ratio 44 | let resized_icon = resize(&icon, 32, icon.height() / icon.width() * 32, Nearest); 45 | 46 | let cursor = glfw::Cursor::create(resized_icon, 0, 0); 47 | 48 | window.set_cursor(Some(cursor)); 49 | } 50 | 51 | while !window.should_close() { 52 | glfw.poll_events(); 53 | for (_, event) in glfw::flush_messages(&events) { 54 | handle_window_event(&mut window, event); 55 | } 56 | } 57 | } 58 | 59 | #[cfg(feature = "image")] 60 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 61 | match event { 62 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 63 | _ => {} 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /examples/defaults.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::Context; 19 | 20 | #[cfg(feature = "vulkan")] 21 | fn vulkan_support(glfw: &mut glfw::Glfw) { 22 | println!("Vulkan supported: {:?}", glfw.vulkan_supported()); 23 | println!( 24 | "Vulkan required extensions: {:?}", 25 | glfw.get_required_instance_extensions().unwrap_or(vec![]) 26 | ); 27 | } 28 | 29 | #[cfg(not(feature = "vulkan"))] 30 | fn vulkan_support(_: &mut glfw::Glfw) {} 31 | 32 | fn main() { 33 | let mut glfw = glfw::init_no_callbacks().unwrap(); 34 | 35 | glfw.window_hint(glfw::WindowHint::Visible(true)); 36 | 37 | let (mut window, _) = glfw 38 | .create_window(640, 480, "Defaults", glfw::WindowMode::Windowed) 39 | .expect("Failed to create GLFW window."); 40 | 41 | window.make_current(); 42 | 43 | let (width, height) = window.get_size(); 44 | println!("window size: ({:?}, {:?})", width, height); 45 | 46 | println!("Context version: {:?}", window.get_context_version()); 47 | println!( 48 | "OpenGL forward compatible: {:?}", 49 | window.is_opengl_forward_compat() 50 | ); 51 | println!( 52 | "OpenGL debug context: {:?}", 53 | window.is_opengl_debug_context() 54 | ); 55 | println!("OpenGL profile: {:?}", window.get_opengl_profile()); 56 | 57 | vulkan_support(&mut glfw); 58 | 59 | let gl_params = [ 60 | (gl::RED_BITS, None, "red bits"), 61 | (gl::GREEN_BITS, None, "green bits"), 62 | (gl::BLUE_BITS, None, "blue bits"), 63 | (gl::ALPHA_BITS, None, "alpha bits"), 64 | (gl::DEPTH_BITS, None, "depth bits"), 65 | (gl::STENCIL_BITS, None, "stencil bits"), 66 | (gl::ACCUM_RED_BITS, None, "accum red bits"), 67 | (gl::ACCUM_GREEN_BITS, None, "accum green bits"), 68 | (gl::ACCUM_BLUE_BITS, None, "accum blue bits"), 69 | (gl::ACCUM_ALPHA_BITS, None, "accum alpha bits"), 70 | (gl::STEREO, None, "stereo"), 71 | (gl::SAMPLES_ARB, Some("GL_ARB_multisample"), "FSAA samples"), 72 | ]; 73 | 74 | for &(param, ext, name) in gl_params.iter() { 75 | if ext.map_or(true, |s| glfw.extension_supported(s)) { 76 | let value = 0; 77 | unsafe { gl::GetIntegerv(param, &value) }; 78 | println!("OpenGL {:?}: {:?}", name, value); 79 | }; 80 | } 81 | } 82 | 83 | mod gl { 84 | #[cfg(target_os = "macos")] 85 | #[link(name = "OpenGL", kind = "framework")] 86 | extern "C" {} 87 | 88 | #[cfg(target_os = "linux")] 89 | #[link(name = "GL")] 90 | extern "C" {} 91 | 92 | pub type GLenum = std::os::raw::c_uint; 93 | pub type GLint = std::os::raw::c_int; 94 | 95 | pub static RED_BITS: GLenum = 0x0D52; 96 | pub static GREEN_BITS: GLenum = 0x0D53; 97 | pub static BLUE_BITS: GLenum = 0x0D54; 98 | pub static ALPHA_BITS: GLenum = 0x0D55; 99 | pub static DEPTH_BITS: GLenum = 0x0D56; 100 | pub static STENCIL_BITS: GLenum = 0x0D57; 101 | pub static ACCUM_RED_BITS: GLenum = 0x0D58; 102 | pub static ACCUM_GREEN_BITS: GLenum = 0x0D59; 103 | pub static ACCUM_BLUE_BITS: GLenum = 0x0D5A; 104 | pub static ACCUM_ALPHA_BITS: GLenum = 0x0D5B; 105 | pub static STEREO: GLenum = 0x0C33; 106 | pub static SAMPLES_ARB: GLenum = 0x80A9; 107 | 108 | #[inline(never)] 109 | #[allow(non_snake_case)] 110 | pub unsafe fn GetIntegerv(pname: GLenum, params: *const GLint) { 111 | glGetIntegerv(pname, params) 112 | } 113 | 114 | extern "C" { 115 | fn glGetIntegerv(pname: GLenum, params: *const GLint); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /examples/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Demonstrates how custom error callbacks with user data can be created 17 | 18 | extern crate glfw; 19 | #[macro_use] 20 | extern crate log; 21 | 22 | fn main() { 23 | let mut glfw = glfw::init(error_callback).unwrap(); 24 | 25 | // Force the error callback to be triggered 26 | glfw.window_hint(glfw::WindowHint::ContextVersion(40000, 3000)); // Ridiculous! 27 | let _ = glfw.create_window(300, 300, "Hey this won't work.", glfw::WindowMode::Windowed); 28 | let _ = glfw.create_window(300, 300, "Nope, not working.", glfw::WindowMode::Windowed); 29 | let _ = glfw.create_window(300, 300, "Stop it! :(", glfw::WindowMode::Windowed); 30 | } 31 | 32 | fn error_callback(err: glfw::Error, description: String) { 33 | error!("GLFW error {:?}: {:?}", err, description); 34 | } 35 | -------------------------------------------------------------------------------- /examples/events.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::{Action, Context, Key}; 19 | 20 | fn main() { 21 | let mut glfw = glfw::init_no_callbacks().unwrap(); 22 | 23 | glfw.window_hint(glfw::WindowHint::Resizable(true)); 24 | 25 | let (mut window, events) = glfw 26 | .create_window( 27 | 800, 28 | 600, 29 | "Hello, I am a window.", 30 | glfw::WindowMode::Windowed, 31 | ) 32 | .expect("Failed to create GLFW window."); 33 | 34 | window.set_sticky_keys(true); 35 | 36 | // Polling of events can be turned on and off by the specific event type 37 | window.set_pos_polling(true); 38 | window.set_all_polling(true); 39 | window.set_size_polling(true); 40 | window.set_close_polling(true); 41 | window.set_refresh_polling(true); 42 | window.set_focus_polling(true); 43 | window.set_iconify_polling(true); 44 | window.set_framebuffer_size_polling(true); 45 | window.set_key_polling(true); 46 | window.set_char_polling(true); 47 | window.set_char_mods_polling(true); 48 | window.set_mouse_button_polling(true); 49 | window.set_cursor_pos_polling(true); 50 | window.set_cursor_enter_polling(true); 51 | window.set_scroll_polling(true); 52 | window.set_maximize_polling(true); 53 | window.set_content_scale_polling(true); 54 | 55 | // Alternatively, all event types may be set to poll at once. Note that 56 | // in this example, this call is redundant as all events have been set 57 | // to poll in the above code. 58 | window.set_all_polling(true); 59 | 60 | window.make_current(); 61 | 62 | while !window.should_close() { 63 | glfw.poll_events(); 64 | for event in glfw::flush_messages(&events) { 65 | handle_window_event(&mut window, event); 66 | } 67 | } 68 | } 69 | 70 | fn handle_window_event(window: &mut glfw::Window, (time, event): (f64, glfw::WindowEvent)) { 71 | match event { 72 | glfw::WindowEvent::Pos(x, y) => { 73 | window.set_title(&format!("Time: {:?}, Window pos: ({:?}, {:?})", time, x, y)) 74 | } 75 | glfw::WindowEvent::Size(w, h) => window.set_title(&format!( 76 | "Time: {:?}, Window size: ({:?}, {:?})", 77 | time, w, h 78 | )), 79 | glfw::WindowEvent::Close => println!("Time: {:?}, Window close requested.", time), 80 | glfw::WindowEvent::Refresh => { 81 | println!("Time: {:?}, Window refresh callback triggered.", time) 82 | } 83 | glfw::WindowEvent::Focus(true) => println!("Time: {:?}, Window focus gained.", time), 84 | glfw::WindowEvent::Focus(false) => println!("Time: {:?}, Window focus lost.", time), 85 | glfw::WindowEvent::Iconify(true) => println!("Time: {:?}, Window was minimised", time), 86 | glfw::WindowEvent::Iconify(false) => println!("Time: {:?}, Window was maximised.", time), 87 | glfw::WindowEvent::FramebufferSize(w, h) => { 88 | println!("Time: {:?}, Framebuffer size: ({:?}, {:?})", time, w, h) 89 | } 90 | glfw::WindowEvent::Char(character) => { 91 | println!("Time: {:?}, Character: {:?}", time, character) 92 | } 93 | glfw::WindowEvent::CharModifiers(character, mods) => println!( 94 | "Time: {:?}, Character: {:?}, Modifiers: [{:?}]", 95 | time, character, mods 96 | ), 97 | glfw::WindowEvent::MouseButton(btn, action, mods) => println!( 98 | "Time: {:?}, Button: {:?}, Action: {:?}, Modifiers: [{:?}]", 99 | time, 100 | glfw::DebugAliases(btn), 101 | action, 102 | mods 103 | ), 104 | glfw::WindowEvent::CursorPos(xpos, ypos) => window.set_title(&format!( 105 | "Time: {:?}, Cursor position: ({:?}, {:?})", 106 | time, xpos, ypos 107 | )), 108 | glfw::WindowEvent::CursorEnter(true) => { 109 | println!("Time: {:?}, Cursor entered window.", time) 110 | } 111 | glfw::WindowEvent::CursorEnter(false) => println!("Time: {:?}, Cursor left window.", time), 112 | glfw::WindowEvent::Scroll(x, y) => window.set_title(&format!( 113 | "Time: {:?}, Scroll offset: ({:?}, {:?})", 114 | time, x, y 115 | )), 116 | glfw::WindowEvent::Key(key, scancode, action, mods) => { 117 | println!( 118 | "Time: {:?}, Key: {:?}, ScanCode: {:?}, Action: {:?}, Modifiers: [{:?}]", 119 | time, key, scancode, action, mods 120 | ); 121 | match (key, action) { 122 | (Key::Escape, Action::Press) => window.set_should_close(true), 123 | (Key::R, Action::Press) => { 124 | // Resize should cause the window to "refresh" 125 | let (window_width, window_height) = window.get_size(); 126 | window.set_size(window_width + 1, window_height); 127 | window.set_size(window_width, window_height); 128 | } 129 | _ => {} 130 | } 131 | } 132 | glfw::WindowEvent::FileDrop(paths) => { 133 | println!("Time: {:?}, Files dropped: {:?}", time, paths) 134 | } 135 | glfw::WindowEvent::Maximize(maximized) => { 136 | println!("Time: {:?}, Window maximized: {:?}.", time, maximized) 137 | } 138 | glfw::WindowEvent::ContentScale(xscale, yscale) => println!( 139 | "Time: {:?}, Content scale x: {:?}, Content scale y: {:?}", 140 | time, xscale, yscale 141 | ), 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /examples/fullscreen.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | // NOTE: Make sure to resize the OpenGL viewport (or whatever else) after any size changes. 17 | 18 | extern crate glfw; 19 | 20 | use glfw::{Action, Context, Key}; 21 | 22 | fn main() { 23 | let mut glfw = glfw::init_no_callbacks().unwrap(); 24 | 25 | let (mut window, events) = glfw 26 | .create_window( 27 | 600, 28 | 400, 29 | "Press F11 to toggle Fullscreen (it will be blank)", 30 | glfw::WindowMode::Windowed, 31 | ) 32 | .expect("Failed to create GLFW window."); 33 | 34 | window.set_key_polling(true); 35 | window.make_current(); 36 | glfw.set_swap_interval(glfw::SwapInterval::Sync(1)); 37 | 38 | //Store fullscreen state 39 | let mut is_fullscreen = false; 40 | 41 | //Keep track of last position and size so we can restore the window to the originals 42 | let mut last_pos = (0, 0); 43 | let mut last_size = (0, 0); 44 | 45 | while !window.should_close() { 46 | glfw.poll_events(); 47 | for (_, event) in glfw::flush_messages(&events) { 48 | match event { 49 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => { 50 | window.set_should_close(true) 51 | } 52 | //F11 is pretty standard for fullscreen 53 | glfw::WindowEvent::Key(Key::F11, _, Action::Press, _) => { 54 | if is_fullscreen { 55 | window.set_monitor( 56 | glfw::WindowMode::Windowed, 57 | last_pos.0, 58 | last_pos.1, 59 | last_size.0 as u32, 60 | last_size.1 as u32, 61 | None, 62 | ); 63 | println!( 64 | "Window restored to {:?} at location {:?}", 65 | last_size, last_pos 66 | ); 67 | } else { 68 | last_pos = window.get_pos(); 69 | last_size = window.get_size(); 70 | 71 | glfw.with_primary_monitor(|_: &mut _, m: Option<&mut glfw::Monitor>| { 72 | let monitor = m.unwrap(); 73 | 74 | let mode = monitor.get_video_mode().unwrap(); 75 | 76 | window.set_monitor( 77 | glfw::WindowMode::FullScreen(&monitor), 78 | 0, 79 | 0, 80 | mode.width, 81 | mode.height, 82 | Some(mode.refresh_rate), 83 | ); 84 | 85 | println!( 86 | "{}x{} fullscreen enabled at {}Hz on monitor {}", 87 | mode.width, 88 | mode.height, 89 | mode.refresh_rate, 90 | monitor.get_name().unwrap() 91 | ); 92 | }); 93 | } 94 | 95 | is_fullscreen = !is_fullscreen; 96 | } 97 | _ => {} 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /examples/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PistonDevelopers/glfw-rs/49fdabc5f957d19cc6e2bb198abc23819a7604e9/examples/icon.png -------------------------------------------------------------------------------- /examples/modes.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | fn main() { 19 | let mut glfw = glfw::init_no_callbacks().unwrap(); 20 | 21 | glfw.with_primary_monitor(|_, monitor| { 22 | let _ = monitor.map(|monitor| { 23 | println!("{:?}:", monitor.get_name()); 24 | println!(" {:?}\n", monitor.get_video_mode().unwrap()); 25 | }); 26 | }); 27 | 28 | println!( 29 | "Available monitors\n\ 30 | ------------------" 31 | ); 32 | glfw.with_connected_monitors(|_, monitors| { 33 | for monitor in monitors.iter() { 34 | println!("{:?}:", monitor.get_name()); 35 | for mode in monitor.get_video_modes().iter() { 36 | println!(" {:?}", *mode); 37 | } 38 | } 39 | }); 40 | } 41 | -------------------------------------------------------------------------------- /examples/monitors.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::{Action, Context, Key}; 19 | 20 | fn main() { 21 | let mut glfw = glfw::init_no_callbacks().unwrap(); 22 | 23 | glfw.with_connected_monitors(|_, monitors| { 24 | for monitor in monitors.iter() { 25 | println!("{:?}: {:?}", monitor.get_name(), monitor.get_video_mode()); 26 | } 27 | }); 28 | 29 | let (mut window, events) = glfw 30 | .with_primary_monitor(|glfw, m| { 31 | glfw.create_window( 32 | 300, 33 | 300, 34 | "Hello this is window", 35 | m.map_or(glfw::WindowMode::Windowed, |m| { 36 | glfw::WindowMode::FullScreen(m) 37 | }), 38 | ) 39 | }) 40 | .expect("Failed to create GLFW window."); 41 | 42 | window.set_key_polling(true); 43 | window.make_current(); 44 | 45 | while !window.should_close() { 46 | glfw.poll_events(); 47 | for (_, event) in glfw::flush_messages(&events) { 48 | handle_window_event(&mut window, event); 49 | } 50 | } 51 | } 52 | 53 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 54 | match event { 55 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 56 | _ => {} 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /examples/multiwindow.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::GlfwReceiver as Receiver; 19 | use glfw::{Action, Key}; 20 | 21 | type WindowInstance = (glfw::PWindow, Receiver<(f64, glfw::WindowEvent)>); 22 | type WindowVector = Vec; 23 | 24 | fn add_window(glfw: &mut glfw::Glfw, window_vector: &mut WindowVector) { 25 | let (mut window, events) = glfw 26 | .create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed) 27 | .expect("Failed to create GLFW window."); 28 | 29 | window.set_key_polling(true); 30 | window_vector.push((window, events)); 31 | } 32 | 33 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 34 | match event { 35 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 36 | _ => {} 37 | } 38 | } 39 | 40 | fn main() { 41 | let mut glfw = glfw::init_no_callbacks().unwrap(); 42 | 43 | // Create two windows 44 | let mut windows = WindowVector::new(); 45 | add_window(&mut glfw, &mut windows); 46 | add_window(&mut glfw, &mut windows); 47 | 48 | // Loop until we no longer have any open windows 49 | while !windows.is_empty() { 50 | // Wait for messages 51 | glfw.wait_events(); 52 | 53 | // Process message queues for all windows 54 | for &mut (ref mut window, ref events) in &mut windows { 55 | for (_, event) in glfw::flush_messages(events) { 56 | handle_window_event(window, event); 57 | } 58 | } 59 | 60 | // Remove closed windows. 61 | windows.retain(|&(ref window, _)| !window.should_close()); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /examples/raw_window_handle.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | #[cfg(feature = "raw-window-handle-v0-6")] 18 | extern crate raw_window_handle_0_6 as raw_window_handle; 19 | 20 | #[cfg(not(feature = "raw-window-handle-v0-6"))] 21 | extern crate raw_window_handle_0_5 as raw_window_handle; 22 | 23 | use glfw::{Action, Context, Key}; 24 | #[cfg(not(feature = "raw-window-handle-v0-6"))] 25 | use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; 26 | #[cfg(feature = "raw-window-handle-v0-6")] 27 | use raw_window_handle::{HasWindowHandle, RawWindowHandle}; 28 | 29 | fn main() { 30 | let mut glfw = glfw::init_no_callbacks().unwrap(); 31 | 32 | let (mut window, events) = glfw 33 | .create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed) 34 | .expect("Failed to create GLFW window."); 35 | 36 | window.set_key_polling(true); 37 | window.make_current(); 38 | #[cfg(feature = "raw-window-handle-v0-6")] 39 | let raw = window.window_handle().unwrap().as_raw(); 40 | #[cfg(not(feature = "raw-window-handle-v0-6"))] 41 | let raw = window.raw_window_handle(); 42 | 43 | match raw { 44 | RawWindowHandle::Win32(handle) => println!("raw handle: {:?}", handle), 45 | RawWindowHandle::Xlib(handle) => println!("raw handle: {:?}", handle), 46 | RawWindowHandle::Wayland(handle) => println!("raw handle: {:?}", handle), 47 | RawWindowHandle::AppKit(handle) => println!("raw handle: {:?}", handle), 48 | _ => unimplemented!(), 49 | } 50 | 51 | while !window.should_close() { 52 | glfw.poll_events(); 53 | for (_, event) in glfw::flush_messages(&events) { 54 | handle_window_event(&mut window, event); 55 | } 56 | } 57 | } 58 | 59 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 60 | match event { 61 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 62 | _ => {} 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /examples/render_task.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Demonstrates how concurrent rendering can be achieved 17 | //! through the use of `RenderContext`s. 18 | 19 | extern crate glfw; 20 | 21 | use glfw::{Action, Context, Key}; 22 | use std::sync::mpsc::{channel, Receiver}; 23 | use std::thread::Builder; 24 | 25 | fn main() { 26 | let mut glfw = glfw::init_no_callbacks().unwrap(); 27 | 28 | let (mut window, events) = glfw 29 | .create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed) 30 | .expect("Failed to create GLFW window."); 31 | 32 | window.set_key_polling(true); 33 | 34 | let render_context = window.render_context(); 35 | let (send, recv) = channel(); 36 | 37 | let render_task = Builder::new().name("render task".to_string()); 38 | let render_task_done = render_task.spawn(move || { 39 | render(render_context, recv); 40 | }); 41 | 42 | while !window.should_close() { 43 | glfw.poll_events(); 44 | for (_, event) in glfw::flush_messages(&events) { 45 | handle_window_event(&mut window, event); 46 | } 47 | } 48 | 49 | // Tell the render task to exit. 50 | send.send(()).ok().expect("Failed signal to render thread."); 51 | 52 | // Wait for acknowledgement that the rendering was completed. 53 | let _ = render_task_done; 54 | } 55 | 56 | fn render(mut context: glfw::PRenderContext, finish: Receiver<()>) { 57 | context.make_current(); 58 | loop { 59 | // Check if the rendering should stop. 60 | if finish.try_recv() == Ok(()) { 61 | break; 62 | }; 63 | 64 | // Perform rendering calls 65 | 66 | context.swap_buffers(); 67 | } 68 | 69 | // required on some platforms 70 | glfw::make_context_current(None); 71 | } 72 | 73 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 74 | match event { 75 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 76 | _ => {} 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /examples/title.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::{Action, Context, Key}; 19 | 20 | fn main() { 21 | let mut glfw = glfw::init_no_callbacks().unwrap(); 22 | 23 | let (mut window, events) = glfw 24 | .create_window( 25 | 400, 26 | 400, 27 | "English 日本語 русский язык 官話", 28 | glfw::WindowMode::Windowed, 29 | ) 30 | .expect("Failed to create GLFW window."); 31 | 32 | window.set_key_polling(true); 33 | window.make_current(); 34 | glfw.set_swap_interval(glfw::SwapInterval::Sync(1)); 35 | 36 | while !window.should_close() { 37 | glfw.poll_events(); 38 | for (_, event) in glfw::flush_messages(&events) { 39 | handle_window_event(&mut window, event); 40 | } 41 | } 42 | } 43 | 44 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 45 | match event { 46 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 47 | _ => {} 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/unbuffered_events.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::{Action, Context, Key, RenderContext, WindowEvent}; 19 | 20 | fn main() { 21 | let mut glfw = glfw::init_no_callbacks().unwrap(); 22 | 23 | let (mut window, events) = glfw 24 | .create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed) 25 | .expect("Failed to create GLFW window."); 26 | 27 | window.set_all_polling(true); 28 | let mut render_context = window.render_context(); 29 | 30 | // Render asynchronously from the main event loop. This prevents a pause in rendering 31 | // during some window interactions (e.g. resizing) on platforms like Windows. 32 | let thread = std::thread::spawn(move || { 33 | render_context.make_current(); 34 | while !render_context.should_close() { 35 | for (_, event) in glfw::flush_messages(&events) { 36 | handle_window_event(&mut render_context, event); 37 | } 38 | render_context.swap_buffers(); 39 | } 40 | }); 41 | 42 | while !window.should_close() { 43 | glfw.wait_events_unbuffered(|window_id, event| { 44 | // Multiple windows may be identified by their `window_id` 45 | assert_eq!(window.window_id(), window_id); 46 | 47 | // Intercept the close request and reset the flag 48 | if let (_, WindowEvent::Close) = event { 49 | window.set_should_close(false); 50 | }; 51 | 52 | // Forward the event to the render thread via the `events` receiver 53 | // to be processed asynchronously from the main event loop thread. 54 | // Returning `None` here would consume the event. 55 | Some(event) 56 | }); 57 | } 58 | 59 | thread.join().unwrap(); 60 | } 61 | 62 | fn handle_window_event(render_context: &mut RenderContext, event: glfw::WindowEvent) { 63 | match event { 64 | glfw::WindowEvent::Close | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => { 65 | render_context.set_should_close(true); 66 | render_context.post_empty_event(); 67 | } 68 | _ => {} 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /examples/version.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | fn main() { 19 | println!("{:?}", glfw::get_version()); 20 | println!("GLFW version: {:?}", glfw::get_version_string()); 21 | } 22 | -------------------------------------------------------------------------------- /examples/vulkan.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #[cfg(not(feature = "vulkan"))] 17 | fn main() { 18 | eprintln!("run with: --features vulkan") 19 | } 20 | 21 | #[cfg(feature = "vulkan")] 22 | use ash::vk; 23 | 24 | #[cfg(feature = "vulkan")] 25 | use std::ptr; 26 | 27 | #[cfg(feature = "vulkan")] 28 | fn main() { 29 | use ash::vk::Handle; 30 | 31 | let mut glfw = glfw::init_no_callbacks().unwrap(); 32 | 33 | glfw.window_hint(glfw::WindowHint::Visible(true)); 34 | glfw.window_hint(glfw::WindowHint::ClientApi(glfw::ClientApiHint::NoApi)); 35 | 36 | let (window, _) = glfw 37 | .create_window(640, 480, "Defaults", glfw::WindowMode::Windowed) 38 | .expect("Failed to create GLFW window."); 39 | 40 | assert!(glfw.vulkan_supported()); 41 | 42 | let required_extensions = glfw.get_required_instance_extensions().unwrap_or(vec![]); 43 | 44 | //VK_KHR_surface will always be available if the previous operations were successful 45 | assert!(required_extensions.contains(&"VK_KHR_surface".to_string())); 46 | 47 | println!("Vulkan required extensions: {:?}", required_extensions); 48 | 49 | //Load up all the entry points using 0 as the VkInstance, 50 | //since you can't have an instance before you get vkCreateInstance... 51 | let entry = unsafe { ash::Entry::load().expect("Failed to load Vulkan library.") }; 52 | 53 | let instance: ash::Instance = unsafe { create_instance(&entry, &required_extensions) }; 54 | 55 | let mut surface: std::mem::MaybeUninit = std::mem::MaybeUninit::uninit(); 56 | 57 | if unsafe { 58 | window.create_window_surface( 59 | instance.handle().as_raw() as _, 60 | ptr::null(), 61 | surface.as_mut_ptr() as _, 62 | ) 63 | } != vk::Result::SUCCESS.as_raw() 64 | { 65 | panic!("Failed to create GLFW window surface."); 66 | } 67 | 68 | // Use other vulkan stuff here. 69 | 70 | println!("Vulkan instance successfully created. Destruction is automatic with Drop."); 71 | } 72 | 73 | #[cfg(feature = "vulkan")] 74 | unsafe fn create_instance(entry: &ash::Entry, extensions: &Vec) -> ash::Instance { 75 | // Turn the list of extensions into a format that can be passed in InstanceCreateInfo 76 | let extensions: Vec = extensions 77 | .iter() 78 | .map(|ext| std::ffi::CString::new(ext.clone()).expect("Failed to convert extension name")) 79 | .collect(); 80 | let extension_pointers: Vec<*const i8> = extensions.iter().map(|ext| ext.as_ptr()).collect(); 81 | //This is literally the bare minimum required to create a blank instance 82 | //You'll want to fill in this with real data yourself 83 | let info: vk::InstanceCreateInfo = 84 | vk::InstanceCreateInfo::default().enabled_extension_names(&extension_pointers); 85 | 86 | unsafe { 87 | entry 88 | .create_instance(&info, None) 89 | .expect("Unable to create instance.") 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /examples/window.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | extern crate glfw; 17 | 18 | use glfw::{Action, Context, Key}; 19 | 20 | fn main() { 21 | let mut glfw = glfw::init_no_callbacks().unwrap(); 22 | 23 | let (mut window, events) = glfw 24 | .create_window(300, 300, "Hello this is window", glfw::WindowMode::Windowed) 25 | .expect("Failed to create GLFW window."); 26 | 27 | window.set_key_polling(true); 28 | window.make_current(); 29 | 30 | while !window.should_close() { 31 | glfw.poll_events(); 32 | for (_, event) in glfw::flush_messages(&events) { 33 | handle_window_event(&mut window, event); 34 | } 35 | } 36 | } 37 | 38 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 39 | match event { 40 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 41 | _ => {} 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /examples/window_icon.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #[cfg(not(feature = "image"))] 17 | fn main() { 18 | eprintln!("run with: --features image") 19 | } 20 | 21 | #[cfg(feature = "image")] 22 | use image::{ 23 | imageops::{resize, Nearest}, 24 | open as open_image, DynamicImage, 25 | }; 26 | 27 | #[cfg(feature = "image")] 28 | use glfw::{Action, Context, Key}; 29 | 30 | #[cfg(feature = "image")] 31 | fn main() { 32 | let mut glfw = glfw::init_no_callbacks().unwrap(); 33 | 34 | let (mut window, events) = glfw 35 | .create_window(600, 600, "Window Icon Testing", glfw::WindowMode::Windowed) 36 | .expect("Failed to create GLFW window."); 37 | 38 | window.set_key_polling(true); 39 | window.make_current(); 40 | glfw.set_swap_interval(glfw::SwapInterval::Sync(1)); 41 | 42 | if let DynamicImage::ImageRgba8(icon) = open_image("examples/icon.png").unwrap() { 43 | //Set the icon to be multiple sizes of the same icon to account for scaling 44 | window.set_icon(vec![ 45 | resize(&icon, 16, 16, Nearest), 46 | resize(&icon, 32, 32, Nearest), 47 | resize(&icon, 48, 48, Nearest), 48 | ]); 49 | } 50 | 51 | while !window.should_close() { 52 | glfw.poll_events(); 53 | for (_, event) in glfw::flush_messages(&events) { 54 | handle_window_event(&mut window, event); 55 | } 56 | } 57 | } 58 | 59 | #[cfg(feature = "image")] 60 | fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) { 61 | match event { 62 | glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => window.set_should_close(true), 63 | _ => {} 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/callbacks.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The GLFW-RS Developers. For a full listing of the authors, 2 | // refer to the AUTHORS file at the top-level directory of this distribution. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | //! Private callback support functions. 17 | 18 | macro_rules! callback ( 19 | ( 20 | args -> ($($args:ty),*), 21 | glfw -> $glfw:ident ($($glfw_arg_names:ident: $glfw_args:ty),*), 22 | convert_args -> ($($convert_args:expr),*) 23 | ) => ( 24 | thread_local!(static CALLBACK_KEY: RefCell>> = RefCell::new(None)); 25 | 26 | pub fn set(f: T) 27 | where T: FnMut($($args),*) + 'static 28 | { 29 | let boxed_cb = Some(Box::new(f) as Box); 30 | CALLBACK_KEY.with(|cb| { 31 | *cb.borrow_mut() = boxed_cb; 32 | }); 33 | unsafe { 34 | crate::ffi::$glfw(Some(callback)); 35 | } 36 | } 37 | 38 | pub fn unset() { 39 | CALLBACK_KEY.with(|cb| { 40 | *cb.borrow_mut() = None; 41 | }); 42 | unsafe { 43 | crate::ffi::$glfw(None); 44 | } 45 | } 46 | 47 | extern "C" fn callback($($glfw_arg_names: $glfw_args),*) { 48 | CALLBACK_KEY.with(|cb| { 49 | match *cb.borrow_mut() { 50 | Some(ref mut cb) => unsafe { cb($($convert_args),*) }, 51 | _ => {} 52 | } 53 | }) 54 | } 55 | ) 56 | ); 57 | 58 | pub mod error { 59 | use std::cell::RefCell; 60 | use std::mem; 61 | use std::os::raw::{c_char, c_int}; 62 | 63 | callback!( 64 | args -> (crate::Error, String), 65 | glfw -> glfwSetErrorCallback(error: c_int, description: *const c_char), 66 | convert_args -> (mem::transmute(error), crate::string_from_c_str(description)) 67 | ); 68 | } 69 | 70 | pub mod monitor { 71 | use std::cell::RefCell; 72 | use std::mem; 73 | use std::os::raw::c_int; 74 | 75 | callback!( 76 | args -> (crate::Monitor, crate::MonitorEvent), 77 | glfw -> glfwSetMonitorCallback(monitor: *mut crate::ffi::GLFWmonitor, event: c_int), 78 | convert_args -> ( 79 | crate::Monitor { ptr: monitor }, 80 | mem::transmute(event) 81 | ) 82 | ); 83 | } 84 | 85 | pub mod joystick { 86 | use std::cell::RefCell; 87 | use std::mem; 88 | use std::os::raw::c_int; 89 | 90 | callback!( 91 | args -> (crate::JoystickId, crate::JoystickEvent), 92 | glfw -> glfwSetJoystickCallback(joystick_id: c_int, event: c_int), 93 | convert_args -> (mem::transmute(joystick_id), mem::transmute(event)) 94 | ); 95 | } 96 | 97 | pub mod unbuffered { 98 | use crate::{WindowEvent, WindowId}; 99 | use std::cell::RefCell; 100 | 101 | type CallbackPtr = *mut std::ffi::c_void; 102 | type HandlerFn = fn( 103 | window_id: WindowId, 104 | event: (f64, WindowEvent), 105 | callback_ptr: CallbackPtr, 106 | ) -> Option<(f64, WindowEvent)>; 107 | 108 | thread_local! { 109 | static HANDLER: RefCell> = RefCell::new(None); 110 | } 111 | 112 | pub struct UnsetHandlerGuard { 113 | _private: (), 114 | } 115 | 116 | impl Drop for UnsetHandlerGuard { 117 | fn drop(&mut self) { 118 | HANDLER.with(|ref_cell| { 119 | *ref_cell.borrow_mut() = None; 120 | }) 121 | } 122 | } 123 | 124 | pub unsafe fn handle( 125 | window_id: WindowId, 126 | event: (f64, WindowEvent), 127 | ) -> Option<(f64, WindowEvent)> { 128 | HANDLER.with(|ref_cell| { 129 | if let Some((handler, callback_ptr)) = *ref_cell.borrow() { 130 | handler(window_id, event, callback_ptr) 131 | } else { 132 | Some(event) 133 | } 134 | }) 135 | } 136 | 137 | pub unsafe fn set_handler(callback: &mut F) -> UnsetHandlerGuard 138 | where 139 | F: FnMut(WindowId, (f64, WindowEvent)) -> Option<(f64, WindowEvent)>, 140 | { 141 | fn handler( 142 | window_id: WindowId, 143 | event: (f64, WindowEvent), 144 | callback_ptr: CallbackPtr, 145 | ) -> Option<(f64, WindowEvent)> 146 | where 147 | F: FnMut(WindowId, (f64, WindowEvent)) -> Option<(f64, WindowEvent)>, 148 | { 149 | unsafe { 150 | let callback: &mut F = &mut *(callback_ptr as *mut F); 151 | callback(window_id, event) 152 | } 153 | } 154 | HANDLER.with(|ref_cell| { 155 | let callback_ptr = callback as *mut F as CallbackPtr; 156 | *ref_cell.borrow_mut() = Some((handler::, callback_ptr)); 157 | }); 158 | UnsetHandlerGuard { _private: () } 159 | } 160 | } 161 | --------------------------------------------------------------------------------