keyboard (more more sorta)

This commit is contained in:
Jeeves 2024-04-10 12:41:06 -06:00
parent 9bf5c3403c
commit 128c8b3d72

View file

@ -68,6 +68,7 @@ pub fn main() !void {
pub const Terminal = struct { pub const Terminal = struct {
tty: fs.File, tty: fs.File,
buffered_writer: io.BufferedWriter(4096, fs.File.Writer),
original_termios: os.linux.termios, original_termios: os.linux.termios,
info: Info, info: Info,
allocator: mem.Allocator, allocator: mem.Allocator,
@ -79,6 +80,7 @@ pub const Terminal = struct {
pub fn init(allocator: mem.Allocator) !Terminal { pub fn init(allocator: mem.Allocator) !Terminal {
var term = Terminal{ var term = Terminal{
.tty = try fs.openFileAbsolute("/dev/tty", .{ .mode = .read_write }), .tty = try fs.openFileAbsolute("/dev/tty", .{ .mode = .read_write }),
.buffered_writer = undefined,
.original_termios = undefined, .original_termios = undefined,
.info = try Info.init(allocator), .info = try Info.init(allocator),
.allocator = allocator, .allocator = allocator,
@ -87,6 +89,7 @@ pub const Terminal = struct {
}; };
errdefer term.tty.close(); errdefer term.tty.close();
errdefer term.info.deinit(); errdefer term.info.deinit();
term.buffered_writer = io.bufferedWriter(term.tty.writer());
try term.uncook(); try term.uncook();
try attachSignalHandlers(); try attachSignalHandlers();
try term.updateWinSize(); try term.updateWinSize();
@ -100,6 +103,7 @@ pub const Terminal = struct {
self.box.deinit(); self.box.deinit();
self.cook() catch @panic("failed to restore termios"); self.cook() catch @panic("failed to restore termios");
self.cursorShow() catch @panic("failed to unhide cursor"); self.cursorShow() catch @panic("failed to unhide cursor");
self.buffered_writer.flush() catch @panic("couldn't flush output buffer");
self.tty.close(); self.tty.close();
self.info.deinit(); self.info.deinit();
} }
@ -214,76 +218,77 @@ pub const Terminal = struct {
pub fn draw(self: *Terminal) !void { pub fn draw(self: *Terminal) !void {
if (self.box.dirty) try self.clearScreen(); if (self.box.dirty) try self.clearScreen();
try self.box.draw(self); try self.box.draw(self);
try self.buffered_writer.flush();
} }
pub fn print(self: *Terminal, comptime format: []const u8, args: anytype) !void { pub fn print(self: *Terminal, comptime format: []const u8, args: anytype) !void {
const formatted = try fmt.allocPrint(self.allocator, format, args); const formatted = try fmt.allocPrint(self.allocator, format, args);
defer self.allocator.free(formatted); defer self.allocator.free(formatted);
try self.tty.writeAll(formatted); try self.buffered_writer.writer().writeAll(formatted);
} }
pub fn cursorShow(self: *Terminal) !void { pub fn cursorShow(self: *Terminal) !void {
try self.info.writeString(.cursor_visible, self.tty.writer(), &[_]u32{}); try self.info.writeString(.cursor_visible, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn cursorHide(self: *Terminal) !void { pub fn cursorHide(self: *Terminal) !void {
try self.info.writeString(.cursor_invisible, self.tty.writer(), &[_]u32{}); try self.info.writeString(.cursor_invisible, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn cursorUp(self: *Terminal) !void { pub fn cursorUp(self: *Terminal) !void {
try self.info.writeString(.cursor_up, self.tty.writer(), &[_]u32{}); try self.info.writeString(.cursor_up, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn cursorDown(self: *Terminal) !void { pub fn cursorDown(self: *Terminal) !void {
try self.info.writeString(.cursor_down, self.tty.writer(), &[_]u32{}); try self.info.writeString(.cursor_down, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn cursorLeft(self: *Terminal) !void { pub fn cursorLeft(self: *Terminal) !void {
try self.info.writeString(.cursor_left, self.tty.writer(), &[_]u32{}); try self.info.writeString(.cursor_left, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn cursorRight(self: *Terminal) !void { pub fn cursorRight(self: *Terminal) !void {
try self.info.writeString(.cursor_right, self.tty.writer(), &[_]u32{}); try self.info.writeString(.cursor_right, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn cursorSet(self: *Terminal, x: u32, y: u32) !void { pub fn cursorSet(self: *Terminal, x: u32, y: u32) !void {
try self.info.writeString(.cursor_address, self.tty.writer(), &[_]u32{ y, x }); try self.info.writeString(.cursor_address, self.buffered_writer.writer(), &[_]u32{ y, x });
} }
pub fn blinkOn(self: *Terminal) !void { pub fn blinkOn(self: *Terminal) !void {
try self.info.writeString(.enter_blink_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.enter_blink_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn blinkOff(self: *Terminal) !void { pub fn blinkOff(self: *Terminal) !void {
try self.info.writeString(.exit_blink_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.exit_blink_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn boldOn(self: *Terminal) !void { pub fn boldOn(self: *Terminal) !void {
try self.info.writeString(.enter_bold_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.enter_bold_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn boldOff(self: *Terminal) !void { pub fn boldOff(self: *Terminal) !void {
try self.info.writeString(.exit_bold_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.exit_bold_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn italicsOn(self: *Terminal) !void { pub fn italicsOn(self: *Terminal) !void {
try self.info.writeString(.enter_italics_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.enter_italics_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn italicsOff(self: *Terminal) !void { pub fn italicsOff(self: *Terminal) !void {
try self.info.writeString(.exit_italics_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.exit_italics_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn underlineOn(self: *Terminal) !void { pub fn underlineOn(self: *Terminal) !void {
try self.info.writeString(.enter_underline_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.enter_underline_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn underlineOff(self: *Terminal) !void { pub fn underlineOff(self: *Terminal) !void {
try self.info.writeString(.exit_underline_mode, self.tty.writer(), &[_]u32{}); try self.info.writeString(.exit_underline_mode, self.buffered_writer.writer(), &[_]u32{});
} }
pub fn clearScreen(self: *Terminal) !void { pub fn clearScreen(self: *Terminal) !void {
try self.info.writeString(.clear_screen, self.tty.writer(), &[_]u32{}); try self.info.writeString(.clear_screen, self.buffered_writer.writer(), &[_]u32{});
} }
// pub fn clearRegion(self: *Terminal, x: u32, y: u32, width: u32, height: u32) !void { // pub fn clearRegion(self: *Terminal, x: u32, y: u32, width: u32, height: u32) !void {
@ -297,7 +302,7 @@ pub const Terminal = struct {
// } // }
pub fn setFg(self: *Terminal, color: Color) !void { pub fn setFg(self: *Terminal, color: Color) !void {
try self.info.writeString(.set_rgb_foreground, self.tty.writer(), &[_]u32{ try self.info.writeString(.set_rgb_foreground, self.buffered_writer.writer(), &[_]u32{
@intFromFloat(color.r * 0xff), @intFromFloat(color.r * 0xff),
@intFromFloat(color.g * 0xff), @intFromFloat(color.g * 0xff),
@intFromFloat(color.b * 0xff), @intFromFloat(color.b * 0xff),
@ -305,7 +310,7 @@ pub const Terminal = struct {
} }
pub fn setBg(self: *Terminal, color: Color) !void { pub fn setBg(self: *Terminal, color: Color) !void {
try self.info.writeString(.set_rgb_background, self.tty.writer(), &[_]u32{ try self.info.writeString(.set_rgb_background, self.buffered_writer.writer(), &[_]u32{
@intFromFloat(color.r * 0xff), @intFromFloat(color.r * 0xff),
@intFromFloat(color.g * 0xff), @intFromFloat(color.g * 0xff),
@intFromFloat(color.b * 0xff), @intFromFloat(color.b * 0xff),