mirror of
https://github.com/fairyglade/ly.git
synced 2026-02-04 08:24:55 +00:00
Move more termbox usage into TerminalBuffer
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
95
src/main.zig
95
src/main.zig
@@ -49,12 +49,12 @@ fn signalHandler(i: c_int) callconv(.c) void {
|
|||||||
_ = std.c.waitpid(session_pid, &status, 0);
|
_ = std.c.waitpid(session_pid, &status, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = termbox.tb_shutdown();
|
TerminalBuffer.shutdownStatic();
|
||||||
std.c.exit(i);
|
std.c.exit(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ttyControlTransferSignalHandler(_: c_int) callconv(.c) void {
|
fn ttyControlTransferSignalHandler(_: c_int) callconv(.c) void {
|
||||||
_ = termbox.tb_shutdown();
|
TerminalBuffer.shutdownStatic();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConfigError = struct {
|
const ConfigError = struct {
|
||||||
@@ -303,37 +303,8 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize termbox
|
|
||||||
try log_writer.writeAll("initializing termbox2\n");
|
|
||||||
_ = termbox.tb_init();
|
|
||||||
defer {
|
|
||||||
log_writer.writeAll("shutting down termbox2\n") catch {};
|
|
||||||
_ = termbox.tb_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
const act = std.posix.Sigaction{
|
|
||||||
.handler = .{ .handler = &signalHandler },
|
|
||||||
.mask = std.posix.sigemptyset(),
|
|
||||||
.flags = 0,
|
|
||||||
};
|
|
||||||
std.posix.sigaction(std.posix.SIG.TERM, &act, null);
|
|
||||||
|
|
||||||
if (config.full_color) {
|
|
||||||
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_TRUECOLOR);
|
|
||||||
try log_writer.writeAll("termbox2 set to 24-bit color output mode\n");
|
|
||||||
} else {
|
|
||||||
try log_writer.writeAll("termbox2 set to eight-color output mode\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = termbox.tb_clear();
|
|
||||||
|
|
||||||
// Let's take some precautions here and clear the back buffer as well
|
|
||||||
try ttyClearScreen();
|
|
||||||
|
|
||||||
// Needed to reset termbox after auth
|
|
||||||
const tb_termios = try std.posix.tcgetattr(std.posix.STDIN_FILENO);
|
|
||||||
|
|
||||||
// Initialize terminal buffer
|
// Initialize terminal buffer
|
||||||
|
try log_writer.writeAll("initializing terminal buffer\n");
|
||||||
const labels_max_length = @max(lang.login.len, lang.password.len);
|
const labels_max_length = @max(lang.login.len, lang.password.len);
|
||||||
|
|
||||||
var seed: u64 = undefined;
|
var seed: u64 = undefined;
|
||||||
@@ -349,10 +320,22 @@ pub fn main() !void {
|
|||||||
.margin_box_h = config.margin_box_h,
|
.margin_box_h = config.margin_box_h,
|
||||||
.margin_box_v = config.margin_box_v,
|
.margin_box_v = config.margin_box_v,
|
||||||
.input_len = config.input_len,
|
.input_len = config.input_len,
|
||||||
|
.full_color = config.full_color,
|
||||||
|
.labels_max_length = labels_max_length,
|
||||||
|
.is_tty = true,
|
||||||
};
|
};
|
||||||
var buffer = TerminalBuffer.init(buffer_options, labels_max_length, random);
|
var buffer = try TerminalBuffer.init(buffer_options, &log_file, random);
|
||||||
|
defer {
|
||||||
|
log_writer.writeAll("shutting down terminal buffer\n") catch {};
|
||||||
|
TerminalBuffer.shutdownStatic();
|
||||||
|
}
|
||||||
|
|
||||||
try log_writer.print("screen resolution is {d}x{d}\n", .{ buffer.width, buffer.height });
|
const act = std.posix.Sigaction{
|
||||||
|
.handler = .{ .handler = &signalHandler },
|
||||||
|
.mask = std.posix.sigemptyset(),
|
||||||
|
.flags = 0,
|
||||||
|
};
|
||||||
|
std.posix.sigaction(std.posix.SIG.TERM, &act, null);
|
||||||
|
|
||||||
// Initialize components
|
// Initialize components
|
||||||
var info_line = InfoLine.init(allocator, &buffer);
|
var info_line = InfoLine.init(allocator, &buffer);
|
||||||
@@ -637,10 +620,10 @@ pub fn main() !void {
|
|||||||
if (!update or animate) {
|
if (!update or animate) {
|
||||||
if (!update) std.Thread.sleep(std.time.ns_per_ms * 100);
|
if (!update) std.Thread.sleep(std.time.ns_per_ms * 100);
|
||||||
|
|
||||||
_ = termbox.tb_present(); // Required to update tb_width() and tb_height()
|
// Required to update tb_width() and tb_height()
|
||||||
|
const new_dimensions = TerminalBuffer.presentBufferStatic();
|
||||||
const width: usize = @intCast(termbox.tb_width());
|
const width = new_dimensions.width;
|
||||||
const height: usize = @intCast(termbox.tb_height());
|
const height = new_dimensions.height;
|
||||||
|
|
||||||
if (width != buffer.width or height != buffer.height) {
|
if (width != buffer.width or height != buffer.height) {
|
||||||
// If it did change, then update the cell buffer, reallocate the current animation's buffers, and force a draw update
|
// If it did change, then update the cell buffer, reallocate the current animation's buffers, and force a draw update
|
||||||
@@ -670,11 +653,11 @@ pub fn main() !void {
|
|||||||
auth_fails = 0;
|
auth_fails = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = termbox.tb_present();
|
_ = TerminalBuffer.presentBufferStatic();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = termbox.tb_clear();
|
try TerminalBuffer.clearScreenStatic(false);
|
||||||
|
|
||||||
var length: usize = config.edge_margin;
|
var length: usize = config.edge_margin;
|
||||||
|
|
||||||
@@ -859,7 +842,7 @@ pub fn main() !void {
|
|||||||
login.label.draw();
|
login.label.draw();
|
||||||
password.draw();
|
password.draw();
|
||||||
|
|
||||||
_ = termbox.tb_present();
|
_ = TerminalBuffer.presentBufferStatic();
|
||||||
}
|
}
|
||||||
|
|
||||||
var timeout: i32 = -1;
|
var timeout: i32 = -1;
|
||||||
@@ -1021,7 +1004,7 @@ pub fn main() !void {
|
|||||||
try log_writer.print("failed to clear info line: {s}\n", .{@errorName(err)});
|
try log_writer.print("failed to clear info line: {s}\n", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
info_line.label.draw();
|
info_line.label.draw();
|
||||||
_ = termbox.tb_present();
|
_ = TerminalBuffer.presentBufferStatic();
|
||||||
break :authenticate;
|
break :authenticate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,7 +1014,7 @@ pub fn main() !void {
|
|||||||
try log_writer.print("failed to clear info line: {s}\n", .{@errorName(err)});
|
try log_writer.print("failed to clear info line: {s}\n", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
info_line.label.draw();
|
info_line.label.draw();
|
||||||
_ = termbox.tb_present();
|
_ = TerminalBuffer.presentBufferStatic();
|
||||||
|
|
||||||
if (config.save) save_last_settings: {
|
if (config.save) save_last_settings: {
|
||||||
// It isn't worth cluttering the code with precise error
|
// It isn't worth cluttering the code with precise error
|
||||||
@@ -1120,12 +1103,7 @@ pub fn main() !void {
|
|||||||
try log_file.reinit();
|
try log_file.reinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take back control of the TTY
|
try buffer.reclaim();
|
||||||
_ = termbox.tb_init();
|
|
||||||
|
|
||||||
if (config.full_color) {
|
|
||||||
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_TRUECOLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auth_err = shared_err.readError();
|
const auth_err = shared_err.readError();
|
||||||
if (auth_err) |err| {
|
if (auth_err) |err| {
|
||||||
@@ -1148,18 +1126,14 @@ pub fn main() !void {
|
|||||||
try log_writer.writeAll("logged out\n");
|
try log_writer.writeAll("logged out\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
try std.posix.tcsetattr(std.posix.STDIN_FILENO, .FLUSH, tb_termios);
|
|
||||||
|
|
||||||
if (config.auth_fails == 0 or auth_fails < config.auth_fails) {
|
if (config.auth_fails == 0 or auth_fails < config.auth_fails) {
|
||||||
_ = termbox.tb_clear();
|
try TerminalBuffer.clearScreenStatic(true);
|
||||||
try ttyClearScreen();
|
|
||||||
|
|
||||||
update = true;
|
update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore the cursor
|
// Restore the cursor
|
||||||
_ = termbox.tb_set_cursor(0, 0);
|
TerminalBuffer.setCursorStatic(0, 0);
|
||||||
_ = termbox.tb_present();
|
_ = TerminalBuffer.presentBufferStatic();
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
if (!insert_mode) {
|
if (!insert_mode) {
|
||||||
@@ -1208,13 +1182,6 @@ fn configErrorHandler(type_name: []const u8, key: []const u8, value: []const u8,
|
|||||||
}) catch return;
|
}) catch return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ttyClearScreen() !void {
|
|
||||||
// Clear the TTY because termbox2 doesn't seem to do it properly
|
|
||||||
const capability = termbox.global.caps[termbox.TB_CAP_CLEAR_SCREEN];
|
|
||||||
const capability_slice = std.mem.span(capability);
|
|
||||||
_ = try std.posix.write(termbox.global.ttyfd, capability_slice);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn addOtherEnvironment(session: *Session, lang: Lang, display_server: DisplayServer, exec: ?[]const u8) !void {
|
fn addOtherEnvironment(session: *Session, lang: Lang, display_server: DisplayServer, exec: ?[]const u8) !void {
|
||||||
const name = switch (display_server) {
|
const name = switch (display_server) {
|
||||||
.shell => lang.shell,
|
.shell => lang.shell,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ pub const termbox = @import("termbox2");
|
|||||||
const Random = std.Random;
|
const Random = std.Random;
|
||||||
|
|
||||||
const interop = ly_core.interop;
|
const interop = ly_core.interop;
|
||||||
|
const LogFile = ly_core.LogFile;
|
||||||
|
|
||||||
const TerminalBuffer = @This();
|
const TerminalBuffer = @This();
|
||||||
|
|
||||||
@@ -17,6 +18,9 @@ pub const InitOptions = struct {
|
|||||||
margin_box_h: u8,
|
margin_box_h: u8,
|
||||||
margin_box_v: u8,
|
margin_box_v: u8,
|
||||||
input_len: u8,
|
input_len: u8,
|
||||||
|
full_color: bool,
|
||||||
|
labels_max_length: usize,
|
||||||
|
is_tty: bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Styling = struct {
|
pub const Styling = struct {
|
||||||
@@ -81,12 +85,36 @@ box_height: usize,
|
|||||||
margin_box_v: u8,
|
margin_box_v: u8,
|
||||||
margin_box_h: u8,
|
margin_box_h: u8,
|
||||||
blank_cell: Cell,
|
blank_cell: Cell,
|
||||||
|
full_color: bool,
|
||||||
|
termios: ?std.posix.termios,
|
||||||
|
|
||||||
|
pub fn init(options: InitOptions, log_file: *LogFile, random: Random) !TerminalBuffer {
|
||||||
|
var log_writer = &log_file.file_writer.interface;
|
||||||
|
|
||||||
|
// Initialize termbox
|
||||||
|
_ = termbox.tb_init();
|
||||||
|
|
||||||
|
if (options.full_color) {
|
||||||
|
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_TRUECOLOR);
|
||||||
|
try log_writer.writeAll("termbox2 set to 24-bit color output mode\n");
|
||||||
|
} else {
|
||||||
|
try log_writer.writeAll("termbox2 set to eight-color output mode\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = termbox.tb_clear();
|
||||||
|
|
||||||
|
// Let's take some precautions here and clear the back buffer as well
|
||||||
|
try clearBackBuffer();
|
||||||
|
|
||||||
|
const width: usize = @intCast(termbox.tb_width());
|
||||||
|
const height: usize = @intCast(termbox.tb_height());
|
||||||
|
|
||||||
|
try log_writer.print("screen resolution is {d}x{d}\n", .{ width, height });
|
||||||
|
|
||||||
pub fn init(options: InitOptions, labels_max_length: usize, random: Random) TerminalBuffer {
|
|
||||||
return .{
|
return .{
|
||||||
.random = random,
|
.random = random,
|
||||||
.width = @intCast(termbox.tb_width()),
|
.width = width,
|
||||||
.height = @intCast(termbox.tb_height()),
|
.height = height,
|
||||||
.fg = options.fg,
|
.fg = options.fg,
|
||||||
.bg = options.bg,
|
.bg = options.bg,
|
||||||
.border_fg = options.border_fg,
|
.border_fg = options.border_fg,
|
||||||
@@ -109,17 +137,54 @@ pub fn init(options: InitOptions, labels_max_length: usize, random: Random) Term
|
|||||||
.left = '|',
|
.left = '|',
|
||||||
.right = '|',
|
.right = '|',
|
||||||
},
|
},
|
||||||
.labels_max_length = labels_max_length,
|
.labels_max_length = options.labels_max_length,
|
||||||
.box_x = 0,
|
.box_x = 0,
|
||||||
.box_y = 0,
|
.box_y = 0,
|
||||||
.box_width = (2 * options.margin_box_h) + options.input_len + 1 + labels_max_length,
|
.box_width = (2 * options.margin_box_h) + options.input_len + 1 + options.labels_max_length,
|
||||||
.box_height = 7 + (2 * options.margin_box_v),
|
.box_height = 7 + (2 * options.margin_box_v),
|
||||||
.margin_box_v = options.margin_box_v,
|
.margin_box_v = options.margin_box_v,
|
||||||
.margin_box_h = options.margin_box_h,
|
.margin_box_h = options.margin_box_h,
|
||||||
.blank_cell = Cell.init(' ', options.fg, options.bg),
|
.blank_cell = Cell.init(' ', options.fg, options.bg),
|
||||||
|
.full_color = options.full_color,
|
||||||
|
// Needed to reclaim the TTY after giving up its control
|
||||||
|
.termios = try std.posix.tcgetattr(std.posix.STDIN_FILENO),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn setCursorStatic(x: usize, y: usize) void {
|
||||||
|
_ = termbox.tb_set_cursor(@intCast(x), @intCast(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clearScreenStatic(clear_back_buffer: bool) !void {
|
||||||
|
_ = termbox.tb_clear();
|
||||||
|
if (clear_back_buffer) try clearBackBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shutdownStatic() void {
|
||||||
|
_ = termbox.tb_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn presentBufferStatic() struct { width: usize, height: usize } {
|
||||||
|
_ = termbox.tb_present();
|
||||||
|
return .{
|
||||||
|
.width = @intCast(termbox.tb_width()),
|
||||||
|
.height = @intCast(termbox.tb_height()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reclaim(self: TerminalBuffer) !void {
|
||||||
|
if (self.termios) |termios| {
|
||||||
|
// Take back control of the TTY
|
||||||
|
_ = termbox.tb_init();
|
||||||
|
|
||||||
|
if (self.full_color) {
|
||||||
|
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_TRUECOLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
try std.posix.tcsetattr(std.posix.STDIN_FILENO, .FLUSH, termios);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cascade(self: TerminalBuffer) bool {
|
pub fn cascade(self: TerminalBuffer) bool {
|
||||||
var changed = false;
|
var changed = false;
|
||||||
var y = self.height - 2;
|
var y = self.height - 2;
|
||||||
@@ -260,3 +325,10 @@ pub fn strWidth(str: []const u8) !u8 {
|
|||||||
|
|
||||||
return @intCast(i);
|
return @intCast(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clearBackBuffer() !void {
|
||||||
|
// Clear the TTY because termbox2 doesn't seem to do it properly
|
||||||
|
const capability = termbox.global.caps[termbox.TB_CAP_CLEAR_SCREEN];
|
||||||
|
const capability_slice = std.mem.span(capability);
|
||||||
|
_ = try std.posix.write(termbox.global.ttyfd, capability_slice);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user