wip: fast
This commit is contained in:
parent
42db065ac5
commit
f7d243b2b7
7 changed files with 231 additions and 55 deletions
|
@ -36,6 +36,8 @@ pub fn build(b: *std.Build) void {
|
|||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
macos.linkFramework("IOKit");
|
||||
macos.linkFramework("CoreFoundation");
|
||||
|
||||
// This declares intent for the library to be installed into the standard
|
||||
// location when the user invokes the "install" step (the default step when
|
||||
|
@ -49,8 +51,10 @@ pub fn build(b: *std.Build) void {
|
|||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.addIncludePath(b.path("./include"));
|
||||
|
||||
exe.linkFramework("IOKIT");
|
||||
exe.linkFramework("CoreFoundation");
|
||||
exe.linkFramework("SystemConfiguration");
|
||||
exe.root_module.addImport("vaxis", vaxis);
|
||||
exe.root_module.addImport("objc", objc);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
.dependencies = .{
|
||||
.vaxis = .{
|
||||
.url = "https://github.com/rockorager/libvaxis/archive/refs/heads/main.tar.gz",
|
||||
.hash = "12209fb0db1467d24882f4a0fca367d25d7ef7353882270ba3b76382c185332c52ae",
|
||||
.hash = "12209e3e6a758023f77c35c88723209ca78f3e8f386cef27ea73ab5ea36d6f21e14f",
|
||||
},
|
||||
.objc = .{
|
||||
.url = "https://github.com/mitchellh/zig-objc/archive/refs/heads/main.tar.gz",
|
||||
|
|
BIN
src/assets/apple-white.png
Normal file
BIN
src/assets/apple-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
BIN
src/assets/freebsd.png
Normal file
BIN
src/assets/freebsd.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
121
src/macos.zig
121
src/macos.zig
|
@ -5,6 +5,11 @@ const c = @cImport({
|
|||
@cInclude("sys/utsname.h");
|
||||
@cInclude("sys/sysctl.h");
|
||||
@cInclude("sys/time.h");
|
||||
@cInclude("IOKit/IOKitLib.h");
|
||||
@cInclude("IOKit/ps/IOPowerSources.h");
|
||||
@cInclude("IOKit/ps/IOPSKeys.h");
|
||||
@cInclude("CoreFoundation/CoreFoundation.h");
|
||||
@cInclude("SystemConfiguration/SystemConfiguration.h");
|
||||
});
|
||||
const OsVersion = struct {
|
||||
name: []const u8,
|
||||
|
@ -57,6 +62,122 @@ pub fn macos_kernel_version(allocator: std.mem.Allocator) ![]const u8 {
|
|||
return buf;
|
||||
}
|
||||
|
||||
pub fn memory_info(allocator: std.mem.Allocator) ![]const u8 {
|
||||
var memsize: u64 = 0;
|
||||
var memsize_size: usize = @sizeOf(u64);
|
||||
|
||||
if (c.sysctlbyname("hw.memsize", &memsize, @as([*c]usize, &memsize_size), null, 0) < 0) {
|
||||
return error.NoMemInfo;
|
||||
}
|
||||
|
||||
const bingb: u64 = (1024 * 1024 * 1024);
|
||||
|
||||
const memsize_gb: u64 = @divFloor(memsize, bingb);
|
||||
return try std.fmt.allocPrint(allocator, ": {d} GiB\n", .{memsize_gb});
|
||||
}
|
||||
|
||||
// Helper function to create CFString from Zig string
|
||||
fn CFStringCreateWithCStringZig(s: []const u8) *c.__CFString {
|
||||
return @constCast(c.CFStringCreateWithCString(
|
||||
null, // Allocator (default: null)
|
||||
s.ptr, // C string pointer
|
||||
c.kCFStringEncodingUTF8, // Encoding (UTF-8)
|
||||
).?);
|
||||
}
|
||||
|
||||
pub fn get_vpn_info() !void {
|
||||
const infoz: []const u8 = "infoz";
|
||||
const cfstringref = CFStringCreateWithCStringZig(infoz);
|
||||
const prefs = c.SCPreferencesCreate(null, cfstringref, null);
|
||||
if (prefs == null) {
|
||||
return error.SCPreferencesCreateError;
|
||||
}
|
||||
|
||||
const networkServices = c.SCNetworkServiceCopyAll(prefs);
|
||||
if (networkServices == null) {
|
||||
return error.SCNetworkServiceCopyAllError;
|
||||
}
|
||||
|
||||
const count = c.CFArrayGetCount(networkServices);
|
||||
|
||||
std.debug.print("Network Services: {d}\n", .{count});
|
||||
|
||||
const zero: usize = 0;
|
||||
for (zero..@as(c.u_long, @intCast(count))) |index| {
|
||||
const long_index = @as(c_long, @intCast(index));
|
||||
const service: c.SCNetworkServiceRef = @ptrCast(c.CFArrayGetValueAtIndex(networkServices, long_index));
|
||||
const serviceName = c.SCNetworkServiceGetName(service);
|
||||
const bufferSize = 256;
|
||||
var buffer: [bufferSize]u8 = undefined;
|
||||
_ = c.CFStringGetCString(serviceName, &buffer[0], bufferSize, c.kCFStringEncodingUTF8);
|
||||
const service_name = std.mem.sliceTo(buffer[0..], 0);
|
||||
std.debug.print("Found VPN service: {s}\n", .{service_name});
|
||||
}
|
||||
|
||||
//const interface = c.SCNetworkServiceGetInterface(service);
|
||||
|
||||
// Convert CFStringRef to C string (null-terminated)
|
||||
}
|
||||
|
||||
pub fn get_battery_info(allocator: std.mem.Allocator) ![]const u8 {
|
||||
const power_sources_info: c.CFTypeRef = c.IOPSCopyPowerSourcesInfo();
|
||||
|
||||
if (power_sources_info == null) {
|
||||
return error.NoPowerSourcesInfo;
|
||||
}
|
||||
|
||||
const power_sources_list = c.IOPSCopyPowerSourcesList(power_sources_info);
|
||||
|
||||
if (power_sources_list == null) {
|
||||
c.CFRelease(power_sources_info);
|
||||
|
||||
return error.NoPowerSourcesList;
|
||||
}
|
||||
|
||||
const power_source = c.IOPSGetPowerSourceDescription(power_sources_info, c.CFArrayGetValueAtIndex(power_sources_list, 0)) orelse null;
|
||||
|
||||
if (power_source == null) {
|
||||
return error.GotNoPowerSource;
|
||||
}
|
||||
const name: c.CFStringRef = @ptrCast(c.CFDictionaryGetValue(power_source, CFStringCreateWithCStringZig(c.kIOPSNameKey)));
|
||||
const power_type: c.CFStringRef = @ptrCast(c.CFDictionaryGetValue(power_source, CFStringCreateWithCStringZig(c.kIOPSTypeKey)));
|
||||
const capacity: c.CFNumberRef = @ptrCast(c.CFDictionaryGetValue(power_source, CFStringCreateWithCStringZig(c.kIOPSCurrentCapacityKey)));
|
||||
const max_capacity: c.CFNumberRef = @ptrCast(c.CFDictionaryGetValue(power_source, CFStringCreateWithCStringZig(c.kIOPSMaxCapacityKey)));
|
||||
const source_state: c.CFStringRef = @ptrCast(c.CFDictionaryGetValue(power_source, CFStringCreateWithCStringZig(c.kIOPSPowerSourceStateKey)));
|
||||
const time_to_empty: c.CFNumberRef = @ptrCast(c.CFDictionaryGetValue(power_source, CFStringCreateWithCStringZig(c.kIOPSTimeToEmptyKey)));
|
||||
|
||||
var name_buffer: [256]u8 = undefined;
|
||||
var power_type_buffer: [256]u8 = undefined;
|
||||
var power_source_state_buffer: [256]u8 = undefined;
|
||||
var maxCapacity: c.u_int32_t = 0;
|
||||
var currentCapacity: c.u_int32_t = 0;
|
||||
var time_to_empty_mins: c.u_int32_t = 0;
|
||||
_ = c.CFNumberGetValue(capacity, c.kCFNumberIntType, ¤tCapacity);
|
||||
_ = c.CFNumberGetValue(max_capacity, c.kCFNumberIntType, &maxCapacity);
|
||||
_ = c.CFNumberGetValue(time_to_empty, c.kCFNumberIntType, &time_to_empty_mins);
|
||||
|
||||
_ = c.CFStringGetCString(name, &name_buffer[0], 256, c.kCFStringEncodingUTF8);
|
||||
|
||||
_ = c.CFStringGetCString(power_type, &power_type_buffer[0], 256, c.kCFStringEncodingUTF8);
|
||||
|
||||
_ = c.CFStringGetCString(source_state, &power_source_state_buffer[0], 256, c.kCFStringEncodingUTF8);
|
||||
const power_source_state = std.mem.sliceTo(power_source_state_buffer[0..], 0);
|
||||
|
||||
const percent = (currentCapacity * 100) / maxCapacity;
|
||||
const hours = time_to_empty_mins / 60;
|
||||
const minutes = time_to_empty_mins % 60;
|
||||
|
||||
if (std.mem.eql(u8, power_source_state, "Battery Power")) {
|
||||
if (time_to_empty_mins < 0) {
|
||||
return try std.fmt.allocPrint(allocator, ": {d}%, ?m left\n", .{ percent, hours, minutes });
|
||||
} else {
|
||||
return try std.fmt.allocPrint(allocator, ": {d}%, {d}h:{d}m left\n", .{ percent, hours, minutes });
|
||||
}
|
||||
} else {
|
||||
return try std.fmt.allocPrint(allocator, ": {d}%, {s}\n", .{ percent, "charging" });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn macos_cpu_info(allocator: std.mem.Allocator) ![]const u8 {
|
||||
var cpu_brand: [128]u8 = undefined;
|
||||
var cpu_brand_size: usize = cpu_brand.len;
|
||||
|
|
114
src/main.zig
114
src/main.zig
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const vaxis = @import("vaxis");
|
||||
const root = @import("root.zig");
|
||||
const macos = @import("macos.zig");
|
||||
|
@ -6,6 +7,9 @@ const sys = @import("sys.zig");
|
|||
|
||||
const log = std.log.scoped(.main);
|
||||
|
||||
const apple_logo = @embedFile("assets/apple-white.png");
|
||||
const freebsd = @embedFile("assets/freebsd.png");
|
||||
|
||||
const Event = union(enum) {
|
||||
key_press: vaxis.Key,
|
||||
winsize: vaxis.Winsize,
|
||||
|
@ -32,8 +36,13 @@ pub fn main() !void {
|
|||
vx.caps.unicode = .unicode;
|
||||
vx.caps.kitty_graphics = true;
|
||||
|
||||
const os = try macos.macos_version(allocator);
|
||||
defer allocator.free(os);
|
||||
const battery = try macos.get_battery_info(allocator);
|
||||
defer allocator.free(battery);
|
||||
// _ = try macos.get_vpn_info();
|
||||
|
||||
// const os = try macos.macos_version(allocator);
|
||||
const os = try sys.get_os_version(allocator);
|
||||
defer allocator.free(os.text);
|
||||
const kernel = try macos.macos_kernel_version(allocator);
|
||||
defer allocator.free(kernel);
|
||||
const uptime = try macos.macos_uptime(allocator);
|
||||
|
@ -42,36 +51,43 @@ pub fn main() !void {
|
|||
defer allocator.free(cpu);
|
||||
const current_shell = try sys.get_shell(allocator);
|
||||
defer allocator.free(current_shell);
|
||||
const memory = try macos.memory_info(allocator);
|
||||
defer allocator.free(memory);
|
||||
|
||||
var term_buf: [64]u8 = undefined;
|
||||
const current_terminal = try sys.get_terminal(&term_buf);
|
||||
|
||||
// try tty.anyWriter().writeAll("\x1bc");
|
||||
// try tty.anyWriter().writeAll("\x1b[1;1H");
|
||||
try tty.anyWriter().writeAll(vaxis.ctlseqs.unicode_set);
|
||||
defer vx.queryTerminalSend(tty.anyWriter()) catch {};
|
||||
defer tty.anyWriter().writeAll(vaxis.ctlseqs.unicode_reset) catch {};
|
||||
|
||||
var buf_writer = tty.bufferedWriter();
|
||||
const writer = buf_writer.writer().any();
|
||||
// try writer.writeAll(vaxis.ctlseqs.unicode_set);
|
||||
// defer vx.queryTerminalSend(writer) catch {};
|
||||
// defer writer.writeAll(vaxis.ctlseqs.unicode_reset) catch {};
|
||||
// defer tty.deinit();
|
||||
const winsize: vaxis.Winsize = try vaxis.Tty.getWinsize(tty.fd);
|
||||
try vx.resize(allocator, tty.anyWriter(), winsize);
|
||||
try vx.resize(allocator, writer, winsize);
|
||||
|
||||
const win = vx.window();
|
||||
win.clear();
|
||||
// win.hideCursor();
|
||||
|
||||
var logo: []const u8 = "/Users/kc/Sync/Images/apple-dark.png";
|
||||
if (try is_dark_mode(allocator)) {
|
||||
logo = "/Users/kc/Sync/Images/apple-white.png";
|
||||
var image: vaxis.Image = undefined;
|
||||
switch (builtin.os.tag) {
|
||||
.macos => {
|
||||
image = try vx.loadImage(allocator, tty.anyWriter(), .{ .mem = apple_logo });
|
||||
},
|
||||
.freebsd => {
|
||||
image = try vx.loadImage(allocator, writer, .{ .mem = freebsd });
|
||||
},
|
||||
else => @compileError("unsupported os"),
|
||||
}
|
||||
|
||||
const koko = try vx.loadImage(allocator, writer, .{ .path = logo });
|
||||
|
||||
const dims = try koko.cellSize(win);
|
||||
const dims = try image.cellSize(win);
|
||||
|
||||
// const cursor_row = vx.state.cursor.row;
|
||||
const logo_win = win.child(.{
|
||||
.y_off = 0,
|
||||
.y_off = 2,
|
||||
.x_off = 0,
|
||||
.width = .{
|
||||
.limit = dims.cols + 1,
|
||||
|
@ -79,15 +95,8 @@ pub fn main() !void {
|
|||
.height = .{
|
||||
.limit = dims.rows + 1,
|
||||
},
|
||||
// .border = .{
|
||||
// .where = .right,
|
||||
// .glyphs = .single_rounded,
|
||||
// .style = .{
|
||||
// .fg = .{ .index = 15 },
|
||||
// },
|
||||
// },
|
||||
});
|
||||
// const logo_text_win = win.child(.{ .y_off = dims.rows });
|
||||
|
||||
var user_buf: [64]u8 = undefined;
|
||||
const user = try sys.get_user(&user_buf);
|
||||
var hostname_buf: [std.posix.HOST_NAME_MAX]u8 = undefined;
|
||||
|
@ -96,7 +105,7 @@ pub fn main() !void {
|
|||
// const logo_win = win.child(.{ .y_off = 0, .x_off = 0 });
|
||||
const border_locations = vaxis.Window.BorderOptions.Locations{
|
||||
.top = true,
|
||||
.bottom = true,
|
||||
.bottom = false,
|
||||
};
|
||||
|
||||
const whoami_win = win.child(.{
|
||||
|
@ -106,7 +115,7 @@ pub fn main() !void {
|
|||
.y_off = 1,
|
||||
.x_off = dims.cols + 1,
|
||||
.width = .{ .limit = 40 },
|
||||
.height = .{ .limit = 10 },
|
||||
.height = .{ .limit = 16 },
|
||||
.border = .{
|
||||
.where = .{
|
||||
.other = border_locations,
|
||||
|
@ -118,32 +127,23 @@ pub fn main() !void {
|
|||
},
|
||||
});
|
||||
|
||||
// logo_win.clear();
|
||||
// info_win.clear();
|
||||
|
||||
var result: vaxis.Window.PrintResult = .{ .col = 0, .row = 0, .overflow = false };
|
||||
// try tty.anyWriter().writeAll(vaxis.ctlseqs.kitty_graphics_query);
|
||||
// var img1 = try vaxis.zigimg.Image.fromFilePath(allocator, "/Users/kc/Sync/Images/apple-white.png");
|
||||
// defer img1.deinit();
|
||||
// const koko = try vx.transmitImage(allocator, tty.anyWriter(), &img1, .png);
|
||||
// win.hideCursor();
|
||||
// win.showCursor(10, 1);
|
||||
|
||||
const whoami_info = [_]vaxis.Cell.Segment{
|
||||
.{ .text = user, .style = .{
|
||||
.fg = .{
|
||||
.index = 3,
|
||||
.index = 7,
|
||||
},
|
||||
} },
|
||||
.{ .text = "@", .style = .{
|
||||
.fg = .{
|
||||
.index = 7,
|
||||
.index = 15,
|
||||
},
|
||||
.bold = true,
|
||||
} },
|
||||
.{ .text = hostname, .style = .{
|
||||
.fg = .{
|
||||
.index = 5,
|
||||
.index = 7,
|
||||
},
|
||||
} },
|
||||
};
|
||||
|
@ -157,7 +157,7 @@ pub fn main() !void {
|
|||
.bold = true,
|
||||
},
|
||||
},
|
||||
.{ .text = os },
|
||||
os,
|
||||
.{
|
||||
.text = " Kernel",
|
||||
.style = .{
|
||||
|
@ -188,6 +188,16 @@ pub fn main() !void {
|
|||
},
|
||||
},
|
||||
.{ .text = cpu },
|
||||
.{
|
||||
.text = " Memory",
|
||||
.style = .{
|
||||
.fg = .{
|
||||
.index = 7,
|
||||
},
|
||||
.bold = true,
|
||||
},
|
||||
},
|
||||
.{ .text = memory },
|
||||
.{
|
||||
.text = " Shell",
|
||||
.style = .{
|
||||
|
@ -208,6 +218,23 @@ pub fn main() !void {
|
|||
},
|
||||
},
|
||||
.{ .text = current_terminal },
|
||||
.{
|
||||
.text = " Battery",
|
||||
.style = .{
|
||||
.fg = .{
|
||||
.index = 7,
|
||||
},
|
||||
.bold = true,
|
||||
},
|
||||
},
|
||||
.{
|
||||
.text = battery,
|
||||
// .style = .{
|
||||
// .fg = .{
|
||||
// .index = 2,
|
||||
// },
|
||||
// },
|
||||
},
|
||||
.{
|
||||
.text = " ▂▂▂",
|
||||
.style = .{
|
||||
|
@ -329,20 +356,23 @@ pub fn main() !void {
|
|||
},
|
||||
},
|
||||
.{
|
||||
.text = " ▂▂▂",
|
||||
.text = " ▂▂▂\n\n\n",
|
||||
.style = .{
|
||||
.fg = .{
|
||||
.index = 15,
|
||||
},
|
||||
},
|
||||
},
|
||||
.{
|
||||
.text = " ",
|
||||
},
|
||||
};
|
||||
// const logo_text = [_]vaxis.Cell.Segment{
|
||||
// .{
|
||||
// .text = " hello",
|
||||
// },
|
||||
// };
|
||||
try koko.draw(logo_win, .{});
|
||||
try image.draw(logo_win, .{});
|
||||
// _ = try logo_text_win.print(&logo_text, .{});
|
||||
// try root.kitty_image_inline_copy(allocator, tty.anyWriter(), "/Users/kc/Sync/Images/apple-dark.png");
|
||||
|
||||
|
@ -353,7 +383,7 @@ pub fn main() !void {
|
|||
// try tty.anyWriter().print("\x1b[{d}A\x1b[9999999D", .{winsize.rows});
|
||||
// try tty.anyWriter().writeAll("\x1b[1J");
|
||||
|
||||
try vx.prettyPrint(writer);
|
||||
// try logo_win.print();
|
||||
// const dimensions = try koko.cellSize(win);
|
||||
|
||||
// const image = try vx.transmitLocalImagePath(allocator, tty.anyWriter(), "/Users/kc/Sync/Images/apple-white.png", dimensions.rows, dimensions.cols, .file, .png);
|
||||
|
@ -362,8 +392,9 @@ pub fn main() !void {
|
|||
// try image.draw(win, .{});
|
||||
|
||||
// try vx.render(tty.anyWriter());
|
||||
// win.clear();
|
||||
try vx.prettyPrint(tty.anyWriter());
|
||||
try buf_writer.flush();
|
||||
|
||||
// try vx.queryTerminalSend(tty.anyWriter());
|
||||
|
||||
// Clear from cursor to beginning of the screen
|
||||
|
@ -381,7 +412,6 @@ pub fn main() !void {
|
|||
// // vaxis.Image.DrawOptions{ .clip_region = .{ .x = 0, .y = 0 } },
|
||||
// };
|
||||
|
||||
// win.hideCursor();
|
||||
// const dims = try image[0].cellSize(win);
|
||||
|
||||
// try vx.render(writer);
|
||||
|
|
43
src/sys.zig
43
src/sys.zig
|
@ -1,4 +1,20 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const vaxis = @import("vaxis");
|
||||
|
||||
const macos = @import("macos.zig");
|
||||
|
||||
const OSVersion = struct {
|
||||
name: []const u8,
|
||||
major: []u64,
|
||||
minor: []u64,
|
||||
patch: []u64,
|
||||
};
|
||||
|
||||
const Shell = struct {
|
||||
name: []const u8,
|
||||
version: []const u8,
|
||||
};
|
||||
|
||||
pub fn get_shell(allocator: std.mem.Allocator) ![]const u8 {
|
||||
const shell_env = std.posix.getenv("SHELL") orelse "Unknown";
|
||||
|
@ -14,7 +30,7 @@ pub fn get_shell(allocator: std.mem.Allocator) ![]const u8 {
|
|||
} else if (std.mem.eql(u8, filename, "bash")) {
|
||||
const bash_version = try get_bash_version(allocator, &buf, shell_env);
|
||||
|
||||
return try std.fmt.allocPrint(allocator, ": {s}\n", .{bash_version});
|
||||
return try std.fmt.allocPrint(allocator, ": bash {s}\n", .{bash_version});
|
||||
} else if (std.mem.eql(u8, filename, "bash")) {
|
||||
const version = try std.process.Child.run(
|
||||
.{
|
||||
|
@ -27,23 +43,28 @@ pub fn get_shell(allocator: std.mem.Allocator) ![]const u8 {
|
|||
|
||||
return try std.fmt.allocPrint(allocator, ": {s}\n", .{version.stdout});
|
||||
}
|
||||
// const version = try std.process.Child.run(.{
|
||||
// .allocator = allocator,
|
||||
// .argv = &.{ shell_env, &version_flag },
|
||||
// });
|
||||
// defer allocator.free(version.stdout);
|
||||
// defer allocator.free(version.stderr);
|
||||
|
||||
// if (std.mem.eql(u8, "zsh", shell)) {
|
||||
// std.debug.print("shell: {s}\n", .{shell});
|
||||
// }
|
||||
|
||||
return try std.fmt.allocPrint(allocator, ": {s}\n", .{shell_env});
|
||||
}
|
||||
|
||||
pub fn get_os_version(allocator: std.mem.Allocator) !vaxis.Cell.Segment {
|
||||
switch (builtin.os.tag) {
|
||||
.macos => {
|
||||
return .{
|
||||
.text = try macos.macos_version(allocator),
|
||||
};
|
||||
},
|
||||
else => return .{ .text = "" },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_terminal(buf: []u8) ![]const u8 {
|
||||
const term_program = std.posix.getenv("TERM_PROGRAM") orelse "Unknown";
|
||||
|
||||
if (std.mem.eql(u8, term_program, "ghostty")) {
|
||||
return try std.fmt.bufPrint(buf, ": {s} \n", .{term_program});
|
||||
}
|
||||
|
||||
return try std.fmt.bufPrint(buf, ": {s}\n", .{term_program});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue