//! GLFW Adaptor // todo restructure to handle multiple windows const std = @import("std"); const nu = @import("../nu.zig"); pub const c = @cImport({ @cDefine("GLFW_INCLUDE_NONE", {}); @cInclude("GLFW/glfw3.h"); }); pub const Bus = @import("Bus.zig"); pub const Config = struct { title: [*:0]const u8 = "Hello World", width: u32 = 1280, height: u32 = 720, x11_class_name: [*:0]const u8 = "floating_window", x11_instance_name: [*:0]const u8 = "floating_window", unfocused_wait: f32 = 1.0 / 20.0, }; const config: Config = nu.config.window; pub fn driver() nu.Driver { return nu.Driver{ .module = .{ .name = "Window", .dependencies = &.{}, // todo bus .setup = setup, .teardown = teardown, }, .next = next, }; } pub var handle: *c.GLFWwindow = undefined; pub fn setup(_: std.mem.Allocator) !void { if (c.glfwInit() != c.GLFW_TRUE) std.debug.panic("GLFW Init Failed", .{}); if (c.glfwVulkanSupported() != c.GLFW_TRUE) std.debug.panic("GLFW Vulkan not supported", .{}); c.glfwWindowHint(c.GLFW_CLIENT_API, c.GLFW_NO_API); c.glfwWindowHintString(c.GLFW_X11_CLASS_NAME, config.x11_class_name); c.glfwWindowHintString(c.GLFW_X11_INSTANCE_NAME, config.x11_instance_name); handle = c.glfwCreateWindow( @intCast(config.width), @intCast(config.height), config.title, null, null, ) orelse std.debug.panic("GLFW Create Window Failed", .{}); _ = c.glfwSetFramebufferSizeCallback(handle, &resize_callback); // bus.connect(handle); // errdefer bus.disconnect(handle); } pub fn teardown() void { c.glfwDestroyWindow(handle); c.glfwTerminate(); } pub fn next() bool { if (c.glfwWindowShouldClose(handle) == c.GLFW_TRUE) return false; if (c.glfwGetWindowAttrib(handle, c.GLFW_FOCUSED) == c.GLFW_TRUE) { c.glfwPollEvents(); } else { c.glfwWaitEventsTimeout(config.unfocused_wait); } return true; } var _resize_callbacks: std.BoundedArray(*const fn (u32, u32) void, 16) = .{}; fn resize_callback(_: ?*c.GLFWwindow, w: c_int, h: c_int) callconv(.C) void { for (_resize_callbacks.slice()) |cb| { cb(@intCast(w), @intCast(h)); } } pub fn add_resize_callback(cb: *const fn (u32, u32) void) void { _resize_callbacks.appendAssumeCapacity(cb); } pub fn set_title(title: [:0]const u8) void { c.glfwSetWindowTitle(handle, title); } pub fn size() std.meta.Tuple(&[_]type{ u32, u32 }) { var w: c_int = undefined; var h: c_int = undefined; c.glfwGetFramebufferSize(handle, &w, &h); return .{ @intCast(w), @intCast(h) }; }