Repository: PistonDevelopers/glfw-rs (language: rust)

Issue:
errors with rust master
I get the following errors with current rust master. Tried that because 0.8 also failed.

rustc 0.9-pre (747213a 2013-11-21 21:51:26 -0800)

```
WARNING: The Rust package manager is experimental and may be unstable
rusth_workspace/src/glfw/extfn.rs:32:21: 32:88 error: expected function but found `~fn(Error, ~str)`
rusth_workspace/src/glfw/extfn.rs:32             unsafe { (**cb)(cast::transmute(error), str::raw::from_c_str(description)) }
                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:47:21: 47:80 error: expected function but found `~fn(&Monitor, MonitorEvent)`
rusth_workspace/src/glfw/extfn.rs:47             unsafe { (**cb)(&Monitor { ptr: monitor }, cast::transmute(event)) }
                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, int, int)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:84:0: 84:129 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, int, int)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:85:0: 85:133 note: expansion site
rusth_workspace/src/glfw/extfn.rs:68:58: 68:73 error: expected function but found `~fn(&Window)`
rusth_workspace/src/glfw/extfn.rs:68                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window));
                                                                                                             ^~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:86:0: 86:107 note: expansion site
rusth_workspace/src/glfw/extfn.rs:68:58: 68:73 error: expected function but found `~fn(&Window)`
rusth_workspace/src/glfw/extfn.rs:68                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window));
                                                                                                             ^~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:87:0: 87:109 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, bool)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:88:0: 88:127 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, bool)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:89:0: 89:131 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, int, int)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:90:0: 90:145 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, MouseButton, Action, Modifiers)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:91:0: 91:190 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, f64, f64)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:92:0: 92:136 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, bool)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:93:0: 93:134 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, f64, f64)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:94:0: 94:132 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, Key, i32, Action, Modifiers)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:95:0: 95:188 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, char)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:96:0: 96:147 note: expansion site
error: aborting due to 15 previous errors
```

errors with rust master
I get the following errors with current rust master. Tried that because 0.8 also failed.

rustc 0.9-pre (747213a 2013-11-21 21:51:26 -0800)

```
WARNING: The Rust package manager is experimental and may be unstable
rusth_workspace/src/glfw/extfn.rs:32:21: 32:88 error: expected function but found `~fn(Error, ~str)`
rusth_workspace/src/glfw/extfn.rs:32             unsafe { (**cb)(cast::transmute(error), str::raw::from_c_str(description)) }
                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:47:21: 47:80 error: expected function but found `~fn(&Monitor, MonitorEvent)`
rusth_workspace/src/glfw/extfn.rs:47             unsafe { (**cb)(&Monitor { ptr: monitor }, cast::transmute(event)) }
                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, int, int)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:84:0: 84:129 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, int, int)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:85:0: 85:133 note: expansion site
rusth_workspace/src/glfw/extfn.rs:68:58: 68:73 error: expected function but found `~fn(&Window)`
rusth_workspace/src/glfw/extfn.rs:68                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window));
                                                                                                             ^~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:86:0: 86:107 note: expansion site
rusth_workspace/src/glfw/extfn.rs:68:58: 68:73 error: expected function but found `~fn(&Window)`
rusth_workspace/src/glfw/extfn.rs:68                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window));
                                                                                                             ^~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:87:0: 87:109 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, bool)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:88:0: 88:127 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, bool)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:89:0: 89:131 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, int, int)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:90:0: 90:145 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, MouseButton, Action, Modifiers)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:91:0: 91:190 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, f64, f64)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:92:0: 92:136 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, bool)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:93:0: 93:134 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, f64, f64)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:94:0: 94:132 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, Key, i32, Action, Modifiers)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:95:0: 95:188 note: expansion site
rusth_workspace/src/glfw/extfn.rs:77:58: 77:89 error: expected function but found `~fn(&Window, char)`
rusth_workspace/src/glfw/extfn.rs:77                 window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
                                                                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rusth_workspace/src/glfw/extfn.rs:63:0: 82:1 note: in expansion of window_callback!
rusth_workspace/src/glfw/extfn.rs:96:0: 96:147 note: expansion site
error: aborting due to 15 previous errors
```



Discussion / hints:
There have been made to the semantics of Rust's closures, and `~fn` is no longer legal. I'm currently away on holiday for the weekend, but I'll have a look at this when I get back. I might also be able to look at this tonight, but no promises.

There have been made to the semantics of Rust's closures, and `~fn` is no longer legal. I'm currently away on holiday for the weekend, but I'll have a look at this when I get back. I might also be able to look at this tonight, but no promises.


Fix patch:
diff --git a/README.md b/README.md
index 239b392a..2524e08b 100644
--- a/README.md
+++ b/README.md
@@ -14,10 +14,8 @@ fn start(argc: int, argv: **u8) -> int {
 }
 
 fn main() {
-    // Set an error callback
-    do glfw::set_error_callback |_, description| {
-        printfln!("GLFW Error: %s", description);
-    }
+    // Set up an error callback
+    glfw::set_error_callback(~ErrorContext);
 
     // Initialize the library
     do glfw::start {
@@ -38,6 +36,13 @@ fn main() {
         }
     }
 }
+
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(_: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
+    }
+}
 ~~~
 
 ## Compilation
diff --git a/src/examples/callbacks/main.rs b/src/examples/callbacks/main.rs
index b0de332e..23548cdd 100644
--- a/src/examples/callbacks/main.rs
+++ b/src/examples/callbacks/main.rs
@@ -17,15 +17,15 @@ extern mod glfw;
 
 use std::libc;
 
+#[link_args="-lglfw"] extern {}
+
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     std::rt::start_on_main_thread(argc, argv, main)
 }
 
 fn main() {
-    do glfw::set_error_callback |_, msg| {
-        println!("GLFW Error: {:s}", msg);
-    }
+    glfw::set_error_callback(~ErrorContext);
 
     do glfw::start {
         glfw::window_hint::resizable(true);
@@ -37,20 +37,20 @@ fn main() {
 
         // Register event callbacks
 
-        window.set_pos_callback(window_pos_callback);
-        window.set_size_callback(window_size_callback);
-        window.set_close_callback(window_close_callback);
-        window.set_refresh_callback(window_refresh_callback);
-        window.set_focus_callback(window_focus_callback);
-        window.set_iconify_callback(window_iconify_callback);
-        window.set_framebuffer_size_callback(framebuffer_size_callback);
-
-        window.set_key_callback(key_callback);
-        window.set_char_callback(char_callback);
-        window.set_mouse_button_callback(mouse_button_callback);
-        window.set_cursor_pos_callback(cursor_pos_callback);
-        window.set_cursor_enter_callback(cursor_enter_callback);
-        window.set_scroll_callback(scroll_callback);
+        window.set_pos_callback(~WindowPosContext);
+        window.set_size_callback(~WindowSizeContext);
+        window.set_close_callback(~WindowCloseContext);
+        window.set_refresh_callback(~WindowRefreshContext);
+        window.set_focus_callback(~WindowFocusContext);
+        window.set_iconify_callback(~WindowIconifyContext);
+        window.set_framebuffer_size_callback(~FramebufferSizeContext);
+
+        window.set_key_callback(~KeyContext);
+        window.set_char_callback(~CharContext);
+        window.set_mouse_button_callback(~MouseButtonContext);
+        window.set_cursor_pos_callback(~CursorPosContext);
+        window.set_cursor_enter_callback(~CursorEnterContext);
+        window.set_scroll_callback(~ScrollContext);
 
         window.make_context_current();
 
@@ -60,85 +60,131 @@ fn main() {
     }
 }
 
-fn window_pos_callback(window: &glfw::Window, x: int, y: int) {
-    window.set_title(format!("Window pos: ({}, {})", x, y));
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(&self, _: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
+    }
 }
 
-fn window_size_callback(window: &glfw::Window, width: int, height: int) {
-    window.set_title(format!("Window size: ({}, {})", width, height));
+struct WindowPosContext;
+impl glfw::WindowPosCallback for WindowPosContext {
+    fn call(&self, window: &glfw::Window, x: int, y: int) {
+        window.set_title(format!("Window pos: ({}, {})", x, y));
+    }
 }
 
-fn window_close_callback(_: &glfw::Window) {
-    println("Window close requested.");
+struct WindowSizeContext;
+impl glfw::WindowSizeCallback for WindowSizeContext {
+    fn call(&self, window: &glfw::Window, width: int, height: int) {
+        window.set_title(format!("Window size: ({}, {})", width, height));
+    }
 }
 
-fn window_refresh_callback(_: &glfw::Window) {
-    println("Window refresh callback triggered.");
+struct WindowCloseContext;
+impl glfw::WindowCloseCallback for WindowCloseContext {
+    fn call(&self, _: &glfw::Window) {
+        println("Window close requested.");
+    }
 }
 
-fn window_focus_callback(_: &glfw::Window, activated: bool) {
-    if activated { println("Window focus gained."); }
-    else         { println("Window focus lost.");   }
+struct WindowRefreshContext;
+impl glfw::WindowRefreshCallback for WindowRefreshContext {
+    fn call(&self, _: &glfw::Window) {
+        println("Window refresh callback triggered.");
+    }
 }
 
-fn window_iconify_callback(_: &glfw::Window, iconified: bool) {
-    if iconified { println("Window was minimised");  }
-    else         { println("Window was maximised."); }
+struct WindowFocusContext;
+impl glfw::WindowFocusCallback for WindowFocusContext {
+    fn call(&self, _: &glfw::Window, activated: bool) {
+        if activated { println("Window focus gained."); }
+        else         { println("Window focus lost.");   }
+    }
 }
 
-fn framebuffer_size_callback(_: &glfw::Window, width: int, height: int) {
-    println!("Framebuffer size: {} {}", width, height);
+struct WindowIconifyContext;
+impl glfw::WindowIconifyCallback for WindowIconifyContext {
+    fn call(&self, _: &glfw::Window, iconified: bool) {
+        if iconified { println("Window was minimised");  }
+        else         { println("Window was maximised."); }
+    }
 }
 
-fn key_callback(window: &glfw::Window, key: glfw::Key, scancode: libc::c_int, action: glfw::Action, mods: glfw::Modifiers) {
-    println!("{} {:s}{:s} (scan code : {})",
-             key.to_str(),
-             action.to_str(),
-             match mods.to_str() {
-                ~"" => ~"",
-                s => format!(" with: {:s}", s),
-             },
-             scancode);
-
-    match (key, action) {
-        (glfw::KeyEscape, glfw::Press) => {
-            window.set_should_close(true);
-        }
+struct FramebufferSizeContext;
+impl glfw::FramebufferSizeCallback for FramebufferSizeContext {
+    fn call(&self, _: &glfw::Window, width: int, height: int) {
+        println!("Framebuffer size: {} {}", width, height);
+    }
+}
 
-        (glfw::KeyR, glfw::Press) => {
-            // Resize should cause the window to "refresh"
-            let (window_width, window_height) = window.get_size();
-            window.set_size(window_width + 1, window_height);
-            window.set_size(window_width, window_height);
+struct KeyContext;
+impl glfw::KeyCallback for KeyContext {
+    fn call(&self, window: &glfw::Window, key: glfw::Key, scancode: libc::c_int, action: glfw::Action, mods: glfw::Modifiers) {
+        println!("{} {:s}{:s} (scan code : {})",
+                 key.to_str(),
+                 action.to_str(),
+                 match mods.to_str() {
+                    ~"" => ~"",
+                    s => format!(" with: {:s}", s),
+                 },
+                 scancode);
+
+        match (key, action) {
+            (glfw::KeyEscape, glfw::Press) => {
+                window.set_should_close(true);
+            }
+
+            (glfw::KeyR, glfw::Press) => {
+                // Resize should cause the window to "refresh"
+                let (window_width, window_height) = window.get_size();
+                window.set_size(window_width + 1, window_height);
+                window.set_size(window_width, window_height);
+            }
+
+            _ => ()
         }
-
-        _ => ()
     }
 }
 
-fn char_callback(_: &glfw::Window, character: char) {
-    println!("Character: {}", character);
+struct CharContext;
+impl glfw::CharCallback for CharContext {
+    fn call(&self, _: &glfw::Window, character: char) {
+        println!("Character: {}", character);
+    }
 }
 
-fn mouse_button_callback(_: &glfw::Window, button: glfw::MouseButton, action: glfw::Action, mods: glfw::Modifiers) {
-    println!("{} {:s}{:s}",
-             button.to_str(),
-             action.to_str(),
-             match mods.to_str() {
-                ~"" => ~"",
-                s => format!(" with: {:s}", s),
-             });
+struct MouseButtonContext;
+impl glfw::MouseButtonCallback for MouseButtonContext {
+    fn call(&self, _: &glfw::Window, button: glfw::MouseButton, action: glfw::Action, mods: glfw::Modifiers) {
+        println!("{} {:s}{:s}",
+                 button.to_str(),
+                 action.to_str(),
+                 match mods.to_str() {
+                    ~"" => ~"",
+                    s => format!(" with: {:s}", s),
+                 });
+    }
 }
 
-fn cursor_pos_callback(window: &glfw::Window, xpos: f64, ypos: f64) {
-    window.set_title(format!("Cursor position: ({}, {})", xpos, ypos));
+struct CursorPosContext;
+impl glfw::CursorPosCallback for CursorPosContext {
+    fn call(&self, window: &glfw::Window, xpos: f64, ypos: f64) {
+        window.set_title(format!("Cursor position: ({}, {})", xpos, ypos));
+    }
 }
 
-fn cursor_enter_callback(_: &glfw::Window, entered: bool) {
-    if entered { println("Cursor entered window."); }
-    else       { println("Cursor left window.");    }
+struct CursorEnterContext;
+impl glfw::CursorEnterCallback for CursorEnterContext {
+    fn call(&self, _: &glfw::Window, entered: bool) {
+        if entered { println("Cursor entered window."); }
+        else       { println("Cursor left window.");    }
+    }
 }
 
-fn scroll_callback(window: &glfw::Window, x: f64, y: f64) {
-    window.set_title(format!("Scroll offset: ({}, {})", x, y));
+struct ScrollContext;
+impl glfw::ScrollCallback for ScrollContext {
+    fn call(&self, window: &glfw::Window, x: f64, y: f64) {
+        window.set_title(format!("Scroll offset: ({}, {})", x, y));
+    }
 }
diff --git a/src/examples/clipboard/main.rs b/src/examples/clipboard/main.rs
index 5fc45b89..eb6f0ae4 100644
--- a/src/examples/clipboard/main.rs
+++ b/src/examples/clipboard/main.rs
@@ -17,20 +17,22 @@ extern mod glfw;
 
 use std::libc;
 
+#[link_args="-lglfw"] extern {}
+
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     std::rt::start_on_main_thread(argc, argv, main)
 }
 
 fn main() {
-    glfw::set_error_callback(error_callback);
+    glfw::set_error_callback(~ErrorContext);
 
     do glfw::start {
         let window = glfw::Window::create(300, 300, "Clipboard Test", glfw::Windowed)
             .expect("Failed to create GLFW window.");
 
+        window.set_key_callback(~KeyContext);
         window.make_context_current();
-        window.set_key_callback(key_callback);
         glfw::set_swap_interval(1);
 
         while !window.should_close() {
@@ -45,25 +47,31 @@ static NATIVE_MOD: glfw::Modifier = glfw::Super;
 #[cfg(not(target_os = "macos"))]
 static NATIVE_MOD: glfw::Modifier = glfw::Control;
 
-fn error_callback(_: glfw::Error, description: ~str) {
-    println!("GLFW Error: {:s}", description);
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(&self, _: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
+    }
 }
 
-fn key_callback(window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, mods: glfw::Modifiers) {
-    if action == glfw::Press {
-        if key == glfw::KeyEscape {
-            window.set_should_close(true);
-        }
-        if (key == glfw::KeyV) && mods.contains(NATIVE_MOD) {
-            match window.get_clipboard_string() {
-                ref s if !s.is_empty() => println!("Clipboard contains \"{:s}\"", *s),
-                _                      => println("Clipboard does not contain a string"),
+struct KeyContext;
+impl glfw::KeyCallback for KeyContext {
+    fn call(&self, window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, mods: glfw::Modifiers) {
+        if action == glfw::Press {
+            if key == glfw::KeyEscape {
+                window.set_should_close(true);
+            }
+            if (key == glfw::KeyV) && mods.contains(NATIVE_MOD) {
+                match window.get_clipboard_string() {
+                    ref s if !s.is_empty() => println!("Clipboard contains \"{:s}\"", *s),
+                    _                      => println("Clipboard does not contain a string"),
+                }
+            }
+            if (key == glfw::KeyC) && mods.contains(NATIVE_MOD) {
+                let s = "Hello GLFW World!";
+                window.set_clipboard_string(s);
+                println!("Setting clipboard to {:s}", s);
             }
-        }
-        if (key == glfw::KeyC) && mods.contains(NATIVE_MOD) {
-            let s = "Hello GLFW World!";
-            window.set_clipboard_string(s);
-            println!("Setting clipboard to {:s}", s);
         }
     }
 }
diff --git a/src/examples/cursor/main.rs b/src/examples/cursor/main.rs
index d62343bd..eb81f226 100644
--- a/src/examples/cursor/main.rs
+++ b/src/examples/cursor/main.rs
@@ -15,15 +15,17 @@
 
 extern mod glfw;
 
+use std::libc;
+
+#[link_args="-lglfw"] extern {}
+
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     std::rt::start_on_main_thread(argc, argv, main)
 }
 
 fn main() {
-    do glfw::set_error_callback |_, description| {
-        println!("GLFW Error: {:s}", description);
-    }
+   glfw::set_error_callback(~ErrorContext);
 
     do glfw::start {
         let window = glfw::Window::create(800, 600, "Hello, I am a window.", glfw::Windowed)
@@ -32,26 +34,42 @@ fn main() {
         window.set_cursor_mode(glfw::CursorDisabled);
         window.make_context_current();
 
-        do window.set_cursor_pos_callback |_, xpos, ypos| {
-            println!("Cursor position: ({}, {})", xpos, ypos);
+        window.set_cursor_pos_callback(~CursorPosContext);
+        window.set_key_callback(~KeyContext);
+
+        while !window.should_close() {
+            glfw::poll_events();
         }
+    }
+}
+
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(&self, _: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
+    }
+}
+
+struct CursorPosContext;
+impl glfw::CursorPosCallback for CursorPosContext {
+    fn call(&self, _: &glfw::Window, xpos: f64, ypos: f64) {
+        println!("Cursor position: ({}, {})", xpos, ypos);
+    }
+}
 
-        do window.set_key_callback |window, key, _, action, _| {
-            match (action, key) {
-                (glfw::Press, glfw::KeyEscape) => window.set_should_close(true),
-                (glfw::Press, glfw::KeySpace) => {
-                    match window.get_cursor_mode() {
-                        glfw::CursorDisabled => window.set_cursor_mode(glfw::CursorNormal),
-                        glfw::CursorNormal   => window.set_cursor_mode(glfw::CursorDisabled),
-                        _ => {}
-                    }
+struct KeyContext;
+impl glfw::KeyCallback for KeyContext {
+    fn call(&self, window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
+        match (action, key) {
+            (glfw::Press, glfw::KeyEscape) => window.set_should_close(true),
+            (glfw::Press, glfw::KeySpace) => {
+                match window.get_cursor_mode() {
+                    glfw::CursorDisabled => window.set_cursor_mode(glfw::CursorNormal),
+                    glfw::CursorNormal   => window.set_cursor_mode(glfw::CursorDisabled),
+                    _ => {}
                 }
-                _ => {}
             }
-        }
-
-        while !window.should_close() {
-            glfw::poll_events();
+            _ => {}
         }
     }
 }
diff --git a/src/examples/defaults/main.rs b/src/examples/defaults/main.rs
index 043ba0c6..60fc73aa 100644
--- a/src/examples/defaults/main.rs
+++ b/src/examples/defaults/main.rs
@@ -15,9 +15,7 @@
 
 extern mod glfw;
 
-fn error_callback(_: glfw::Error, description: ~str) {
-    println!("GLFW Error: {:s}", description);
-}
+#[link_args="-lglfw"] extern {}
 
 #[start]
 fn start(argc: int, argv: **u8) -> int {
@@ -25,7 +23,7 @@ fn start(argc: int, argv: **u8) -> int {
 }
 
 fn main() {
-    glfw::set_error_callback(error_callback);
+    glfw::set_error_callback(~ErrorContext);
 
     do glfw::start {
         glfw::window_hint::visible(true);
@@ -70,6 +68,13 @@ fn main() {
     }
 }
 
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(&self, _: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
+    }
+}
+
 mod gl {
     use std::libc;
 
diff --git a/src/examples/managed-state/main.rs b/src/examples/managed-state/main.rs
deleted file mode 100644
index acda987f..00000000
--- a/src/examples/managed-state/main.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
-// refer to the AUTHORS file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-//! This example shows how managed objects can be accessed from callbacks
-
-#[feature(managed_boxes)];
-
-extern mod glfw;
-
-use std::local_data;
-
-static tls_key: local_data::Key<@mut State> = &local_data::Key;
-
-struct State {
-    priv pos: (f64, f64),
-}
-
-impl State {
-    pub fn update(x: f64, y: f64) {
-        do local_data::get(tls_key) |opt| {
-            match opt {
-                Some(state) => state.pos = (x, y),
-                None => local_data::set(tls_key, @mut State { pos: (x, y) }),
-            }
-        }
-    }
-
-    pub fn get_pos() -> Option<(f64, f64)> {
-        do local_data::get(tls_key) |opt| {
-            opt.map(|state| state.pos)
-        }
-    }
-}
-
-#[start]
-fn start(argc: int, argv: **u8) -> int {
-    std::rt::start_on_main_thread(argc, argv, main)
-}
-
-fn main() {
-    do glfw::set_error_callback |_, msg| {
-        println!("GLFW Error: {:s}", msg);
-    }
-
-    do glfw::start {
-        let window = glfw::Window::create(300, 300, "Move cursor in window", glfw::Windowed)
-            .expect("Failed to create GLFW window.");
-
-        do window.set_cursor_pos_callback |_, x, y| {
-            State::update(x, y);
-        }
-
-        do window.set_key_callback |win, key, _, action, _mods| {
-            if action == glfw::Press && key == glfw::KeyEscape {
-                win.set_should_close(true);
-            }
-        }
-        window.make_context_current();
-
-        while !window.should_close() {
-            glfw::poll_events();
-
-            do State::get_pos().map |(x, y)| {
-                window.set_title(format!("({}, {})", x, y));
-            };
-        }
-    }
-}
-
diff --git a/src/examples/manual-init/main.rs b/src/examples/manual-init/main.rs
index 7ca293c0..8c84f1d8 100644
--- a/src/examples/manual-init/main.rs
+++ b/src/examples/manual-init/main.rs
@@ -18,6 +18,8 @@ extern mod glfw;
 use std::libc;
 use std::unstable::finally::Finally;
 
+#[link_args="-lglfw"] extern {}
+
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     // GLFW must run on the main platform thread
@@ -25,7 +27,7 @@ fn start(argc: int, argv: **u8) -> int {
 }
 
 fn main() {
-    glfw::set_error_callback(error_callback);
+    glfw::set_error_callback(~ErrorContext);
 
     if glfw::init().is_err() {
         fail!(~"Failed to initialize GLFW");
@@ -34,7 +36,7 @@ fn main() {
             let window = glfw::Window::create(300, 300, "Hello this is window", glfw::Windowed)
                 .expect("Failed to create GLFW window.");
 
-            window.set_key_callback(key_callback);
+            window.set_key_callback(~KeyContext);
             window.make_context_current();
 
             while !window.should_close() {
@@ -45,12 +47,18 @@ fn main() {
     }
 }
 
-fn key_callback(window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
-    if action == glfw::Press && key == glfw::KeyEscape {
-        window.set_should_close(true);
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(&self, _: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
     }
 }
 
-fn error_callback(_: glfw::Error, description: ~str) {
-    println!("GLFW Error: {:s}", description);
+struct KeyContext;
+impl glfw::KeyCallback for KeyContext {
+    fn call(&self, window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
+        if action == glfw::Press && key == glfw::KeyEscape {
+            window.set_should_close(true);
+        }
+    }
 }
diff --git a/src/examples/modes/main.rs b/src/examples/modes/main.rs
index f504b751..9989910d 100644
--- a/src/examples/modes/main.rs
+++ b/src/examples/modes/main.rs
@@ -15,6 +15,8 @@
 
 extern mod glfw;
 
+#[link_args="-lglfw"] extern {}
+
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     std::rt::start_on_main_thread(argc, argv, main)
diff --git a/src/examples/title/main.rs b/src/examples/title/main.rs
index 97d1ff5c..c9660b17 100644
--- a/src/examples/title/main.rs
+++ b/src/examples/title/main.rs
@@ -17,20 +17,22 @@ extern mod glfw;
 
 use std::libc;
 
+#[link_args="-lglfw"] extern {}
+
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     std::rt::start_on_main_thread(argc, argv, main)
 }
 
 fn main() {
-    glfw::set_error_callback(error_callback);
+    glfw::set_error_callback(~ErrorContext);
 
     do glfw::start {
         let window = glfw::Window::create(400, 400, "English 日本語 русский язык 官話", glfw::Windowed)
             .expect("Failed to create GLFW window.");
 
+        window.set_key_callback(~KeyContext);
         window.make_context_current();
-        window.set_key_callback(key_callback);
         glfw::set_swap_interval(1);
 
         while !window.should_close() {
@@ -39,12 +41,18 @@ fn main() {
     }
 }
 
-fn key_callback(window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
-    if action == glfw::Press && key == glfw::KeyEscape {
-        window.set_should_close(true);
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(&self, _: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
     }
 }
 
-fn error_callback(_: glfw::Error, description: ~str) {
-    println!("GLFW Error: {:s}", description);
+struct KeyContext;
+impl glfw::KeyCallback for KeyContext {
+    fn call(&self, window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
+        if action == glfw::Press && key == glfw::KeyEscape {
+            window.set_should_close(true);
+        }
+    }
 }
diff --git a/src/examples/version/main.rs b/src/examples/version/main.rs
index 531b9eed..7464f218 100644
--- a/src/examples/version/main.rs
+++ b/src/examples/version/main.rs
@@ -15,6 +15,8 @@
 
 extern mod glfw;
 
+#[link_args="-lglfw"] extern {}
+
 fn main() {
     println(glfw::get_version().to_str());
     println!("GLFW version: {:s}", glfw::get_version_string());
diff --git a/src/examples/window/main.rs b/src/examples/window/main.rs
index 610ddbaf..b11ba030 100644
--- a/src/examples/window/main.rs
+++ b/src/examples/window/main.rs
@@ -17,21 +17,21 @@ extern mod glfw;
 
 use std::libc;
 
+#[link_args="-lglfw"] extern {}
+
 #[start]
 fn start(argc: int, argv: **u8) -> int {
     std::rt::start_on_main_thread(argc, argv, main)
 }
 
 fn main() {
-    do glfw::set_error_callback |_, msg| {
-        println!("GLFW Error: {:s}", msg);
-    }
+    glfw::set_error_callback(~ErrorContext);
 
     do glfw::start {
         let window = glfw::Window::create(300, 300, "Hello this is window", glfw::Windowed)
             .expect("Failed to create GLFW window.");
 
-        window.set_key_callback(key_callback);
+        window.set_key_callback(~KeyContext);
         window.make_context_current();
 
         while !window.should_close() {
@@ -40,8 +40,18 @@ fn main() {
     }
 }
 
-fn key_callback(window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
-    if action == glfw::Press && key == glfw::KeyEscape {
-        window.set_should_close(true);
+struct ErrorContext;
+impl glfw::ErrorCallback for ErrorContext {
+    fn call(&self, _: glfw::Error, description: ~str) {
+        println!("GLFW Error: {:s}", description);
+    }
+}
+
+struct KeyContext;
+impl glfw::KeyCallback for KeyContext {
+    fn call(&self, window: &glfw::Window, key: glfw::Key, _: libc::c_int, action: glfw::Action, _: glfw::Modifiers) {
+        if action == glfw::Press && key == glfw::KeyEscape {
+            window.set_should_close(true);
+        }
     }
 }
diff --git a/src/glfw/extfn.rs b/src/glfw/callbacks.rs
similarity index 57%
rename from src/glfw/extfn.rs
rename to src/glfw/callbacks.rs
index affd5286..6dd72420 100644
--- a/src/glfw/extfn.rs
+++ b/src/glfw/callbacks.rs
@@ -24,39 +24,38 @@ use super::*;
 
 // Global callbacks
 
-static error_fun_tls_key: local_data::Key<ErrorFun> = &local_data::Key;
+static error_callback_tls_key: local_data::Key<~ErrorCallback> = &local_data::Key;
+static monitor_callback_tls_key: local_data::Key<~MonitorCallback> = &local_data::Key;
 
 pub extern "C" fn error_callback(error: c_int, description: *c_char) {
-    do local_data::get(error_fun_tls_key) |data| {
+    do local_data::get(error_callback_tls_key) |data| {
         do data.as_ref().map |&ref cb| {
-            unsafe { (**cb)(cast::transmute(error), str::raw::from_c_str(description)) }
+            unsafe { cb.call(cast::transmute(error), str::raw::from_c_str(description)) }
         };
     }
 }
 
-pub fn set_error_fun(cbfun: ErrorFun, f: &fn(ffi::GLFWerrorfun) ) {
-    local_data::set(error_fun_tls_key, cbfun);
+pub fn set_error_callback<Cb: ErrorCallback + Send>(callback: ~Cb, f: &fn(ffi::GLFWerrorfun) ) {
+    local_data::set(error_callback_tls_key, callback as ~ErrorCallback);
     f(error_callback);
 }
 
-static monitor_fun_tls_key: local_data::Key<MonitorFun> = &local_data::Key;
 
 pub extern "C" fn monitor_callback(monitor: *ffi::GLFWmonitor, event: c_int) {
-    do local_data::get(monitor_fun_tls_key) |data| {
+    do local_data::get(monitor_callback_tls_key) |data| {
         do data.as_ref().map |&ref cb| {
-            unsafe { (**cb)(&Monitor { ptr: monitor }, cast::transmute(event)) }
+            unsafe { cb.call(&Monitor { ptr: monitor }, cast::transmute(event)) }
         };
     }
 }
 
-pub fn set_monitor_fun(cbfun: MonitorFun, f: &fn(ffi::GLFWmonitorfun) ) {
-    local_data::set(monitor_fun_tls_key, cbfun);
+pub fn set_monitor_callback<Cb: MonitorCallback + Send>(callback: ~Cb, f: &fn(ffi::GLFWmonitorfun) ) {
+    local_data::set(monitor_callback_tls_key, callback as ~MonitorCallback);
     f(monitor_callback);
 }
 
 // External window callbacks
-#[fixed_stack_segment]
-unsafe fn get_fns(window: *ffi::GLFWwindow) -> &WindowFns {
+unsafe fn get_callbacks(window: *ffi::GLFWwindow) -> &WindowCallbacks {
     cast::transmute(ffi::glfwGetWindowUserPointer(window))
 }
 
@@ -65,7 +64,7 @@ macro_rules! window_callback(
          pub extern "C" fn $name(window: *ffi::GLFWwindow) {
             unsafe {
                 let window = Window { ptr: window, is_shared: false };
-                window.get_fns().$field.as_ref().map(|cb| (*cb)(&window));
+                window.get_callbacks().$field.as_ref().map(|cb| cb.call(&window));
                 cast::forget(window);
             }
          }
@@ -74,23 +73,23 @@ macro_rules! window_callback(
          pub extern "C" fn $name(window: *ffi::GLFWwindow $(, $ext_arg: $ext_arg_ty)*) {
             unsafe {
                 let window = Window { ptr: window, is_shared: false };
-                window.get_fns().$field.as_ref().map(|cb| (*cb)(&window $(, $arg_conv)*));
+                window.get_callbacks().$field.as_ref().map(|cb| cb.call(&window $(, $arg_conv)*));
                 cast::forget(window);
             }
          }
      );
 )
 
-window_callback!(fn window_pos_callback(xpos: c_int, ypos: c_int)                           => pos_fun(xpos as int, ypos as int))
-window_callback!(fn window_size_callback(width: c_int, height: c_int)                       => size_fun(width as int, height as int))
-window_callback!(fn window_close_callback()                                                 => close_fun())
-window_callback!(fn window_refresh_callback()                                               => refresh_fun())
-window_callback!(fn window_focus_callback(focused: c_int)                                   => focus_fun(focused == ffi::TRUE))
-window_callback!(fn window_iconify_callback(iconified: c_int)                               => iconify_fun(iconified == ffi::TRUE))
-window_callback!(fn framebuffer_size_callback(width: c_int, height: c_int)                  => framebuffer_size_fun(width as int, height as int))
-window_callback!(fn mouse_button_callback(button: c_int, action: c_int, mods: c_int)        => mouse_button_fun(cast::transmute(button), cast::transmute(action), Modifiers { values: mods }))
-window_callback!(fn cursor_pos_callback(xpos: c_double, ypos: c_double)                     => cursor_pos_fun(xpos as f64, ypos as f64))
-window_callback!(fn cursor_enter_callback(entered: c_int)                                   => cursor_enter_fun(entered == ffi::TRUE))
-window_callback!(fn scroll_callback(xpos: c_double, ypos: c_double)                         => scroll_fun(xpos as f64, ypos as f64))
-window_callback!(fn key_callback(key: c_int, scancode: c_int, action: c_int, mods: c_int)   => key_fun(cast::transmute(key), scancode, cast::transmute(action), Modifiers { values: mods }))
-window_callback!(fn char_callback(character: c_uint)                                        => char_fun(::std::char::from_u32(character).unwrap()))
+window_callback!(fn window_pos_callback(xpos: c_int, ypos: c_int)                           => pos_callback(xpos as int, ypos as int))
+window_callback!(fn window_size_callback(width: c_int, height: c_int)                       => size_callback(width as int, height as int))
+window_callback!(fn window_close_callback()                                                 => close_callback())
+window_callback!(fn window_refresh_callback()                                               => refresh_callback())
+window_callback!(fn window_focus_callback(focused: c_int)                                   => focus_callback(focused == ffi::TRUE))
+window_callback!(fn window_iconify_callback(iconified: c_int)                               => iconify_callback(iconified == ffi::TRUE))
+window_callback!(fn framebuffer_size_callback(width: c_int, height: c_int)                  => framebuffer_size_callback(width as int, height as int))
+window_callback!(fn mouse_button_callback(button: c_int, action: c_int, mods: c_int)        => mouse_button_callback(cast::transmute(button), cast::transmute(action), Modifiers { values: mods }))
+window_callback!(fn cursor_pos_callback(xpos: c_double, ypos: c_double)                     => cursor_pos_callback(xpos as f64, ypos as f64))
+window_callback!(fn cursor_enter_callback(entered: c_int)                                   => cursor_enter_callback(entered == ffi::TRUE))
+window_callback!(fn scroll_callback(xpos: c_double, ypos: c_double)                         => scroll_callback(xpos as f64, ypos as f64))
+window_callback!(fn key_callback(key: c_int, scancode: c_int, action: c_int, mods: c_int)   => key_callback(cast::transmute(key), scancode, cast::transmute(action), Modifiers { values: mods }))
+window_callback!(fn char_callback(character: c_uint)                                        => char_callback(::std::char::from_u32(character).unwrap()))
diff --git a/src/glfw/lib.rs b/src/glfw/lib.rs
index 24cd1fcd..03f2b409 100644
--- a/src/glfw/lib.rs
+++ b/src/glfw/lib.rs
@@ -14,8 +14,8 @@
 // limitations under the License.
 
 #[link(name = "glfw",
+       package_id = "glfw",
        vers = "0.1",
-       uuid = "6199FAD3-6D03-4E29-87E7-7DC1B1B65C2C",
        author = "Brendan Zabarauskas",
        url = "https://github.com/bjz/glfw3-rs")];
 
@@ -34,7 +34,7 @@ use std::str;
 use std::vec;
 
 pub mod ffi;
-mod extfn;
+mod callbacks;
 
 #[repr(C)]
 #[deriving(Clone, Eq, IterBytes, ToStr)]
@@ -204,7 +204,6 @@ pub enum Error {
     FormatUnavailable           = ffi::FORMAT_UNAVAILABLE,
 }
 
-pub type ErrorFun = ~fn(error: Error, description: ~str);
 
 #[repr(C)]
 #[deriving(Clone, Eq, IterBytes, ToStr)]
@@ -261,7 +260,6 @@ pub type GLProc = ffi::GLFWglproc;
 /// Returns `true` if the initialisation was successful, otherwise `false`.
 ///
 /// Wrapper for `glfwInit`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn init() -> Result<(),()> {
     match unsafe { ffi::glfwInit() } {
         ffi::TRUE => Ok(()),
@@ -272,7 +270,6 @@ pub fn init() -> Result<(),()> {
 /// Terminate glfw. This must be called on the main platform thread.
 ///
 /// Wrapper for `glfwTerminate`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn terminate() {
     unsafe { ffi::glfwTerminate() }
 }
@@ -282,11 +279,13 @@ pub fn terminate() {
 ///
 /// # Parameters
 ///
-/// - `f`: A closure to be called after the GLFW is initialised.
-pub fn start(f: ~fn()) {
-    use std::unstable::finally::Finally;
+/// - `f`: to be called after the GLFW is initialised.
+pub fn start(f: proc()) {
+    // use std::unstable::finally::Finally;
     if init().is_ok() {
-        f.finally(terminate);
+        // f.finally(terminate);
+        f();
+        terminate();
     } else {
         fail!(~"Failed to initialize GLFW");
     }
@@ -315,7 +314,6 @@ impl ToStr for Version {
 }
 
 /// Wrapper for `glfwGetVersion`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn get_version() -> Version {
     unsafe {
         let mut major = 0;
@@ -331,19 +329,21 @@ pub fn get_version() -> Version {
 }
 
 /// Wrapper for `glfwGetVersionString`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn get_version_string() -> ~str {
     unsafe { str::raw::from_c_str(ffi::glfwGetVersionString()) }
 }
 
+pub trait ErrorCallback { fn call(&self, error: Error, description: ~str); }
+
 /// Wrapper for `glfwSetErrorCallback`.
-#[fixed_stack_segment] #[inline(never)]
-pub fn set_error_callback(cbfun: ErrorFun) {
-    do extfn::set_error_fun(cbfun) |ext_cb| {
+pub fn set_error_callback<Cb: ErrorCallback + Send>(callback: ~Cb) {
+    do callbacks::set_error_callback(callback) |ext_cb| {
         unsafe { ffi::glfwSetErrorCallback(Some(ext_cb)); }
     }
 }
 
+pub trait MonitorCallback { fn call(&self, monitor: &Monitor, event: MonitorEvent); }
+
 /// A struct that wraps a `*GLFWmonitor` handle.
 #[deriving(Eq)]
 pub struct Monitor {
@@ -352,7 +352,6 @@ pub struct Monitor {
 
 impl Monitor {
     /// Wrapper for `glfwGetPrimaryMonitor`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_primary() -> Result<Monitor,()> {
         unsafe {
             ffi::glfwGetPrimaryMonitor()
@@ -363,7 +362,6 @@ impl Monitor {
     }
 
     /// Wrapper for `glfwGetMonitors`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_connected() -> ~[Monitor] {
         unsafe {
             let mut count = 0;
@@ -373,7 +371,6 @@ impl Monitor {
     }
 
     /// Wrapper for `glfwGetMonitorPos`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_pos(&self) -> (int, int) {
         unsafe {
             let mut xpos = 0;
@@ -384,7 +381,6 @@ impl Monitor {
     }
 
     /// Wrapper for `glfwGetMonitorPhysicalSize`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_physical_size(&self) -> (int, int) {
         unsafe {
             let mut width = 0;
@@ -395,21 +391,18 @@ impl Monitor {
     }
 
     /// Wrapper for `glfwGetMonitorName`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_name(&self) -> ~str {
         unsafe { str::raw::from_c_str(ffi::glfwGetMonitorName(self.ptr)) }
     }
 
     /// Wrapper for `glfwSetMonitorCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_callback(cbfun: MonitorFun) {
-        do extfn::set_monitor_fun(cbfun) |ext_cb| {
+    pub fn set_callback<Cb: MonitorCallback + Send>(callback: ~Cb) {
+        do callbacks::set_monitor_callback(callback) |ext_cb| {
             unsafe { ffi::glfwSetMonitorCallback(Some(ext_cb)); }
         }
     }
 
     /// Wrapper for `glfwGetVideoModes`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_video_modes(&self) -> ~[VidMode] {
         unsafe {
             let mut count = 0;
@@ -419,7 +412,6 @@ impl Monitor {
     }
 
     /// Wrapper for `glfwGetVideoMode`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_video_mode(&self) -> Option<VidMode> {
         unsafe {
             ffi::glfwGetVideoMode(self.ptr).to_option().map(|v| VidMode::from_glfw_vid_mode(v))
@@ -427,13 +419,11 @@ impl Monitor {
     }
 
     /// Wrapper for `glfwSetGamma`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_gamma(&self, gamma: f32) {
         unsafe { ffi::glfwSetGamma(self.ptr, gamma as c_float); }
     }
 
     /// Wrapper for `glfwGetGammaRamp`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_gamma_ramp(&self) -> GammaRamp {
         unsafe {
             let llramp = *ffi::glfwGetGammaRamp(self.ptr);
@@ -446,7 +436,6 @@ impl Monitor {
     }
 
     /// Wrapper for `glfwSetGammaRamp`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_gamma_ramp(&self, ramp: &GammaRamp) {
         unsafe {
             ffi::glfwSetGammaRamp(
@@ -462,9 +451,7 @@ impl Monitor {
     }
 }
 
-pub type MonitorFun = ~fn(monitor: &Monitor, event: MonitorEvent);
 #[repr(C)]
-
 pub enum MonitorEvent {
     Connected                   = ffi::CONNECTED,
     Disconnected                = ffi::DISCONNECTED,
@@ -507,122 +494,102 @@ pub mod window_hint {
     use super::*;
 
     /// Wrapper for `glfwDefaultWindowHints`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn default() {
         unsafe { ffi::glfwDefaultWindowHints(); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `RED_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn red_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::RED_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `GREEN_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn green_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::GREEN_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `BLUE_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn blue_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::BLUE_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `ALPHA_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn alpha_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::ALPHA_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `DEPTH_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn depth_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::DEPTH_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `STENCIL_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn stencil_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::STENCIL_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `ACCUM_RED_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn accum_red_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::ACCUM_RED_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `ACCUM_GREEN_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn accum_green_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::ACCUM_GREEN_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `ACCUM_BLUE_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn accum_blue_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::ACCUM_BLUE_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `ACCUM_ALPHA_BITS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn accum_alpha_bits(bits: uint) {
         unsafe { ffi::glfwWindowHint(ffi::ACCUM_ALPHA_BITS, bits as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `AUX_BUFFERS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn aux_buffers(buffers: uint) {
         unsafe { ffi::glfwWindowHint(ffi::AUX_BUFFERS, buffers as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `STEREO`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn stereo(value: bool) {
         unsafe { ffi::glfwWindowHint(ffi::STEREO, value as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `SAMPLES`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn samples(samples: uint) {
         unsafe { ffi::glfwWindowHint(ffi::SAMPLES, samples as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `SRGB_CAPABLE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn srgb_capable(value: bool) {
         unsafe { ffi::glfwWindowHint(ffi::SRGB_CAPABLE, value as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `REFRESH_RATE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn refresh_rate(rate: int) {
         unsafe { ffi::glfwWindowHint(ffi::REFRESH_RATE, rate as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `CLIENT_API`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn client_api(api: ClientApi) {
         unsafe { ffi::glfwWindowHint(ffi::CLIENT_API, api as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `CONTEXT_VERSION_MAJOR`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn context_version_major(major: uint) {
         unsafe { ffi::glfwWindowHint(ffi::CONTEXT_VERSION_MAJOR, major as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `CONTEXT_VERSION_MINOR`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn context_version_minor(minor: uint) {
         unsafe { ffi::glfwWindowHint(ffi::CONTEXT_VERSION_MINOR, minor as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `CONTEXT_VERSION_MAJOR` and
     /// `CONTEXT_VERSION_MINOR`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn context_version(major: uint, minor: uint) {
         unsafe {
             ffi::glfwWindowHint(ffi::CONTEXT_VERSION_MAJOR, major as c_int);
@@ -631,43 +598,36 @@ pub mod window_hint {
     }
 
     /// Wrapper for `glfwWindowHint` called with `CONTEXT_ROBUSTNESS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn context_robustness(value: ContextRobustness) {
         unsafe { ffi::glfwWindowHint(ffi::CONTEXT_ROBUSTNESS, value as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `OPENGL_FORWARD_COMPAT`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn opengl_forward_compat(value: bool) {
         unsafe { ffi::glfwWindowHint(ffi::OPENGL_FORWARD_COMPAT, value as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `OPENGL_DEBUG_CONTEXT`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn opengl_debug_context(value: bool) {
         unsafe { ffi::glfwWindowHint(ffi::OPENGL_DEBUG_CONTEXT, value as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `OPENGL_PROFILE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn opengl_profile(profile: OpenGlProfile) {
         unsafe { ffi::glfwWindowHint(ffi::OPENGL_PROFILE, profile as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `RESIZABLE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn resizable(value: bool) {
         unsafe { ffi::glfwWindowHint(ffi::RESIZABLE, value as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `VISIBLE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn visible(value: bool) {
         unsafe { ffi::glfwWindowHint(ffi::VISIBLE, value as c_int); }
     }
 
     /// Wrapper for `glfwWindowHint` called with `DECORATED`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn decorated(value: bool) {
         unsafe { ffi::glfwWindowHint(ffi::DECORATED, value as c_int); }
     }
@@ -754,54 +714,54 @@ impl ToStr for Modifiers {
     }
 }
 
-pub type WindowPosFun = ~fn(window: &Window, xpos: int, ypos: int);
-pub type WindowSizeFun = ~fn(window: &Window, width: int, height: int);
-pub type WindowCloseFun = ~fn(window: &Window);
-pub type WindowRefreshFun = ~fn(window: &Window);
-pub type WindowFocusFun = ~fn(window: &Window, focused: bool);
-pub type WindowIconifyFun = ~fn(window: &Window, iconified: bool);
-pub type FramebufferSizeFun = ~fn(window: &Window, width: int, height: int);
-pub type MouseButtonFun = ~fn(window: &Window, button: MouseButton, action: Action, modifiers: Modifiers);
-pub type CursorPosFun = ~fn(window: &Window, xpos: f64, ypos: f64);
-pub type CursorEnterFun = ~fn(window: &Window, entered: bool);
-pub type ScrollFun = ~fn(window: &Window, xpos: f64, ypos: f64);
-pub type KeyFun = ~fn(window: &Window, key: Key, scancode: c_int, action: Action, modifiers: Modifiers);
-pub type CharFun = ~fn(window: &Window, character: char);
-
-/// Holds the callback functions associated with a window
-struct WindowFns {
-    pos_fun:                Option<WindowPosFun>,
-    size_fun:               Option<WindowSizeFun>,
-    close_fun:              Option<WindowCloseFun>,
-    refresh_fun:            Option<WindowRefreshFun>,
-    focus_fun:              Option<WindowFocusFun>,
-    iconify_fun:            Option<WindowIconifyFun>,
-    framebuffer_size_fun:   Option<FramebufferSizeFun>,
-    mouse_button_fun:       Option<MouseButtonFun>,
-    cursor_pos_fun:         Option<CursorPosFun>,
-    cursor_enter_fun:       Option<CursorEnterFun>,
-    scroll_fun:             Option<ScrollFun>,
-    key_fun:                Option<KeyFun>,
-    char_fun:               Option<CharFun>,
+pub trait WindowPosCallback { fn call(&self, window: &Window, xpos: int, ypos: int); }
+pub trait WindowSizeCallback { fn call(&self, window: &Window, width: int, height: int); }
+pub trait WindowCloseCallback { fn call(&self, window: &Window); }
+pub trait WindowRefreshCallback { fn call(&self, window: &Window); }
+pub trait WindowFocusCallback { fn call(&self, window: &Window, focused: bool); }
+pub trait WindowIconifyCallback { fn call(&self, window: &Window, iconified: bool); }
+pub trait FramebufferSizeCallback { fn call(&self, window: &Window, width: int, height: int); }
+pub trait MouseButtonCallback { fn call(&self, window: &Window, button: MouseButton, action: Action, modifiers: Modifiers); }
+pub trait CursorPosCallback { fn call(&self, window: &Window, xpos: f64, ypos: f64); }
+pub trait CursorEnterCallback { fn call(&self, window: &Window, entered: bool); }
+pub trait ScrollCallback { fn call(&self, window: &Window, xpos: f64, ypos: f64); }
+pub trait KeyCallback { fn call(&self, window: &Window, key: Key, scancode: c_int, action: Action, modifiers: Modifiers); }
+pub trait CharCallback { fn call(&self, window: &Window, character: char); }
+
+/// Holds the callbacks associated with a window
+struct WindowCallbacks {
+    pos_callback:                Option<~WindowPosCallback>,
+    size_callback:               Option<~WindowSizeCallback>,
+    close_callback:              Option<~WindowCloseCallback>,
+    refresh_callback:            Option<~WindowRefreshCallback>,
+    focus_callback:              Option<~WindowFocusCallback>,
+    iconify_callback:            Option<~WindowIconifyCallback>,
+    framebuffer_size_callback:   Option<~FramebufferSizeCallback>,
+    mouse_button_callback:       Option<~MouseButtonCallback>,
+    cursor_pos_callback:         Option<~CursorPosCallback>,
+    cursor_enter_callback:       Option<~CursorEnterCallback>,
+    scroll_callback:             Option<~ScrollCallback>,
+    key_callback:                Option<~KeyCallback>,
+    char_callback:               Option<~CharCallback>,
 }
 
-impl WindowFns {
+impl WindowCallbacks {
     /// Initialize the struct with all callbacks set to `None`.
-    fn new() -> WindowFns {
-        WindowFns {
-            pos_fun:                None,
-            size_fun:               None,
-            close_fun:              None,
-            refresh_fun:            None,
-            focus_fun:              None,
-            iconify_fun:            None,
-            framebuffer_size_fun:   None,
-            mouse_button_fun:       None,
-            cursor_pos_fun:         None,
-            cursor_enter_fun:       None,
-            scroll_fun:             None,
-            key_fun:                None,
-            char_fun:               None,
+    fn new() -> WindowCallbacks {
+        WindowCallbacks {
+            pos_callback:                None,
+            size_callback:               None,
+            close_callback:              None,
+            refresh_callback:            None,
+            focus_callback:              None,
+            iconify_callback:            None,
+            framebuffer_size_callback:   None,
+            mouse_button_callback:       None,
+            cursor_pos_callback:         None,
+            cursor_enter_callback:       None,
+            scroll_callback:             None,
+            key_callback:                None,
+            char_callback:               None,
         }
     }
 }
@@ -809,12 +769,13 @@ impl WindowFns {
 macro_rules! set_window_callback(
     (
         setter:   $ll_fn:ident,
-        callback: $ext_fn:ident,
+        cb_trait: $cb_trait:ident,
+        callback: $ext_callback:ident,
         field:    $data_field:ident
     ) => ({
         unsafe {
-            self.get_fns().$data_field = Some(cbfun);
-            ffi::$ll_fn(self.ptr, Some(extfn::$ext_fn));
+            self.get_callbacks().$data_field = Some(callback as ~$cb_trait);
+            ffi::$ll_fn(self.ptr, Some(callbacks::$ext_callback));
         }
     })
 )
@@ -831,7 +792,6 @@ impl Window {
     }
 
     /// Internal wrapper for `glfwCreateWindow`.
-    #[fixed_stack_segment] #[inline(never)]
     fn create_intern(width: uint, height: uint, title: &str, mode: WindowMode, share: Option<&Window>) -> Option<Window> {
         let ptr = unsafe {
             do title.with_c_str |title| {
@@ -849,7 +809,7 @@ impl Window {
             None
         } else {
             unsafe {
-                ffi::glfwSetWindowUserPointer(ptr, cast::transmute(~WindowFns::new()));
+                ffi::glfwSetWindowUserPointer(ptr, cast::transmute(~WindowCallbacks::new()));
             }
             let window = Window {
                 ptr: ptr,
@@ -860,14 +820,14 @@ impl Window {
     }
 
     #[fixed_stack_segment]
-    unsafe fn get_fns(&self) -> &mut WindowFns {
+    unsafe fn get_callbacks(&self) -> &mut WindowCallbacks {
         cast::transmute(ffi::glfwGetWindowUserPointer(self.ptr))
     }
 
     #[fixed_stack_segment]
-    unsafe fn free_fns(&self) {
+    unsafe fn free_callbacks(&self) {
         if !self.ptr.is_null() {
-            let _: ~WindowFns =
+            let _: ~WindowCallbacks =
                 cast::transmute(ffi::glfwGetWindowUserPointer(self.ptr));
         }
     }
@@ -877,19 +837,16 @@ impl Window {
     }
 
     /// Wrapper for `glfwWindowShouldClose`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn should_close(&self) -> bool {
         unsafe { ffi::glfwWindowShouldClose(self.ptr) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwSetWindowShouldClose`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_should_close(&self, value: bool) {
         unsafe { ffi::glfwSetWindowShouldClose(self.ptr, value as c_int) }
     }
 
     /// Wrapper for `glfwSetWindowTitle`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_title(&self, title: &str) {
         unsafe {
             do title.with_c_str |title| {
@@ -899,7 +856,6 @@ impl Window {
     }
 
     /// Wrapper for `glfwGetWindowPos`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_pos(&self) -> (int, int) {
         unsafe {
             let mut xpos = 0;
@@ -910,13 +866,11 @@ impl Window {
     }
 
     /// Wrapper for `glfwSetWindowPos`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_pos(&self, xpos: int, ypos: int) {
         unsafe { ffi::glfwSetWindowPos(self.ptr, xpos as c_int, ypos as c_int); }
     }
 
     /// Wrapper for `glfwGetWindowSize`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_size(&self) -> (int, int) {
         unsafe {
             let mut width = 0;
@@ -927,13 +881,11 @@ impl Window {
     }
 
     /// Wrapper for `glfwSetWindowSize`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_size(&self, width: int, height: int) {
         unsafe { ffi::glfwSetWindowSize(self.ptr, width as c_int, height as c_int); }
     }
 
     /// Wrapper for `glfwGetFramebufferSize`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_framebuffer_size(&self) -> (int, int) {
         unsafe {
             let mut width = 0;
@@ -944,25 +896,21 @@ impl Window {
     }
 
     /// Wrapper for `glfwIconifyWindow`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn iconify(&self) {
         unsafe { ffi::glfwIconifyWindow(self.ptr); }
     }
 
     /// Wrapper for `glfwRestoreWindow`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn restore(&self) {
         unsafe { ffi::glfwRestoreWindow(self.ptr); }
     }
 
     /// Wrapper for `glfwShowWindow`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn show(&self) {
         unsafe { ffi::glfwShowWindow(self.ptr); }
     }
 
     /// Wrapper for `glfwHideWindow`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn hide(&self) {
         unsafe { ffi::glfwHideWindow(self.ptr); }
     }
@@ -972,7 +920,6 @@ impl Window {
     /// # Returns
     ///
     /// The window mode; either glfw::FullScreen or glfw::Windowed
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_window_mode(&self) -> WindowMode {
         WindowMode::from_ptr(
             unsafe { ffi::glfwGetWindowMonitor(self.ptr) }
@@ -980,19 +927,16 @@ impl Window {
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `FOCUSED`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_focused(&self) -> bool {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::FOCUSED) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `ICONIFIED`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_iconified(&self) -> bool {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::ICONIFIED) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `CLIENT_API`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_client_api(&self) -> c_int {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::CLIENT_API) }
     }
@@ -1003,7 +947,6 @@ impl Window {
     /// # Returns
     ///
     /// The client API version of the window's context in a version struct.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_context_version(&self) -> Version {
         unsafe {
             Version {
@@ -1015,153 +958,137 @@ impl Window {
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `CONTEXT_ROBUSTNESS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_context_robustness(&self) -> c_int {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::CONTEXT_ROBUSTNESS) }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `OPENGL_FORWARD_COMPAT`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_opengl_forward_compat(&self) -> bool {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::OPENGL_FORWARD_COMPAT) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `OPENGL_DEBUG_CONTEXT`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_opengl_debug_context(&self) -> bool {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::OPENGL_DEBUG_CONTEXT) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `OPENGL_PROFILE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_opengl_profile(&self) -> c_int {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::OPENGL_PROFILE) }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `RESIZABLE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_resizable(&self) -> bool {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::RESIZABLE) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `VISIBLE`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_visible(&self) -> bool {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::VISIBLE) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwGetWindowAttrib` called with `DECORATED`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_decorated(&self) -> bool {
         unsafe { ffi::glfwGetWindowAttrib(self.ptr, ffi::DECORATED) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwSetWindowPosCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_pos_callback(&self, cbfun: WindowSizeFun) {
+    pub fn set_pos_callback<Cb: WindowPosCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetWindowPosCallback,
+                             cb_trait: WindowPosCallback,
                              callback: window_pos_callback,
-                             field:    pos_fun);
+                             field:    pos_callback);
     }
 
     /// Wrapper for `glfwSetWindowSizeCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_size_callback(&self, cbfun: WindowSizeFun) {
+    pub fn set_size_callback<Cb: WindowSizeCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetWindowSizeCallback,
+                             cb_trait: WindowSizeCallback,
                              callback: window_size_callback,
-                             field:    size_fun);
+                             field:    size_callback);
     }
 
     /// Wrapper for `glfwSetWindowCloseCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_close_callback(&self, cbfun: WindowCloseFun) {
+    pub fn set_close_callback<Cb: WindowCloseCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetWindowCloseCallback,
+                             cb_trait: WindowCloseCallback,
                              callback: window_close_callback,
-                             field:    close_fun);
+                             field:    close_callback);
     }
 
     /// Wrapper for `glfwSetWindowRefreshCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_refresh_callback(&self, cbfun: WindowRefreshFun) {
+    pub fn set_refresh_callback<Cb: WindowRefreshCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetWindowRefreshCallback,
+                             cb_trait: WindowRefreshCallback,
                              callback: window_refresh_callback,
-                             field:    refresh_fun);
+                             field:    refresh_callback);
     }
 
     /// Wrapper for `glfwSetWindowFocusCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_focus_callback(&self, cbfun: WindowFocusFun) {
+    pub fn set_focus_callback<Cb: WindowFocusCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetWindowFocusCallback,
+                             cb_trait: WindowFocusCallback,
                              callback: window_focus_callback,
-                             field:    focus_fun);
+                             field:    focus_callback);
     }
 
     /// Wrapper for `glfwSetWindowIconifyCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_iconify_callback(&self, cbfun: WindowIconifyFun) {
+    pub fn set_iconify_callback<Cb: WindowIconifyCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetWindowIconifyCallback,
+                             cb_trait: WindowIconifyCallback,
                              callback: window_iconify_callback,
-                             field:    iconify_fun);
+                             field:    iconify_callback);
     }
 
     /// Wrapper for `glfwSetFramebufferSizeCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_framebuffer_size_callback(&self, cbfun: FramebufferSizeFun) {
+    pub fn set_framebuffer_size_callback<Cb: FramebufferSizeCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetFramebufferSizeCallback,
+                             cb_trait: FramebufferSizeCallback,
                              callback: framebuffer_size_callback,
-                             field:    framebuffer_size_fun);
+                             field:    framebuffer_size_callback);
     }
 
     /// Wrapper for `glfwGetInputMode` called with `CURSOR`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_cursor_mode(&self) -> CursorMode {
         unsafe { cast::transmute(ffi::glfwGetInputMode(self.ptr, ffi::CURSOR)) }
     }
 
     /// Wrapper for `glfwSetInputMode` called with `CURSOR`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_cursor_mode(&self, mode: CursorMode) {
         unsafe { ffi::glfwSetInputMode(self.ptr, ffi::CURSOR, mode as c_int); }
     }
 
     /// Wrapper for `glfwGetInputMode` called with `STICKY_KEYS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn has_sticky_keys(&self) -> bool {
         unsafe { ffi::glfwGetInputMode(self.ptr, ffi::STICKY_KEYS) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwSetInputMode` called with `STICKY_KEYS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_sticky_keys(&self, value: bool) {
         unsafe { ffi::glfwSetInputMode(self.ptr, ffi::STICKY_KEYS, value as c_int); }
     }
 
     /// Wrapper for `glfwGetInputMode` called with `STICKY_MOUSE_BUTTONS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn has_sticky_mouse_buttons(&self) -> bool {
         unsafe { ffi::glfwGetInputMode(self.ptr, ffi::STICKY_MOUSE_BUTTONS) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwSetInputMode` called with `STICKY_MOUSE_BUTTONS`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_sticky_mouse_buttons(&self, value: bool) {
         unsafe { ffi::glfwSetInputMode(self.ptr, ffi::STICKY_MOUSE_BUTTONS, value as c_int); }
     }
 
     /// Wrapper for `glfwGetKey`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_key(&self, key: Key) -> Action {
         unsafe { cast::transmute(ffi::glfwGetKey(self.ptr, key as c_int)) }
     }
 
     /// Wrapper for `glfwGetMouseButton`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_mouse_button(&self, button: MouseButton) -> Action {
         unsafe { cast::transmute(ffi::glfwGetMouseButton(self.ptr, button as c_int)) }
     }
 
     /// Wrapper for `glfwGetCursorPos`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_cursor_pos(&self) -> (f64, f64) {
         unsafe {
             let mut xpos = 0.0;
@@ -1172,61 +1099,59 @@ impl Window {
     }
 
     /// Wrapper for `glfwSetCursorPos`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_cursor_pos(&self, xpos: f64, ypos: f64) {
         unsafe { ffi::glfwSetCursorPos(self.ptr, xpos as c_double, ypos as c_double); }
     }
 
     /// Wrapper for `glfwSetKeyCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_key_callback(&self, cbfun: KeyFun) {
+    pub fn set_key_callback<Cb: KeyCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetKeyCallback,
+                             cb_trait: KeyCallback,
                              callback: key_callback,
-                             field:    key_fun);
+                             field:    key_callback);
     }
 
     /// Wrapper for `glfwSetCharCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_char_callback(&self, cbfun: CharFun) {
+    pub fn set_char_callback<Cb: CharCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetCharCallback,
+                             cb_trait: CharCallback,
                              callback: char_callback,
-                             field:    char_fun);
+                             field:    char_callback);
     }
 
     /// Wrapper for `glfwSetMouseButtonCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_mouse_button_callback(&self, cbfun: MouseButtonFun) {
+    pub fn set_mouse_button_callback<Cb: MouseButtonCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetMouseButtonCallback,
+                             cb_trait: MouseButtonCallback,
                              callback: mouse_button_callback,
-                             field:    mouse_button_fun);
+                             field:    mouse_button_callback);
     }
 
     /// Wrapper for `glfwSetCursorPosCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_cursor_pos_callback(&self, cbfun: CursorPosFun) {
+    pub fn set_cursor_pos_callback<Cb: CursorPosCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetCursorPosCallback,
+                             cb_trait: CursorPosCallback,
                              callback: cursor_pos_callback,
-                             field:    cursor_pos_fun);
+                             field:    cursor_pos_callback);
     }
 
     /// Wrapper for `glfwSetCursorEnterCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_cursor_enter_callback(&self, cbfun: CursorEnterFun) {
+    pub fn set_cursor_enter_callback<Cb: CursorEnterCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetCursorEnterCallback,
+                             cb_trait: CursorEnterCallback,
                              callback: cursor_enter_callback,
-                             field:    cursor_enter_fun);
+                             field:    cursor_enter_callback);
     }
 
     /// Wrapper for `glfwSetScrollCallback`.
-    #[fixed_stack_segment] #[inline(never)]
-    pub fn set_scroll_callback(&self, cbfun: ScrollFun) {
+    pub fn set_scroll_callback<Cb: ScrollCallback + Send>(&self, callback: ~Cb) {
         set_window_callback!(setter:   glfwSetScrollCallback,
+                             cb_trait: ScrollCallback,
                              callback: scroll_callback,
-                             field:    scroll_fun);
+                             field:    scroll_callback);
     }
 
     /// Wrapper for `glfwGetClipboardString`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn set_clipboard_string(&self, string: &str) {
         unsafe {
             do string.with_c_str |string| {
@@ -1236,7 +1161,6 @@ impl Window {
     }
 
     /// Wrapper for `glfwGetClipboardString`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_clipboard_string(&self) -> ~str {
         unsafe { str::raw::from_c_str(ffi::glfwGetClipboardString(self.ptr)) }
     }
@@ -1247,62 +1171,53 @@ impl Window {
     }
 
     /// Wrapper for `glfwGetCurrentContext`
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_current_context(&self) -> bool {
         self.ptr == unsafe { ffi::glfwGetCurrentContext() }
     }
 
     /// Wrapper for `glfwSwapBuffers`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn swap_buffers(&self) {
         unsafe { ffi::glfwSwapBuffers(self.ptr); }
     }
 
     /// Wrapper for `glfwGetWin32Window`
     #[cfg(target_os="win32")]
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_win32_window(&self) -> *c_void {
         unsafe { ffi::glfwGetWin32Window(self.ptr) }
     }
 
     /// Wrapper for `glfwGetWGLContext`
     #[cfg(target_os="win32")]
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_wgl_context(&self) -> *c_void {
         unsafe { ffi::glfwGetWGLContext(self.ptr) }
     }
 
     /// Wrapper for `glfwGetCocoaWindow`
     #[cfg(target_os="macos")]
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_cocoa_window(&self) -> *c_void {
         unsafe { ffi::glfwGetCocoaWindow(self.ptr) }
     }
 
     /// Wrapper for `glfwGetNSGLContext`
     #[cfg(target_os="macos")]
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_nsgl_context(&self) -> *c_void {
         unsafe { ffi::glfwGetNSGLContext(self.ptr) }
     }
 
     /// Wrapper for `glfwGetX11Window`
     #[cfg(target_os="linux")]
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_x11_window(&self) -> *c_void {
         unsafe { ffi::glfwGetX11Window(self.ptr) }
     }
 
     /// Wrapper for `glfwGetGLXContext`
     #[cfg(target_os="linux")]
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_glx_context(&self) -> *c_void {
         unsafe { ffi::glfwGetGLXContext(self.ptr) }
     }
 }
 
 /// Wrapper for `glfwMakeContextCurrent`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn make_context_current(context: Option<&Window>) {
     match context {
         Some(window) => unsafe { ffi::glfwMakeContextCurrent(window.ptr) },
@@ -1312,7 +1227,6 @@ pub fn make_context_current(context: Option<&Window>) {
 
 /// Wrapper for `glfwGetX11Display`
 #[cfg(target_os="linux")]
-#[fixed_stack_segment] #[inline(never)]
 pub fn get_x11_display() -> *c_void {
     unsafe { ffi::glfwGetX11Display() }
 }
@@ -1322,24 +1236,21 @@ impl Drop for Window {
     /// Closes the window and removes all associated callbacks.
     ///
     /// Wrapper for `glfwDestroyWindow`.
-    #[fixed_stack_segment] #[inline(never)]
     fn drop(&mut self) {
         if !self.is_shared {
             unsafe { ffi::glfwDestroyWindow(self.ptr); }
         }
 
-        unsafe { self.free_fns() }
+        unsafe { self.free_callbacks() }
     }
 }
 
 /// Wrapper for `glfwPollEvents`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn poll_events() {
     unsafe { ffi::glfwPollEvents(); }
 }
 
 /// Wrapper for `glfwWaitEvents`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn wait_events() {
     unsafe { ffi::glfwWaitEvents(); }
 }
@@ -1367,13 +1278,11 @@ pub enum Joystick {
 
 impl Joystick {
     /// Wrapper for `glfwJoystickPresent`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn is_present(&self) -> bool {
         unsafe { ffi::glfwJoystickPresent(*self as c_int) == ffi::TRUE }
     }
 
     /// Wrapper for `glfwGetJoystickAxes`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_axes(&self) -> ~[f32] {
         unsafe {
             let mut count = 0;
@@ -1383,7 +1292,6 @@ impl Joystick {
     }
 
     /// Wrapper for `glfwGetJoystickButtons`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_buttons(&self) -> ~[c_int] {
         unsafe {
             let mut count = 0;
@@ -1393,32 +1301,27 @@ impl Joystick {
     }
 
     /// Wrapper for `glfwGetJoystickName`.
-    #[fixed_stack_segment] #[inline(never)]
     pub fn get_name(&self) -> ~str {
         unsafe { str::raw::from_c_str(ffi::glfwGetJoystickName(*self as c_int)) }
     }
 }
 
 /// Wrapper for `glfwGetTime`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn get_time() -> f64 {
     unsafe { ffi::glfwGetTime() as f64 }
 }
 
 /// Wrapper for `glfwSetTime`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn set_time(time: f64) {
     unsafe { ffi::glfwSetTime(time as c_double); }
 }
 
 /// Wrapper for `glfwSwapInterval`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn set_swap_interval(interval: int) {
     unsafe { ffi::glfwSwapInterval(interval as c_int); }
 }
 
 /// Wrapper for `glfwExtensionSupported`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn extension_supported(extension: &str) -> bool {
     unsafe {
         do extension.with_c_str |extension| {
@@ -1428,7 +1331,6 @@ pub fn extension_supported(extension: &str) -> bool {
 }
 
 /// Wrapper for `glfwGetProcAddress`.
-#[fixed_stack_segment] #[inline(never)]
 pub fn get_proc_address(procname: &str) -> Option<GLProc> {
     unsafe {
         do procname.with_c_str |procname| {


Test patch: