// Input constants // Copyright (C) 2021, 2023 Nguyễn Gia Phong // // This file is part of gfz. // // gfz is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // gfz is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with gfz. If not, see . const Int = std.meta.Int; const EnumField = std.builtin.Type.EnumField; const endian = @import("builtin").target.cpu.arch.endian(); const c = @import("cimport.zig"); const std = @import("std"); const keys = [_][:0]const u8{ // Printable keys "SPACE", "APOSTROPHE", "COMMA", "MINUS", "PERIOD", "SLASH", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "SEMICOLON", "EQUAL", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "LEFT_BRACKET", "BACKSLASH", "RIGHT_BRACKET", "GRAVE_ACCENT", "WORLD_1", "WORLD_2", // keys lacking a clear US mapping // Function keys "ESCAPE", "ENTER", "TAB", "BACKSPACE", "INSERT", "DELETE", "RIGHT", "LEFT", "DOWN", "UP", "PAGE_UP", "PAGE_DOWN", "HOME", "END", "CAPS_LOCK", "SCROLL_LOCK", "NUM_LOCK", "PRINT_SCREEN", "PAUSE", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23", "F24", "F25", "KP_0", "KP_1", "KP_2", "KP_3", "KP_4", "KP_5", "KP_6", "KP_7", "KP_8", "KP_9", "KP_DECIMAL", "KP_DIVIDE", "KP_MULTIPLY", "KP_SUBTRACT", "KP_ADD", "KP_ENTER", "KP_EQUAL", "LEFT_SHIFT", "LEFT_CONTROL", "LEFT_ALT", "LEFT_SUPER", "RIGHT_SHIFT", "RIGHT_CONTROL", "RIGHT_ALT", "RIGHT_SUPER", "MENU", }; /// Keyboard key enumeration: https://www.glfw.org/docs/latest/group__keys.html pub const Key = @Type(.{ .@"enum" = .{ .tag_type = c_int, .fields = blk: { var fields: [keys.len]EnumField = undefined; for (keys, 0..) |name, i| fields[i] = .{ .name = name, .value = @field(c, "GLFW_KEY_" ++ name), }; break :blk fields[0..]; }, .decls = &.{}, .is_exhaustive = true, } }); /// Modifier key flags: https://www.glfw.org/docs/latest/group__mods.html pub const Mods = packed struct { /// One or more Shift keys are held down. shift: bool, /// One or more Control keys are held down. control: bool, /// One or more Alt keys are held down. alt: bool, /// One or more Super keys are held down. super: bool, /// The Caps Lock key is enabled and InputMode.lock_key_mods is set. caps_lock: bool, /// The Num Lock key is enabled and InputMode.lock_key_mods is set. num_lock: bool, // @bitCast will not work directly with an integer // due to alignment: https://github.com/ziglang/zig/issues/8102 const MaskInt = Int(.unsigned, @bitSizeOf(Mods)); const Mask = packed struct { integer: MaskInt }; /// Convert c_int to Mods. pub fn fromInt(mask: c_int) Mods { const integer: MaskInt = @intCast(mask); return @bitCast(Mask{ .integer = switch (endian) { .big => @bitReverse(integer), .little => integer, }, }); } /// Convert Mods to c_int. pub fn toInt(self: Mods) c_int { const integer = @as(Mask, @bitCast(self)).integer; return @intCast(switch (endian) { .big => @bitReverse(integer), .little => integer, }); } }; /// Key action: https://www.glfw.org/docs/latest/input_guide.html#input_key // TODO: move inside Key: https://github.com/ziglang/zig/issues/6709 pub const KeyAction = enum(c_int) { press = c.GLFW_PRESS, release = c.GLFW_RELEASE, repeat = c.GLFW_REPEAT, }; /// Mouse buttons: https://www.glfw.org/docs/latest/group__buttons.html pub const MouseButton = enum(c_int) { @"1" = c.GLFW_MOUSE_BUTTON_1, @"2" = c.GLFW_MOUSE_BUTTON_2, @"3" = c.GLFW_MOUSE_BUTTON_3, @"4" = c.GLFW_MOUSE_BUTTON_4, @"5" = c.GLFW_MOUSE_BUTTON_5, @"6" = c.GLFW_MOUSE_BUTTON_6, @"7" = c.GLFW_MOUSE_BUTTON_7, @"8" = c.GLFW_MOUSE_BUTTON_8, pub const left: MouseButton = @enumFromInt(c.GLFW_MOUSE_BUTTON_LEFT); pub const right: MouseButton = @enumFromInt(c.GLFW_MOUSE_BUTTON_RIGHT); pub const middle: MouseButton = @enumFromInt(c.GLFW_MOUSE_BUTTON_MIDDLE); /// Mouse button input action: /// https://www.glfw.org/docs/latest/input_guide.html#input_mouse_button pub const Action = enum(c_int) { press = c.GLFW_PRESS, release = c.GLFW_RELEASE, }; };