const std = @import("std"); const Cmd = @import("Cmd.zig"); const Allocator = std.mem.Allocator; pub const Msg = union(enum) { quit, interrupt, suspended, resumed, key_press: Key, key_release: Key, mouse_click: Mouse, mouse_release: Mouse, mouse_wheel: Mouse, mouse_motion: Mouse, paste_start, paste_end, /// UTF-8 paste payload. By convention the producer allocates with the /// program's gpa, and `Program.run` frees the slice after the model /// dispatches the msg. Bracketed-paste readers and `clipboard.pasteCmd` /// both follow this rule. paste: []const u8, focus, blur, window_size: WindowSize, cursor_position: CursorPosition, color_profile: ColorProfile, foreground_color: Color, background_color: Color, cursor_color: Color, keyboard_enhancements: KeyboardEnhancements, mode_report: ModeReport, capability: []const u8, terminal_version: []const u8, clipboard: Clipboard, env: Env, raw: []const u8, clear_screen, print_above: []const u8, batch: []const Cmd, sequence: []const Cmd, tick, custom: Custom, pub const Key = struct { kind: Kind, rune: u21 = 0, mods: Mods = .{}, pub const Mods = packed struct(u8) { shift: bool = false, alt: bool = false, ctrl: bool = false, meta: bool = false, hyper: bool = false, super: bool = false, caps_lock: bool = false, num_lock: bool = false, }; pub const Kind = enum(u8) { rune, space, enter, tab, backspace, escape, up, down, left, right, home, end, page_up, page_down, begin, insert, delete, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, }; }; pub const Mouse = struct { x: u16 = 0, y: u16 = 0, button: Button = .none, mods: Key.Mods = .{}, pub const Button = enum(u8) { none, left, middle, right, wheel_up, wheel_down, wheel_left, wheel_right, backward, forward, extra_10, extra_11, }; }; pub const WindowSize = struct { width: u16, height: u16, }; pub const CursorPosition = struct { x: u16, y: u16, }; pub const ColorProfile = enum(u8) { no_tty, ascii, ansi, ansi256, true_color, }; pub const Color = struct { r: u8, g: u8, b: u8, a: u8 = 255, pub fn isDark(color: Color) bool { const lum: f32 = 0.299 * @as(f32, @floatFromInt(color.r)) + 0.587 * @as(f32, @floatFromInt(color.g)) + 0.114 * @as(f32, @floatFromInt(color.b)); return lum < 128.0; } }; pub const KeyboardEnhancements = packed struct(u8) { disambiguate_escape_codes: bool = false, report_event_types: bool = false, report_alternate_keys: bool = false, report_all_keys_as_escape_codes: bool = false, report_associated_text: bool = false, _pad: u3 = 0, pub fn supportsKeyDisambiguation(self: KeyboardEnhancements) bool { return @as(u8, @bitCast(self)) != 0; } }; pub const ModeReport = struct { mode: u32, value: Setting, pub const Setting = enum(u8) { not_recognized, set, reset, permanently_set, permanently_reset, }; }; pub const Clipboard = struct { content: []const u8, selection: Selection = .system, pub const Selection = enum(u8) { /// 'c': system clipboard system, /// 'p': X11/Wayland primary selection primary, }; }; pub const Env = struct { entries: []const Entry, pub const Entry = struct { key: []const u8, value: []const u8, }; pub fn get(env: Env, key: []const u8) ?[]const u8 { for (env.entries) |e| if (std.mem.eql(u8, e.key, key)) return e.value; return null; } }; pub const Custom = struct { type_id: usize, payload: ?*anyopaque = null, free: ?*const fn (allocator: Allocator, payload: *anyopaque) void = null, }; };