summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Window.zig90
1 files changed, 49 insertions, 41 deletions
diff --git a/src/Window.zig b/src/Window.zig
index d947977..f72ed71 100644
--- a/src/Window.zig
+++ b/src/Window.zig
@@ -23,14 +23,49 @@ const checkError = gfz.checkError;
 const getError = gfz.getError;
 const gfz = @import("gfz.zig");
 
-const Self = @This();
 pub const Impl = GLFWwindow;
 pimpl: *Impl,
 
-const Options = struct {
-    fullscreen: ?Monitor = null,
-    share: ?Self = null,
-};
+const Self = @This();
+const CursorPosFun = fn (window: Self, xpos: f64, ypos: f64) void;
+const KeyFun = fn (window: Self, key: c_int, scancode: c_int,
+                   action: c_int, mods: c_int) void;
+const MouseButtonFun = fn (window: Self, button: c_int,
+                           action: c_int, mods: c_int) void;
+const SizeFun = fn (window: Self, width: c_int, height: c_int) void;
+
+/// Convert given function to GLFW callback.
+fn fnCast(comptime DestType: type, comptime fun: anytype) DestType {
+    return switch (DestType) {
+        GLFWcursorposfun => struct {
+            pub fn callback(window: ?*Impl, xpos: f64,
+                            ypos: f64) callconv(.C) void {
+                fun(@fieldParentPtr(Self, "pimpl", &window.?).*, xpos, ypos);
+            }
+        },
+        GLFWkeyfun => struct {
+            pub fn callback(window: ?*Impl, key: c_int, scancode: c_int,
+                            action: c_int, mods: c_int) callconv(.C) void {
+                fun(@fieldParentPtr(Self, "pimpl", &window.?).*,
+                    key, scancode, action, mods);
+            }
+        },
+        GLFWmousebuttonfun => struct {
+            pub fn callback(window: ?*Impl, button: c_int,
+                            action: c_int, mods: c_int) callconv(.C) void {
+                fun(@fieldParentPtr(Self, "pimpl", &window.?).*,
+                    button, action, mods);
+            }
+        },
+        GLFWwindowsizefun => struct {
+            pub fn callback(window: ?*Impl, width: c_int,
+                            height: c_int) callconv(.C) void {
+                fun(@fieldParentPtr(Self, "pimpl", &window.?).*, width, height);
+            }
+        },
+        else => unreachable,
+    }.callback;
+}
 
 pub const Hints = struct {
     pub const dont_care = GLFW_DONT_CARE;
@@ -117,6 +152,11 @@ fn setHint(hint: c_int, value: anytype) Error!void {
     try checkError();
 }
 
+const Options = struct {
+    fullscreen: ?Monitor = null,
+    share: ?Self = null,
+};
+
 /// Create a window and its associated context.
 pub fn create(width: c_int, height: c_int, title: [:0]const u8,
               options: Options, hints: Hints) Error!Self {
@@ -260,16 +300,9 @@ pub fn setCursorPos(self: Self, xpos: f64, ypos: f64) Error!void {
     try checkError();
 }
 
-const CursorPosFun = fn (window: Self, xpos: f64, ypos: f64) void;
-
 /// Set the cursor position callback.
 pub fn setCursorPosCallback(self: Self, comptime fun: CursorPosFun) Error!void {
-    _ = glfwSetCursorPosCallback(self.pimpl, struct {
-        pub fn callback(window: ?*Impl,
-                        xpos: f64, ypos: f64) callconv(.C) void {
-            fun(@fieldParentPtr(Self, "pimpl", &window.?).*, xpos, ypos);
-        }
-    }.callback);
+    _ = glfwSetCursorPosCallback(self.pimpl, fnCast(GLFWcursorposfun, fun));
     try checkError();
 }
 
@@ -285,19 +318,10 @@ pub fn getMouseButton(self: Self, button: c_int) Error!State {
     return @intToEnum(State, state);
 }
 
-const MouseButtonFun = fn (window: Self, button: c_int,
-                           action: c_int, mods: c_int) void;
-
 /// Set the mouse button callback.
 pub fn setMouseButtonCallback(self: Self,
                               comptime fun: MouseButtonFun) Error!void {
-    _ = glfwSetMouseButtonCallback(self.pimpl, struct {
-        pub fn callback(window: ?*Impl, button: c_int,
-                        action: c_int, mods: c_int) callconv(.C) void {
-            fun(@fieldParentPtr(Self, "pimpl", &window.?).*,
-                button, action, mods);
-        }
-    }.callback);
+    _ = glfwSetMouseButtonCallback(self.pimpl, fnCast(GLFWmousebuttonfun, fun));
     try checkError();
 }
 
@@ -308,18 +332,9 @@ pub fn getKey(self: Self, key: c_int) Error!State {
     return @intToEnum(State, state);
 }
 
-const KeyFun = fn (window: Self, key: c_int, scancode: c_int,
-                   action: c_int, mods: c_int) void;
-
 /// Set the key callback.
 pub fn setKeyCallback(self: Self, comptime fun: KeyFun) Error!void {
-    _ = glfwSetKeyCallback(self.pimpl, struct {
-        pub fn callback(window: ?*Impl, key: c_int, scancode: c_int,
-                        action: c_int, mods: c_int) callconv(.C) void {
-            fun(@fieldParentPtr(Self, "pimpl", &window.?).*,
-                key, scancode, action, mods);
-        }
-    }.callback);
+    _ = glfwSetKeyCallback(self.pimpl, fnCast(GLFWkeyfun, fun));
     try checkError();
 }
 
@@ -329,15 +344,8 @@ pub fn setSize(self: Self, width: c_int, height: c_int) Error!void {
     try checkError();
 }
 
-const SizeFun = fn (window: Self, width: c_int, height: c_int) void;
-
 /// Set the size callback.
 pub fn setSizeCallback(self: Self, comptime fun: SizeFun) Error!void {
-    _ = glfwSetWindowSizeCallback(self.pimpl, struct {
-        pub fn callback(window: ?*Impl,
-                        width: c_int, height: c_int) callconv(.C) void {
-            fun(@fieldParentPtr(Self, "pimpl", &window.?).*, width, height);
-        }
-    }.callback);
+    _ = glfwSetWindowSizeCallback(self.pimpl, fnCast(GLFWwindowsizefun, fun));
     try checkError();
 }