const std = @import("std"); const glfw = @import("glfw"); const vk = @import("vulkan"); const Renderer = @import("Renderer.zig"); const Instance = @import("instance.zig").Instance; // TODO memory var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); pub const Display = struct { pub fn getWorkSize() !glfw.Window.Size { try glfw.init(.{}); const monitor = try glfw.Monitor.getPrimary() orelse error.NoPrimaryMonitor; const work_area = try monitor.getWorkarea(); if (work_area.width <= 0 or work_area.height <= 0) { return error.WorkareaNotReady; } return glfw.Window.Size{ .width = work_area.width, .height = work_area.height, }; } pub fn getFullSize() !glfw.Window.Size { try glfw.init(.{}); const monitor = try glfw.Monitor.getPrimary() orelse error.NoPrimaryMonitor; const modes = try monitor.getVideoModes(allocator); defer allocator.free(modes); if (modes.len <= 0) { return error.NoModes; } var chosenArea: ?u32 = null; var chosenMode: ?*const glfw.VideoMode = null; for (modes) |mode| { const area = mode.getWidth() * mode.getHeight(); if (area > chosenArea orelse 0) { chosenArea = area; chosenMode = &mode; } } if (chosenArea == null) { return error.NoModes; } return glfw.Window.Size{ .width = (chosenMode orelse unreachable).getWidth(), .height = (chosenMode orelse unreachable).getHeight(), }; } pub fn getSize(fullscreen: bool) !glfw.Window.Size { return if (fullscreen) try getFullSize() else try getWorkSize(); } }; pub const Window = struct { const Self = @This(); fullscreen: bool, handle: glfw.Window, size: glfw.Window.Size, surface: vk.SurfaceKHR, pub fn init(instance: *const Instance, title: [*:0]const u8, width: u32, height: u32, fullscreen: bool) !Self { try glfw.init(.{}); const handle = try glfw.Window.create(width, height, title, try glfw.Monitor.getPrimary() orelse error.NoPrimaryMonitor, null, .{ .client_api = .no_api, .srgb_capable = true, .auto_iconify = !fullscreen, .maximized = !fullscreen, }); errdefer handle.destroy(); // TODO: input: register window var surface: vk.SurfaceKHR = undefined; _ = try glfw.createWindowSurface(instance.handle, handle, null, &surface); return Self{ .fullscreen = fullscreen, .handle = handle, .size = try handle.getFramebufferSize(), .surface = surface, }; } pub fn deinit(self: *const Self, instance: *const Instance) void { instance.dispatch.destroySurfaceKHR(instance.handle, self.surface, null); self.handle.destroy(); } pub fn updateSize(self: *Self) !bool { const prevSize = self.size; self.size = try self.handle.getFramebufferSize(); const changed = prevSize.width != self.size.width or prevSize.height != self.size.height; return changed; } pub fn getPosition(self: *Self) !glfw.Pos { return try self.handle.getPos(); } pub fn setPosition(self: *Self, pos: glfw.Pos) !glfw.Pos { return try self.handle.setPos(pos); } pub fn isOpen(self: *Self) !bool { return try self.handle.shouldClose(); } pub fn poll() !void { return try glfw.pollEvents(); } };