From 3939e07ac6f8f3c6950d6cc9d907101c7fca8e34 Mon Sep 17 00:00:00 2001 From: Chris Heyes <22148308+hazeycode@users.noreply.github.com> Date: Thu, 21 Nov 2024 01:17:34 +0000 Subject: [PATCH] API revisions - Support flat vanilla API aswell as encapulated, objecty API - Fix some incorrect types - More error handling - Add some missing bindings (closes #1, closes #3, closes #4) --- README.md | 4 + src/zglfw.zig | 854 +++++++++++++++++++++++++------------------------- 2 files changed, 434 insertions(+), 424 deletions(-) diff --git a/README.md b/README.md index d48844e..3b796f7 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,10 @@ pub fn main() !void { try glfw.init(); defer glfw.terminate(); + const window = try glfw.createWindow(600, 600, "zig-gamedev: minimal_glfw_gl", null); + defer glfw.destroyWindow(window); + + // or, using the equivilent, encapsulated, "objecty" API: const window = try glfw.Window.create(600, 600, "zig-gamedev: minimal_glfw_gl", null); defer window.destroy(); diff --git a/src/zglfw.zig b/src/zglfw.zig index 5bf589a..3d57e41 100644 --- a/src/zglfw.zig +++ b/src/zglfw.zig @@ -8,12 +8,18 @@ comptime { _ = std.testing.refAllDeclsRecursive(@This()); } +const zglfw = @This(); + //-------------------------------------------------------------------------------------------------- // // Misc // //-------------------------------------------------------------------------------------------------- -pub const InitHint = enum(i32) { +pub const Bool = c_int; +pub const TRUE: Bool = 1; +pub const FALSE: Bool = 0; + +pub const InitHint = enum(c_int) { joystick_hat_buttons = 0x00050001, angle_platform_type = 0x00050002, platform = 0x00050003, @@ -22,18 +28,26 @@ pub const InitHint = enum(i32) { x11_xcb_vulkan_surface = 0x00052001, wayland_libdecor = 0x00053001, - pub fn set(hint: InitHint, value: bool) void { - glfwInitHint(hint, @intFromBool(value)); - } - extern fn glfwInitHint(hint: InitHint, value: i32) void; + pub const set = initHint; }; +pub fn initHint(hint: InitHint, value: anytype) Error!void { + glfwInitHint(hint, switch (@typeInfo(@TypeOf(value))) { + .int => value, + .@"enum" => @intFromEnum(value), + .bool => @intFromBool(value), + else => @compileError("Invalid hint value type."), + }); + try maybeError(); +} +extern fn glfwInitHint(hint: InitHint, value: c_int) void; pub fn init() Error!void { - if (glfwInit() != 0) return; + if (glfwInit() == TRUE) { + return; + } try maybeError(); - unreachable; } -extern fn glfwInit() i32; +extern fn glfwInit() Bool; /// `pub fn terminate() void` pub const terminate = glfwTerminate; @@ -52,9 +66,9 @@ pub const waitEventsTimeout = glfwWaitEventsTimeout; extern fn glfwWaitEventsTimeout(timeout: f64) void; pub fn isVulkanSupported() bool { - return if (glfwVulkanSupported() == 0) false else true; + return glfwVulkanSupported() == TRUE; } -extern fn glfwVulkanSupported() i32; +extern fn glfwVulkanSupported() Bool; pub fn getRequiredInstanceExtensions() Error![][*:0]const u8 { var count: u32 = 0; @@ -74,6 +88,8 @@ extern fn glfwGetTime() f64; pub const setTime = glfwSetTime; extern fn glfwSetTime(time: f64) void; +pub const ErrorCode = c_int; + pub const Error = error{ NotInitialized, NoCurrentContext, @@ -92,7 +108,7 @@ pub const Error = error{ Unknown, }; -fn convertError(e: i32) Error!void { +fn convertError(e: ErrorCode) Error!void { return switch (e) { 0 => {}, 0x00010001 => Error.NotInitialized, @@ -123,17 +139,15 @@ pub fn maybeErrorString(str: *?[:0]const u8) Error!void { return err; }; } -extern fn glfwGetError(description: ?*?[*:0]const u8) i32; -/// `pub fn setErrorCallback(callback: ?ErrorFn) ?ErrorFn` +pub const getError = glfwGetError; +extern fn glfwGetError(out_desc: ?*?[*:0]const u8) ErrorCode; + pub const setErrorCallback = glfwSetErrorCallback; -extern fn glfwSetErrorCallback(callback: ?ErrorFn) ?ErrorFn; -pub const ErrorFn = *const fn ( - error_code: i32, - description: *?[:0]const u8, -) callconv(.C) void; +extern fn glfwSetErrorCallback(?ErrorFn) ?ErrorFn; +pub const ErrorFn = *const fn (ErrorCode, desc: *?[:0]const u8) callconv(.C) void; -pub const InputMode = enum(i32) { +pub const InputMode = enum(c_int) { cursor = 0x00033001, sticky_keys = 0x00033002, sticky_mouse_buttons = 0x00033003, @@ -142,9 +156,9 @@ pub const InputMode = enum(i32) { }; pub fn rawMouseMotionSupported() bool { - return glfwRawMouseMotionSupported() == 1; + return glfwRawMouseMotionSupported() == TRUE; } -extern fn glfwRawMouseMotionSupported() i32; +extern fn glfwRawMouseMotionSupported() c_int; pub const makeContextCurrent = glfwMakeContextCurrent; extern fn glfwMakeContextCurrent(window: ?*Window) void; @@ -153,7 +167,7 @@ pub const getCurrentContext = glfwGetCurrentContext; extern fn glfwGetCurrentContext() ?*Window; pub const swapInterval = glfwSwapInterval; -extern fn glfwSwapInterval(interval: i32) void; +extern fn glfwSwapInterval(interval: c_int) void; pub const GlProc = *const anyopaque; @@ -167,13 +181,13 @@ extern fn glfwGetProcAddress(procname: [*:0]const u8) ?GlProc; // Keyboard/Mouse // //-------------------------------------------------------------------------------------------------- -pub const Action = enum(i32) { +pub const Action = enum(c_int) { release, press, repeat, }; -pub const MouseButton = enum(i32) { +pub const MouseButton = enum(c_int) { left, right, middle, @@ -184,7 +198,7 @@ pub const MouseButton = enum(i32) { eight, }; -pub const Key = enum(i32) { +pub const Key = enum(c_int) { unknown = -1, space = 32, @@ -310,7 +324,7 @@ pub const Key = enum(i32) { menu = 348, }; -pub const Mods = packed struct(i32) { +pub const Mods = packed struct(c_int) { shift: bool = false, control: bool = false, alt: bool = false, @@ -325,7 +339,7 @@ pub const Mods = packed struct(i32) { // //-------------------------------------------------------------------------------------------------- pub const Cursor = opaque { - pub const Shape = enum(i32) { + pub const Shape = enum(c_int) { arrow = 0x00036001, ibeam = 0x00036002, crosshair = 0x00036003, @@ -340,106 +354,112 @@ pub const Cursor = opaque { not_allowed = 0x0003600A, }; - pub const Mode = enum(i32) { + pub const Mode = enum(c_int) { normal = 0x00034001, hidden = 0x00034002, disabled = 0x00034003, captured = 0x00034004, }; - /// `pub fn destroy(cursor: *Cursor) void` - pub const destroy = glfwDestroyCursor; - extern fn glfwDestroyCursor(cursor: *Cursor) void; - - pub fn create(width: i32, height: i32, pixels: []const u8, xhot: i32, yhot: i32) Error!*Cursor { - assert(pixels.len == 4 * width * height); - if (glfwCreateCursor(&.{ - .width = width, - .height = height, - .pixels = @constCast(pixels.ptr), - }, xhot, yhot)) |ptr| return ptr; - try maybeError(); - unreachable; - } - extern fn glfwCreateCursor(image: *const Image, xhot: c_int, yhot: c_int) ?*Cursor; - - pub fn createStandard(shape: Shape) Error!*Cursor { - if (glfwCreateStandardCursor(shape)) |ptr| return ptr; - try maybeError(); - unreachable; - } - extern fn glfwCreateStandardCursor(shape: Shape) ?*Cursor; + pub const create = createCursor; + pub const createStandard = createStandardCursor; + pub const destroy = destroyCursor; }; + +pub fn createCursor(width: i32, height: i32, pixels: []const u8, xhot: i32, yhot: i32) Error!*Cursor { + assert(pixels.len == 4 * width * height); + const image = Image{ + .width = width, + .height = height, + .pixels = @constCast(pixels.ptr), + }; + if (glfwCreateCursor(&image, xhot, yhot)) |ptr| return ptr; + try maybeError(); +} +extern fn glfwCreateCursor(image: *const Image, xhot: c_int, yhot: c_int) ?*Cursor; + +pub fn createStandardCursor(shape: Cursor.Shape) Error!*Cursor { + if (glfwCreateStandardCursor(shape)) |ptr| return ptr; + try maybeError(); +} +extern fn glfwCreateStandardCursor(shape: Cursor.Shape) ?*Cursor; + +pub const destroyCursor = glfwDestroyCursor; +extern fn glfwDestroyCursor(cursor: *Cursor) void; + //-------------------------------------------------------------------------------------------------- // // Joystick // //-------------------------------------------------------------------------------------------------- -pub const Joystick = struct { - jid: Id, - - pub const Id = u4; +pub const Joystick = enum(c_int) { + _, - pub const maximum_supported = std.math.maxInt(Id) + 1; + pub const maximum_supported = 16; pub const ButtonAction = enum(u8) { release = 0, press = 1, }; - pub fn getGuid(self: Joystick) [:0]const u8 { - return std.mem.span(glfwGetJoystickGUID(@as(i32, @intCast(self.jid)))); - } - extern fn glfwGetJoystickGUID(jid: i32) [*:0]const u8; + pub const isPresent = joystickPresent; + pub const getGuid = getJoystickGUID; + pub const getAxes = getJoystickAxes; + pub const getButtons = getJoystickButtons; + pub const isGamepad = joystickIsGamepad; + pub const asGamepad = joystickAsGamepad; +}; - pub fn getAxes(self: Joystick) []const f32 { - var count: i32 = undefined; - const state = glfwGetJoystickAxes(@as(i32, @intCast(self.jid)), &count); - if (count == 0) { - return @as([*]const f32, undefined)[0..0]; - } - return state[0..@as(usize, @intCast(count))]; - } - extern fn glfwGetJoystickAxes(jid: i32, count: *i32) [*]const f32; +pub fn joystickPresent(joystick: Joystick) bool { + return glfwJoystickPresent(joystick) == TRUE; +} +extern fn glfwJoystickPresent(Joystick) Bool; - pub fn getButtons(self: Joystick) []const ButtonAction { - var count: i32 = undefined; - const state = glfwGetJoystickButtons(@as(i32, @intCast(self.jid)), &count); - if (count == 0) { - return @as([*]const ButtonAction, undefined)[0..0]; - } - return @as([]const ButtonAction, @ptrCast(state[0..@as(usize, @intCast(count))])); +pub fn getJoystickGUID(joystick: Joystick) Error![:0]const u8 { + if (glfwGetJoystickGUID(joystick)) |guid| { + return std.mem.span(guid); } - extern fn glfwGetJoystickButtons(jid: i32, count: *i32) [*]const u8; + try maybeError(); + return ""; +} +extern fn glfwGetJoystickGUID(Joystick) ?[*:0]const u8; - fn isGamepad(self: Joystick) bool { - return glfwJoystickIsGamepad(@as(i32, @intCast(self.jid))) == @intFromBool(true); +pub fn getJoystickAxes(joystick: Joystick) Error![]const f32 { + var count: c_int = 0; + if (glfwGetJoystickAxes(joystick, &count)) |state| { + return state[0..@as(usize, @intCast(count))]; } + try maybeError(); + return @as([*]const f32, undefined)[0..0]; +} +extern fn glfwGetJoystickAxes(Joystick, count: *c_int) ?[*]const f32; - pub fn asGamepad(self: Joystick) ?Gamepad { - return if (self.isGamepad()) .{ .jid = self.jid } else null; +pub fn getJoystickButtons(joystick: Joystick) Error![]const Joystick.ButtonAction { + var count: c_int = 0; + if (glfwGetJoystickButtons(joystick, &count)) |state| { + return @as([]const Joystick.ButtonAction, @ptrCast(state[0..@as(usize, @intCast(count))])); } - extern fn glfwJoystickIsGamepad(jid: i32) i32; + try maybeError(); + return @as([*]const Joystick.ButtonAction, undefined)[0..0]; +} +extern fn glfwGetJoystickButtons(Joystick, count: *c_int) ?[*]const u8; - pub fn isPresent(jid: Id) bool { - return glfwJoystickPresent(@as(i32, @intCast(jid))) == @intFromBool(true); - } - extern fn glfwJoystickPresent(jid: i32) i32; +pub fn joystickIsGamepad(joystick: Joystick) bool { + return glfwJoystickIsGamepad(joystick) == TRUE; +} +extern fn glfwJoystickIsGamepad(Joystick) Bool; + +pub fn joystickAsGamepad(joystick: Joystick) ?Gamepad { + return if (joystickIsGamepad(joystick)) @enumFromInt(@intFromEnum(joystick)) else null; +} - pub fn get(jid: Id) ?Joystick { - if (!isPresent(jid)) { - return null; - } - return .{ .jid = jid }; - } -}; //-------------------------------------------------------------------------------------------------- // // Gamepad // //-------------------------------------------------------------------------------------------------- -pub const Gamepad = struct { - jid: Joystick.Id, +pub const Gamepad = enum(c_int) { + _, pub const Axis = enum(u8) { left_x = 0, @@ -449,7 +469,7 @@ pub const Gamepad = struct { left_trigger = 4, right_trigger = 5, - const last = Axis.right_trigger; + pub const count = std.meta.fields(@This()).len; }; pub const Button = enum(u8) { @@ -469,12 +489,12 @@ pub const Gamepad = struct { dpad_down = 13, dpad_left = 14, - const last = Button.dpad_left; + pub const count = std.meta.fields(@This()).len; - const cross = Button.a; - const circle = Button.b; - const square = Button.x; - const triangle = Button.y; + pub const cross = Button.a; + pub const circle = Button.b; + pub const square = Button.x; + pub const triangle = Button.y; }; pub const State = extern struct { @@ -485,82 +505,96 @@ pub const Gamepad = struct { assert(@offsetOf(c.GLFWgamepadstate, field_name) == @offsetOf(State, field_name)); } } - buttons: [15]Joystick.ButtonAction, - axes: [6]f32, + buttons: [Button.count]Joystick.ButtonAction = .{Joystick.ButtonAction.release} ** Button.count, + axes: [Axis.count]f32 = .{@as(f32, 0)} ** Axis.count, }; - pub fn getName(self: Gamepad) [:0]const u8 { - return std.mem.span(glfwGetGamepadName(@as(i32, @intCast(self.jid)))); - } - extern fn glfwGetGamepadName(jid: i32) [*:0]const u8; + pub const getName = getGamepadName; + pub const getState = getGamepadState; + pub const updateMappings = updateGamepadMappings; +}; + +pub fn getGamepadName(gamepad: Gamepad) [:0]const u8 { + return std.mem.span(glfwGetGamepadName(gamepad)); +} +extern fn glfwGetGamepadName(Gamepad) [*:0]const u8; - pub fn getState(self: Gamepad) State { - var state: State = undefined; - _ = glfwGetGamepadState(@as(i32, @intCast(self.jid)), &state); - // return value of glfwGetGamepadState is ignored as - // it is expected this is guarded by glfwJoystickIsGamepad +pub fn getGamepadState(gamepad: Gamepad) Error!Gamepad.State { + var state: Gamepad.State = undefined; + if (glfwGetGamepadState(gamepad, &state) == TRUE) { return state; } - extern fn glfwGetGamepadState(jid: i32, state: *Gamepad.State) i32; + try maybeError(); + return .{}; +} +extern fn glfwGetGamepadState(Gamepad, *Gamepad.State) c_int; + +pub fn updateGamepadMappings(mappings: [:0]const u8) bool { + return glfwUpdateGamepadMappings(mappings) == TRUE; +} +extern fn glfwUpdateGamepadMappings(mappings: [*:0]const u8) c_int; - pub fn updateMappings(mappings: [:0]const u8) bool { - return glfwUpdateGamepadMappings(mappings) == @intFromBool(true); - } - extern fn glfwUpdateGamepadMappings(mappings: [*:0]const u8) i32; -}; //-------------------------------------------------------------------------------------------------- // // Monitor // //-------------------------------------------------------------------------------------------------- pub const Monitor = opaque { - pub fn getPos(monitor: *Monitor) [2]i32 { + pub const getPrimary = zglfw.getPrimaryMonitor; + pub const getAll = zglfw.getMonitors; + pub const getName = zglfw.getMonitorName; + pub const getVideoMode = zglfw.getVideoMode; + pub const getVideoModes = zglfw.getVideoModes; + + pub fn getPos(self: Monitor) []f32 { var xpos: i32 = 0; var ypos: i32 = 0; - glfwGetMonitorPos(monitor, &xpos, &ypos); + getMonitorPos(self, &xpos, &ypos); return .{ xpos, ypos }; } - extern fn glfwGetMonitorPos(monitor: *Monitor, xpos: *i32, ypos: *i32) void; +}; - /// `pub fn getPrimary() ?*Monitor` - pub const getPrimary = glfwGetPrimaryMonitor; - extern fn glfwGetPrimaryMonitor() ?*Monitor; +pub const getPrimaryMonitor = glfwGetPrimaryMonitor; +extern fn glfwGetPrimaryMonitor() ?*Monitor; - pub fn getAll() ?[]*Monitor { - var count: i32 = 0; - if (glfwGetMonitors(&count)) |monitors| { - return monitors[0..@as(usize, @intCast(count))]; - } - return null; +pub fn getMonitors() []*Monitor { + var count: c_int = 0; + if (glfwGetMonitors(&count)) |monitors| { + return monitors[0..@as(usize, @intCast(count))]; } - extern fn glfwGetMonitors(count: *i32) ?[*]*Monitor; + return @as([*]*Monitor, undefined)[0..0]; +} +extern fn glfwGetMonitors(count: *c_int) ?[*]*Monitor; - pub fn getName(monitor: *Monitor) Error![*:0]const u8 { - if (glfwGetMonitorName(monitor)) |name| { - return name; - } - try maybeError(); - unreachable; +pub const getMonitorPos = glfwGetMonitorPos; +extern fn glfwGetMonitorPos(*Monitor, xpos: ?*c_int, ypos: ?*c_int) void; + +pub fn getMonitorName(monitor: *Monitor) Error![]const u8 { + if (glfwGetMonitorName(monitor)) |name| { + return std.mem.span(name); } - extern fn glfwGetMonitorName(monitor: *Monitor) ?[*:0]const u8; + try maybeError(); + return ""; +} +extern fn glfwGetMonitorName(monitor: *Monitor) ?[*:0]const u8; - pub fn getVideoMode(monitor: *Monitor) Error!*VideoMode { - if (glfwGetVideoMode(monitor)) |video_mode| return video_mode; - try maybeError(); - unreachable; +pub fn getVideoMode(monitor: *Monitor) Error!*VideoMode { + if (glfwGetVideoMode(monitor)) |video_mode| { + return video_mode; } - extern fn glfwGetVideoMode(monitor: *Monitor) ?*VideoMode; + try maybeError(); +} +extern fn glfwGetVideoMode(*Monitor) ?*VideoMode; - pub fn getVideoModes(monitor: *Monitor) Error![]VideoMode { - var count: i32 = 0; - if (glfwGetVideoModes(monitor, &count)) |video_modes| { - return video_modes[0..@as(usize, @intCast(count))]; - } - try maybeError(); - unreachable; +pub fn getVideoModes(monitor: *Monitor) Error![]VideoMode { + var count: c_int = 0; + if (glfwGetVideoModes(monitor, &count)) |video_modes| { + return video_modes[0..@as(usize, @intCast(count))]; } - extern fn glfwGetVideoModes(monitor: *Monitor, count: *i32) ?[*]VideoMode; -}; + try maybeError(); + unreachable; +} +extern fn glfwGetVideoModes(*Monitor, count: *c_int) ?[*]VideoMode; pub const VideoMode = extern struct { comptime { @@ -601,7 +635,7 @@ pub const Image = extern struct { // //-------------------------------------------------------------------------------------------------- pub const Window = opaque { - pub const Attribute = enum(i32) { + pub const Attribute = enum(c_int) { focused = 0x00020001, iconified = 0x00020002, resizable = 0x00020003, @@ -615,287 +649,256 @@ pub const Window = opaque { hovered = 0x0002000B, focus_on_show = 0x0002000C, }; - pub fn getAttribute(window: *Window, attrib: Attribute) bool { - return glfwGetWindowAttrib(window, attrib) != 0; - } - extern fn glfwGetWindowAttrib(window: *Window, attrib: Attribute) i32; - pub fn setAttribute(window: *Window, attrib: Attribute, value: bool) void { - glfwSetWindowAttrib(window, attrib, @intFromBool(value)); + pub const create = zglfw.createWindow; + pub const destroy = zglfw.destroyWindow; + pub const getAttribute = zglfw.getWindowAttribute; + pub const setAttribute = zglfw.setWindowAttribute; + pub const getUserPointer = zglfw.getWindowUserPointer; + pub const setUserPointer = zglfw.setWindowUserPointer; + pub const setFramebufferCallback = zglfw.setFramebufferCallback; + pub const setSizeCallback = zglfw.setWindowSizeCallback; + pub const setPosCallback = zglfw.setWindowPosCallback; + pub const setFocusCallback = zglfw.setWindowFocusCallback; + pub const setIconifyCallback = zglfw.setWindowIconifyCallback; + pub const setContentScaleCallback = zglfw.setWindowContentScaleCallback; + pub const setCloseCallback = zglfw.setWindowCloseCallback; + pub const setKeyCallback = zglfw.setKeyCallback; + pub const setCharCallback = zglfw.setCharCallback; + pub const setMonitor = zglfw.setWindowMonitor; + pub const show = zglfw.showWindow; + pub const focus = zglfw.focusWindow; + pub const getKey = zglfw.getKey; + pub const getMouseButton = zglfw.getMouseButton; + pub const setSizeLimits = zglfw.setWindowSizeLimits; + pub const setPos = zglfw.setWindowPos; + pub const setTitle = zglfw.setWindowTitle; + pub const setIcon = zglfw.setWindowIcon; + pub const shouldClose = zglfw.windowShouldClose; + pub const setCursor = zglfw.setCursor; + pub const setInputMode = zglfw.setInputMode; + pub const swapBuffers = zglfw.swapBuffers; + + pub fn getCursorPos(self: *Window) [2]f64 { + var xpos: f64 = 0.0; + var ypos: f64 = 0.0; + zglfw.getCursorPos(self, &xpos, &ypos); + return .{ xpos, ypos }; } - extern fn glfwSetWindowAttrib(window: *Window, attrib: Attribute, value: i32) void; - pub fn getUserPointer(window: *Window, comptime T: type) ?*T { - return @ptrCast(@alignCast(glfwGetWindowUserPointer(window))); + pub fn getContentScale(self: *Window) [2]f32 { + var xscale: f32 = 0.0; + var yscale: f32 = 0.0; + zglfw.getWindowContentScale(self, &xscale, &yscale); + return .{ xscale, yscale }; } - extern fn glfwGetWindowUserPointer(window: *Window) ?*anyopaque; - pub fn setUserPointer(window: *Window, pointer: ?*anyopaque) void { - glfwSetWindowUserPointer(window, pointer); + pub fn getFramebufferSize(self: *Window) [2]c_int { + var width: c_int = 0.0; + var height: c_int = 0.0; + zglfw.getFramebufferSize(self, &width, &height); + return .{ width, height }; } - extern fn glfwSetWindowUserPointer(window: *Window, pointer: ?*anyopaque) void; - pub fn shouldClose(window: *Window) bool { - return if (glfwWindowShouldClose(window) == 0) false else true; + pub fn getSize(self: *Window) [2]c_int { + var width: c_int = 0.0; + var heght: c_int = 0.0; + zglfw.getWindowSize(self, &width, &heght); + return .{ width, heght }; } - extern fn glfwWindowShouldClose(window: *Window) i32; - pub fn setShouldClose(window: *Window, should_close: bool) void { - return glfwSetWindowShouldClose(window, if (should_close) 1 else 0); + pub fn getPos(self: *Window) [2]c_int { + var xpos: c_int = 0.0; + var ypos: c_int = 0.0; + zglfw.getWindowPos(self, &xpos, &ypos); + return .{ xpos, ypos }; } - extern fn glfwSetWindowShouldClose(window: *Window, should_close: i32) void; +}; - /// `pub fn destroy(window: *Window) void` - pub const destroy = glfwDestroyWindow; - extern fn glfwDestroyWindow(window: *Window) void; +pub fn createWindow( + width: c_int, + height: c_int, + title: [:0]const u8, + monitor: ?*Monitor, +) Error!*Window { + if (glfwCreateWindow(width, height, title, monitor, null)) |window| return window; + try maybeError(); + unreachable; +} +extern fn glfwCreateWindow( + width: c_int, + height: c_int, + title: [*:0]const u8, + monitor: ?*Monitor, + share: ?*Window, +) ?*Window; - /// `pub fn setSizeLimits(window: *Window, min_w: i32, min_h: i32, max_w: i32, max_h: i32) void` - pub const setSizeLimits = glfwSetWindowSizeLimits; - extern fn glfwSetWindowSizeLimits(window: *Window, min_w: i32, min_h: i32, max_w: i32, max_h: i32) void; +pub const destroyWindow = glfwDestroyWindow; +extern fn glfwDestroyWindow(window: *Window) void; - pub fn getContentScale(window: *Window) [2]f32 { - var xscale: f32 = 0.0; - var yscale: f32 = 0.0; - glfwGetWindowContentScale(window, &xscale, &yscale); - return .{ xscale, yscale }; - } - extern fn glfwGetWindowContentScale(window: *Window, xscale: *f32, yscale: *f32) void; +pub fn getWindowAttribute(window: *Window, attrib: Window.Attribute) bool { + return glfwGetWindowAttrib(window, attrib) == TRUE; +} +extern fn glfwGetWindowAttrib(window: *Window, attrib: Window.Attribute) c_int; - /// `pub getKey(window: *Window, key: Key) Action` - pub const getKey = glfwGetKey; - extern fn glfwGetKey(window: *Window, key: Key) Action; +pub fn setWindowAttribute(window: *Window, attrib: Window.Attribute, value: bool) void { + glfwSetWindowAttrib(window, attrib, @intFromBool(value)); +} +extern fn glfwSetWindowAttrib(window: *Window, attrib: Window.Attribute, value: i32) void; - /// `pub fn getMouseButton(window: *Window, button: MouseButton) Action` - pub const getMouseButton = glfwGetMouseButton; - extern fn glfwGetMouseButton(window: *Window, button: MouseButton) Action; +pub fn getWindowUserPointer(window: *Window, comptime T: type) ?*T { + return @ptrCast(@alignCast(glfwGetWindowUserPointer(window))); +} +extern fn glfwGetWindowUserPointer(window: *Window) ?*anyopaque; - pub fn getCursorPos(window: *Window) [2]f64 { - var xpos: f64 = 0.0; - var ypos: f64 = 0.0; - glfwGetCursorPos(window, &xpos, &ypos); - return .{ xpos, ypos }; - } - extern fn glfwGetCursorPos(window: *Window, xpos: *f64, ypos: *f64) void; +pub fn setWindowUserPointer(window: *Window, pointer: ?*anyopaque) void { + glfwSetWindowUserPointer(window, pointer); +} +extern fn glfwSetWindowUserPointer(window: *Window, pointer: ?*anyopaque) void; + +pub const setFramebufferSizeCallback = glfwSetFramebufferSizeCallback; +extern fn glfwSetFramebufferSizeCallback(*Window, ?FramebufferSizeFn) ?FramebufferSizeFn; +pub const FramebufferSizeFn = *const fn (*Window, width: c_int, height: c_int) callconv(.C) void; + +pub const setWindowSizeCallback = glfwSetWindowSizeCallback; +extern fn glfwSetWindowSizeCallback(*Window, ?WindowSizeFn) ?WindowSizeFn; +pub const WindowSizeFn = *const fn (*Window, width: c_int, height: c_int) callconv(.C) void; + +pub const setPosCallback = glfwSetWindowPosCallback; +extern fn glfwSetWindowPosCallback(*Window, ?WindowPosFn) ?WindowPosFn; +pub const WindowPosFn = *const fn (*Window, x: c_int, y: c_int) callconv(.C) void; + +pub const setFocusCallback = glfwSetWindowFocusCallback; +extern fn glfwSetWindowFocusCallback(*Window, ?WindowFocusFn) ?WindowFocusFn; +pub const WindowFocusFn = *const fn (*Window, focused: Bool) callconv(.C) void; + +pub const setIconifyCallback = glfwSetWindowIconifyCallback; +extern fn glfwSetWindowIconifyCallback(*Window, ?IconifyFn) ?IconifyFn; +pub const IconifyFn = *const fn (*Window, iconified: Bool) callconv(.C) void; + +pub const setWindowContentScaleCallback = glfwSetWindowContentScaleCallback; +extern fn glfwSetWindowContentScaleCallback(*Window, ?WindowContentScaleFn) ?WindowContentScaleFn; +pub const WindowContentScaleFn = *const fn (*Window, xscale: f32, yscale: f32) callconv(.C) void; + +pub const setWindowCloseCallback = glfwSetWindowCloseCallback; +extern fn glfwSetWindowCloseCallback(*Window, ?WindowCloseFn) ?WindowCloseFn; +pub const WindowCloseFn = *const fn (*Window) callconv(.C) void; + +pub const setKeyCallback = glfwSetKeyCallback; +extern fn glfwSetKeyCallback(*Window, ?KeyFn) ?KeyFn; +pub const KeyFn = *const fn (*Window, Key, scancode: c_int, Action, Mods) callconv(.C) void; + +pub const setCharCallback = glfwSetCharCallback; +extern fn glfwSetCharCallback(*Window, ?CharFn) ?CharFn; +pub const CharFn = *const fn (*Window, codepoint: u32) callconv(.C) void; + +pub const setDropCallback = glfwSetDropCallback; +extern fn glfwSetDropCallback(*Window, ?DropFn) ?DropFn; +pub const DropFn = *const fn (*Window, path_count: c_int, paths: [*][*:0]const u8) callconv(.C) void; + +pub const setMouseButtonCallback = glfwSetMouseButtonCallback; +extern fn glfwSetMouseButtonCallback(*Window, ?MouseButtonFn) ?MouseButtonFn; +pub const MouseButtonFn = *const fn (*Window, MouseButton, Action, Mods) callconv(.C) void; + +pub const setCursorPosCallback = glfwSetCursorPosCallback; +extern fn glfwSetCursorPosCallback(*Window, ?CursorPosFn) ?CursorPosFn; +pub const CursorPosFn = *const fn (*Window, xpos: f64, ypos: f64) callconv(.C) void; + +pub const setScrollCallback = glfwSetScrollCallback; +extern fn glfwSetScrollCallback(*Window, ?ScrollFn) ?ScrollFn; +pub const ScrollFn = *const fn (*Window, xoffset: f64, yoffset: f64) callconv(.C) void; + +pub const setCursorEnterCallback = glfwSetCursorEnterCallback; +extern fn glfwSetCursorEnterCallback(*Window, ?CursorEnterFn) ?CursorEnterFn; +pub const CursorEnterFn = *const fn (*Window, entered: Bool) callconv(.C) void; + +pub const setWindowMonitor = glfwSetWindowMonitor; +extern fn glfwSetWindowMonitor( + *Window, + ?*Monitor, + xpos: c_int, + ypos: c_int, + width: c_int, + height: c_int, + refreshRate: c_int, +) void; - pub fn getFramebufferSize(window: *Window) [2]i32 { - var width: i32 = 0.0; - var height: i32 = 0.0; - glfwGetFramebufferSize(window, &width, &height); - return .{ width, height }; - } - extern fn glfwGetFramebufferSize(window: *Window, width: *i32, height: *i32) void; +pub const showWindow = glfwShowWindow; +extern fn glfwShowWindow(*Window) void; - pub fn getSize(window: *Window) [2]i32 { - var width: i32 = 0.0; - var height: i32 = 0.0; - glfwGetWindowSize(window, &width, &height); - return .{ width, height }; - } - extern fn glfwGetWindowSize(window: *Window, width: *i32, height: *i32) void; +pub const focuswindow = glfwFocusWindow; +extern fn glfwFocusWindow(*Window) void; - /// `pub fn setSize(window: *Window, width: i32, height: i32) void` - pub const setSize = glfwSetWindowSize; - extern fn glfwSetWindowSize(window: *Window, width: i32, height: i32) void; +pub const getKey = glfwGetKey; +extern fn glfwGetKey(*Window, key: Key) Action; - pub fn getPos(window: *Window) [2]i32 { - var xpos: i32 = 0.0; - var ypos: i32 = 0.0; - glfwGetWindowPos(window, &xpos, &ypos); - return .{ xpos, ypos }; - } - extern fn glfwGetWindowPos(window: *Window, xpos: *i32, ypos: *i32) void; +pub const getMouseButton = glfwGetMouseButton; +extern fn glfwGetMouseButton(*Window, button: MouseButton) Action; - /// `pub fn setPos(window: *Window, width: i32, height: i32) void` - pub const setPos = glfwSetWindowPos; - extern fn glfwSetWindowPos(window: *Window, xpos: i32, ypos: i32) void; +pub const getCursorPos = glfwGetCursorPos; +extern fn glfwGetCursorPos(*Window, xpos: ?*f64, ypos: ?*f64) void; - pub inline fn setTitle(window: *Window, title: [:0]const u8) void { - glfwSetWindowTitle(window, title); - } - extern fn glfwSetWindowTitle(window: *Window, title: [*:0]const u8) void; +pub const setCursorPos = glfwSetCursorPos; +extern fn glfwSetCursorPos(*Window, xpos: f64, ypos: f64) void; - pub fn getClipboardString(window: *Window) ?[:0]const u8 { - return std.mem.span(glfwGetClipboardString(window)); - } - extern fn glfwGetClipboardString(window: *Window) ?[*:0]const u8; +pub const setWindowSizeLimits = glfwSetWindowSizeLimits; +extern fn glfwSetWindowSizeLimits(*Window, min_w: c_int, min_h: c_int, max_w: c_int, max_h: c_int) void; - pub inline fn setClipboardString(window: *Window, string: [:0]const u8) void { - return glfwSetClipboardString(window, string); - } - extern fn glfwSetClipboardString( - window: *Window, - string: [*:0]const u8, - ) void; - - /// `pub fn setFramebufferSizeCallback(window: *Window, callback: ?FramebufferSizeFn) ?FramebufferSizeFn` - pub const setFramebufferSizeCallback = glfwSetFramebufferSizeCallback; - extern fn glfwSetFramebufferSizeCallback(window: *Window, callback: ?FramebufferSizeFn) ?FramebufferSizeFn; - pub const FramebufferSizeFn = *const fn ( - window: *Window, - width: i32, - height: i32, - ) callconv(.C) void; - - /// `pub fn setSizeCallback(window: *Window, callback: ?WindowSizeFn) ?WindowSizeFn` - pub const setSizeCallback = glfwSetWindowSizeCallback; - extern fn glfwSetWindowSizeCallback(window: *Window, callback: ?WindowSizeFn) ?WindowSizeFn; - pub const WindowSizeFn = *const fn ( - window: *Window, - width: i32, - height: i32, - ) callconv(.C) void; - - /// `pub fn setPosCallback(window: *Window, callback: ?WindowPosFn) ?WindowPosFn` - pub const setPosCallback = glfwSetWindowPosCallback; - extern fn glfwSetWindowPosCallback(window: *Window, callback: ?WindowPosFn) ?WindowPosFn; - pub const WindowPosFn = *const fn ( - window: *Window, - xpos: i32, - ypos: i32, - ) callconv(.C) void; - - /// `pub const setFocusCallback(window: *Window, callback: ?WindowFocusFn) ?WindowFocusFn` - pub const setFocusCallback = glfwSetWindowFocusCallback; - extern fn glfwSetWindowFocusCallback(window: *Window, callback: ?WindowFocusFn) ?WindowFocusFn; - pub const WindowFocusFn = *const fn ( - window: *Window, - focused: i32, - ) callconv(.C) void; - - /// `pub const setIconifyCallback(window: *Window, callback: ?IconifyFn) ?IconifyFn` - pub const setIconifyCallback = glfwSetWindowIconifyCallback; - extern fn glfwSetWindowIconifyCallback(window: *Window, callback: ?IconifyFn) ?IconifyFn; - pub const IconifyFn = *const fn ( - window: *Window, - iconified: i32, - ) callconv(.C) void; - - /// `pub const setContentScaleCallback(window: *Window, callback: ?WindowContentScaleFn) ?WindowContentScaleFn` - pub const setContentScaleCallback = glfwSetWindowContentScaleCallback; - extern fn glfwSetWindowContentScaleCallback(window: *Window, callback: ?WindowContentScaleFn) ?WindowContentScaleFn; - pub const WindowContentScaleFn = *const fn ( - window: *Window, - xscale: f32, - yscale: f32, - ) callconv(.C) void; - - /// `pub fn setKeyCallback(window: *Window, callback: ?KeyFn) ?KeyFn` - pub const setKeyCallback = glfwSetKeyCallback; - extern fn glfwSetKeyCallback(window: *Window, callback: ?KeyFn) ?KeyFn; - pub const KeyFn = *const fn ( - window: *Window, - key: Key, - scancode: i32, - action: Action, - mods: Mods, - ) callconv(.C) void; - - /// `pub fn setCharCallback(window: *Window, callback: ?CharFn) ?CharFn` - pub const setCharCallback = glfwSetCharCallback; - extern fn glfwSetCharCallback(window: *Window, callback: ?CharFn) ?CharFn; - pub const CharFn = *const fn ( - window: *Window, - codepoint: u32, - ) callconv(.C) void; - - /// `pub fn setDropCallback(window: *Window, callback: ?DropFn) ?DropFn` - pub const setDropCallback = glfwSetDropCallback; - extern fn glfwSetDropCallback(window: *Window, callback: ?DropFn) ?DropFn; - pub const DropFn = *const fn ( - window: *Window, - path_count: i32, - paths: [*][*:0]const u8, - ) callconv(.C) void; - - /// `pub fn setMouseButtonCallback(window: *Window, callback: ?MouseButtonFn) ?MouseButtonFn` - pub const setMouseButtonCallback = glfwSetMouseButtonCallback; - extern fn glfwSetMouseButtonCallback(window: *Window, callback: ?MouseButtonFn) ?MouseButtonFn; - pub const MouseButtonFn = *const fn ( - window: *Window, - button: MouseButton, - action: Action, - mods: Mods, - ) callconv(.C) void; - - /// `pub fn setCursorPosCallback(window: *Window, callback: ?CursorPosFn) ?CursorPosFn` - pub const setCursorPosCallback = glfwSetCursorPosCallback; - extern fn glfwSetCursorPosCallback(window: *Window, callback: ?CursorPosFn) ?CursorPosFn; - pub const CursorPosFn = *const fn ( - window: *Window, - xpos: f64, - ypos: f64, - ) callconv(.C) void; - - /// `pub fn setScrollCallback(window: *Window, callback: ?ScrollFn) ?ScrollFn` - pub const setScrollCallback = glfwSetScrollCallback; - extern fn glfwSetScrollCallback(window: *Window, callback: ?ScrollFn) ?ScrollFn; - pub const ScrollFn = *const fn ( - window: *Window, - xoffset: f64, - yoffset: f64, - ) callconv(.C) void; - - /// `pub fn setCursorEnterCallback(window: *Window, callback: ?CursorEnterFn) ?CursorEnterFn` - pub const setCursorEnterCallback = glfwSetCursorEnterCallback; - extern fn glfwSetCursorEnterCallback(window: *Window, callback: ?CursorEnterFn) ?CursorEnterFn; - pub const CursorEnterFn = *const fn ( - window: *Window, - entered: i32, - ) callconv(.C) void; - - /// `pub fn setCursor(window: *Window, cursor: ?*Cursor) void` - pub const setCursor = glfwSetCursor; - extern fn glfwSetCursor(window: *Window, cursor: ?*Cursor) void; - - pub fn setInputMode(window: *Window, mode: InputMode, value: anytype) void { - const T = @TypeOf(value); - const i32_value = switch (@typeInfo(T)) { - .@"enum", .enum_literal => @intFromEnum(@as(Cursor.Mode, value)), - .bool => @intFromBool(value), - else => unreachable, - }; - glfwSetInputMode(window, mode, i32_value); - } - extern fn glfwSetInputMode(window: *Window, mode: InputMode, value: i32) void; +pub const getWindowContentScale = glfwGetWindowContentScale; +extern fn glfwGetWindowContentScale(*Window, xscale: ?*f32, yscale: ?*f32) void; - pub fn focus(window: *Window) void { - glfwFocusWindow(window); - } - extern fn glfwFocusWindow(window: *Window) void; +pub const getFramebufferSize = glfwGetFramebufferSize; +extern fn glfwGetFramebufferSize(*Window, width: ?*c_int, height: ?*c_int) void; - pub const swapBuffers = glfwSwapBuffers; - extern fn glfwSwapBuffers(window: *Window) void; +pub const getWindowSize = glfwGetWindowSize; +extern fn glfwGetWindowSize(*Window, width: ?*c_int, height: ?*c_int) void; - pub fn setMonitor(window: *Window, monitor: ?*Monitor, xpos: i32, ypos: i32, width: i32, height: i32, refreshRate: i32) void { - glfwSetWindowMonitor(window, monitor, xpos, ypos, width, height, refreshRate); - } - extern fn glfwSetWindowMonitor(window: *Window, monitor: ?*Monitor, xpos: i32, ypos: i32, width: i32, height: i32, refreshRate: i32) void; - - pub fn create( - width: i32, - height: i32, - title: [:0]const u8, - monitor: ?*Monitor, - ) Error!*Window { - if (glfwCreateWindow(width, height, title, monitor, null)) |window| return window; - try maybeError(); - unreachable; - } - extern fn glfwCreateWindow( - width: i32, - height: i32, - title: [*:0]const u8, - monitor: ?*Monitor, - share: ?*Window, - ) ?*Window; - - pub fn show(window: *Window) void { - glfwShowWindow(window); - } - extern fn glfwShowWindow(window: *Window) void; -}; +pub const setSize = glfwSetWindowSize; +extern fn glfwSetWindowSize(*Window, width: c_int, height: c_int) void; + +pub const getWindowPos = glfwGetWindowPos; +extern fn glfwGetWindowPos(*Window, xpos: *c_int, ypos: *c_int) void; + +pub const setWindowPos = glfwSetWindowPos; +extern fn glfwSetWindowPos(*Window, xpos: i32, ypos: i32) void; -pub const WindowHint = enum(i32) { +pub fn setWindowTitle(window: *Window, title: [:0]const u8) void { + glfwSetWindowTitle(window, title); +} +extern fn glfwSetWindowTitle(*Window, title: [*:0]const u8) void; + +pub fn setWindowIcon(window: *Window, images: []const Image) void { + glfwSetWindowIcon(window, images.items.len, images.ptr); +} +extern fn glfwSetWindowIcon(*Window, count: c_int, images: [*]const Image) void; + + +pub fn windowShouldClose(window: *Window) bool { + return glfwWindowShouldClose(window) == TRUE; +} +extern fn glfwWindowShouldClose(window: *Window) Bool; + +pub fn setWindowShouldClose(window: *Window, should_close: bool) void { + return glfwSetWindowShouldClose(window, if (should_close) TRUE else FALSE); +} +extern fn glfwSetWindowShouldClose(*Window, should_close: c_int) void; + +pub const setCursor = glfwSetCursor; +extern fn glfwSetCursor(*Window, ?*Cursor) void; + +pub fn setInputMode(window: *Window, mode: InputMode, value: anytype) void { + glfwSetInputMode(window, mode, switch (@typeInfo(@TypeOf(value))) { + .@"enum", .enum_literal => @intFromEnum(@as(Cursor.Mode, value)), + .bool => @intFromBool(value), + else => unreachable, + }); +} +extern fn glfwSetInputMode(*Window, InputMode, value: i32) void; + +pub const swapBuffers = glfwSwapBuffers; +extern fn glfwSwapBuffers(*Window) void; + +pub const WindowHint = enum(c_int) { focused = 0x00020001, iconified = 0x00020002, resizable = 0x00020003, @@ -961,15 +964,15 @@ pub const WindowHint = enum(i32) { .focus_on_show, .mouse_passthrough, => bool, - .position_x, .position_y => i32, - .red_bits, .green_bits, .blue_bits, .alpha_bits, .depth_bits, .stencil_bits => i32, + .position_x, .position_y => c_int, + .red_bits, .green_bits, .blue_bits, .alpha_bits, .depth_bits, .stencil_bits => c_int, .stereo => bool, - .samples => i32, + .samples => c_int, .srgb_capable => bool, - .refresh_rate => i32, + .refresh_rate => c_int, .doublebuffer => bool, .client_api => ClientApi, - .context_version_major, .context_version_minor, .context_revision => i32, + .context_version_major, .context_version_minor, .context_revision => c_int, .context_robustness => ContextRobustness, .opengl_forward_compat, .opengl_debug_context => bool, .opengl_profile => OpenGLProfile, @@ -985,18 +988,23 @@ pub const WindowHint = enum(i32) { }; } - /// DEPRECATED: Does not allow setting string type hints. - /// Use `windowHint`, `windowHintString` or `windowHintTyped` instead. - pub const set = glfwWindowHint; + pub const set = windowHint; }; -pub fn windowHintTyped( +/// DDEPRECATED: Use `windowHintComptime` instead +pub const windowHintTyped = windowHintComptime; + +pub fn windowHintComptime( comptime window_hint: WindowHint, value: WindowHint.ValueType(window_hint), ) void { - const ValueType = WindowHint.ValueType(window_hint); + windowHint(window_hint, value); +} + +pub fn windowHint(window_hint: WindowHint, value: anytype) void { + const ValueType = @TypeOf(value); switch (ValueType) { - else => windowHint(window_hint, switch (@typeInfo(ValueType)) { + else => glfwWindowHint(window_hint, switch (@typeInfo(ValueType)) { .int => @intCast(value), .@"enum" => @intFromEnum(value), .bool => @intFromBool(value), @@ -1005,40 +1013,38 @@ pub fn windowHintTyped( [:0]const u8 => windowHintString(window_hint, value), } } - -pub const windowHint = glfwWindowHint; -extern fn glfwWindowHint(WindowHint, value: i32) void; +extern fn glfwWindowHint(WindowHint, value: c_int) void; pub fn windowHintString(window_hint: WindowHint, string: [:0]const u8) void { glfwWindowHintString(window_hint, string); } extern fn glfwWindowHintString(WindowHint, string: [*:0]const u8) void; -pub const ClientApi = enum(i32) { +pub const ClientApi = enum(c_int) { no_api = 0, opengl_api = 0x00030001, opengl_es_api = 0x00030002, }; -pub const OpenGLProfile = enum(i32) { +pub const OpenGLProfile = enum(c_int) { opengl_any_profile = 0, opengl_core_profile = 0x00032001, opengl_compat_profile = 0x00032002, }; -pub const ContextRobustness = enum(i32) { +pub const ContextRobustness = enum(c_int) { no_robustness = 0, no_reset_notification = 0x00031001, lose_context_on_reset = 0x00031002, }; -pub const ReleaseBehaviour = enum(i32) { +pub const ReleaseBehaviour = enum(c_int) { any = 0, flush = 0x00035001, none = 0x00035002, }; -pub const ContextCreationApi = enum(i32) { +pub const ContextCreationApi = enum(c_int) { native = 0x00036001, egl = 0x00036002, osmesa = 0x00036003,