glfw.zig (3446B)
1 const builtin = @import("builtin"); 2 3 const c = @cImport({ 4 @cInclude("glfw3.h"); 5 if (builtin.target.os.tag == .linux) { 6 @cDefine("GLFW_EXPOSE_NATIVE_X11", "1"); 7 } else if (builtin.target.os.tag == .macos) { 8 @cDefine("GLFW_EXPOSE_NATIVE_COCOA", "1"); 9 } 10 11 @cInclude("glfw3native.h"); 12 }); 13 14 const Error = error{ 15 NotInitialized, 16 NoCurrentContext, 17 InvalidEnum, 18 InvalidValue, 19 OutOfMemory, 20 APIUnavailable, 21 VersionUnavailable, 22 PlatformError, 23 FormatUnavailable, 24 NoWindowContext, 25 Unknown, 26 }; 27 28 const Monitor = opaque {}; 29 30 pub const Window = opaque { 31 pub fn create( 32 width: c_int, 33 height: c_int, 34 title: [*:0]const u8, 35 monitor: ?*Monitor, 36 share: ?*Window, 37 ) !*Window { 38 const window = c.glfwCreateWindow( 39 width, 40 height, 41 title, 42 @ptrCast(monitor), 43 @ptrCast(share), 44 ); 45 try getError(); 46 return @ptrCast(window.?); 47 } 48 49 pub fn destroy(window: *Window) void { 50 c.glfwDestroyWindow(@ptrCast(window)); 51 } 52 53 pub fn shouldClose(window: *Window) bool { 54 return c.glfwWindowShouldClose(@ptrCast(window)) == c.GLFW_TRUE; 55 } 56 }; 57 58 pub fn pollEvents() void { 59 c.glfwPollEvents(); 60 } 61 62 fn getError() !void { 63 const error_code = c.glfwGetError(null); 64 return switch (error_code) { 65 c.GLFW_NO_ERROR => {}, 66 c.GLFW_NOT_INITIALIZED => Error.NotInitialized, 67 c.GLFW_NO_CURRENT_CONTEXT => Error.NoCurrentContext, 68 c.GLFW_INVALID_ENUM => Error.InvalidEnum, 69 c.GLFW_INVALID_VALUE => Error.InvalidValue, 70 c.GLFW_OUT_OF_MEMORY => Error.OutOfMemory, 71 c.GLFW_API_UNAVAILABLE => Error.APIUnavailable, 72 c.GLFW_VERSION_UNAVAILABLE => Error.VersionUnavailable, 73 c.GLFW_PLATFORM_ERROR => Error.PlatformError, 74 c.GLFW_FORMAT_UNAVAILABLE => Error.FormatUnavailable, 75 c.GLFW_NO_WINDOW_CONTEXT => Error.NoWindowContext, 76 else => unreachable, 77 }; 78 } 79 80 pub fn init() !void { 81 const status = c.glfwInit(); 82 return switch (status) { 83 c.GLFW_TRUE => {}, 84 c.GLFW_FALSE => getError(), 85 else => unreachable, 86 }; 87 } 88 89 pub fn terminate() void { 90 c.glfwTerminate(); 91 } 92 93 const Hint = enum(u32) { 94 client_api = 0x00022001, 95 }; 96 97 pub const ClientApi = enum(u32) { 98 no_api = 0x00000000, 99 opengl_api = 0x00030001, 100 opengl_es_api = 0x00030002, 101 }; 102 103 pub fn windowHint(hint: Hint, value: anytype) void { 104 c.glfwWindowHint( 105 @intCast(@intFromEnum(hint)), 106 @intCast(@intFromEnum(value)), 107 ); 108 } 109 110 pub const native = switch (builtin.target.os.tag) { 111 .linux => struct { 112 const X11Display = opaque {}; 113 const X11Window = u64; 114 115 pub fn getX11Display() !*X11Display { 116 const display = c.glfwGetX11Display(); 117 if (display == null) { 118 try getError(); 119 } 120 return @ptrCast(display.?); 121 } 122 123 pub fn getX11Window(window: *Window) !X11Window { 124 return @intCast(c.glfwGetX11Window(@ptrCast(window))); 125 } 126 }, 127 .macos => struct { 128 const NSWindow = opaque {}; 129 130 pub fn getCocoaWindow(window: *Window) !*NSWindow { 131 return @ptrCast(c.glfwGetCocoaWindow(@ptrCast(window))); 132 } 133 134 pub const getMetalLayer = @import("metal.zig").getMetalLayer; 135 136 }, 137 else => error.UnsupportedOS, 138 };