diff --git a/readme.md b/readme.md index d0d137b..8a12e39 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,13 @@ -# Ly - a TUI display manager +# Ly with image support - a TUI display manager with image support ![Ly screenshot](.github/screenshot.png "Ly screenshot") Ly is a lightweight TUI (ncurses-like) display manager for Linux and BSD. +## Create your Custom Image +Use [**LyArt**](https://augusto-p.github.io/ly-Image-maker/) To Create Your Image Here + + ## Dependencies - Compile-time: - zig >=0.12.0 diff --git a/res/config.ini b/res/config.ini index 1d28cb8..9cc5dbf 100644 --- a/res/config.ini +++ b/res/config.ini @@ -33,8 +33,10 @@ # none -> Nothing # doom -> PSX DOOM fire # matrix -> CMatrix -animation = none +# image -> Image +animation = image +image_path = /etc/ly/Img.lyim # Stop the animation after some time # 0 -> Run forever # 1..2e12 -> Stop the animation after this many seconds diff --git a/res/default_img.lyim b/res/default_img.lyim new file mode 100644 index 0000000..74da981 --- /dev/null +++ b/res/default_img.lyim @@ -0,0 +1 @@ +WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN333333333Y!!!!!!!'WWWWWWWW WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN33333338`Y!!!!!!!(WWWWWWWW WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN33333338!!!!!!!!!!!?WWWWWW WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN333333`Y!!!$<<<9!!!(`_WWWW WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN333338!!!!![37WX!!!!!_WWWW WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN33333\!!!(`[37WX`Y!!!$_WWW WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN33338!!!!(3337WWWY!!!!_WWW WWWWWWWWWWW333333333333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN3333Y!!$`[3337WWWX`Y!!$WWW WWWW_WWWWWW333333433333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN33339!!(333337WWWWWY!!!WWW WWWW?WWWWWW333333433333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN333Y!!![333337WWWWWX9!!(WW WWWX@WWWWWW333333<;3333333NNNNNNNNNNNNNNNNNNNNNNNNNNNN333Y!!@3333337WWWWWW\!!(WW WWWT= terminal_buffer.width or y >= terminal_buffer.height) { + @panic("Coordinates out of bounds of the buffer"); + } + + _ = termbox.tb_set_cell(@intCast(x), @intCast(y + 1), ' ', color + 1, color + 1); +} + +pub fn min(a: usize, b: usize) usize { + if (a < b) { + return a; + } + return b; +} + +pub fn readFile(path: []const u8) ![]const u8 { + var file_path = path; + const allocator = std.heap.page_allocator; + const fs = std.fs; + const cwd = fs.cwd(); + var flag = false; + var file = cwd.openFile(file_path, .{ .mode = .read_write}) catch |err| { + if (err == error.FileNotFound) { + file_path = "/etc/ly/default_img.lyim"; + flag = true; + + } + return err; + }; + if (flag){ + file = try cwd.openFile(file_path, .{ .mode = .read_write}); + } + + defer file.close(); + const file_size = (try file.stat()).size; + const buffer = try allocator.alloc(u8, file_size); + _ = try file.readAll(buffer); + + const Text_size = buffer.len * 2; + var Text = try allocator.alloc(u8, Text_size); + var Index:usize = 0; + + for (buffer) |c| { + if (c != ' ') { + const Nchar: usize = getAsciiChar(c); + const NBinary: [6]u8 = getBinary(Nchar - 33); + const ColorABin: [3]u8 = getBinPart(NBinary, 1); + const ColorBBin: [3]u8 = getBinPart(NBinary, 2); + const ColorA: usize = binarytoUsize(ColorABin); + const ColorB: usize = binarytoUsize(ColorBBin); + Text[Index] = UsizeToU8(ColorA); + Index += 1; + Text[Index] = UsizeToU8(ColorB); + Index += 1; + }else{ + Text[Index] = '\n'; + Index += 1; + } + } + + return Text[0..Index]; + +} + +pub fn writeTextToFile(file_path: []const u8, text: []const u8) !void { + var file = try std.fs.cwd().createFile(file_path, .{ .truncate = true }); + defer file.close(); + try file.writeAll(text); +} + +pub fn getAsciiChar(char: u8) usize { + const ascii_table = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; + var index: usize = 0; + while (index < ascii_table.len) { + if (ascii_table[index] == char) { + return index + 32; + } + index += 1; + } + return 0; +} + + +pub fn getBinary(N: usize) [6]u8 { + var binary: [6]u8 = undefined; + var num: usize = N; + var index: usize = 6; + while (num > 1) { + if (num % 2 == 0) { + binary[index-1] = '0'; + } else { + binary[index-1] = '1'; + } + + + num = num / 2; + index -= 1; + } + if (num == 0) { + binary[index-1] = '0'; + } else { + binary[index-1] = '1'; + } + + index -= 1; + while (index > 0) { + binary[index-1] = '0'; + index -= 1; + } + + + + return binary; +} + +pub fn getBinPart(Bin: [6]u8, part:usize) [3]u8{ + var binary: [3]u8 = undefined; + if (part == 1){ + binary[0] = Bin[0]; + binary[1] = Bin[1]; + binary[2] = Bin[2]; + }else{ + binary[0] = Bin[3]; + binary[1] = Bin[4]; + binary[2] = Bin[5]; + } + return binary; +} + +pub fn UsizeToU8(dec: usize) u8{ + + if(dec == 0){ + return '0'; + }else if(dec == 1){ + return '1'; + }else if(dec == 2){ + return '2'; + }else if(dec == 3){ + return '3'; + }else if(dec == 4){ + return '4'; + }else if(dec == 5){ + return '5'; + }else if(dec == 6){ + return '6'; + }else if(dec == 7){ + return '7'; + }else if(dec == 8){ + return '8'; + }else if(dec == 9){ + return '9'; + }else{ + return '0'; + } + +} + +pub fn binarytoUsize(slice: [3]u8) usize { + var result: usize = 0; + for (slice) |bit| { + result = result * 2 + (bit-48); + } + return result; +} diff --git a/src/config/Config.zig b/src/config/Config.zig index 38c8b4c..b5818aa 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -9,6 +9,7 @@ const Bigclock = enums.Bigclock; animation: Animation = .none, animation_timeout_sec: u12 = 0, asterisk: ?u8 = '*', +image_path: []const u8 = "", auth_fails: u64 = 10, bg: u16 = 0, bigclock: Bigclock = .none, diff --git a/src/config/migrator.zig b/src/config/migrator.zig index ad7c378..ee64be0 100644 --- a/src/config/migrator.zig +++ b/src/config/migrator.zig @@ -30,6 +30,7 @@ pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniFie mapped_field.value = switch (animation) { 0 => "doom", 1 => "matrix", + 2 => "image", else => "none", }; diff --git a/src/enums.zig b/src/enums.zig index ad0cc47..47f1dff 100644 --- a/src/enums.zig +++ b/src/enums.zig @@ -2,6 +2,7 @@ pub const Animation = enum { none, doom, matrix, + image, }; pub const DisplayServer = enum { diff --git a/src/main.zig b/src/main.zig index 4afefad..4af4606 100644 --- a/src/main.zig +++ b/src/main.zig @@ -8,6 +8,7 @@ const bigclock = @import("bigclock.zig"); const interop = @import("interop.zig"); const Doom = @import("animations/Doom.zig"); const Matrix = @import("animations/Matrix.zig"); +const Image = @import("animations/Image.zig"); const TerminalBuffer = @import("tui/TerminalBuffer.zig"); const Session = @import("tui/components/Session.zig"); const Text = @import("tui/components/Text.zig"); @@ -303,17 +304,21 @@ pub fn main() !void { // Initialize the animation, if any var doom: Doom = undefined; var matrix: Matrix = undefined; + var image: Image = undefined; switch (config.animation) { .none => {}, .doom => doom = try Doom.init(allocator, &buffer), .matrix => matrix = try Matrix.init(allocator, &buffer, config.cmatrix_fg), + .image => image = try Image.init(allocator, &buffer, config.image_path), + } defer { switch (config.animation) { .none => {}, .doom => doom.deinit(), .matrix => matrix.deinit(), + .image => {}, } } @@ -365,6 +370,7 @@ pub fn main() !void { .matrix => matrix.realloc() catch { try info_line.addMessage(lang.err_alloc, config.error_bg, config.error_fg); }, + .image => {}, } update = true; @@ -378,11 +384,14 @@ pub fn main() !void { _ = termbox.tb_clear(); if (!animation_timed_out) { + switch (config.animation) { .none => {}, .doom => doom.draw(), .matrix => matrix.draw(), + .image => try image.draw(), } + } if (config.bigclock != .none and buffer.box_height + (bigclock.HEIGHT + 2) * 2 < buffer.height) draw_big_clock: { @@ -542,6 +551,7 @@ pub fn main() !void { .none => {}, .doom => doom.deinit(), .matrix => matrix.deinit(), + .image => {}, } } } else if (config.bigclock != .none and config.clock == null) {