mirror of https://github.com/fairyglade/ly.git
Enable true color output (closes #705)
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
parent
a766dc2b9c
commit
d0ccaa4d69
|
@ -72,6 +72,7 @@ pub fn build(b: *std.Build) !void {
|
|||
.optimize = optimize,
|
||||
});
|
||||
translate_c.defineCMacroRaw("TB_IMPL");
|
||||
translate_c.defineCMacro("TB_OPT_ATTR_W", "32"); // Enable 24-bit color support + styling (32-bit)
|
||||
const termbox2 = translate_c.addModule("termbox2");
|
||||
exe.root_module.addImport("termbox2", termbox2);
|
||||
|
||||
|
|
|
@ -1,33 +1,19 @@
|
|||
# The color settings in Ly take a digit 0-8 corresponding to:
|
||||
#define TB_DEFAULT 0x00
|
||||
#define TB_BLACK 0x01
|
||||
#define TB_RED 0x02
|
||||
#define TB_GREEN 0x03
|
||||
#define TB_YELLOW 0x04
|
||||
#define TB_BLUE 0x05
|
||||
#define TB_MAGENTA 0x06
|
||||
#define TB_CYAN 0x07
|
||||
#define TB_WHITE 0x08
|
||||
# The default color varies, but usually it makes the background black and the foreground white.
|
||||
# You can also combine these colors with the following style attributes using bitwise OR:
|
||||
#define TB_BOLD 0x0100
|
||||
#define TB_UNDERLINE 0x0200
|
||||
#define TB_REVERSE 0x0400
|
||||
#define TB_ITALIC 0x0800
|
||||
#define TB_BLINK 0x1000
|
||||
#define TB_HI_BLACK 0x2000
|
||||
#define TB_BRIGHT 0x4000
|
||||
#define TB_DIM 0x8000
|
||||
# For example, to set the foreground color to red and bold, you would do 0x02 | 0x0100 = 0x0102.
|
||||
# Note that you must pre-calculate the value because Ly doesn't parse bitwise OR operations in its config.
|
||||
#
|
||||
# Moreover, to set the VT color palette, you are encouraged to use another tool such as
|
||||
# mkinitcpio-colors (https://github.com/evanpurkhiser/mkinitcpio-colors). Note that the color palette defined with
|
||||
# mkinitcpio-colors takes 16 colors (0-15), only values 0-8 are valid with Ly and these values do not correspond
|
||||
# exactly. For instance, in defining palettes with mkinitcpio-colors, the order is black, dark red, dark green, brown, dark
|
||||
# blue, dark purple, dark cyan, light gray, dark gray, bright red, bright green, yellow, bright blue, bright purple, bright
|
||||
# cyan, and white, indexed in that order 0 through 15. For example, the color defined for white (indexed at 15 in the mkinitcpio
|
||||
# config) will be used by Ly for fg = 0x0008.
|
||||
# Ly supports 24-bit true color with styling, which means each color is a 32-bit value.
|
||||
# The format is 0xSSRRGGBB, where SS is the styling, RR is red, GG is green, and BB is blue.
|
||||
# Here are the possible styling options:
|
||||
#define TB_BOLD 0x01000000
|
||||
#define TB_UNDERLINE 0x02000000
|
||||
#define TB_REVERSE 0x04000000
|
||||
#define TB_ITALIC 0x08000000
|
||||
#define TB_BLINK 0x10000000
|
||||
#define TB_HI_BLACK 0x20000000
|
||||
#define TB_BRIGHT 0x40000000
|
||||
#define TB_DIM 0x80000000
|
||||
# Programmatically, you'd apply them using the bitwise OR operator (|), but because Ly's
|
||||
# configuration doesn't support using it, you have to manually compute the color value.
|
||||
# Note that, if you want to use the default color value of the terminal, you can use the
|
||||
# special value 0x00000000. This means that, if you want to use black, you *must* use
|
||||
# the styling option TB_HI_BLACK (the RGB values are ignored when using this option).
|
||||
|
||||
# The active animation
|
||||
# none -> Nothing
|
||||
|
@ -50,7 +36,7 @@ asterisk = *
|
|||
auth_fails = 10
|
||||
|
||||
# Background color id
|
||||
bg = 0x0000
|
||||
bg = 0x00000000
|
||||
|
||||
# Change the state and language of the big clock
|
||||
# none -> Disabled (default)
|
||||
|
@ -63,7 +49,7 @@ bigclock = none
|
|||
blank_box = true
|
||||
|
||||
# Border foreground color id
|
||||
border_fg = 0x0008
|
||||
border_fg = 0x00FFFFFF
|
||||
|
||||
# Title to show at the top of the main box
|
||||
# If set to null, none will be shown
|
||||
|
@ -89,16 +75,16 @@ clear_password = false
|
|||
clock = null
|
||||
|
||||
# CMatrix animation foreground color id
|
||||
cmatrix_fg = 0x0003
|
||||
cmatrix_fg = 0x0000FF00
|
||||
|
||||
# Color mixing animation first color id
|
||||
colormix_col1 = 0x0002
|
||||
colormix_col1 = 0x00FF0000
|
||||
|
||||
# Color mixing animation second color id
|
||||
colormix_col2 = 0x0005
|
||||
colormix_col2 = 0x000000FF
|
||||
|
||||
# Color mixing animation third color id
|
||||
colormix_col3 = 0x0001
|
||||
colormix_col3 = 0x20000000
|
||||
|
||||
# Console path
|
||||
console_dev = /dev/console
|
||||
|
@ -108,14 +94,14 @@ console_dev = /dev/console
|
|||
default_input = login
|
||||
|
||||
# Error background color id
|
||||
error_bg = 0x0000
|
||||
error_bg = 0x00000000
|
||||
|
||||
# Error foreground color id
|
||||
# Default is red and bold: TB_RED | TB_BOLD
|
||||
error_fg = 0x0102
|
||||
# Default is red and bold
|
||||
error_fg = 0x11FF0000
|
||||
|
||||
# Foreground color id
|
||||
fg = 0x0008
|
||||
fg = 0x00FFFFFF
|
||||
|
||||
# Remove main box borders
|
||||
hide_borders = false
|
||||
|
|
|
@ -20,7 +20,7 @@ pattern_cos_mod: f32,
|
|||
pattern_sin_mod: f32,
|
||||
palette: [palette_len]utils.Cell,
|
||||
|
||||
pub fn init(terminal_buffer: *TerminalBuffer, col1: u16, col2: u16, col3: u16) ColorMix {
|
||||
pub fn init(terminal_buffer: *TerminalBuffer, col1: u32, col2: u32, col3: u32) ColorMix {
|
||||
return .{
|
||||
.terminal_buffer = terminal_buffer,
|
||||
.frames = 0,
|
||||
|
|
|
@ -34,9 +34,9 @@ dots: []Dot,
|
|||
lines: []Line,
|
||||
frame: u64,
|
||||
count: u64,
|
||||
fg_ini: u16,
|
||||
fg_ini: u32,
|
||||
|
||||
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, fg_ini: u16) !Matrix {
|
||||
pub fn init(allocator: Allocator, terminal_buffer: *TerminalBuffer, fg_ini: u32) !Matrix {
|
||||
const dots = try allocator.alloc(Dot, terminal_buffer.width * (terminal_buffer.height + 1));
|
||||
const lines = try allocator.alloc(Line, terminal_buffer.width);
|
||||
|
||||
|
|
|
@ -2,17 +2,17 @@ const std = @import("std");
|
|||
const interop = @import("interop.zig");
|
||||
const utils = @import("tui/utils.zig");
|
||||
const enums = @import("enums.zig");
|
||||
const Lang = @import("bigclock/Lang.zig");
|
||||
const en = @import("bigclock/en.zig");
|
||||
const fa = @import("bigclock/fa.zig");
|
||||
const Lang = @import("bigclock/Lang.zig");
|
||||
const en = @import("bigclock/en.zig");
|
||||
const fa = @import("bigclock/fa.zig");
|
||||
|
||||
const termbox = interop.termbox;
|
||||
const Bigclock = enums.Bigclock;
|
||||
pub const WIDTH = Lang.WIDTH;
|
||||
const termbox = interop.termbox;
|
||||
const Bigclock = enums.Bigclock;
|
||||
pub const WIDTH = Lang.WIDTH;
|
||||
pub const HEIGHT = Lang.HEIGHT;
|
||||
pub const SIZE = Lang.SIZE;
|
||||
pub const SIZE = Lang.SIZE;
|
||||
|
||||
pub fn clockCell(animate: bool, char: u8, fg: u16, bg: u16, bigclock: Bigclock) [SIZE]utils.Cell {
|
||||
pub fn clockCell(animate: bool, char: u8, fg: u32, bg: u32, bigclock: Bigclock) [SIZE]utils.Cell {
|
||||
var cells: [SIZE]utils.Cell = undefined;
|
||||
|
||||
var tv: interop.system_time.timeval = undefined;
|
||||
|
@ -37,9 +37,9 @@ pub fn alphaBlit(x: usize, y: usize, tb_width: usize, tb_height: usize, cells: [
|
|||
|
||||
fn toBigNumber(char: u8, bigclock: Bigclock) []const u21 {
|
||||
const locale_chars = switch (bigclock) {
|
||||
.fa => fa.locale_chars,
|
||||
.en => en.locale_chars,
|
||||
.none => unreachable,
|
||||
.fa => fa.locale_chars,
|
||||
.en => en.locale_chars,
|
||||
.none => unreachable,
|
||||
};
|
||||
return switch (char) {
|
||||
'0' => &locale_chars.ZERO,
|
||||
|
|
|
@ -10,10 +10,10 @@ animation: Animation = .none,
|
|||
animation_timeout_sec: u12 = 0,
|
||||
asterisk: ?u8 = '*',
|
||||
auth_fails: u64 = 10,
|
||||
bg: u16 = 0,
|
||||
bg: u32 = 0x00000000,
|
||||
bigclock: Bigclock = .none,
|
||||
blank_box: bool = true,
|
||||
border_fg: u16 = 8,
|
||||
border_fg: u32 = 0x00FFFFFF,
|
||||
box_title: ?[]const u8 = null,
|
||||
brightness_down_cmd: [:0]const u8 = build_options.prefix_directory ++ "/bin/brightnessctl -q s 10%-",
|
||||
brightness_down_key: []const u8 = "F5",
|
||||
|
@ -21,15 +21,15 @@ brightness_up_cmd: [:0]const u8 = build_options.prefix_directory ++ "/bin/bright
|
|||
brightness_up_key: []const u8 = "F6",
|
||||
clear_password: bool = false,
|
||||
clock: ?[:0]const u8 = null,
|
||||
cmatrix_fg: u16 = 3,
|
||||
colormix_col1: u16 = 2,
|
||||
colormix_col2: u16 = 5,
|
||||
colormix_col3: u16 = 1,
|
||||
cmatrix_fg: u32 = 0x0000FF00,
|
||||
colormix_col1: u32 = 0x00FF0000,
|
||||
colormix_col2: u32 = 0x000000FF,
|
||||
colormix_col3: u32 = 0x20000000,
|
||||
console_dev: []const u8 = "/dev/console",
|
||||
default_input: Input = .login,
|
||||
error_bg: u16 = 0,
|
||||
error_fg: u16 = 258,
|
||||
fg: u16 = 8,
|
||||
error_bg: u32 = 0x00000000,
|
||||
error_fg: u32 = 0x11FF0000,
|
||||
fg: u32 = 0x00FFFFFF,
|
||||
hide_borders: bool = false,
|
||||
hide_key_hints: bool = false,
|
||||
initial_info_text: ?[]const u8 = null,
|
||||
|
|
|
@ -2,9 +2,34 @@
|
|||
|
||||
const std = @import("std");
|
||||
const ini = @import("zigini");
|
||||
const interop = @import("../interop.zig");
|
||||
const Save = @import("Save.zig");
|
||||
const enums = @import("../enums.zig");
|
||||
|
||||
const termbox = interop.termbox;
|
||||
const color_properties = [_][]const u8{
|
||||
"bg",
|
||||
"border_fg",
|
||||
"cmatrix_fg",
|
||||
"colormix_col1",
|
||||
"colormix_col2",
|
||||
"colormix_col3",
|
||||
"error_bg",
|
||||
"error_fg",
|
||||
"fg",
|
||||
};
|
||||
const removed_properties = [_][]const u8{
|
||||
"wayland_specifier",
|
||||
"max_desktop_len",
|
||||
"max_login_len",
|
||||
"max_password_len",
|
||||
"mcookie_cmd",
|
||||
"term_reset_cmd",
|
||||
"term_restore_cursor_cmd",
|
||||
"x_cmd_setup",
|
||||
"wayland_cmd",
|
||||
};
|
||||
|
||||
var temporary_allocator = std.heap.page_allocator;
|
||||
|
||||
pub var maybe_animate: ?bool = null;
|
||||
|
@ -12,7 +37,7 @@ pub var maybe_save_file: ?[]const u8 = null;
|
|||
|
||||
pub var mapped_config_fields = false;
|
||||
|
||||
pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniField {
|
||||
pub fn configFieldHandler(allocator: std.mem.Allocator, field: ini.IniField) ?ini.IniField {
|
||||
if (std.mem.eql(u8, field.key, "animate")) {
|
||||
// The option doesn't exist anymore, but we save its value for "animation"
|
||||
maybe_animate = std.mem.eql(u8, field.value, "true");
|
||||
|
@ -37,6 +62,18 @@ pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniFie
|
|||
return mapped_field;
|
||||
}
|
||||
|
||||
inline for (color_properties) |property| {
|
||||
if (std.mem.eql(u8, field.key, property)) {
|
||||
// These options now uses a 32-bit RGB value instead of an arbitrary 16-bit integer
|
||||
const color = std.fmt.parseInt(u16, field.value, 0) catch return field;
|
||||
var mapped_field = field;
|
||||
|
||||
mapped_field.value = mapColor(allocator, color) catch return field;
|
||||
mapped_config_fields = true;
|
||||
return mapped_field;
|
||||
}
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, field.key, "blank_password")) {
|
||||
// The option has simply been renamed
|
||||
var mapped_field = field;
|
||||
|
@ -70,19 +107,12 @@ pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniFie
|
|||
return null;
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, field.key, "wayland_specifier") or
|
||||
std.mem.eql(u8, field.key, "max_desktop_len") or
|
||||
std.mem.eql(u8, field.key, "max_login_len") or
|
||||
std.mem.eql(u8, field.key, "max_password_len") or
|
||||
std.mem.eql(u8, field.key, "mcookie_cmd") or
|
||||
std.mem.eql(u8, field.key, "term_reset_cmd") or
|
||||
std.mem.eql(u8, field.key, "term_restore_cursor_cmd") or
|
||||
std.mem.eql(u8, field.key, "x_cmd_setup") or
|
||||
std.mem.eql(u8, field.key, "wayland_cmd"))
|
||||
{
|
||||
// The options don't exist anymore
|
||||
mapped_config_fields = true;
|
||||
return null;
|
||||
inline for (removed_properties) |property| {
|
||||
if (std.mem.eql(u8, field.key, property)) {
|
||||
// The options don't exist anymore
|
||||
mapped_config_fields = true;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (std.mem.eql(u8, field.key, "bigclock")) {
|
||||
|
@ -90,14 +120,14 @@ pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniFie
|
|||
// It also includes the ability to change active bigclock's language
|
||||
var mapped_field = field;
|
||||
|
||||
if (std.mem.eql(u8, field.value, "true")){
|
||||
if (std.mem.eql(u8, field.value, "true")) {
|
||||
mapped_field.value = "en";
|
||||
mapped_config_fields = true;
|
||||
}else if (std.mem.eql(u8, field.value, "false")){
|
||||
} else if (std.mem.eql(u8, field.value, "false")) {
|
||||
mapped_field.value = "none";
|
||||
mapped_config_fields = true;
|
||||
}
|
||||
|
||||
|
||||
return mapped_field;
|
||||
}
|
||||
|
||||
|
@ -142,3 +172,28 @@ pub fn tryMigrateSaveFile(user_buf: *[32]u8) Save {
|
|||
|
||||
return save;
|
||||
}
|
||||
|
||||
fn mapColor(allocator: std.mem.Allocator, color: u16) ![]const u8 {
|
||||
const color_no_styling = color & 0x00FF;
|
||||
const styling_only = color & 0xFF00;
|
||||
|
||||
var new_color: u32 = switch (color_no_styling) {
|
||||
termbox.TB_BLACK => termbox.TB_HI_BLACK,
|
||||
termbox.TB_RED => 0x00FF0000,
|
||||
termbox.TB_GREEN => 0x0000FF00,
|
||||
termbox.TB_YELLOW => 0x00FFFF00,
|
||||
termbox.TB_BLUE => 0x000000FF,
|
||||
termbox.TB_MAGENTA => 0x00FF00FF,
|
||||
termbox.TB_CYAN => 0x0000FFFF,
|
||||
termbox.TB_WHITE => 0x00FFFFFF,
|
||||
else => termbox.TB_DEFAULT,
|
||||
};
|
||||
|
||||
// Only applying styling if color isn't black and styling isn't also black
|
||||
if (!(new_color == termbox.TB_HI_BLACK and styling_only == termbox.TB_HI_BLACK)) {
|
||||
// Shift styling by 16 to the left to apply it to the new 32-bit color
|
||||
new_color |= @as(u32, @intCast(styling_only)) << 16;
|
||||
}
|
||||
|
||||
return try std.fmt.allocPrint(allocator, "0x{X}", .{new_color});
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ pub fn main() !void {
|
|||
};
|
||||
std.posix.sigaction(std.posix.SIG.TERM, &act, null);
|
||||
|
||||
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_NORMAL);
|
||||
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_TRUECOLOR);
|
||||
_ = termbox.tb_clear();
|
||||
|
||||
// Needed to reset termbox after auth
|
||||
|
@ -729,7 +729,7 @@ pub fn main() !void {
|
|||
|
||||
// Take back control of the TTY
|
||||
_ = termbox.tb_init();
|
||||
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_NORMAL);
|
||||
_ = termbox.tb_set_output_mode(termbox.TB_OUTPUT_TRUECOLOR);
|
||||
|
||||
const auth_err = shared_err.readError();
|
||||
if (auth_err) |err| {
|
||||
|
|
|
@ -14,9 +14,9 @@ random: Random,
|
|||
width: usize,
|
||||
height: usize,
|
||||
buffer: [*]termbox.tb_cell,
|
||||
fg: u16,
|
||||
bg: u16,
|
||||
border_fg: u16,
|
||||
fg: u32,
|
||||
bg: u32,
|
||||
border_fg: u32,
|
||||
box_chars: struct {
|
||||
left_up: u32,
|
||||
left_down: u32,
|
||||
|
@ -170,7 +170,7 @@ pub fn drawLabel(self: TerminalBuffer, text: []const u8, x: usize, y: usize) voi
|
|||
drawColorLabel(text, x, y, self.fg, self.bg);
|
||||
}
|
||||
|
||||
pub fn drawColorLabel(text: []const u8, x: usize, y: usize, fg: u16, bg: u16) void {
|
||||
pub fn drawColorLabel(text: []const u8, x: usize, y: usize, fg: u32, bg: u32) void {
|
||||
const yc: c_int = @intCast(y);
|
||||
const utf8view = std.unicode.Utf8View.init(text) catch return;
|
||||
var utf8 = utf8view.iterator();
|
||||
|
|
|
@ -12,8 +12,8 @@ const InfoLine = @This();
|
|||
const Message = struct {
|
||||
width: u8,
|
||||
text: []const u8,
|
||||
bg: u16,
|
||||
fg: u16,
|
||||
bg: u32,
|
||||
fg: u32,
|
||||
};
|
||||
|
||||
label: MessageLabel,
|
||||
|
@ -28,7 +28,7 @@ pub fn deinit(self: InfoLine) void {
|
|||
self.label.deinit();
|
||||
}
|
||||
|
||||
pub fn addMessage(self: *InfoLine, text: []const u8, bg: u16, fg: u16) !void {
|
||||
pub fn addMessage(self: *InfoLine, text: []const u8, bg: u32, fg: u32) !void {
|
||||
if (text.len == 0) return;
|
||||
|
||||
try self.label.addItem(.{
|
||||
|
|
|
@ -5,11 +5,11 @@ const termbox = interop.termbox;
|
|||
|
||||
pub const Cell = struct {
|
||||
ch: u32,
|
||||
fg: u16,
|
||||
bg: u16,
|
||||
fg: u32,
|
||||
bg: u32,
|
||||
};
|
||||
|
||||
pub fn initCell(ch: u32, fg: u16, bg: u16) Cell {
|
||||
pub fn initCell(ch: u32, fg: u32, bg: u32) Cell {
|
||||
return .{
|
||||
.ch = ch,
|
||||
.fg = fg,
|
||||
|
|
Loading…
Reference in New Issue